GitHub Actions 成本優化:讓你的團隊更具競爭力
大家好,我是張晉濤。
本週 Docker 就發佈 10 週年了,爲了慶祝這個里程碑,我將會發布一系列文章,涉及 Docker,CI/CD, 容器等各個方面。
這篇文章我將介紹如何降低 GitHub Actions 上的消費,以及一些建議
根據 G2 的統計報告, GitHub Actions 是最易用的 CI/CD 工具,越來越多的人都喜歡它。
由於 GitHub Actions 是 GitHub 原生的 CI/CD 工具,在 marketplace 有上萬個 Actions 可直接使用,且對於公共倉庫是免費的,所以越來越多的項目也將其使用的 CI 工具切換成了 GitHub Actions。
我也很喜歡 GitHub Actions,並且幾乎在我所有託管在 GitHub 上的倉庫中使用它。
但是最近我在一個項目中,觸發了 GitHub Actions 配額的限制。這讓我花費了一些時間去關注它的費用。
爲什麼會耗盡配額
最近我發現了一個有趣的項目: upptime/upptime: ⬆️ Free uptime monitor and status page powered by GitHub
我想要嘗試用它將自己的開發的一些服務監控起來,做一個 status page,但這會涉及到一些 API 的配置,我並不想將它公開,所以我將該倉庫 fork 到了一個私有倉庫中。 經過簡單的配置後,它就正常工作了。
由於我想要得到更多數據,所以我調整了其中中 CI 調度配置。讓這些任務執行的更加頻繁。
workflowSchedule:
graphs: "0 * * * *"
responseTime: "0 * * * *"
staticSite: "0 * * * *"
summary: "0 * * * *"
updateTemplate: "0 * * * *"
updates: "0 * * * *"
uptime: "*/5 * * * *"
根據 GitHub Actions 的費用文檔,GitHub Actions 對於公開倉庫是免費的,但是對私有倉庫是有配額限制的。
GitHub Actions usage is free for standard GitHub-hosted runners in public repositories, and for Self-hosted runners. For private repositories, each GitHub account receives a certain amount of free minutes and storage for use with GitHub-hosted runners, depending on the product used with the account. Any usage beyond the included amounts is controlled by spending limits.
很快我就收到了 GitHub 的額度提醒郵件,提醒我配額即將用完。
這讓我開始思考如何解決它。
使用 GitHub Actions 的成本
將倉庫設置爲公開顯然是最簡單的辦法,但我在上文中說明了不能設置成公開倉庫的原因。只能去找其他的解決辦法。
顯然爲 GitHub Actions 付費也是一個很直接的解決辦法。
在決定爲它付費之前,我想要預估一下成本。 GitHub 提供了一個 Pricing Calculator,可以方便的預估花費。
由於我修改了 CI 的調度配置,最頻繁運行的任務每 5 分鐘會運行一次。
我使用 Meercode 採集了這個倉庫中 GitHub Actions 的運行數據,它默認提供了一些 dashboard,比較方便:
同時也允許用戶自己進行自定義,我創建了自己的 dashboard,如果你對 Meercode 感興趣,請在評論中告訴我。
從上面的圖中可以看到,每次任務耗時不超過 0.5min,每小時會有不超過 12 個任務。使用價格計算器進行計算,大概 每月花費是 $35
,每年 $420
。
節約成本的辦法
由於我的這個倉庫中是運行 uptime 的 CI,它消耗的資源很少,但是任務比較頻繁,所以我想知道如果我使用 Self-hosted runner 是否可以節約成本。
我對比了幾家雲服務提供商的價格(規避廣告嫌疑,這裏就不列了)
其中 1C1G 的實例最低是 $5/month
。
我選擇了其中一家最低規格的實例,並且有 1TB 流量。
我分別嘗試了使用它的 Kubernetes 服務,和 compute instance ,它們都可以工作的很好。
使用 compute instance
在 Linux compute instance 中部署 GitHub Actions runner 簡單,只需要在項目 https://github.com/<Your name>/<Project name>/settings/actions/runners/new
添加即可。
在該頁面有完整的部署步驟,按步驟執行即可。
我的執行過程如下:
moelove@polished-bush-99d8-1926a1:~$ mkdir actions-runner && cd actions-runner
moelove@polished-bush-99d8-1926a1:~/actions-runner$ curl -o actions-runner-linux-x64-2.301.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.301.1/actions-runner-linux-x64-2.301.1.tar.gz
moelove@polished-bush-99d8-1926a1:~/actions-runner$ echo "3ee9c3b83de642f919912e0594ee2601835518827da785d034c1163f8efdf907 actions-runner-linux-x64-2.301.1.tar.gz" | shasum -a 256 -c
actions-runner-linux-x64-2.301.1.tar.gz: OK
moelove@polished-bush-99d8-1926a1:~/actions-runner$ tar xzf ./actions-runner-linux-x64-2.301.1.tar.gz
moelove@polished-bush-99d8-1926a1:~/actions-runner$ ./config.sh --url https://github.com/MoeLove/monitoring --token $TOKEN
--------------------------------------------------------------------------------
| ____ _ _ _ _ _ _ _ _ |
| / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ |
| | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| |
| | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ |
| \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ |
| |
| Self-hosted runner registration |
| |
--------------------------------------------------------------------------------
執行完成後,會在當前目錄下增加一些文件。執行 ./env.sh
即可啓動 GitHub Actions runner 。
moelove@polished-bush-99d8-1926a1:~/actions-runner$ ls
_diag _work actions-runner-linux-x64-2.301.1.tar.gz bin config.sh env.sh externals run-helper.cmd.template run-helper.sh run-helper.sh.template run.sh safe_sleep.sh svc.sh
如果想要穩定的在後臺運行,可以執行 ./svc.sh install
將 runner 安裝爲 systemd 的 service,通過 systemd 管理它的生命週期。
使用 Kubernetes
我選擇的這個服務對於 Kubernetes 的 control plane 不收費,僅對 Worker Node 收費,使用 Kubernetes 的好處在於我可以在該集羣中進行自動擴縮容,並且可以輕鬆的運行創建多個 runner 給不同的項目使用。
由於 GitHub 官方尚未真正提供在 Kubernetes 上部署 Self-hosted runner, 我使用了 Actions Runner Controller (ARC) 項目, 該項目允許通過 Runner
自定義資源,快速的部署 Self-hosted runner。
部署過程在文檔 https://github.com/actions/actions-runner-controller/blob/master/docs/quickstart.md 中已經描述的很清楚了,以下是我的部署過程。
# deploy cert-manager
(MoeLove) ➜ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
# deploy ARC
(MoeLove) ➜ helm repo add actions-runner-controller https://actions-runner-controller.github.io/actions-runner-controller
(MoeLove) ➜ helm upgrade --install --namespace actions-runner-system --create-namespace\
--set=authSecret.create=true\
--set=authSecret.github_token="REPLACE_YOUR_TOKEN_HERE"\
--wait actions-runner-controller actions-runner-controller/actions-runner-controller
# create runner
(MoeLove) ➜ cat <<EOF | kubectl apply -f -
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
name: moelove-runner
spec:
replicas: 1
template:
spec:
repository: MoeLove/monitoring
EOF
安裝後達成了如下效果:
Self-hosted vs GitHub-managed
上面的內容我介紹了我是如何使用 Meercode 度量 CI 的關鍵指標,以及估算 GitHub Actions 成本的。 根據我實際的低資源消耗,高耗時的場景,我選擇了 Self-hosted 的模式。
那麼什麼時候選擇 GitHub-managed runner 更合適呢?GitHub-managed 有什麼優勢呢?
GitHub-managed runner 有如下優勢:
-
支持多種操作系統:GitHub-managed runner 除了提供 Linux 系統外,還支持 macOS 和 Windows ,但是大多數雲供應商是不提供 macOS 環境的。(我曾經爲了特定場景將一些 Mac mini 作爲服務器放在了機房中)
-
VM 級別的隔離性:根據 GitHub Actions 的文檔,GitHub Actions 的 runner 在執行 job 的時候,是通過創建 VM 來運行所有任務的,這帶來了一定的安全性和隔離性的保證。如果是 Self-hosted runner,當通過二進制運行的時候,任務將共享主機環境,如果是通過 ARC 運行,則是通過 Pod 帶來隔離。這都會產生一定的安全問題。Alex 創建了 actuated https://actuated.dev/ 通過使用 MicroVMs 技術,帶來輕量且安全的解決方案; cirun.io 是通過直接使用 cloud provider 創建實例。
-
低維護成本:事實上在任何大型系統中,維護成本都是非常昂貴的。如果只是個人使用,或者僅僅有幾個項目在使用 Self-hosted runner 時,維護成本相對可控。一旦規模變大,將會帶來很多複雜性。顯然 GitHub-managed runner 是由 GitHub 進行維護的。
此外,還有兩個做 Self-hosted runner 服務的產品:
-
Actuated
-
cirun
它們降低了 runner 的維護和管理成本,提供了更安全的隔離性,以及基於 Arm 環境的支持。cirun 還提供了 GPU runner 的支持。
如果有上述的需求,也可以考慮這些服務。
總結
總的來說,想要節約 GitHub Actions 的成本,需要如下步驟
-
可視化 / 可觀測性:通過實際數據來預估成本;
-
比較多個廠商 / 解決方案:不同的廠商在不同的場景或者產品中提供了不同的定價,可以根據自己的實際情況進行選擇;
-
安全性和維護成本也需要考慮在內;
歡迎訂閱我的文章公衆號【MoeLove】
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/f0RqbknZ7SMdKx0C8SIeQg