← 返回上一頁
CI/CD Kubernetes

GitOps 實戰:Git Repository 架構規劃與 K8s Manifest 工具選擇指南

本頁目錄
Monorepo vs Polyrepo 架構比較圖

前言

隨著 GitOps 在 Kubernetes 生態系中越來越普及,像是 ArgoCD、Flux 等工具已經幫助許多團隊解決了持續部署(CD)的痛點。不過「GitOps」這個詞聽起來簡單,實際落地的時候,光是 Git Repository 的架構規劃就有不少眉角。

今天這篇文章,我想聊聊在實務上常見的幾種 Git Repo 組織方式,以及搭配不同 K8s Manifest 管理工具時各自的優缺點。沒有所謂的標準答案,重點還是要依據團隊規模、流程成熟度來做取捨。

GitOps 的基本流程與挑戰

在透過 GitOps 將應用程式部署到 Kubernetes 時,典型的工作流程大致如下:

ArgoCD GitOps Architecture Diagram
ArgoCD 架構示意圖(來源:Argo CD 官方文件)

整個流程涵蓋了:

  1. 開發者撰寫應用程式原始碼
  2. 透過 CI 建置容器映像檔
  3. 將映像檔推送到 Container Registry
  4. 同步更新 K8s YAML 描述檔
  5. GitOps 工具(透過 Webhook 或 Polling)偵測到 YAML 變更
  6. 將變更套用到目標 Kubernetes 叢集
  7. Kubernetes 從 Registry 拉取最新版本的映像檔

看起來很直覺,但實際執行時經常會遇到以下幾個問題:

常見問題 說明
K8s YAML 管理工具選擇 要用 Helm、Kustomize、Jsonnet 還是原生 YAML?
原始碼與 K8s YAML 的歸屬 放同一個 Repo 還是分開管理?
映像檔版本更新的責任歸屬 新版容器產生後,由誰來更新 K8s YAML 中的 image tag?

K8s Manifest 管理工具比較

先來快速回顧一下常見的四種 K8s 資源描述管理方式。

原生 YAML

最直覺的方式,直接用 YAML 描述所有 Kubernetes 物件。

面向 說明
優點 入門門檻低、不需額外工具、可直接搭配 kubectl 使用
缺點 缺乏彈性、多環境維護成本高、沒有版本控制概念
適用場景 學習用途、小型專案、第三方工具的安裝範例

簡單來說,每個環境都要維護一組幾乎一模一樣的檔案,環境一多就會崩潰。

Helm

Helm 應該是目前最廣為人知的 K8s 應用定義工具了。透過 Helm Chart 搭配 Go Template,可以根據不同環境動態產生最終的 K8s 資源。

面向 說明
優點 Go Template 動態產生資源、支援打包發布與版本控制、Dependency 機制可組合 Umbrella Chart、生態系豐富
缺點 學習曲線較陡、Template 語法偶爾讓人抓狂、需額外安裝 Helm CLI、可能需要維護 Helm Chart Server

Helm 的運作模式是:團隊維護一份主要的 Chart,再針對不同部署環境準備對應的 values.yaml,動態產生符合各環境需求的 K8s 物件。

另外值得一提的是 Umbrella Chart 的概念——當你交付的不是單一應用而是一整套服務時,可以透過 Helm dependency 將多個 Chart 串在一起,使用者只需要準備一份 values.yaml 就能一次部署所有相依的 Chart。

Kustomize

跟 Helm 的模板化思路不同,Kustomize 提供了一種更簡潔的方式來客製化 K8s 資源。所有檔案都維持原生 K8s 格式,透過 overlay 和 patch 機制來做動態修改。

