技術深度解析:Kubernetes 上的 GitLab Runners、Operator 安裝、Helm 引數、自動擴縮容及 FinOps 成本模型。如需簡版,請閱讀停止為閒置 CI 付費。
大多數團隊為持續整合付費的方式,彷彿每個夜晚和週末仍是週一早晨。伺服器持續執行,磁碟空間持續佔用。沒有人正在合併程式碼——而賬單卻毫無察覺。這句話不是口號;它是固定 Runner 叢集的預設形態。
本文是GitLab Server 和 Kubernetes 上的 GitLab Runner實操指南的技術配套:Kubernetes 執行器如何將每個 CI 任務轉換為臨時 Pod,如何實現容量的動態配置與釋放,以及該設計如何釋放巨大的成本節約,在夜間和週末需求驟降時回收 CPU、記憶體和儲存空間。
先觀看兩場演示,再以本文件作為書面架構與成本模型參考。
1. Runners 與流水線— 基於 Kubernetes 的 GitLab Runner 工作負載自動擴縮容。
觀看:完整的 GitLab Runners 與 CI/CD 在 Kubernetes 上的部署· 通俗版本:停止為閒置 CI 付費
2. HA 叢集上的 GitLab Server Kubernetes— 幾分鐘內透過 Operator 部署 GitLab。
觀看:使用 Operator 在 HA Kubernetes 叢集中部署 GitLab· 文件:GitLab Operator 安裝
1. 論點
GitLab on Kubernetes + Kubernetes executor將 CI 容量的單位從“我們整個月擁有的機器”轉變為“為任務租用的 pods(和節點)”。Runner 管理器保持精簡且始終線上。任務 pod 在構建時出現,構建後消失。藉助叢集自動伸縮,工作節點遵循相同的曲線。這就是如何保護週一早間的吞吐量,並避免在週二凌晨 03:00 和安靜的週六支付週一早間的價格。
用一句話概括——與入門指南相同的一句話:為峰值配置資源,為低谷釋放資源。
2. 昂貴的習慣,被表述為一種架構異味
傳統的 CI 通常看起來像一支永久艦隊:一組固定的構建機器,始終線上“以防萬一”。當流量穩定時,這種方式行得通;但當需求呈尖峰狀時,它只會浪費錢。
- 白天:開發人員推送分支、開啟合併請求、執行測試——需求激增。
- 傍晚和夜間:活動減少,但機器仍在消耗 CPU 和記憶體。
- 週末:通常接近空閒——但儲存卷和雲節點可能仍被預留並計費。
你支付的不是“已完成的構建”,而是無論是否有人使用都存在的容量。固定艦隊還會積累粘性狀態:“在 runner 3 上執行正常”、漂移的包、永遠不會過期的快取。彈性容器並不自行解決紀律問題,但它們讓“從零開始”成為預設選項。
3. 系統架構圖
| 層級 | 角色 | 典型部署位置 |
|---|---|---|
| GitLab 伺服器 | 原始碼管理、CI 協調、登錄檔、UI/API | 透過 GitLab Operator / Helm 圖表部署(例如 k3s 實驗室) |
| Runner 管理器 | 註冊代理,輪詢任務 | Helm 版本在專用名稱空間中執行(例如gitlab-runner) |
| 任務 Pod | 實際的構建/測試/打包步驟 | 由 Kubernetes 執行器為每個任務建立,隨後刪除 |
| 可選 DinD 服務 | Docker 在任務內部構建 | 位於任務旁邊的特權服務容器 |
| 叢集/節點自動伸縮器 | 在 Pod 壓力條件下新增/移除工作節點 | 雲 ASG、Cluster Autoscaler、Karpenter 或等效方案 |
普通指南中的類比在此層級仍然適用:GitLab Runner 是工人;Kubernetes 是排程器,僅在包裹(任務)到達時呼叫工人,然後將其遣返。
4. 在叢集中安裝 GitLab(操作者路徑)
Day 1 培訓路徑使用官方操作者安裝 GitLab,因此伺服器與執行器共享相同的 Kubernetes 基礎架構。配套影片使用操作者在 HA Kubernetes 叢集中部署 GitLab在幾分鐘內演示了該安裝過程。前置條件:叢集需具備 ingress、Helm、kubectl以及 cert-manager(當圖表管理 TLS 時)。
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm install gitlab-operator gitlab/gitlab-operator \
--create-namespace \
--namespace gitlab-system
kubectl -n gitlab-system get deployment gitlab-controller-manager
# Apply the GitLab custom resource (pin chart version in the manifest)
kubectl -n gitlab-system apply -f deploy_gitlab_server.yaml
示例 CR 結構(根據您的環境自定義域和頒發者郵箱):
apiVersion: apps.gitlab.com/v1beta1
kind: GitLab
metadata:
name: gitlab
spec:
chart:
version: "9.2.2"
values:
global:
hosts:
domain: "example.com"
ingress:
configureCertmanager: true
certmanager-issuer:
email: you@example.com
首次安裝通常需要 10–15 分鐘,在此期間 web 服務、Sidekiq、資料儲存及相關元件完成初始化。從叢集金鑰中獲取初始 root 密碼:
kubectl get secret gitlab-gitlab-initial-root-password -n gitlab-system \
-o jsonpath='{.data.password}' | base64 -d
參考:GitLab 操作者安裝(該頁面 Helm 標籤頁)。圖表概覽:docs.gitlab.com/charts· 安裝指南:charts 安裝。
5. 使用 Kubernetes 執行器的 GitLab 執行器
GitLab 執行器是與 GitLab CI/CD 協作以在流水線中執行任務的應用程式。使用Kubernetes 執行器時,管理器不會自行編譯。對於每個任務,它會:
- 建立一個 Pod(並根據配置新增輔助/服務容器)。
- 將日誌流式傳輸回 GitLab。
- 收集製品和退出狀態。
- 刪除 Pod——將 CPU 和 RAM 歸還給叢集。
建立/執行/刪除迴圈是第一個成本槓桿。已完成的工作不應在夜間佔用專用機器。
5.1 Helm 安裝模式
訓練指令碼建立名稱空間、傳遞註冊令牌,並可能安裝多個版本(例如基於 Alpine 和基於 Ubuntu 的 Runner),以便作業可以選擇不同的環境。官方流程:使用 Helm 圖表安裝 GitLab Runner;值參考:配置 GitLab Runner Helm 圖表。
helm upgrade --install --namespace gitlab-runner gitlab-runner-alpine \
-f config-runner-alpine.yaml \
--set serviceAccount.create=true \
gitlab/gitlab-runner \
--create-namespace
從 GitLab UI(例項/組/專案 Runner)或操作者管理的金鑰中獲取令牌。優先使用現代 Runner 認證令牌;註冊令牌正逐步棄用(面向 GitLab 18)。切勿提交活動令牌— 實驗室指令碼有時包含需要本地替換的佔位符。
5.2 影響規模與隔離的關鍵值
來自 Workstation 模板(gitlab-runner-values-template.yaml/ generatedconfig-runner-*.yaml):
| Setting | 為何重要 |
|---|---|
concurrent | 該管理器同時執行的最大任務數。白天高峰時調高(培訓筆記提到繁忙實驗室中為數十個,如 20–40)。在叢集限制前進行軟節流。 |
runners.privileged/ executorprivileged | 若無需 DinD,通常可收緊。 |
[runners.kubernetes].namespace | 任務 Pod 的部署位置——應與 GitLab 系統元件保持分離。 |
預設image/ 輔助映象 | 鎖定標籤以確保 alpine/ubuntu 池的可復現性。 |
[[runners.kubernetes.services]]DinD | Sidecardocker:dind用於映象構建;僅按需配置登錄檔映象/不安全登錄檔。 |
RBACclusterWideAccess | 僅當任務必須管理叢集級資源時使用;生產環境中優先遵循最小許可權原則。 |
| host aliases / DNS 配置 | 實驗室中叢集內 GitLab 和登錄檔主機名的便捷配置。 |
gitlabUrl: http://gitlab-webservice-default.gitlab-system.svc.cluster.local:8080/
concurrent: 2
rbac:
create: true
clusterWideAccess: true
runners:
privileged: true
config: |
[[runners]]
environment = ["GIT_SSL_NO_VERIFY=1"]
[runners.kubernetes]
namespace = "gitlab-runner"
image = "alpine/git:latest"
service_account = "gitlab-runner"
privileged = true
僅靠 CPU 無法實現併發,只會延長佇列。請將concurrent與真實的節點空閒容量或節點自動伸縮配合使用。
6. 兩級(實際上是四級)自動伸縮
"在 Kubernetes 上自動伸縮 GitLab Runner" 不是一個開關。疊加這些槓桿:
- 任務 Pod 彈性— 內建於 Kubernetes 執行器中。零任務 → 零任務 Pod。僅此一項即可消除共享叢集上大部分按任務產生的浪費。
- Runner
concurrent及多個 Runner 部署— 將 alpine 與 ubuntu(或 CPU 與更大規模的構建器)分開,避免專用容量因錯誤配比而閒置。 - 叢集/節點自動伸縮— 待處理 Pod 增加節點;空閒節點在晚間高峰過後自動釋放。
- 可選的日程感知策略— 在日曆上降低併發上限或按日程縮節點池,作為自然需求下降的額外保障。
超大規模場景的故事相同,但振幅更尖銳:佇列深入時向外擴充套件,隨後激進地釋放資源,確保一週中安靜的半天在賬單上不會與忙碌的半天相仿。
6.1 關於 GitLab Runner 語境下"空閒"的說明
某些執行器會保留少量空閒機器以保持溫熱,以便在無需冷啟動延遲的情況下吸收下一個任務。在 Kubernetes 上,冷啟動通常是建立 Pod(數秒),而非啟動虛擬機器(數分鐘)。更傾向於讓 Pod 歸零,並接受短暫的排程延遲,而不是保留一整夜的空閒節點"以防萬一"。如果必須維持一個最小基線,請根據值班現實來設定該基線的大小——而非週一的合併風暴。
6.2 動態配置與取消配置端到端流程
追蹤一個流水線任務:
- 開發者推送程式碼;GitLab 在待處理佇列中建立任務。
- Runner 管理器認領該任務並向 API 請求一個 Pod。
- 如果叢集中 CPU/記憶體不足,自動伸縮器會新增節點(配置)。
- Pod 執行指令碼、上傳製品,然後退出。
- Pod 被刪除,資源歸還到池中(任務級別的取消配置)。
- 當許多節點在超過縮放下限閾值後仍然空閒——通常在晚間和整個週末之後——節點會被移除(基礎設施級別的取消配置)。
這個完整迴圈就是影片中提到的超大規模 GitLab Runner 用於成本最佳化的含義:並非某個花哨的開關,而是任務生命週期與叢集彈性協同工作。
7. 成本模型:鉅額節省出現在哪裡
務必精確。自動伸縮並不能讓構建免費。它只是讓你不必在非高峰時段支付高峰費率。節省來自於將支出與實際需求相匹配——來自基礎指南的四個要點,針對運維人員進行了擴充套件。
7.1 僅在有人(或機器人)工作時進行擴容
當忙碌的早晨湧入數十個流水線時,Kubernetes 會並行排程多個任務 Pod,直至達到併發和叢集限制。當合並壓力真實存在時,吞吐量才會顯現。
7.2 需求消失時果斷縮減規模
任務完成後,Pod 隨之消失。藉助叢集自動擴縮容(或合理規模的節點池),未使用的雲節點會自動退出節點池。夜間和週末——通常是產品團隊最安靜的時段——正是你應該率先停止付費的容量。
7.3 停止浪費 CPU、RAM 和儲存
| 資源 | 常駐執行器 VM | Kubernetes 任務 Pod + 節點自動擴縮容 |
|---|---|---|
| CPU | 佇列空閒時預留核心處於閒置狀態 | Pod 退出時釋放;節點可自動縮容 |
| RAM | Agent 作業系統 + 空閒執行器全天候駐留 | 每次 Pod 刪除時記憶體隨之釋放 |
| 儲存 | 每臺 VM 上的熱資料盤和映象層 | 預設使用臨時性臨時儲存;共享快取變為顯式且可指定大小的選項 |
一個月下來,安靜時段佔據了大部分時間。回收夜間和週末的容量,正是節省成本產生複利效應的關鍵。
7.4 為成果付費,而非為傢俱付費
你仍需為 GitLab 和輕量級控制平面(執行器管理器 + 叢集基礎元件)付費。你所停止付費的,是一堆空椅子的倉庫。
7.5 直覺上的理解(並非人為製造的基準)
假設白天可持續需要相當於 20 個忙碌執行器槽位,而夜間和週末僅需 2 個。固定規模的艦隊按 20 個全天候計費。彈性池在白天支付約 20 個,在安靜時段支付約 2 個(加上控制平面)。對於許多產品團隊,安靜時段佔整個月的很大比例——因此回收這些時段是節省變得巨大的方式,而無需發明營銷百分比。財務部門將本地節點小時價格相乘;架構工作的任務是讓計費賬戶中的空閒時段真正變為空閒。
巨大的成本節省體現在:週一的峰值不再決定週二凌晨三點的賬單——以及週六的寂靜終於在發票上也顯得安靜了。
7.6 你仍然有意為之而支付的費用
- GitLab Server 元件——按使用者和 CI 協調規模配置,而非編譯農場。
- Runner 管理器部署——規模小於作業農場。
- 有意為之的快取(依賴代理、PVC 等)——有幫助,但已配置規模;快取並非免費儲存。
- 特權 DinD——方便但更重;當密度和隔離比熟悉度更重要時,請考慮 Kaniko/BuildKit。
8. CI/CD 實踐中的流水線
當 Runner 線上後,.gitlab-ci.yml定義階段和任務。GitLab 負責排程;Kubernetes 執行器將 Pod 例項化。保持流水線對成本的誠實:
- 在重型映象構建之前,儘早對 lint/單元測試失敗。
- 使用
rules和workflow,使草稿分支不會擴散出完整的矩陣。 - 優先使用具有清晰鍵的共享快取,而非無限制的每臺 VM 磁碟增長。
- 將任務標記到正確的 Runner 池(alpine 與 ubuntu、小型與大型構建器)。
stages: [lint, test, build]
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
lint:
stage: lint
image: alpine:3.19
script:
- echo "cheap checks first"
test:
stage: test
tags: [kubernetes, alpine]
script:
- echo "unit tests"
build:
stage: build
tags: [kubernetes, dind]
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- echo "heavy image build only on default branch"
經濟理念與平臺理念相同:不要在沒有廉價檢查就會失敗的情況下排程昂貴的工作,也不要為那些週六永遠不會到來的任務保持專用 Runner 處於溫暖狀態。
9. 安全與多租戶說明
臨時 Pod 改善了衛生狀況(更少的粘性狀態),但特權 DinD 和叢集範圍的 RBAC 可能擴大爆炸半徑。大多數團隊的實用預設值:
- 在專用名稱空間中執行任務 Pod,並設定 ResourceQuotas 和 LimitRanges。
- 儘可能優先使用非特權構建;透過特定標籤隔離 DinD Runner。
- 避免將長期有效的雲憑證掛載到每個任務中;為每條流水線注入短期令牌。
- 將 Runner 註冊令牌視為秘密——當人員離職或實驗室共享時進行輪換。
- 如果多個團隊共享一個叢集,請分離 Runner 管理器(以及可選的節點池),以便一個嘈雜的鄰居無法讓整個農場保持高溫——並保持成本故事可按團隊歸因。
10. 可觀測性證明節省效果
你不能聲稱夜間和週末有節省,而不進行檢視。至少跟蹤以下內容:
| 訊號 | 什麼是"良好"的狀態 |
|---|---|
| 按小時統計的 Job Pod 數量 | 工作日工作時段出現峰值;夜間和週末接近地板值 |
| 待處理 Pod | 僅在峰值時短暫出現尖峰;持續待處理意味著併發度/節點不足 |
| 節點 CPU / 節點數量 | 跟蹤 Pod 需求;空節點不應長時間滯留 |
| Runner 管理器 CPU/RAM | 相對於 Job Farm 保持平穩且較小 |
| 按每週小時計的雲賬單 | 切換後,安靜時段明顯更便宜 |
如果夜間 Pod 數量下降但節點賬單沒有下降,那麼需要調整的是縮容設定——而不是 GitLab。
11. 固定 VM 與 Kubernetes 執行器(決策表)
| 固定執行器 VM | Kubernetes 執行器 + 自動擴縮 | |
|---|---|---|
| 容量單位 | 整臺機器,始終分配 | 每任務一個 Pod(可選節點) |
| 週一高峰 | 排隊或超額購買 VM | 提高併發 + 擴充套件節點 |
| 夜間/週末 | VM 保持執行仍計費 | Pod 消失;節點可離開 |
| CPU / RAM / 儲存浪費 | 空閒時結構性浪費 | 預設回收 |
| 漂移/"在執行器 3 上有效" | 常見 | 減少(預設臨時) |
| 運維複雜度 | 初始較低 | 較高(需要叢集技能) |
僅在您確實擁有平穩的 24×7 需求或存在禁止使用叢集的限制時,才選擇固定 VM。所有其他人擁有尖峰式人工驅動流水線,都在支付"傢俱稅"。
12. 您並未放棄的內容
自動擴縮並不意味著"失去控制"。您仍然可以設定併發數、允許映象、DinD 許可權、網路策略和註冊範圍。關鍵在於在保留這些控制的同時,讓未使用的容量蒸發——與通俗語言文章中的保證相同,現在透過 RBAC、名稱空間和獨立的執行器釋出來強制執行。
13. 執行清單
- Pin 操作者/圖表版本;升級時需謹慎。
- 輪換 runner 令牌;在釋出前從任何指令碼中清除 lab 令牌。
- 隔離名稱空間:GitLab 系統與 runner 任務。
- 監控待處理的 pods——待處理數量上升意味著峰值時併發或節點容量不足。
- 監控空閒節點小時數——節點在夜間持續空閒意味著縮容延遲或池策略需要調整。
- 將特權 runner 限制為確實需要它們的任務。
- 獨立於 runner 彈性對 GitLab 進行備份。
- 彈性 CI 上線後,按每週小時審查賬單——夜間和週末的費用應明顯下降。
14. 適用物件
- 在 Kubernetes 上實施 GitLab CI 的平臺工程師和 SRE。
- 用 executor pods 替代常駐 runner VM 的 DevOps 負責人。
- 需要 CI 像按使用量計費的公用事業而非固定傢俱的工程與財務合作伙伴。
15. 官方 GitLab 文件
這些頁面是上述 Helm 部署和擴充套件行為的權威參考。版本變更時,請優先參考這些頁面而非部落格文章。
Kubernetes 上的 GitLab Server
- 安裝 GitLab Operator— 培訓演示中使用的 Operator + Helm 安裝路徑。
- GitLab Helm 圖表— 頂層圖表文件。
- 使用 Helm 圖表安裝 GitLab— 透過圖表而非 Operator 部署 GitLab 時。
- gitlab-runner 子圖表(GitLab 圖表)— 主圖表中與 GitLab 捆綁的 runner(區別於獨立的 runner 圖表)。
GitLab Runner Helm 圖表
- 使用 Helm 圖表安裝 GitLab Runner—
helm repo add gitlab,安裝/升級,OCI 圖表說明。 - 配置 GitLab Runner Helm 圖表—
concurrent,配置模板,RBAC,快取,映象選擇。 - gitlab-runner 圖表
values.yaml— 完整預設值(包括可選的 HPA 佔位符)。
Kubernetes 執行器和自動伸縮
- Kubernetes 執行器— 作業 Pod、輔助元件、服務(如 DinD)、資源請求、RBAC 動詞。
- 配置自動伸縮(Kubernetes 執行器/圖表)— 暫停 Pod、
[runners.kubernetes.autoscaler],週期策略(夜間/週末空閒)。 - 自動伸縮 GitLab Runner— 通用自動伸縮模型(也涵蓋分散式快取)。
- 規劃和管理工作隊— 工作隊級別的伸縮和運維。
- 高階配置(
config.toml)— 嵌入在 Helmrunners.config中的全域性concurrent和執行器部分。
GitLab 中的 CI 作業、構建和 Runner 設定
- 在 GitLab 中配置 Runner— 註冊、標籤、run-untagged、受保護的 Runner。
- 使用 Docker 在 CI 中構建映象— DinD 和替代方案(當
privileged/ Docker 服務在 Runner 配置中啟用時相關)。
為夜間和週末成本控制,結合:(1) Kubernetes 執行器作業 Pod 縮至零,(2) 圖表concurrent和自動伸縮器策略配合非高峰時段idle_count = 0,以及 (3) 叢集/節點自動伸縮使空閒節點離開池 — 如第 6–7 節所述。
16. 回到影片和倉庫
YouTube 課程 —約 20 分鐘完成 GitLab。使用 Kubernetes自動擴充套件 GitLab Runner 工作負載,展示了 Kubernetes 上的 GitLab、透過 Helm 的 Runner,以及超大規模成本方案:動態建立和銷燬基礎設施,讓您無需為空閒的夜晚和週末支付峰值費用。請使用本倉庫中的課程構建提示gitlab-runners-k3s-hyperscale-course.prompt.md,以上方官方文件作為版本化權威來源。對於同一理念的面向非技術人員的表述,請參閱停止為空閒 CI 付費。
結語
Kubernetes 不僅託管 GitLab Runner。正確使用它,將改變 CI 的經濟模式:按需建立、空閒時銷燬、人類下班時回收 CPU/記憶體/儲存。這就是超大規模模式——任何願意以常駐叢集換取佇列式 Pod 的團隊均可採用。
從觀看影片開始,在實驗室中搭建操作節點和 Runner Helm,開啟節點自動擴充套件,然後檢視週六的賬單是否終於安靜了。
由Workstation釋出。