Argo Rolloutsとは?カナリア・ブルーグリーンの設定と自動ロールバックの実装【v1.9.1】

Argo Rolloutsは、Kubernetesの標準Deploymentでは書けない「10%だけ新版に流し、成功率を測り、駄目なら自動で戻す」という段階リリースを、Rolloutというカスタムリソースで宣言的に記述するコントローラーです。ここでは最新安定版v1.9.1(2026年7月17日公開)の仕様に沿って、カナリアとブルーグリーンの設定値、AnalysisTemplateによる自動ロールバックのしきい値設計、既存Deploymentからの移行手順、そして採用を見送るべき条件までを実際のマニフェストで整理します。

まとめ:Argo Rolloutsの設定判断で押さえる5点

  • Rolloutは Deployment の置き換えapiVersionargoproj.io/v1alpha1kindRollout に変え、strategy を canary か blueGreen にする。Pod テンプレート以下はそのまま流用できる。
  • trafficRouting を設定しないカナリアは、重みをレプリカ数で近似する。10台構成で setWeight: 41 なら新版4台・旧版6台。1%刻みの制御が要るならIstioやALBなどのルーターを併用する。
  • ブルーグリーンの既定は「自動昇格する」autoPromotionEnabled 既定 true)。手動確認を挟むなら明示的に false を書く。旧版の縮退は scaleDownDelaySeconds 既定30秒後。
  • 自動ロールバックの実体は AnalysisTemplatesuccessConditionfailureLimit(既定0=失敗を一切許容しない)で判定し、条件を割ると Rollout は abort されて安定版へ戻る。
  • メトリクス基盤が無ければ自動分析は成立しない。PrometheusなどのSLI計測が先で、Argo Rolloutsの導入はその後。順序を逆にすると pause だけの手動運用に終わる。

Rolloutリソースの構造とDeploymentから変わる点

Argo Rolloutsは、Rollout・AnalysisTemplate・AnalysisRun・Experiment・ClusterAnalysisTemplate というCRD群と、それらを監視するコントローラーで構成されます。コントローラーはRolloutの .spec.template の変更を検知してReplicaSetを作り、戦略に書かれた手順に沿って新旧ReplicaSetのレプリカ数とService、必要ならサービスメッシュのルーティング設定を書き換えます。ReplicaSetとPodを操作する点はDeploymentと同じで、置き換わるのは「どう切り替えるか」の記述部分だけです。

サポートする戦略はBlueGreen、Canary、そしてRollingUpdateの3種類です。Deploymentから移す際に変えるのは次の3フィールドに限られます。

フィールド Deployment Rollout
apiVersion apps/v1 argoproj.io/v1alpha1
kind Deployment Rollout
strategy rollingUpdate / recreate canary / blueGreen

注意点として、Rolloutを新規作成した直後は戦略が適用されません。比較対象となる安定版ReplicaSetが存在しないため、コントローラーは .spec.template から一気にスケールアップして定常状態を作ります。段階リリースが働くのは2回目以降の更新からです。

もう一点、公式FAQが明記しているのは「Argo CDへの依存は無い」ことです。GitOpsを採っていない従来型のCI/CDからマニフェストを更新しても、コントローラーは変更を検知して動きます。ArgoCDと組み合わせる場合の同期の仕組みはArgoCDとは?GitOpsによるKubernetes継続的デリバリーの仕組みと導入判断を実装者目線で解説で扱っています。

カナリアの設定:setWeightとpauseによる手順の宣言

カナリア戦略は steps に手順を並べる形で書きます。setWeight がカナリアへ流す割合、pause が待機です。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: example-rollout
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.15.4
          ports:
            - containerPort: 80
  minReadySeconds: 30
  revisionHistoryLimit: 3
  strategy:
    canary:
      maxSurge: '25%'
      maxUnavailable: 0
      steps:
        - setWeight: 10
        - pause:
            duration: 1h
        - setWeight: 20
        - pause: {}

pauseduration は接尾辞で単位を指定し、”s”(既定)・”m”・”h” が使えます。duration を省いた pause: {} は無期限停止で、再開はkubectlプラグインの promote コマンドで行います。kubectl argo rollouts はkubectlのプラグインで、コントローラーとは別にインストールが必要です(Homebrewの argoproj/tap/kubectl-argo-rollouts、またはリリースページのバイナリ)。

kubectl argo rollouts promote <rollout>

ここで最初に踏みやすい落とし穴が、重みの解像度です。trafficRouting を設定していないカナリアでは、指定した割合をレプリカ数の比で近似します。レプリカ10台で setWeight: 10 なら新版1台・旧版9台。setWeight: 41 は差の小さい整数へ丸められ、新版4台・旧版6台になります。5%刻みのような細かい制御をレプリカ数だけで実現しようとすると、必要な台数が現実的でなくなります。細粒度の重み付けが要件なら、後述のトラフィックルーターを併用してください。