面向 說明
優點 基於原生 YAML 格式、不需學額外 Template 語法、已整合進 kubectl(kubectl apply -k
缺點 生態系不如 Helm 豐富、缺乏版本概念不利於分發、整體架構仍需花時間理解

基本用法是在 base 資料夾放共用的基礎物件,各環境資料夾則放客製化的內容,全部透過 kustomization.yaml 串接。

Jsonnet

Jsonnet 是一個基於 JSON 的程式語言,利用程式邏輯(if/else、迴圈、函式等)來產生 K8s 物件描述檔。

面向 說明
優點 支援程式邏輯運算、支援 Library 概念減少重複程式碼
缺點 需要學習新語言、文件和生態系相對較少

搭配 k8s-libsonnet 等函式庫,可以快速產生對應不同 K8s 版本的資源物件。整體流程就是撰寫 jsonnet 檔案 → 用 jsonnet 指令產生 YAML/JSON → 用 kubectl 套用到叢集。

工具選擇小結

這四種工具沒有絕對的好壞,ArgoCD 全部都支援。實務上更常見的是混合使用——畢竟很多開源專案是用 Helm 來發布,但團隊內部可能偏好 Kustomize 或 Jsonnet 來管理自己的應用,這些不同的方式可以共存。

Git Repository 架構策略

搞定了 Manifest 工具的選擇,接下來就是重頭戲:Source Code 和 K8s Manifest 到底要怎麼放?

Monorepo vs Polyrepo 架構比較圖
Monorepo vs Polyrepo 架構比較(來源:Spacelift)

方案一:程式碼與 YAML 放在同一個 Repo

也就是每個應用程式的 Git Repo 同時包含 Source Code、Dockerfile 和 K8s Manifest。

特性 說明
一站式管理 從開發到部署的所有資源都在同一處,方便交叉參照
同步修改 應用需要新增環境變數等變更時,可以連同部署 YAML 一起改
CI/CD 整合 Pipeline 可以一條龍處理,甚至用 KIND 測試 K8s 部署
Helm 友善 可在 CI/CD 中打包並發布 Helm Chart
共用困難 使用 Kustomize/Jsonnet 時,跨應用共用檔案比較麻煩
全局視角不足 維運人員要了解整體部署狀況,得逐個 Repo 去翻

這個模式還有一個常見的痛點:Image Tag 的更新時機。開發者開 PR 新增功能時,通常還不知道最終的 Container Image Tag 是什麼,所以無法同步更新 K8s YAML。常見的解法包括使用 latest tag、開第二個 PR 更新、或是建立 GitHub App 動態更新 PR 內容。

方案二:程式碼與 YAML 分開不同 Repo

這是目前比較主流的做法——職責分離。開發者專注在應用程式開發和容器化,另外用一個專門的 Git Repo 來處理所有 GitOps 的管理與部署。

特性 說明
全局可見 所有部署物件集中管理,快速掌握各環境部署差異
職責分離 開發人員和維運人員各司其職
共用友善 Kustomize/Jsonnet 的共用概念更容易實現
環境區分 可透過 Branch 或 Folder 來區分不同環境的部署資源
專屬 CI/CD 可以針對整體服務部署做驗證,而非只驗證單一應用
同步成本 應用的新版本若需要 YAML 變更,得另外到這個 Repo 處理

以 Kustomize 為例,常見的目錄結構如下:

├── base
│   ├── app-foo
│   │   ├── deployment.yaml
│   │   ├── kustomization.yaml
│   │   └── service.yaml
│   └── app-bar
│       ├── deployment.yaml
│       ├── kustomization.yaml
│       └── service.yaml
└── overlays
    ├── dev
    │   ├── app-foo/
    │   └── app-bar/
    └── prod
        ├── app-foo/
        └── app-bar/

另外,因為 Kustomize 目前也支援使用 Helm Chart,所以實務上也會看到 Kustomize + Helm 混合使用的目錄結構。

方案三:混合模式(搭配 Helm Chart Server)

既然 Helm Chart 可以打包並推送到 Chart Server,那就可以把前兩種方案的優點結合起來:

步驟 說明
應用 Repo 專注維護 Helm Chart 的發布與設定
CI/CD 打包 在 Pipeline 中打包 Helm Chart 並推送到 Chart Server
K8s YAML Repo 從 Chart Server 取得打包好的 Chart,用不同的 values 部署到各環境
職責保留 維持分離 Repo 的特性,各自有獨立的 Git 工作流程

這種架構通常需要額外維護一個 Helm Chart Server。好消息是 Helm v3 支援 OCI 格式,所以可以直接使用支援 OCI 的 Container Registry(如 ECR、Harbor)來存放,不一定要另外架設 Chart Museum

Image Tag 自動更新

在方案二和方案三的架構下,很多團隊會進一步思考:當 Container Image 有新版本 tag 時,如何自動更新部署 Repo 中的描述檔?

常見的做法包括:

  • 使用 Argo Image Updater 自動偵測並更新
  • 自建 CI/CD 流程,在映像檔推送成功後自動觸發 YAML 更新

總結

回顧一下今天聊到的重點:

  1. K8s Manifest 工具:原生 YAML、Helm、Kustomize、Jsonnet 各有特色與適用情境,實務上經常混合使用。
  2. Git Repo 架構:同 Repo vs 分 Repo vs 混合模式,沒有標準答案,取決於團隊規模、流程成熟度和工作負荷。
  3. Image Tag 更新:分 Repo 架構下,可搭配 Argo Image Updater 或自建流程來自動化。

最終選擇什麼方案,還是得回到團隊實際的需求和能力來評估。希望這篇整理能幫助你在規劃 GitOps 架構時有更清楚的方向。

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料