· 5 分鐘閱讀

公司導入 GitLab Self-Managed:架構與 CI/CD 流程設計分享

公司導入 GitLab Self-Managed:架構與 CI/CD 流程設計分享

公司原本用 SVN,隨著團隊擴張到 10 個團隊、開發語言從單一 Java 擴散到 .NET / Python,加上未來要拿 ISO 27001,SVN 已經明顯撐不住。於是這次規劃把版本控制平台搬到 GitLab Self-Managed CE,順便把 CI/CD 一起做起來。

這篇分享我們在規劃階段定下來的兩件事:整體系統架構CI/CD 流程設計。不寫 gitlab.rb 設定值,只談架構決策與背後的取捨,給其他在規劃內部 GitLab 的朋友參考。


一、整體系統架構

先上圖。一張圖可以看完:5 台主機 + 1 個 NAS,對外只一條 HTTPS 通道,LDAP / SMTP 沿用既有資源。

GitLab 系統架構

部署模式:Self-Managed + Omnibus 單機

我們選了 Self-Managed,自有機房、單機部署,不做 HA。理由很簡單:

  1. 資料留在公司內部 — 程式碼是公司核心資產,不放雲端是組織共識
  2. 100 人規模單機足夠 — GitLab Omnibus 在 8 vCPU / 32GB / SSD 的機器上跑 100 人沒壓力
  3. HA 不是現在的痛點 — 業務還能容忍計畫內維護,真要做 HA 至少要 3 台 + Gitaly Cluster,複雜度是 5 倍以上的跳躍

當然這是取捨 — 主機掛了就全公司停擺。但靠每日完整備份 + 異機保存(寫到 NAS 的 NFS),最壞情況下還原時間可接受。將來業務關鍵性提升,再升級到 HA。

為什麼選 CE 不選 Premium

預算其實不是限制,但盤點商業版差異後發現核心需求 CE 都能滿足:

商業版獨有我們怎麼補
LDAP Group Sync群組與角色手動維護(訂季度核對 SOP)
Required Approvers訂 MR 簽核 SOP,以人工流程實施
Audit Events 完整版從 application log + OS log 反查
SAST / DAST整合 SonarQube、Trivy 等開源工具

這些落差走流程跟外部工具補,不形成技術 lock-in,將來規模或合規要求提高再升級也來得及。

外部依賴(沿用既有,不另建)

  • AD / LDAP — 認證來源,GitLab 用一個專屬服務帳號 svc-gitlab-ldap 做 read-only bind
  • SMTP — 寄通知信,同樣用專屬服務帳號
  • NAS(NFS) — 備份目標,用 NFS export rules + UID 對映授權,不用額外密碼

小心一個紅線: GitLab 的加密金鑰(gitlab-secrets.json)跟 DB 備份必須分開存放。同時失守 = 加密形同虛設。我們在備份 SOP 把這個列為硬規。


二、CI/CD 流程設計(以及 Runner Pool 是「共用資源池」的觀念)

接下來這張圖比較精彩。我們在規劃 CI/CD 時遇到一個觀念上的轉換 — Runner Pool 不該被看成 Build 的附屬,而是整條 Pipeline 共用的執行資源池。

GitLab CI/CD 完整資料流

Pipeline Stages 的順序:Lint → Build → Test

我們把每個專案的 Pipeline 切成三個 stage:

  1. Stage 1 — Code Quality / Lint:語法、規範、靜態掃描。最快、最便宜,有錯就直接擋下,不浪費後面資源
  2. Stage 2 — Build:Java、Python 在 Linux Docker Runner 跑;.NET Framework / IIS 在 Windows Shell Runner 跑
  3. Stage 3 — Automated Testing:Unit Test、Integration Test。Test 通過才產 artifact,失敗就不污染 Registry

Runner Pool 的設計觀念

Pipeline 上跑的 4 個動作 — Lint / Build / Test / Deploy — 每一個 job 都需要 Runner 才能執行。Runner 不是 Build 專屬的東西,而是整條 Pipeline 共用的「執行容器」。

把這個觀念內化後,圖上的 Runner Pool 就被我們從 Build 旁邊獨立出來,畫成右側的「共用資源池」,讓所有 stage 都用虛線指向它,標示「派 job 借用」。

這個觀念上的修正帶來幾個重要副作用:

之前的誤解修正後
Runner 只給 Build 用 → 規劃時容易低估負載Lint/Test/Build/Deploy 都在搶 → 規劃 Runner 數量要看所有 stage 併發
Test 卡住跟 Build 卡住是兩件事都是 Runner 卡住 → 監控 Runner 利用率才看得出真因
加 Runner 只能加速 Build加 Runner = 加速整條 pipeline,所有 stage 同步受益

Linux Runner × 3 + Windows Runner × 1 的搭配

我們的環境同時有 Java / Python(Linux 友善)跟 .NET Framework / IIS(只能 Windows),所以 Runner Pool 分平台:

  • Linux Docker Runner × 3 — 跑 Java、Python、容器化 build。3 台讓多團隊併發不互卡
  • Windows Shell Runner × 1 — 跑 .NET Framework、IIS build。先 1 台觀察使用後再擴

兩平台工具鏈無法混用,所以是分開設備,不是「一台 Runner 兩種 OS」。

Deploy 為什麼要 manual + 三條路徑共存

正式環境部署用 when: manual,流程到 Deploy 就停下,等授權人員按按鈕。這是合規與資安要求 — 自動 deploy 到 prod 在內部稽核會被打。結合 Protected Environment 機制,只有特定 role 可以觸發。

部署到正式環境的路徑視目標主機而定,我們有三條共存:

  • A. OpenSSH — Linux 目標(如 Tomcat on Linux),Linux Runner 直接 SSH 推送
  • B. WinRM — Windows 目標,Linux Runner 跨平台用 MSDeploy / PowerShell Remoting
  • C. Windows Runner 直部署 — 同網段 Windows 目標,最直接但要 Runner 跟目標都通

每個專案在落地階段視目標環境選一條,不強制統一。這是正視「組織內就是 Linux + Windows 混合環境」的務實作法。


三、幾個值得分享的取捨

最後快速列幾個我覺得其他公司也會遇到的決策點:

  1. SVN 歷史不搬,全新起步 — 評估後發現轉換工具與歷史保真度的成本,遠大於從新起步的痛。換到 GitLab 後 SVN repo 凍結唯讀供查詢即可
  2. 對外只開 HTTPS(443),不開 SSH(22) — 簡化 firewall、減少對外暴露、省掉全公司 SSH key 管理。代價是自動化腳本要改用 Personal Access Token
  3. 不導入外部 Vault,先用 GitLab 內建加密 — AES-256-GCM 已經符合多數合規要求,Vault 留給未來真有 dynamic secret 需求再評估
  4. Container Registry 跟 Package Registry 都啟用 — 用統一平台管所有 build 產出,組件可追溯性對 ISO 27001 的「組件版本管理」很重要
  5. 試點 1~2 個團隊先跑 — 不要一次全公司搬,先讓一兩個團隊跑通再推廣

結語

GitLab Self-Managed 的導入,架構選擇通常比實作細節更重要。我們在規劃階段把「Runner Pool 是共用資源池」這個觀念釐清,直接影響後續 Runner 數量規劃、監控指標設計、容量預測;把「Deploy 三條路徑共存」訂為原則,讓各團隊不必為了統一而扭曲既有環境。