逆に、重みとカナリアのスケールを切り離したい場合は setCanaryScale を使います。公開はまだ0%にしたまま検証用にPodだけ立ち上げる、ヘッダーベースのルーティングで社内からだけ叩く、といった用途です。

spec:
  strategy:
    canary:
      steps:
        - setCanaryScale:
            replicas: 3          # 台数を直接指定
        - setCanaryScale:
            weight: 25           # spec.replicas に対する割合
        - setCanaryScale:
            matchTrafficWeight: true   # 既定動作(重みに追随)へ戻す

setCanaryScale はトラフィックルーター併用時のみ有効です。ルーター無しの素のカナリアは、重みの実現手段そのものがレプリカ数なので併用できません。また setWeight と組み合わせる際は、少数のPodへ大半のトラフィックが集中する配分にならないか確認してください。段階リリースの考え方そのものはカナリアリリースとは?段階リリースの仕組み・他方式との違い・実装と採用判断を実装視点で解説で整理しています。

ブルーグリーンの設定:activeServiceとscaleDownDelaySecondsの既定値

ブルーグリーンは、本番用のServiceと検証用のServiceを切り替える戦略です。設定の中心は次の4フィールドです。

spec:
  strategy:
    blueGreen:
      activeService: rollout-bluegreen-active
      previewService: rollout-bluegreen-preview
      autoPromotionEnabled: false
      scaleDownDelaySeconds: 30
      prePromotionAnalysis:
        templates:
          - templateName: success-rate
      postPromotionAnalysis:
        templates:
          - templateName: success-rate

更新時の流れは、新ReplicaSetの作成 → previewService を新版へ向ける → 新版Podが揃ったら prePromotionAnalysis 実行 → 昇格(activeService の切り替え)→ postPromotionAnalysis 実行 → scaleDownDelaySeconds 経過後に旧ReplicaSetを縮退、という順序になります。

既定値には注意が必要です。autoPromotionEnabled既定でtrue、つまり何も書かなければ検証用Serviceで確認する間もなく自動昇格します。人の確認を挟む運用なら明示的に false を書く必要があります。時間で自動昇格させたい場合は autoPromotionSeconds に正の値を入れますが、autoPromotionEnabled: false のときは無視される点も押さえてください。

scaleDownDelaySeconds の既定は30秒です。この待機は無駄な猶予ではなく、Serviceのセレクタ変更が全ノードのIPテーブルに伝播するまでの時間を稼ぐためのものです。ゼロに近づけると、まだ更新が届いていないノードが削除済みPodへパケットを送る可能性があります。切り替え時の中断をどこまで詰められるかはゼロダウンタイムデプロイとは?無停止を壊す発生源と設定順序・計測方法を実装者目線で解説の観点と併せて判断してください。

AnalysisTemplateによる自動ロールバック:しきい値とfailureLimitの決め方

Argo Rolloutsの中核は、この分析による自動判定です。AnalysisTemplateにメトリクスの取得先と合否条件を書き、Rolloutから参照します。

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]
            ))

バックグラウンド分析の開始位置(startingStep)

Rollout側からは、ステップの進行と並行して走らせるバックグラウンド分析として参照できます。startingStep を指定すると、そのステップに到達するまで分析を開始しません。トラフィックが少ない初期段階の数値でしきい値を割る事故を避けられます。

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}

ここで数え方に注意が必要です。startingStep は0起点で数えます。上の例の startingStep: 2 は3番目のステップ、つまり setWeight: 40 から分析を開始する指定であり、公式ドキュメントも同じマニフェストに「step 3 (Set Weight 40%)まで遅らせる」と注記しています。1つずらして書くと、意図より早い(あるいは遅い)タイミングで判定が始まります。

failureLimitとconsecutiveSuccessLimitで反転する0の意味

設計上いちばん誤解されるのが failureLimit です。既定値は0で、これは「無効」ではなく「失敗を1回も許容しない」という意味です。5分間隔で成功率を測る構成なら、一時的なスパイク1回で昇格が止まります。逆に failureLimit: -1 と書くと失敗回数による判定を無効化できます。もう一方の consecutiveSuccessLimit も既定0ですが、こちらは0が「無効」を意味し、同じ0でも解釈が反転します。両方を無効化するとバリデーションエラーになります。

もう一つ、公式FAQが区別しているのが失敗(failure)とエラー(error)です。失敗は failureCondition が真になった、あるいは失敗条件を書いていないときに successCondition が偽になった場合。エラーはPrometheusのURLが不正でメトリクスを取得できないなど、測定自体が成立しなかった場合を指します。しきい値を詰める前に、そもそもクエリが値を返しているかを kubectl argo rollouts get rollout で確認してください。

Prometheus以外にも、Datadog、New Relic、CloudWatch、Graphite、InfluxDB、SkyWalking、Wavefront、Kayenta、任意のHTTPエンドポイントを叩くweb、Kubernetes Jobを実行するjob、そしてプラグイン方式が提供されています。既存の監視基盤に合わせて選べます。なお、本番トラフィックとは切り離してN個のバージョンを並走比較したい場合は、Rolloutとは別にExperimentリソースを使うと、指定した期間だけReplicaSetとAnalysisRunを立ち上げて比較できます。分析による昇格判断そのものの設計論はプログレッシブデリバリーとは?自動分析で昇格とロールバックを判断する実装と採用基準で扱っています。

トラフィックルーティングの対応プロバイダーと使い分け

細かい重み制御、ヘッダーベースのルーティング、ミラーリングを行うには、外部のトラフィックプロバイダーが必要です。v1.9.1時点でサポートされているのは次のとおりです。

種別 プロバイダー
サービスメッシュ Istio、Service Mesh Interface(SMI)
Ingress/ゲートウェイ Nginx Ingress Controller、AWS ALB Ingress Controller、Kong Ingress、Traefik Proxy、Apache APISIX、Ambassador Edge Stack、Gateway API(プラグイン方式)
クラウド Google Cloud
複合 Multiple Providers(複数併用)

どのプロバイダーでも、Rollout側にはカナリア用とStable用のServiceを両方書く必要があります。

spec:
  strategy:
    canary:
      canaryService: canary-service
      stableService: stable-service
      trafficRouting: {}   # 実際は istio: や nginx: などプロバイダー固有の設定を書く

Stable側がフルスケールで残る挙動とdynamicStableScale

ルーターを併用すると、コントローラーの挙動が一点変わります。トラフィック配分をメッシュ側が持つため、Stable側のReplicaSetはカナリア進行中もフルスケールのまま維持されます。いつ切り戻しても100%を受けられる状態を保つためで、その分だけ移行中のPod総数は増えます。レプリカ数が大きくリソースコストが問題になる場合や、ノードを増設できないベアメタル環境では canary.dynamicStableScale: true を設定すると、カナリアへ重みが移るのに合わせてStable側を段階的に縮退できます。ただしこの設定を入れると、abort時にカナリア側も traffic の戻りに合わせて縮退するため、切り戻し検証のためにカナリアを残したい場合は abortScaleDownDelaySeconds を明示してください。ヘッダーベースやミラーのルートを管理させる機能(managed routes)は、v1.9.1時点ではIstioのみの対応です。Istio側の構成はIstioとは?サービスメッシュの仕組みとサイドカー/アンビエント方式・導入判断を解説【2026年版】を参照してください。

サービスメッシュを入れていない環境でもArgo Rolloutsは使えます。ルーターが無い場合はkube-proxyによる通常のService経由でReplicaSetの台数比によって分配されるだけで、導入の前提条件にはなりません。

既存Deploymentからの移行手順とworkloadRefのscaleDown設定

移行には2通りあります。DeploymentをRolloutへ書き換える方法と、Deploymentを残したまま workloadRef で参照する方法です。

前者で本番稼働中のDeploymentを直接置き換えると、切り替えのタイミングによってはダウンタイムが発生します。公式ドキュメントも、Deploymentを削除・縮退する前にRolloutを並走させるよう明記しています。並走中はPod数が一時的に倍になる点も見込んでおいてください。

後者の workloadRef は、Rolloutが既存Deploymentのテンプレートを参照する形です。以降の更新はDeployment側のPodテンプレートを変更して行います。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-ref-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: rollout-ref-deployment
  workloadRef:
    apiVersion: apps/v1
    kind: Deployment
    name: rollout-ref-deployment
    scaleDown: onsuccess
  strategy:
    canary:
      steps:
        - setWeight: 20
        - pause: {duration: 10s}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rollout-ref-deployment
spec:
  replicas: 0                # 参照される側は0へ縮退させておく
  selector:
    matchLabels:
      app: rollout-ref-deployment
  template:
    metadata:
      labels:
        app: rollout-ref-deployment
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:blue
          ports:
            - containerPort: 8080

参照される側のDeploymentは replicas: 0 へ落としておくか、scaleDown でコントローラーに畳ませます。scaleDown の値は3つあり、CRDに既定値は定義されていないため、いずれかを明示する必要があります。

  • never:Deploymentを縮退させない。切り戻し先を手元に残したい移行初期向け。
  • onsuccess:RolloutがHealthyになった後に縮退。ロールアウトが完了するまで旧Deploymentを丸ごと残すため、切り戻し先を最後まで確保したい場合の選択。
  • progressively:Rolloutのスケールアップに合わせて段階的に縮退。二重稼働の期間とPod数のピークをいずれも抑えられるため、リソース制約のあるクラスタ向け。

参照先Deploymentの世代はRolloutのアノテーション rollout.argoproj.io/workload-generation にコピーされ、Rolloutのstatusの workloadObservedGeneration と突き合わせることで、意図した世代が反映されているかを確認できます。段階リリースを入れず標準のローリング更新で足りるかどうかはローリングアップデートとは?仕組みとKubernetes・ECSの設定値・採用判断を解説と比較して決めてください。

Argo Rolloutsの採用を見送るべき条件

公式ドキュメントは機能の説明に徹していますが、実装側から見ると入れない方がよいケースがはっきりあります。

第一に、SLIを測れていない組織は導入しても自動化に届きません。AnalysisTemplateは既存のメトリクスにクエリを投げるだけで、判定に使う指標は利用者側で用意する前提です。成功率やレイテンシがダッシュボードで即答できない状態でRolloutへ移すと、結局 pause: {} で止めて人が目視する運用になり、Deploymentのままロールアウトを手動停止するのと変わりません。監視の整備が先です。

第二に、マルチクラスタを一元管理したい要件には応えられません。Argo CDと違い、コントローラーとRollout CRDはワークロードを動かすクラスタごとに必要です。中央のクラスタから外部クラスタのRolloutを回す構成は設計上サポートされていません。クラスタ数だけコントローラーの運用対象が増えます。

第三に、リリース頻度が月数回以下で、障害時の切り戻しが数分で済むシステムでは、CRDとコントローラーを増やすコストが段階リリースの利益を上回りがちです。この場合はDeploymentの maxSurgemaxUnavailable の調整と、ヘルスチェックの精度を上げる方が費用対効果が高くなります。

逆に、コントローラー自体の可用性は懸念材料になりません。--leader-elect フラグを付けてレプリカを増やせばHA構成で動き、リーダー選出はclient-goのleaderelectionパッケージに基づくためレプリカ間の時刻ずれにも耐えます。--leader-election-lease-duration--leader-election-renew-deadline で許容度を調整できます。

よくある質問

Argo Rolloutsを使うにはArgo CDが必要ですか?

不要です。Argo Rolloutsは単独で動くKubernetesコントローラーで、同じクラスタにArgo CDが入っている必要はありません。組み合わせた場合はArgo CDがLuaのヘルスチェックでRolloutのProgressing/Suspended/Degraded/Healthyを解釈し、resumeとrestartをリソースアクションとして実行できるようになります。

Kubernetesのロールアウトとどう違うのですか?

標準のDeploymentが提供するのはローリングアップデートで、新旧Podを入れ替えながら置き換える方式です。重みを段階的に上げる、途中で止める、メトリクスを見て自動で戻すといった制御は書けません。Argo RolloutsはRollout CRDでその手順を宣言し、BlueGreen・Canary・RollingUpdateの3戦略を扱えるようにします。

Argo RolloutsはIstioなどのサービスメッシュが前提ですか?

前提ではありません。トラフィックルーターが無い環境では、コントローラーがカナリアとStableのReplicaSetの台数比を操作して重みを近似し、kube-proxyの通常のServiceルーティングで分配します。1%刻みの重み制御やヘッダーベースのルーティングが必要になった時点で、Istioなど対応プロバイダーの導入を検討すれば十分です。

自動ロールバックが起きたとき、Gitのマニフェストは書き戻されますか?

書き戻されません。Argo Rolloutsはクラスタ内のRolloutリソースを安定版へ戻し、アプリケーションをDegradedとして扱うだけで、Gitリポジトリには一切触れません。Argo CDと併用しても同期の無限ループは起きません。Git上のRolloutオブジェクトとクラスタ上のそれはどちらもN+1のままで差分が出ないため、Argo CDは追加の同期動作を行わず、ArgoCD側とArgo Rollouts側の両方でDegradedと表示されます。公式FAQはGitへの書き戻しを「通常は不要」とし、原因を修正して次のバージョンをロールフォワードする運用を推奨しています。

kubectlプラグインのバージョンはコントローラーと揃える必要がありますか?

厳密に揃える必要はありません。プラグインはRolloutオブジェクトにパッチを当てるか、フィールドを読むだけで、独立したAPIを持ちません。Rollout仕様からフィールドを意図的に削除する破壊的変更は行われていないため、古いプラグインでも新しいコントローラーに対して動作します。ただし新機能のフィールドは古いプラグインが解釈できません。

関連記事

資料請求

RELATED POSTS 関連記事