iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Kubernetes

從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台系列 第 17

[Day 17] GitOps 降臨:為什麼我們需要 ArgoCD? —— 從「推動式」轉向「聲明式」,順便看清它跟 CI 的分工。

  • 分享至 

  • xImage
  •  

Day 17: GitOps 降臨:為什麼我們需要 ArgoCD?

從「推動式」轉向「聲明式」,順便看清它跟 CI 的分工。

1. 傳統 CI/CD (推動式) 的痛點

傳統做法是在 Pipeline 最後一步執行 kubectl apply,把配置「推 (Push)」進叢集。這會衍生兩個嚴重問題:

  1. 安全風險:CI 伺服器必須持有 K8S 的最高權限憑證 (kubeconfig)。CI 一旦被攻破,整個叢集直接淪陷。
  2. 配置漂移 (Configuration Drift):有人手癢在叢集上 kubectl edit 改了 replica 數,Git 裡的 YAML 跟實際環境就對不上了。三個月後沒人記得叢集到底長什麼樣,下次部署就是災難現場。

2. GitOps (拉取式) 哲學

GitOps 的核心理念一句話:「Git 是唯一的真理 (Single Source of Truth)」。

把一個叫 ArgoCD 的 Controller 裝在 K8S 裡面,它會定期去「拉 (Pull)」Git 倉庫的設定,跟叢集實際狀態比對。只要不一致,就把叢集「同步」成跟 Git 一模一樣。方向反過來之後,兩個痛點同時解掉:

  • CI 不再需要碰叢集憑證——它只要會 push Git 就好
  • 手動改叢集?ArgoCD 的 selfHeal 直接把你改回去,漂移不存在的

3. ArgoCD 是什麼?開源嗎?

先把身家背景交代清楚,因為「要不要把整套部署流程押在一個工具上」這種決定,值得先知道它是誰做的。

ArgoCD 是一個給 Kubernetes 用的宣告式 GitOps 持續交付工具,用 Go 寫的,以 controller 的形式住在叢集裡面。它不是外掛在 K8S 旁邊的服務,而是用 CRD 擴充 K8S 自己的 API——你之前看到的 kubectl get application -n argocd,那個 Application 就是 ArgoCD 新增的資源類型,跟 Deployment、Service 一樣是叢集裡的一等公民。

項目 說明
授權 Apache License 2.0,完全開源,核心功能沒有付費牆
出身 2018 年由 Intuit 團隊開源
治理 捐給 CNCF,並於 2022 年 12 月畢業 (Graduated)——跟 Kubernetes、Prometheus 同一個等級
家族 Argo 專案包含 Workflows、CD、Rollouts、Events 四個成員。Day 20 要用的 Argo Rollouts 就是同一家人,所以 UI 風格和操作邏輯是通的

CNCF 畢業這件事對選型來說是有意義的訊號:它代表專案有多家廠商共同維護、有明確的治理與安全流程,不是某家公司哪天不爽就能收回去的東西。

那它跟 GitHub Actions、Jenkins 是什麼關係?

這是我自己一開始最混淆的地方——它們不是競爭對手,是分工

比較項目 GitHub Actions / Jenkins ArgoCD
定位 通用 CI(也能兼做 CD) 只做 K8S 的 CD
跑在哪 叢集外面(雲端 runner / 自架 server) 叢集裡面
模式 推 (Push):流程跑到最後 kubectl apply 拉 (Pull):controller 主動比對 Git
憑證 需要 kubeconfig,等於握有叢集最高權限 只需要 Git 的讀取權限;叢集憑證不出叢集
什麼時候知道狀態 只有部署當下那一瞬間 持續比對,隨時知道現在跟 Git 差在哪
有人手動改叢集 完全不知情 標成 OutOfSync,開了 selfHeal 就改回去
能不能 build image ✅ 這是它的主場 ❌ 完全不做
回滾方式 重跑一次舊的 pipeline 讓 Git 退回去(Day 20 詳談)

Actions/Jenkins 擅長「把程式碼變成 image」,ArgoCD 擅長「讓叢集永遠等於 Git」。前者是一次性的動作,後者是持續的狀態維護。我們的架構就是兩個都用——這也是目前業界最常見的組合。

如果你想比較同類型的工具,GitOps 這個領域主要的另一個選擇是 Flux CD(同樣是 CNCF 畢業專案)。粗略的差別是 Flux 更輕、更「純 CLI / CRD」,ArgoCD 則有一個功能完整的 UI——如果你的團隊有非 K8S 專家需要看部署狀態,ArgoCD 的 UI 會方便很多。

4. 眼見為憑:從 OutOfSync 到 Synced

概念很抽象?直接看實測。我在本機叢集註冊了一個 Application,指向這個 repo 的 k8s/base/observability(就是 Day 24 會用到的 Jaeger),並且故意不開自動同步——因為要拍的正是「Git 有、叢集還沒有」的那一刻。

https://ithelp.ithome.com.tw/upload/images/20260819/20182549z8jDonfvCk.png

▲ 剛註冊完:Status 是 Missing + OutOfSync,左側過濾器統計 OutOfSync 1、Missing 1

卡片上每一行都是 ArgoCD 的世界觀:Repository(哪個 repo)、Target Revision(哪個分支)、Path(哪個目錄)、Destination(哪座叢集)、Namespace(哪個命名空間)。這五個欄位就是「期望狀態」的完整定義,不多不少,GitOps 要設定的東西就這些。

此刻 ArgoCD 已經知道「應該長什麼樣」,也知道「現在長什麼樣」,而且兩者不一樣。但它什麼都沒做——因為我沒開自動同步,它現在只是個盡責的觀察者。

按下 Sync 之後:

https://ithelp.ithome.com.tw/upload/images/20260819/20182549XOhEhYHtnM.png

▲ 同一張卡片:Missing + OutOfSync 變成 Healthy + Synced,並多出一行 Last Sync 時間

同一張卡片、同樣的五個欄位,只有狀態變了。「Git 裡寫什麼、叢集就長什麼樣」這句話,在畫面上是看得見的。

這裡有一組概念值得先建立,因為之後排查會一直用到:Sync 和 Health 是兩個獨立的維度

  • Sync Status 回答的是「叢集跟 Git 一不一樣」
  • Health Status 回答的是「這些東西跑得起來嗎」

兩者可以任意組合,每種組合代表的狀況不同:Synced 但 Degraded,代表你部署的正是 Git 裡那個壞掉的版本(Day 20 會實測這種情況);Healthy 但 OutOfSync,代表現在跑得好好的,但有人手動改過、或 Git 已經前進了。把這兩個維度混為一談,排查時很容易找錯方向。

至於資源樹長什麼樣、按下 Sync 的瞬間叢集發生什麼事——那是明天實作篇的主場。

5. 除了「同步」,ArgoCD 還有這些功能

第一次用大概只會用到 Sync 按鈕,但真正讓它從「自動 apply 工具」變成「部署平台」的是下面這些。

5-1. Sync Policy:三段變速

同步策略其實是三個獨立開關疊出來的:

syncPolicy:
  automated:
    prune: true      # Git 裡刪掉的資源,叢集也跟著刪
    selfHeal: true   # 有人手動改叢集,自動改回來
  • 什麼都不開(手動):ArgoCD 只當警報器,告訴你 OutOfSync,動手要你自己按
  • 只開 automated:Git 一變就自動部署,但你手動改叢集它不管、Git 裡刪掉的資源也留在叢集
  • 加 prune:Git 是唯一真理,刪除也算真理
  • 加 selfHeal:連手動改都不被允許

新環境建議從手動開始,等你信得過這條鏈路再往上加。特別是 prune,它真的會刪東西——如果有人把某個資源從 Git 拿掉只是想「先註解起來試試看」,prune 會忠實地把 production 的那個資源刪掉。

5-2. Diff:部署前先看差異

UI 上那顆 DIFF 按鈕(或 CLI 的 argocd app diff)會逐個資源顯示 Git 與叢集的差異,像 code review 一樣。這是「聲明式」最舒服的地方:部署前你能確切知道這次會改到什麼,而不是按下去才知道。

5-3. Sync Waves:誰要先部署

預設情況下 ArgoCD 會一次把所有資源丟進去,但有些東西有順序依賴。Day 10 提過我們踩到的例子:Chart 裡有一張 cert-manager 的 ClusterIssuer,叢集還沒裝 cert-manager 就會直接報 no matches for kind

解法是 sync wave,用 annotation 標一個數字,小的先跑

metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"   # 比預設的 0 早一步

同一個 wave 內平行處理,前一個 wave 全部健康了才進下一個。再進階還有 hooks(PreSync / Sync / PostSync / SyncFail),可以在同步前跑資料庫遷移、同步後跑煙霧測試、失敗時自動通知。

5-4. ignoreDifferences:跟「永遠 OutOfSync」和解

有些欄位天生就會一直變,比對起來永遠不一致。我們自己就有一個現成的例子:Helm 模板裡的 deployed-at: {{ now }} Pod annotation,每次渲染出來的值都不同,ArgoCD 會覺得永遠有差異,開了 selfHeal 還會不停重新部署。

ignoreDifferences 就是拿來畫免戰牌的:

spec:
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/template/metadata/annotations/deployed-at

常見用途還有:被 HPA 動態調整的 replicas(Day 25 會裝 HPA,如果 Git 寫死 replicas 又開 selfHeal,兩個控制器會打架)、被 webhook 注入的欄位、憑證輪替的 Secret。不是所有欄位都該由 Git 決定,這點在設計時很容易忽略。

5-5. History and Rollback:以及它的陷阱

App 詳情頁上那顆 HISTORY AND ROLLBACK 會列出每一次同步的紀錄(時間、commit、作者),可以直接選一筆退回去。

但這裡有個關鍵限制:開了 automated sync 的 App,ArgoCD 會擋住你回滾。原因很單純——就算讓你退回去,下一輪比對它又會把 Git 的版本推回來。想用這顆按鈕,得先把自動同步關掉。

這件事我在 Day 20 會用實測數字說得更完整:在 GitOps 底下,真正有效的回滾只有一種,就是讓 Git 本身退回去。

5-6. App of Apps 與 ApplicationSet

當你有十個微服務、三個環境的時候,手動維護三十個 Application 是災難。兩種解法:

  • App of Apps:做一個「總管 Application」,它的內容就是其他 Application 的 YAML。管一個等於管全部
  • ApplicationSet:用產生器自動長出 Application——例如掃描 Git 目錄,每個資料夾自動生一個 App;或用 list 產生器把同一份設定套到 dev/staging/prod

我們的規模用不到,但值得知道它存在——順帶一提,applicationset-controller 就算你沒用它,官方安裝檔也會把它裝起來一直跑著。我自己的叢集裡它就默默壞了 96 天、重啟了四千多次都沒人發現,因為沒人用它,所以沒人在意。明天講安裝驗證時會把這個案例完整攤開。

6. Wafer BI 的 GitOps 轉型

引入 ArgoCD 後,我們的架構變得很乾淨:

GitHub Actions:只負責 build image + 改寫 Git 上的版本號(不碰叢集)
ArgoCD(住在叢集裡):盯著 Git,有變化就同步(不碰 CI)

職責徹底分離,憑證不出叢集。這裡分享一個我自己踩過的反面教材:Helm 化之前,CI 曾經改的是一個 ArgoCD 根本沒在看的目錄——CI 每次都「成功」,但 production 永遠是舊版,兩邊各自運作良好,就是沒接在一起,哭啊。GitOps 的鏈路是「CI 改的檔案」=「ArgoCD 看的檔案」,這條等式斷了整套就是空轉,強烈建議把它寫進 checklist 用工具檢查(我們後來就寫了 scripts/check-config-sync.py)。

7. 小結

今天把 ArgoCD 的 Why 講完了,順便交代它的身家背景,以及那些第一次用不會碰到、但遲早會需要的功能。三個重點:

  1. ArgoCD 不取代 CI,它接手 CI 不該做的那一段——build image 是 Actions 的事,讓叢集等於 Git 是 ArgoCD 的事
  2. Sync 和 Health 是兩個獨立維度——Synced 不代表跑得起來,Healthy 也不代表跟 Git 一致
  3. 自動化的每一格開關都有代價——prune 會真的刪東西、selfHeal 會讓你的手動操作失效(Day 20 會用實測告訴你失效得多快)

明天來 How:實際安裝 ArgoCD、登入那個著名的章魚 UI、建立 Application。


上一篇
[Day 16] CI/CD 自動化 (二):多架構 (Multi-Arch) Docker Image 構建 —— 支援 ARM 與 AMD64,讓 Image 在各種節點都能跑。
系列文
從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言