在先前的文章有稍微介紹過常見的 DevOps Tools,而本篇文章筆者會分享幫 free5GC 開源專案加入 CI pipeline 的實作!
free5GC 專案中的每個 Network Function 都是獨立的專案,最後再由主專案連接這些子專案,透過修改 submodule 的 commit hash 做新版本的釋出。
因為有子專案的特性,對外部貢獻者提交的 Pull Request 進行審查時其實會遇到一個問題:
也因為這樣,雖然我們也有要將每一次的釋出的快速的交付的客人手上,但有任何新功能加入時都要耗費不少的功伕。
為了解決這個問題,我們就來看看如何用市面上的 CI 工具做出一個可用的解決方案吧!
已知的 CI/CD Tools 大概有:Circle CI、Jenkins、Drone CI、GitLab CI 以及 GitHub Actions,我想,每有哪一個 solution 一定是最好的,只有最合適當的!
而我們的需求有:
原先我們是考慮以自建 Drone CI 去整合目前的專案,但偶然我看到了兩個很有趣的東西:
前者幫我解決了 Linux kernel module 沒辦法 inject 到 GitHub-hosted runner 的問題,而後者可以讓我在本地開發與測試 workflow,這樣可以提高 CI pipeline 的開發效率。
Run your GitHub Actions locally! Why would you want to do this? Two reasons:
- Fast Feedback - Rather than having to commit/push every time you want to test out the changes you are making to your .github/workflows/ files (or for any changes to embedded GitHub actions), you can use act to run the actions locally. The environment variables and filesystem are all configured to match what GitHub provides.
- Local Task Runner - I love make. However, I also hate repeating myself. With act, you can use the GitHub Actions defined in your .github/workflows/ to replace your Makefile!
上面這段描述取自 Act 專案的 README,如果沒有一個這樣的工具,要把基本的功能測試加入 CI pipeline 其實需要反覆的測試,而且加上我們有安裝 Linux kernel module 的需要,能夠在本地先驗證 workflow 毫無疑問是最有效的開發方式。
Act 的使用方式其實相當簡單:
1. 在專案的 .github/workflows
下放置寫好的 CI 腳本(副檔名為 .yml
)
2. 如果你的測試教本有監聽 push event,只要輸入 act
就會觸發 workflow 了:
$ act
當然,如果你的測試腳本會在收到 pull request event 時觸發,可以使用 $ act pull_request
。
GitHub Actions 的腳本是以 job 的概念執行的,每個 job 可以執行多個動作,GitHub 上也有很多開發者提供寫好的腳本讓大家參考:
name: Functionality Test
# trigger workflow in local: sudo act --privileged --container-cap-add CAP_SYS_ADMIN --container-cap-add NET_ADMIN pull_request
on:
branches:
- main
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.17
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.7.0
with:
mongodb-version: 4.4
- name: Install dependencies
run: |
sudo apt -y update
apt -y install netcat psmisc iproute2 git gcc g++ cmake autoconf libtool pkg-config libmnl-dev libyaml-dev
go get -u github.com/sirupsen/logrus
- name: Build
run: make
- name: Basic Test
run: |
./test_ci.sh TestRegistration
sleep 1
./test_ci.sh TestGUTIRegistration
sleep 1
./test_ci.sh TestServiceRequest
sleep 1
./test_ci.sh TestXnHandover
sleep 1
./test_ci.sh TestDeregistration
sleep 1
./test_ci.sh TestPDUSessionReleaseRequest
sleep 1
./test_ci.sh TestPaging
sleep 1
./test_ci.sh TestN2Handover
sleep 1
./test_ci.sh TestReSynchronization
上面的腳本可以分成兩塊,第一部分描述腳本在什麼狀況下會被觸發,第二部分則是描述了有哪些 job 要被執行。
on:
branches:
- main
pull_request:
main
分支的 push eventjobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.17
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.7.0
with:
mongodb-version: 4.4
- name: Install dependencies
run: |
sudo apt -y update
apt -y install netcat psmisc iproute2 git gcc g++ cmake autoconf libtool pkg-config libmnl-dev libyaml-dev
go get -u github.com/sirupsen/logrus
- name: Build
run: make
- name: Basic Test
run: |
./test_ci.sh TestRegistration
sleep 1
./test_ci.sh TestGUTIRegistration
sleep 1
./test_ci.sh TestServiceRequest
sleep 1
./test_ci.sh TestXnHandover
sleep 1
./test_ci.sh TestDeregistration
sleep 1
./test_ci.sh TestPDUSessionReleaseRequest
sleep 1
./test_ci.sh TestPaging
sleep 1
./test_ci.sh TestN2Handover
sleep 1
./test_ci.sh TestReSynchronization
make
編譯所有的 Network Function,再去執行 free5GC 提供的測試腳本就大功告成啦!補充:
- 這個腳本在本地測試之前,必須確保主機已經安裝了 gtp5g。
- 實際放上 GitHub 上面使用時,需要將 runner 的環境從
ubuntu-latest
替換成我們自架的 Self-hosted runner。
這部分可以參考官方提供的文件,其實 GitHub 已將把這一塊弄的非常完善,要在公有雲或是私有雲上建立一個 runner 不會花費超過 10 分鐘的時間。
本文使用 Act 快速的撰寫了一個 free5GC 能用的 CI workflow,之後有任何的 pull request,我們只要請提交者更新 submodule hash 並且提交一份 PR 到 free5GC main repository,GitHub Actions 就可以幫我們驗證基本的功能性是否正確囉!
但這份腳本其實也還有一些缺點,像是 Non3gpp 的測試項目受限於 container 與 sandbox 的環境無法正常運作。此外,對於商業使用上,我們可能還需要在新版本釋出時自動的將通過測試的程式部署到客戶端。
這邊我們可以參考 Erricson 的實作方法:
簡單來說,Erricson 使用的 solution 多了部署與部署後的測試,新版本 release 會先經過 Acceptance tests,確認沒問題以後,可以使用任何你想得到的方式部署新版本的軟體到客戶端(之前提到的 Infrastructure as Code、Event Notify、GitOps 等方法),部署完成後再對客戶端的核心網路執行 Acceptance test,確保這次的軟體交付是沒有問題的。
目前這份 CI workflow 已經整合到 free5GC 專案內,有興趣的朋友可以參考: