← 返回上一頁
CI/CD Kubernetes

使用 Argo Rollouts 在 Kubernetes 實現漸進式交付:藍綠與金絲雀部署完整指南

本頁目錄
Argo Rollouts 控制器管理 ReplicaSet 與 AnalysisTemplate 的架構圖

在 Kubernetes 的世界裡,部署新版本的應用程式其實是件讓人又期待又怕受傷害的事。傳統的滾動更新雖然堪用,但遇到需要更精細控制的場景時就顯得力不從心了。這時候 Argo Rollouts 就派上用場了——它是一個 Kubernetes Operator,能替你的叢集帶來藍綠部署、金絲雀發布、自動分析回滾等進階能力,讓整個交付流程變得更安全、更可控。

我自己在實務上用了一陣子之後,覺得它最大的優勢就是把「漸進式交付」這個概念落地得非常好。以下就來整理一下 Argo Rollouts 的核心概念、架構原理與實戰操作。

Argo Rollouts 支援哪些能力?

Argo Rollouts 支援的部署策略與整合功能特性圖

以下用表格快速總覽它所支援的特性:

類別 支援項目
部署策略 藍綠(Blue-Green)、金絲雀(Canary)
流量控制 細粒度加權流量分割、自動復原、手動判斷
指標分析 自訂 KPI 查詢、Prometheus、Wavefront、Datadog、New Relic、Kayenta
Ingress 整合 NGINX Ingress、AWS ALB
Service Mesh Istio、Linkerd、SMI

運作原理是什麼?

Argo Rollouts 控制器管理 ReplicaSet 與 AnalysisTemplate 的架構圖

Argo Rollouts 的運作邏輯其實跟原生 Deployment 蠻像的——它也是透過管理 ReplicaSet 來控制 Pod 的建立與縮放。差別在於,當你修改了 spec.template(比如換了 container image),Rollouts 控制器會依據 spec.strategy 裡定義的策略,決定舊版 ReplicaSet 與新版 ReplicaSet 之間的過渡方式。

新版 ReplicaSet 一旦被完全放大並通過分析驗證,控制器就會將其標記為 stable。如果在過渡期間又發生了新的變更,先前的新版 ReplicaSet 會被縮小,控制器會直接朝最新的版本推進。

幾個你該知道的核心概念

Rollout 資源

Rollout 是 Argo 提供的 CRD,定位上是用來取代原生 Deployment 的。它額外提供了藍綠、金絲雀部署能力,還能跟 Ingress、Service Mesh 以及指標系統整合,根據分析結果自動決定要繼續發布還是回滾。

漸進式交付(Progressive Delivery)

白話說就是:不要一次把所有流量都切到新版本,而是先讓一小部分使用者接觸新版,觀察指標,確認沒問題後再逐步加大比例。這樣做能大幅降低上線風險。

部署策略比較

策略 說明 適用場景
Rolling Update 新版逐步取代舊版,是 Deployment 的預設行為 一般應用、風險較低的更新
Recreate 先刪除所有舊版,再啟動新版,中間會有短暫停機 不允許新舊版本並存的場景
Blue-Green 新舊版本同時部署,切換流量前可先測試新版 需要零停機切換、快速回滾
Canary 先將少量流量導向新版,驗證後逐步加大 需要精細流量控制的核心服務

架構元件一覽

元件 用途
Rollout Controller 主控制器,監聽 Rollout 資源變更並執行部署策略
Rollout Resource 自訂 CRD,與 Deployment 相容但多了進階部署欄位
ReplicaSet(新/舊版) 標準 K8s ReplicaSet,控制器透過 metadata 追蹤版本
Ingress / Service 流量入口,支援多種 Service Mesh 與 Ingress 整合方案
Analysis / AnalysisRun 定義指標查詢範本與實際執行結果,驅動自動升級或回滾
Metric Provider 整合 Prometheus、Datadog 等指標系統
CLI / Dashboard 命令列工具與視覺化介面,方便管理與監控

值得一提的是,Argo Rollouts 控制器不會干擾你叢集裡原本的 Deployment 資源,所以你可以安心地在既有環境中安裝它。

安裝方式

安裝非常直覺,幾行指令就搞定:

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/download/v1.2.2/install.yaml

確認 Pod 是否正常運行:

kubectl get pods -n argo-rollouts
NAME                             READY   STATUS    RESTARTS   AGE
argo-rollouts-845b79ff9-crx9v    1/1     Running   0          58s

另外建議安裝 kubectl 外掛,管理 Rollout 會方便很多:

curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.2.2/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
sudo mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

驗證安裝:

kubectl argo rollouts version
kubectl-argo-rollouts: v1.2.2+22aff27
  BuildDate: 2022-07-26T17:24:43Z
  GitCommit: 22aff273bf95646e0cd02555fbe7d2da0f903316
  GitTreeState: clean
  GoVersion: go1.17.6
  Compiler: gc
  Platform: linux/amd64

實戰操作

Step 1:部署 Rollout 資源

先建立一個採用金絲雀策略的 Rollout,策略是先把 20% 流量導向新版後暫停等待手動確認,之後再自動逐步加大:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-demo
spec:
  replicas: 5
  strategy:
    canary:
      steps:
        - setWeight: 20
        - pause: {}
        - setWeight: 40
        - pause: { duration: 10 }
        - setWeight: 60
        - pause: { duration: 10 }
        - setWeight: 80
        - pause: { duration: 10 }
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: rollouts-demo
  template:
    metadata:
      labels:
        app: rollouts-demo
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:blue
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            requests:
              memory: 32Mi
              cpu: 5m

搭配一個 Service:

apiVersion: v1
kind: Service
metadata:
  name: rollouts-demo
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: rollouts-demo

套用後可以用 kubectl argo rollouts get rollout rollouts-demo --watch 即時觀察狀態。

Step 2:觸發更新

跟 Deployment 一樣,修改 Pod template 就會觸發新版本部署。最方便的方式是用外掛直接換 image:

kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

這時控制器會按策略走——先把 20% 流量切到新版然後暫停,等你確認。

Step 3:手動 Promote

確認新版沒問題後,執行 promote 讓 Rollout 繼續走完剩餘步驟:

kubectl argo rollouts promote rollouts-demo

如果想跳過所有剩餘步驟直接切換,可以加上 --full 旗標。

Step 4:中斷更新(Abort)

萬一新版有問題,可以直接中斷,Rollout 會自動回退到 stable 版本:

kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:red

# 觀察到問題後中斷
kubectl argo rollouts abort rollouts-demo

中斷後,要讓 Rollout 回到 Healthy 狀態,需要把 image 設回穩定版本:

kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

控制器會偵測到這是一次回滾而非新部署,因此會跳過分析步驟直接回復。

Dashboard 儀表板

Argo Rollouts 附帶一個本機 Dashboard,執行以下指令就能在 localhost:3100 瀏覽:

kubectl argo rollouts dashboard

在 Dashboard 上可以看到所有 Rollout 的狀態、設定資訊,也能直接操作重啟、promote、abort 等動作,非常方便。

Analysis 分析機制

這是 Argo Rollouts 最強大的功能之一——能自動根據指標決定要不要繼續發布。相關的 CRD 包括:

資源 說明
AnalysisTemplate 定義查詢哪些指標、多久查一次、成功/失敗閾值(Namespace 層級)
ClusterAnalysisTemplate 同上,但是叢集層級,可跨 Namespace 共用
AnalysisRun AnalysisTemplate 的實例,類似 Job,最終結果為成功/失敗/不確定

後台分析(Background Analysis)

在金絲雀逐步推進的同時,在背景持續跑分析。例如每 10 分鐘加 20% 流量,同時用 Prometheus 監控成功率:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: guestbook
spec:
  strategy:
    canary:
      analysis:
        templates:
          - templateName: success-rate
        startingStep: 2
        args:
          - name: service-name
            value: guestbook-svc.default.svc.cluster.local
      steps:
        - setWeight: 20
        - pause: { duration: 10m }
        - setWeight: 40
        - pause: { duration: 10m }
        - setWeight: 60
        - pause: { duration: 10m }
        - setWeight: 80
        - pause: { duration: 10m }

對應的 AnalysisTemplate:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      interval: 5m
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.example.com:9090
          query: |
            sum(irate(
              istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code!~"5.*"}[5m]
            )) /
            sum(irate(
              istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m]
            ))

如果成功率低於 95% 且累計 3 次,分析判定為失敗,Rollout 會自動回滾。

內聯分析(Inline Analysis)

也能把分析寫成 Rollout 的一個步驟,走到那步時才開始跑,跑完才決定要不要繼續:

strategy:
  canary:
    steps:
      - setWeight: 20
      - pause: { duration: 5m }
      - analysis:
          templates:
            - templateName: success-rate
          args:
            - name: service-name
              value: guestbook-svc.default.svc.cluster.local

藍綠部署的分析

藍綠策略也能搭配分析使用:

分析時機 行為
prePromotionAnalysis(預發布) 新版就緒後、切流量前執行。失敗則中止,不切換流量
postPromotionAnalysis(發布後) 切換流量後執行。失敗則回滾到舊版穩定 ReplicaSet

進階分析配置

失敗條件(failureCondition):可以主動定義什麼情況算失敗,例如錯誤數超過 10 就判定失敗:

metrics:
  - name: total-errors
    interval: 5m
    failureCondition: result[0] >= 10
    failureLimit: 3
    provider:
      prometheus:
        address: http://prometheus.example.com:9090
        query: |
          sum(irate(
            istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code=~"5.*"}[5m]
          ))

不確定結果(Inconclusive):當指標既不滿足成功條件也不滿足失敗條件時,分析結果為「不確定」,Rollout 會暫停等待人工介入。

延遲分析(Delayed Analysis):可以設定 initialDelay 讓分析延後啟動,給指標系統足夠的時間收集金絲雀版本的數據:

metrics:
  - name: success-rate
    initialDelay: 5m
    successCondition: result[0] >= 0.90
    provider:
      prometheus:
        address: http://prometheus.example.com:9090
        query: ...

多模板組合

一個 Rollout 可以同時引用多個 AnalysisTemplate(例如 success-rate + error-rate),控制器會將它們合併成一個 AnalysisRun 來執行。不過要注意:如果不同模板裡有同名指標或同名且帶值的參數,合併時會報錯。

參數化模板

AnalysisTemplate 支援參數佔位符 {{ args.<name> }},可以從 Rollout 傳入動態值。也支援從 Rollout 的 metadata labels 或 Pod template hash 取值,讓分析更加靈活。

小結

Argo Rollouts 把 Kubernetes 的部署能力提升到了一個新的層次。對我來說,它最大的價值在於讓「安全上線」不再只是口號——透過金絲雀分析、自動回滾、多階段流量控制,真的能做到用數據驅動的漸進式交付。

如果你的團隊目前還在用原生 Deployment 做滾動更新,而且對上線品質有更高的要求,那非常推薦試試 Argo Rollouts。

另外補充一下,OpenKruise 專案也推出了類似的工具 Kruise Rollouts,有興趣的朋友也可以研究看看。

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

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

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