TECHSTEP

ITインフラ関連の記事を公開してます。

Argo Rolloutsに入門する

先日ArgoCDを利用してみましたが、今回は同じArgo Projectの中からArgo Rolloutsを試してみました。Argo Rolloutsを利用することで、より高度なデプロイ・リリースを実現することができます。

リリース方式の違いと特徴について

Argo Rolloutsを利用する前に、Kubernetes上で利用することの多いデリバリー/リリース方式について整理しておきます。なお、記載に当たり、以下のドキュメントを参照いたしました。

※参考ドキュメント:

Rolling Update

KubernetesでPod(Deployment)をデプロイする際に利用できる方法として、デフォルトではRecreate Rolling Updateなどの方法があります。特にアプリケーションのダウンタイムをゼロにするRolling Updateは、様々なアプリケーションで利用されていると思われます。

Rolling Updateでは、稼働中のPodが新しいバージョンに置き換わるまで、一つずつPodがアップグレードされます。新しいバージョンのPodが起動するまでは、それまで稼働していた古いバージョンの残りのPodが通信を受け付け、新しいバージョンのPodが起動すると別の古いバージョンのPodがアップデートを開始します。

Rolling Updateを利用すると、一時的に複数のアプリケーションのバージョンが同居することになりますが、アプリケーション全体としてはダウンタイムが発生することなくアップデートを完了することができます。

※画像:Search ITOperations

rolling-update

Rolling UpdateはKubernetesのDeploymentリソースにてspec.strategy.type: RollingUpdateがデフォルトで設定されています。またアップデート時にPodの数をどのように増減させるかはspec.strategy.rollingUpdate.maxSurge spec.strategy.rollingUpdate.maxUnavailableを設定することでコントロールすることができます。

このようにゼロダウンタイムでのアップデートを実現することのできるRolling Updateですが、いくつかの欠点も抱えています。そのため、大規模な本番環境で採用するにはリスクが高いと考えられています。

異なるバージョンが混在する状況が生まれる

前述の通りRolling Updateでは同じクラスター上に異なるバージョンのPodが共存する状況が発生し、アプリケーションによってはこの状況が望ましくない場合があります。例えば、バージョン間で著しく機能やUIに差分がある場合、ユーザーごとに異なる体験をすることになります。アプリケーションのサポートは2つのバージョンについて把握する必要があり、またユーザーがどちらのバージョンを利用しているか識別できるようにしなければなりません。

また、異なるバージョンが同時に稼働することでN-1 data compatibilityという問題も発生します。これは新しいバージョンで書き込まれたデータが古いバージョンでも読み込めるようにしなければならないことを指しますが、他のデプロイ方法でも同様に問題となる項目となります。

ロールアウトの実行時間が長くなる

Rolling Updateでは基本的に1つずつPodを更新するので、Podが大量に存在する場合はアップデートの完了までに非常に時間がかかる場合があります。前述のmaxSurge maxUnavailableを変更することで、アップデートが完了するまでの時間を短縮することはできますが、クラスターにかかる負荷が増加するなどのデメリットも存在します。またmaxSurge maxUnavailableをどの程度の値にすればよいかは環境に依存するため、最適値を求めるまでに試行錯誤が必要になります。

その他
  • トランザクションやセッションが失われる: 新しいPodへと通信先が変わるため、トランザクションやセッションが切断されます。こちらも他のデプロイ方法で共通の問題となる項目になります。

  • アップデートを検証するために外部メトリクスにクエリを投げる機能がない: いつアップデートが完了したかを知ることが難しくなります。

  • アップデートを停止することはできるが、自動的にアップデートを停止してロールバックする方法がない: アップデートに失敗した場合も、自動的にロールバックをすることができず、オペレーションが必要となります。

Blue/Green Deployment

Blue/Green DeploymentはRolling Updateと異なり、Podを一つずつ更新するのではなく、まず新しいバージョンのアプリケーションが起動するための環境を別に作成し、通信の先を新しいバージョンへ一斉に切り替えます。

※画像:Search ITOperations

blue-green

新しいバージョンへの切り替えは一瞬で完了するため、ユーザーが切り替えに気づく前に完了することができます。

またユーザーの利用できるバージョンを一斉に切り替えるため、複数のバージョンが共存している状況については考える必要がなくなります。また新しいバージョンで問題が発生した場合は、通信先を古いバージョンへ戻すことで、素早いロールバックを実現することもできます。

Blue/Green Deploymentによるもう一つの大きな利点は、本番環境でのテストを実行することができるという点です。アプリケーションの稼働する環境を事前に用意するため、新しいアプリケーションに対してのテストを、本番環境で実施することができます。また、それでも新しいバージョンで問題が発生した場合も、古いバージョンに切り替えることで対応することができます。

一方でBlue/Green Deploymentにも問題はあります。

  • アプリケーションを起動するための2倍のスペックが必要: 切り替え時には新しいバージョンの動作環境を用意するため、アプリケーションを起動するのに必要なスペックの2倍を用意する必要があります。

  • N-1 data compatibilityへの対応が必要: 異なるバージョンが同時に起動する状況は防ぐことができますが、バージョン間でのデータの互換性は担保する必要があります。

  • トランザクションやセッションが失われる

Canary Deployment

Canary Deploymentは、新しいバージョンの環境を一部のユーザーだけに提供し、問題がなければ他のユーザーに対しても新しいバージョンを提供する方法です。一部のユーザーに対して新しいバージョンを先に提供するという意味ではRolling Updateとも似ているように見えますが、Canary Deploymentでは特定のユーザーをターゲットにしている点で異なります。

※画像:Search ITOperations

canary

Canary Deploymentを採用することで、より早期のフィードバックとバグの特定を行うことができます。特定のユーザーグループからのフィードバックを得ることで、全てのユーザーに新しいバージョンを展開する前に改善をすることができます。何か問題が発生したとしても、その影響範囲をごく一部に限定することができます。

またBlue/Green Deploymentのように、アプリケーションを動作する2倍のキャパシティを持つ環境を用意する必要もなくなります。

Progressive Delivery

Progressive DeliveryはCDの次のステップとして位置づけられた比較的新しい方法です。新しいバージョンのアプリケーションなどを一部のユーザーに向けてデプロイし、全てのユーザー向けに公開する前に、デプロイしたアプリケーションに対する評価を行い、基準を満たさなければロールバックを実行します。従来のデリバリーに「分析」という観点を加えることで、CDパイプラインによるデプロイスピードと、デプロイに伴うリスクの軽減を実現することが期待されます。

Progressive Deliveryは「Release Progression」と「Progressive Delegation」という2つの観点を含んでいます。Release Progressionは、ビジネスとして適したタイミングでエンドユーザーへアプリケーションや機能をリリースすることを意味します。新機能のデプロイ後にスモークテストを実施したり、一部ユーザーからの利用状況などをベースにして評価を行い、基準を下回る場合は自動的にロールバックを行います。Progressive Delegationは、機能のリリースに関する制御権を、それがビジネスに対してもたらす結果に責任を持つ者へと委任することを意味します。エンジニア以外のチームに機能リリースの制御権を委任し、ビジネス的により適切なタイミングで新機能をリリースすることを可能にします。

Progressive Deliveryにより、リリースへのリスクを軽減することが可能になります。一部のユーザーにのみ先行して機能を提供し、さらに問題があれば以前のバージョンへと切り戻すことで、リリース時に生じる不安感を軽減し、より迅速にデプロイを行うことにつながります。

Argo Rolloutsとは

Argo RolloutsはBlue/Green Deployment、Canary Release、Progressive Deliveryなどのデプロイメント方式をKubernetes上で実現するために開発されたプロダクトになります。Argo Rolloutsでは、以下のような機能を提供し、ArgoCDだけでは実現が難しいデプロイプロセスも実現することができます。

Argo Rolloutsの機能

Blue/Green Deployment・Canary Deploymentの利用

Argo RolloutsはBlue/Green DeploymentやCanary Releaseなどのリリース方式を提供します。Argo RolloutsはRolloutというCRDを利用し、spec.strategyにリリース方式やその内容を定義することで、Rolling Updateよりも高度なデプロイ・リリースを実現します。

spec.strategy.blueGreenを利用する場合、そのRolloutリソースと紐づけるServiceを指定する必要があります。コンテナイメージタグの変更などによってRolloutマニフェストが更新される、と新しいReplicaSetが作成されます。ReplicaSetが正常にデプロイされHealthyとなると、古いPodから新しいPodへ、Serviceからのトラフィック転送先が変更されます。

spec.strategy.canaryを利用する場合、Rolloutにリリースのステップを定義する必要があります。例えばsetWeightではCanary側へ送るトラフィック流量を指定することができます。またpauseを利用すると、条件を満たす、あるいは管理者がステップを進行するよう操作するまで、リリースステップを一時的に中断することができます。

※参考ドキュメント:

自動ロールバック

Argo RolloutsにはAnalysisTemplate AnalysisRunなどのCRDが存在します。これらはRollout中に利用するAnalysisを指定し、その結果によってデプロイ・リリースを進行したり、中断して自動的にロールバックすることを可能にします。

例えばBlue/Green Deploymentではspec.strategy.blueGreen.postPromotionAnalysisという項目で、あらかじめ作成したAnalysisを指定し、その結果に問題がある場合は前のバージョンにロールバックをするよう定義することが可能となります。

※参考ドキュメント:

トラフィックコントロール

Argo Rolloutsは、以下の様なService Meshリソースを操作することで、高度なトラフィックコントロールを実現します。現在対応しているリソースは以下の通りです。

  • Istio
  • Nginx Ingress Controller
  • AWS ALB Ingress Controller
  • Service Mesh Interface (SMI)

※参考ドキュメント:

Progressive Deliveryを実現する分析機能

「自動ロールバック」の項でも少し触れましたが、Argo RolloutsはRolloutに加え、Progressive Deliveryを実現するうえで必要な「分析」に関するCRDを複数備えています。

  • AnalysisTemplate: どのような分析を行うかを定義するテンプレート。Namespace単位で利用することが可能で、利用するメトリクスや実行頻度、成功・失敗を決定する値などを指定します。
  • ClusterAnalysisTemplate: AnalysisTemplateと同じような役割を担いますが、クラスター全体を対象にします。
  • AnalysisRun: AnalysisTemplateを実行するために利用する、KubernetesJobリソースのようなもの。AnalysisRunの結果が、Rolloutのアップデートを継続するか中断するかなどを決定します。
  • Experiment: 分析を行うため、1つ以上のReplicaSetを実行します。

上記CRDはRollout中に指定し、アップデートの過程で実行したり、常時実行するよう設定することも可能です。またBlue/Green Deploymentでは、デプロイ後の切り替え前・切り替え後にAnalysisTemplateを指定することなどもできます。

Analysisに利用できるメトリクスとしては、KubernetesJobWavefrontメトリクスなどがあります。

※参考ドキュメント:

その他

Argo Rolloutsの利用方法

ここからは実際にArgo Rolloutsを利用してみます。今回はArgo Rolloutsドキュメントで紹介されている例を試してみます。

構築環境

今回のKubernetes環境は以下の通りです。

Argo Rolloutsのデプロイ

まずはArgo Rolloutsをデプロイします。

# Argo Rolloutsデプロイ
$ kubectl get ns
NAME              STATUS   AGE
default           Active   21h
kube-node-lease   Active   21h
kube-public       Active   21h
kube-system       Active   21h

$ kubectl create namespace argo-rollouts
namespace/argo-rollouts created

$ kubectl get ns
NAME              STATUS   AGE
argo-rollouts     Active   3s
default           Active   21h
kube-node-lease   Active   21h
kube-public       Active   21h
kube-system       Active   21h

$ kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml
customresourcedefinition.apiextensions.k8s.io/analysisruns.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/analysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/clusteranalysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/experiments.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/rollouts.argoproj.io created
serviceaccount/argo-rollouts created
role.rbac.authorization.k8s.io/argo-rollouts-role created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-admin created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-edit created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-view created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-clusterrole created
rolebinding.rbac.authorization.k8s.io/argo-rollouts-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/argo-rollouts-clusterrolebinding created
service/argo-rollouts-metrics created
deployment.apps/argo-rollouts created


# デプロイ後の確認
$ kubectl get crd
NAME                                         CREATED AT
analysisruns.argoproj.io                     2020-10-10T01:51:57Z
analysistemplates.argoproj.io                2020-10-10T01:51:57Z
clusteranalysistemplates.argoproj.io         2020-10-10T01:51:57Z
eniconfigs.crd.k8s.amazonaws.com             2020-10-09T04:46:45Z
experiments.argoproj.io                      2020-10-10T01:51:57Z
rollouts.argoproj.io                         2020-10-10T01:51:58Z
securitygrouppolicies.vpcresources.k8s.aws   2020-10-09T04:46:47Z

$ kubectl get sa -n argo-rollouts
NAME            SECRETS   AGE
argo-rollouts   1         31s
default         1         48s

$ kubectl get role -n argo-rollouts
NAME                 AGE
argo-rollouts-role   53s

$ kubectl get rolebinding -n argo-rollouts
NAME                         AGE
argo-rollouts-role-binding   74s

$ kubectl get clusterrole
NAME                                                                   AGE
admin                                                                  21h
argo-rollouts-aggregate-to-admin                                       88s★
argo-rollouts-aggregate-to-edit                                        88s★
argo-rollouts-aggregate-to-view                                        87s★
argo-rollouts-clusterrole                                              87s★
aws-node                                                               21h
cluster-admin                                                          21h
edit                                                                   21h
eks:fargate-manager                                                    21h
eks:node-bootstrapper                                                  21h
eks:node-manager                                                       21h
eks:podsecuritypolicy:privileged                                       21h
system:aggregate-to-admin                                              21h
system:aggregate-to-edit                                               21h
system:aggregate-to-view                                               21h
system:auth-delegator                                                  21h
system:basic-user                                                      21h
system:certificates.k8s.io:certificatesigningrequests:nodeclient       21h
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   21h
system:controller:attachdetach-controller                              21h
system:controller:certificate-controller                               21h
system:controller:clusterrole-aggregation-controller                   21h
system:controller:cronjob-controller                                   21h
system:controller:daemon-set-controller                                21h
system:controller:deployment-controller                                21h
system:controller:disruption-controller                                21h
system:controller:endpoint-controller                                  21h
system:controller:expand-controller                                    21h
system:controller:generic-garbage-collector                            21h
system:controller:horizontal-pod-autoscaler                            21h
system:controller:job-controller                                       21h
system:controller:namespace-controller                                 21h
system:controller:node-controller                                      21h
system:controller:persistent-volume-binder                             21h
system:controller:pod-garbage-collector                                21h
system:controller:pv-protection-controller                             21h
system:controller:pvc-protection-controller                            21h
system:controller:replicaset-controller                                21h
system:controller:replication-controller                               21h
system:controller:resourcequota-controller                             21h
system:controller:route-controller                                     21h
system:controller:service-account-controller                           21h
system:controller:service-controller                                   21h
system:controller:statefulset-controller                               21h
system:controller:ttl-controller                                       21h
system:coredns                                                         21h
system:discovery                                                       21h
system:heapster                                                        21h
system:kube-aggregator                                                 21h
system:kube-controller-manager                                         21h
system:kube-dns                                                        21h
system:kube-scheduler                                                  21h
system:kubelet-api-admin                                               21h
system:node                                                            21h
system:node-bootstrapper                                               21h
system:node-problem-detector                                           21h
system:node-proxier                                                    21h
system:persistent-volume-provisioner                                   21h
system:public-info-viewer                                              21h
system:volume-scheduler                                                21h
view                                                                   21h
vpc-resource-controller-role                                           21h

$ kubectl get clusterrolebinding
NAME                                                   AGE
argo-rollouts-clusterrolebinding                       96s★
aws-node                                               21h
cluster-admin                                          21h
eks:fargate-manager                                    21h
eks:kube-proxy                                         21h
eks:kube-proxy-fargate                                 21h
eks:kube-proxy-windows                                 21h
eks:node-bootstrapper                                  21h
eks:node-manager                                       21h
eks:podsecuritypolicy:authenticated                    21h
system:basic-user                                      21h
system:controller:attachdetach-controller              21h
system:controller:certificate-controller               21h
system:controller:clusterrole-aggregation-controller   21h
system:controller:cronjob-controller                   21h
system:controller:daemon-set-controller                21h
system:controller:deployment-controller                21h
system:controller:disruption-controller                21h
system:controller:endpoint-controller                  21h
system:controller:expand-controller                    21h
system:controller:generic-garbage-collector            21h
system:controller:horizontal-pod-autoscaler            21h
system:controller:job-controller                       21h
system:controller:namespace-controller                 21h
system:controller:node-controller                      21h
system:controller:persistent-volume-binder             21h
system:controller:pod-garbage-collector                21h
system:controller:pv-protection-controller             21h
system:controller:pvc-protection-controller            21h
system:controller:replicaset-controller                21h
system:controller:replication-controller               21h
system:controller:resourcequota-controller             21h
system:controller:route-controller                     21h
system:controller:service-account-controller           21h
system:controller:service-controller                   21h
system:controller:statefulset-controller               21h
system:controller:ttl-controller                       21h
system:coredns                                         21h
system:discovery                                       21h
system:kube-controller-manager                         21h
system:kube-dns                                        21h
system:kube-scheduler                                  21h
system:node                                            21h
system:node-proxier                                    21h
system:public-info-viewer                              21h
system:volume-scheduler                                21h
vpc-resource-controller-rolebinding                    21h

$ kubectl get all -n argo-rollouts
NAME                                READY   STATUS    RESTARTS   AGE
pod/argo-rollouts-bf4f66974-mdwpq   1/1     Running   0          2m6s

NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/argo-rollouts-metrics   ClusterIP   10.100.214.129   <none>        8090/TCP   2m6s

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argo-rollouts   1/1     1            1           2m6s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/argo-rollouts-bf4f66974   1         1         1       2m6s

Argo Rollouts Pluginのインストール

続いてArgo RolloutsのPluginをインストールします。

$ curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/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: v0.9.1+3e25fa3
  BuildDate: 2020-09-28T21:50:53Z
  GitCommit: 3e25fa3dfc1788a4a00222d8cd020971d77d72a8
  GitTreeState: clean
  GoVersion: go1.13.1
  Compiler: gc
  Platform: linux/amd64

Rolloutのデプロイ

次にテスト用のRolloutリソースを作成します。今回利用するのは、以下のようにrollout-demoというコンテナイメージを利用したものです。rollout-demoイメージは、複数の「色」をタグに利用することができ(yellow / green / redなど)、デプロイ後のロールアウトは、イメージのタグを変更することで実行します。

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

上記ファイルについて、少しだけ追記します。

  • Rollout: Rolloutリソースの定義は、KubernetesDeploymentと似たような構成となっており、既にKubernetesを利用している方には使いやすいものかと思います。
  • spec.strategy.canary.steps: 今回のRolloutではCanary Deploymentを利用します。またspec.strategy.canary.stepsでは、各ステップのトラフィック流入量 (setWeight)と一時停止 (pause)の処理を指定しています。

なお、Traffic Managementを利用しない場合、各ステップで指定したsetWeightの値に従って、新しいPodが作成されます。今回はspec.replicas5に設定していますが、最初のステップにあるsetWeight: 20が実行されると、新しいReplicaSetのほうにPodが「1つ」作成され、古いReplicaSetのほうのPodが「1つ」削除されます。以降setWeightの数が増加するに従って、新旧のReplicaSetでのPod数が増減します。spec.replicasをコントロールせずにトラフィックを制御してい場合は、Traffic Managementの機能を利用する必要があります。

# GitHubリポジトリのクローン
$ git clone https://github.com/argoproj/argo-rollouts.git
$ cd argo-rollouts/docs/getting-started/basic/


# Rolloutリソースのデプロイ
$ kubectl apply -f rollout.yaml
rollout.argoproj.io/rollouts-demo created

$ kubectl apply -f service.yaml
service/rollouts-demo created


# デプロイ後の確認
$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
rollouts-demo-7bf84f9696-57qs6   1/1     Running   0          14s
rollouts-demo-7bf84f9696-hv5hz   1/1     Running   0          14s
rollouts-demo-7bf84f9696-vtz2m   1/1     Running   0          14s
rollouts-demo-7bf84f9696-wbwrk   1/1     Running   0          14s
rollouts-demo-7bf84f9696-xp6dt   1/1     Running   0          14s

$ kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.100.0.1      <none>        443/TCP   35h
rollouts-demo   ClusterIP   10.100.36.201   <none>        80/TCP    11s

$ kubectl get rollout
NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE
rollouts-demo   5         5         5            5

$ kubectl argo rollouts get rollout rollouts-demo
Name:            rollouts-demo
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          argoproj/rollouts-demo:blue (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       5
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS     AGE  INFO
⟳ rollouts-demo                            Rollout     ✔ Healthy  65s
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy  65s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running  65s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running  65s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running  65s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running  65s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-xp6dt  Pod         ✔ Running  65s  ready:1/1

※参考ドキュメント:

Rolloutのアップデート

次にデプロイしたRolloutで利用するコンテナイメージを変更し、アップデートを行います。Rolloutspec.templateに変更が走ったときにそれを検知し、アップデートを開始します。ここではkubectl argo rollouts set imageコマンドを利用し、コンテナイメージを変更します。

# マニフェストファイル更新の前に別のターミナルを開き、実行しておく
$ kubectl argo rollouts get rollout rollouts-demo --watch

# イメージタグの変更
$ kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow
rollout "rollouts-demo" image updated

コンテナイメージを変更すると、別ウィンドウでは以下のように表示内容が変化し、アップデートの進行状況を確認することができます。今回のspec.strategy.canary.stepsでは、まず20%

# ロールアウトの経過を確認する
## 変更直後
Name:            rollouts-demo
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          argoproj/rollouts-demo:blue (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       5
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS     AGE   INFO
⟳ rollouts-demo                            Rollout     ✔ Healthy  2m3s
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy  2m3s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running  2m3s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running  2m3s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running  2m3s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running  2m3s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-xp6dt  Pod         ✔ Running  2m3s  ready:1/1


## ロールアウトの開始 (StatusがProgressingになる)
Name:            rollouts-demo
Namespace:       default
Status:          ◌ Progressing
Strategy:        Canary
  Step:          0/8
  SetWeight:     20
  ActualWeight:  0
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       6
  Updated:       1
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS         AGE   INFO
⟳ rollouts-demo                            Rollout     ◌ Progressing  2m5s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ◌ Progressing  1s    canary
│     └──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running      1s    ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy      2m5s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running      2m5s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running      2m5s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running      2m5s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running      2m5s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-xp6dt  Pod         ✔ Running      2m5s  ready:1/1


## 1つ目のステップ (setWeight: 20)が完了し、Status=Pausedになる
Name:            rollouts-demo
Namespace:       default
Status:          ॥ Paused
Strategy:        Canary
  Step:          1/8
  SetWeight:     20
  ActualWeight:  20
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       5
  Updated:       1
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS     AGE    INFO
⟳ rollouts-demo                            Rollout     ॥ Paused   2m19s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy  15s    canary
│     └──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running  15s    ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy  2m19s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running  2m19s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running  2m19s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running  2m19s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running  2m19s  ready:1/1

Rolloutの進行

テスト用のRolloutの定義を見ると、spec.strategy.canary.stepspauseが定義されています。上記までの手順では、2つ目のステップの時点でpauseがセットされており、またその終了条件が記載されていません。これを以降のステップへ進行するため、kubectl argo rolloutsコマンドを実行します。

# Pauseを完了する前に、別のターミナルを開き、実行しておく
$ kubectl argo rollouts get rollout rollouts-demo --watch


# Pause状態からの進行を行う
$ kubectl argo rollouts promote rollouts-demo
rollout 'rollouts-demo' promoted


# ロールアウトの経過を確認する
## 変更直後
Name:            rollouts-demo
Namespace:       default
Status:          ॥ Paused
Strategy:        Canary
  Step:          1/8
  SetWeight:     20
  ActualWeight:  20
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       5
  Updated:       1
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS     AGE    INFO
⟳ rollouts-demo                            Rollout     ॥ Paused   4m23s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy  2m19s  canary
│     └──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running  2m19s  ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy  4m23s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running  4m23s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running  4m23s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running  4m23s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running  4m23s  ready:1/1


## 進行開始
### StatusがProgressingになる
Name:            rollouts-demo
Namespace:       default
Status:          ◌ Progressing
Strategy:        Canary
  Step:          2/8
  SetWeight:     40
  ActualWeight:  20
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       5
  Updated:       1
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS         AGE    INFO
⟳ rollouts-demo                            Rollout     ◌ Progressing  4m23s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ◌ Progressing  2m19s  canary
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running      2m19s  ready:1/1
│     └──□ rollouts-demo-789746c88d-nnv2n  Pod         ◌ Pending      0s     ready:0/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy      4m23s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running      4m23s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running      4m23s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running      4m23s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running      4m23s  ready:1/1


### Pauseが終了し、次のステップに移行 (新しいPodが作成され始める)

Name:            rollouts-demo
Namespace:       default
Status:          ◌ Progressing
Strategy:        Canary
  Step:          2/8
  SetWeight:     40
  ActualWeight:  20
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       6
  Updated:       2
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS               AGE    INFO
⟳ rollouts-demo                            Rollout     ◌ Progressing        4m24s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ◌ Progressing        2m20s  canary
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running            2m20s  ready:1/1
│     └──□ rollouts-demo-789746c88d-nnv2n  Pod         ◌ ContainerCreating  1s     ready:0/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy            4m24s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running            4m24s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running            4m24s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running            4m24s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running            4m24s  ready:1/1

### 新しいPodが作成される

Name:            rollouts-demo
Namespace:       default
Status:          ◌ Progressing
Strategy:        Canary
  Step:          2/8
  SetWeight:     40
  ActualWeight:  20
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       6
  Updated:       2
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS         AGE    INFO
⟳ rollouts-demo                            Rollout     ◌ Progressing  4m24s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ◌ Progressing  2m20s  canary
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running      2m20s  ready:1/1
│     └──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running      1s     ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy      4m24s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running      4m24s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running      4m24s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running      4m24s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ✔ Running      4m24s  ready:1/1


## 以降のステップがが順次進行される
Name:            rollouts-demo
Namespace:       default
Status:          ◌ Progressing
Strategy:        Canary
  Step:          4/8
  SetWeight:     60
  ActualWeight:  40
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       5
  Current:       6
  Updated:       3
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS               AGE    INFO
⟳ rollouts-demo                            Rollout     ◌ Progressing        4m34s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ◌ Progressing        2m30s  canary
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running            2m30s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running            11s    ready:1/1
│     └──□ rollouts-demo-789746c88d-vghjp  Pod         ◌ ContainerCreating  0s     ready:0/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy            4m34s  stable
      ├──□ rollouts-demo-7bf84f9696-57qs6  Pod         ✔ Running            4m34s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-hv5hz  Pod         ✔ Running            4m34s  ready:1/1
      ├──□ rollouts-demo-7bf84f9696-vtz2m  Pod         ✔ Running            4m34s  ready:1/1
      └──□ rollouts-demo-7bf84f9696-wbwrk  Pod         ◌ Terminating        4m34s  ready:1/1


## 完了後
Name:            rollouts-demo
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       5
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS         AGE    INFO
⟳ rollouts-demo                            Rollout     ✔ Healthy      5m17s
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy      3m13s  stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running      3m13s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running      54s    ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running      43s    ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running      32s    ready:1/1
│     └──□ rollouts-demo-789746c88d-8plpp  Pod         ✔ Running      21s    ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown   5m17s
      └──□ rollouts-demo-7bf84f9696-57qs6  Pod         ◌ Terminating  5m17s  ready:0/1

また完了後のPod・Rolloutなどのリソースは以下のようになっています。

$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
rollouts-demo-789746c88d-8plpp   1/1     Running   0          2m41s
rollouts-demo-789746c88d-gjgbl   1/1     Running   0          5m33s
rollouts-demo-789746c88d-jsjxg   1/1     Running   0          2m52s
rollouts-demo-789746c88d-nnv2n   1/1     Running   0          3m14s
rollouts-demo-789746c88d-vghjp   1/1     Running   0          3m3s


$ kubectl get rollout
NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE
rollouts-demo   5         5         5            5


$ kubectl describe rollout rollouts-demo
Name:         rollouts-demo
Namespace:    default
Labels:       <none>
Annotations:  rollout.argoproj.io/revision: 2
API Version:  argoproj.io/v1alpha1
Kind:         Rollout
Metadata:
  Creation Timestamp:  2020-10-10T16:00:06Z
  Generation:          45
  Resource Version:    393821
  Self Link:           /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/rollouts-demo
  UID:                 77fe4f75-920b-4286-957f-3d4dd22a6639
Spec:
  Paused:                  false
  Replicas:                5
  Revision History Limit:  2
  Selector:
    Match Labels:
      App:  rollouts-demo
  Strategy:
    Canary:
      Steps:
        Set Weight:  20
        Pause:
        Set Weight:  40
        Pause:
          Duration:  10
        Set Weight:  60
        Pause:
          Duration:  10
        Set Weight:  80
        Pause:
          Duration:  10
  Template:
    Metadata:
      Creation Timestamp:  <nil>
      Labels:
        App:  rollouts-demo
    Spec:
      Containers:
        Image:  argoproj/rollouts-demo:yellow
        Name:   rollouts-demo
        Ports:
          Container Port:  8080
          Name:            http
          Protocol:        TCP
        Resources:
          Requests:
            Cpu:     5m
            Memory:  32Mi
Status:
  HPA Replicas:        5
  Available Replicas:  5
  Blue Green:
  Canary:
    Stable RS:  789746c88d
  Conditions:
    Last Transition Time:  2020-10-10T16:00:09Z
    Last Update Time:      2020-10-10T16:00:09Z
    Message:               Rollout has minimum availability
    Reason:                AvailableReason
    Status:                True
    Type:                  Available
    Last Transition Time:  2020-10-10T16:05:02Z
    Last Update Time:      2020-10-10T16:05:03Z
    Message:               ReplicaSet "rollouts-demo-789746c88d" has successfully progressed.
    Reason:                NewReplicaSetAvailable
    Status:                True
    Type:                  Progressing
  Current Pod Hash:        789746c88d
  Current Step Hash:       f64cdc9d
  Current Step Index:      8
  Observed Generation:     fcd8c79f9
  Ready Replicas:          5
  Replicas:                5
  Selector:                app=rollouts-demo
  Stable RS:               789746c88d
  Updated Replicas:        5
Events:
  Type    Reason             Age                  From                 Message
  ----    ------             ----                 ----                 -------
  Normal  ScalingReplicaSet  8m3s                 rollouts-controller  Scaled up replica set rollouts-demo-7bf84f9696 to 5
  Normal  SettingStableRS    8m3s                 rollouts-controller  Setting StableRS to CurrentPodHash: StableRS hash: 7bf84f9696
  Normal  ScalingReplicaSet  5m59s                rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 1
  Normal  ScalingReplicaSet  5m58s                rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 4
  Normal  SetStepIndex       5m58s                rollouts-controller  Set Step Index to 1
  Normal  SetStepIndex       3m40s                rollouts-controller  Set Step Index to 2
  Normal  ScalingReplicaSet  3m40s                rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 2
  Normal  ScalingReplicaSet  3m39s                rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 3
  Normal  SetStepIndex       3m39s                rollouts-controller  Set Step Index to 3
  Normal  SetStepIndex       3m29s                rollouts-controller  Set Step Index to 4
  Normal  ScalingReplicaSet  3m29s                rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 3
  Normal  ScalingReplicaSet  3m28s                rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 2
  Normal  SetStepIndex       3m28s                rollouts-controller  Set Step Index to 5
  Normal  SetStepIndex       3m18s                rollouts-controller  Set Step Index to 6
  Normal  ScalingReplicaSet  3m18s                rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 4
  Normal  ScalingReplicaSet  3m18s                rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 1
  Normal  SetStepIndex       3m17s                rollouts-controller  Set Step Index to 7
  Normal  SettingStableRS    3m7s                 rollouts-controller  Completed all steps
  Normal  SetStepIndex       3m7s                 rollouts-controller  Set Step Index to 8
  Normal  ScalingReplicaSet  3m6s (x2 over 3m7s)  rollouts-controller  (combined from similar events): Scaled down replica set rollouts-demo-7bf84f9696 to 0

Rolloutの中断

次に、先ほどPause状態から次ステップへ進めた段階でロールアウトを中断する例を見てみます。先ほどデプロイしたRolloutを引き続き利用し、今度はイメージタグをredに変更します。

# 別のターミナルで実行
$ kubectl argo rollouts get rollout rollouts-demo --watch


# イメージタグの更新
$ kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:red
rollout "rollouts-demo" image updated


# Pause状態まで待機
Name:            rollouts-demo
Namespace:       default
Status:          ॥ Paused
Strategy:        Canary
  Step:          1/8
  SetWeight:     20
  ActualWeight:  20
Images:          argoproj/rollouts-demo:red (canary)
                 argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       1
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS         AGE    INFO
⟳ rollouts-demo                            Rollout     ॥ Paused       9m11s
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  ✔ Healthy      8s     canary
│     └──□ rollouts-demo-6f75f48b7-4pg88   Pod         ✔ Running      8s     ready:1/1
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy      7m7s   stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running      7m7s   ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running      4m48s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running      4m37s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running      4m26s  ready:1/1
│     └──□ rollouts-demo-789746c88d-8plpp  Pod         ◌ Terminating  4m15s  ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown   9m11s

Pause状態になったら、今回はkubectl argo rollouts abortコマンドを実行し、ロールアウトを中断します。

# 別のターミナルで実行
$ kubectl argo rollouts get rollout rollouts-demo --watch


# ロールアウトの中断
$ kubectl argo rollouts abort rollouts-demo
rollout 'rollouts-demo' aborted


# ロールアウトの経過を確認
## 中断直後
Name:            rollouts-demo
Namespace:       default
Status:          ॥ Paused
Strategy:        Canary
  Step:          1/8
  SetWeight:     20
  ActualWeight:  20
Images:          argoproj/rollouts-demo:red (canary)
                 argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       1
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS        AGE    INFO
⟳ rollouts-demo                            Rollout     ॥ Paused      10m
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  ✔ Healthy     97s    canary
│     └──□ rollouts-demo-6f75f48b7-4pg88   Pod         ✔ Running     97s    ready:1/1
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy     8m36s  stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running     8m36s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running     6m17s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running     6m6s   ready:1/1
│     └──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running     5m55s  ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown  10m


## 中断開始
Name:            rollouts-demo
Namespace:       default
Status:          ✖ Degraded
Strategy:        Canary
  Step:          0/8
  SetWeight:     0
  ActualWeight:  0
Images:          argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       0
  Ready:         4
  Available:     4

NAME                                       KIND        STATUS               AGE    INFO
⟳ rollouts-demo                            Rollout     ✖ Degraded           10m
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown         98s    canary
│     └──□ rollouts-demo-6f75f48b7-4pg88   Pod         ◌ Terminating        98s    ready:1/1
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ◌ Progressing        8m37s  stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running            8m37s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running            6m18s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running            6m7s   ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running            5m56s  ready:1/1
│     └──□ rollouts-demo-789746c88d-wqcjc  Pod         ◌ ContainerCreating  0s     ready:0/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown         10m


## 完了後
Name:            rollouts-demo
Namespace:       default
Status:          ✖ Degraded
Strategy:        Canary
  Step:          0/8
  SetWeight:     0
  ActualWeight:  0
Images:          argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       0
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS        AGE    INFO
⟳ rollouts-demo                            Rollout     ✖ Degraded    10m
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown  111s   canary
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy     8m50s  stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running     8m50s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running     6m31s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running     6m20s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running     6m9s   ready:1/1
│     └──□ rollouts-demo-789746c88d-wqcjc  Pod         ✔ Running     13s    ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown  10m

上記のようにロールバックを中断すると、StatusはDegradedとなります。これを再びHealthyの状態にするには、正常なイメージタグを指定して再デプロイする必要があります。既にデプロイ済みのバージョンを指定するので、デプロイ自体は高速で完了します。

# 別ターミナルで実行
$ kubectl argo rollouts get rollout rollouts-demo --watch


# 再デプロイ
$ kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow
rollout "rollouts-demo" image updated


# ロールアウトの経過を確認
## 再デプロイ直後
Name:            rollouts-demo
Namespace:       default
Status:          ✖ Degraded
Strategy:        Canary
  Step:          0/8
  SetWeight:     0
  ActualWeight:  0
Images:          argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       0
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS        AGE    INFO
⟳ rollouts-demo                            Rollout     ✖ Degraded    12m
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown  3m42s  canary
├──# revision:2
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy     10m    stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running     10m    ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running     8m22s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running     8m11s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running     8m     ready:1/1
│     └──□ rollouts-demo-789746c88d-wqcjc  Pod         ✔ Running     2m4s   ready:1/1
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown  12m


## 再デプロイの開始
Name:            rollouts-demo
Namespace:       default
Status:          ✖ Degraded
Strategy:        Canary
  Step:          0/8
  SetWeight:     0
  ActualWeight:  0
Images:          argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       0
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS        AGE    INFO
⟳ rollouts-demo                            Rollout     ✖ Degraded    12m
├──# revision:4
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy     10m    stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running     10m    ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running     8m23s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running     8m12s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running     8m1s   ready:1/1
│     └──□ rollouts-demo-789746c88d-wqcjc  Pod         ✔ Running     2m5s   ready:1/1
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown  3m43s  canary
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown  12m


## 完了後
Name:            rollouts-demo
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       5
  Ready:         5
  Available:     5

NAME                                       KIND        STATUS        AGE    INFO
⟳ rollouts-demo                            Rollout     ✔ Healthy     12m
├──# revision:4
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy     10m    stable
│     ├──□ rollouts-demo-789746c88d-gjgbl  Pod         ✔ Running     10m    ready:1/1
│     ├──□ rollouts-demo-789746c88d-nnv2n  Pod         ✔ Running     8m23s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-vghjp  Pod         ✔ Running     8m12s  ready:1/1
│     ├──□ rollouts-demo-789746c88d-jsjxg  Pod         ✔ Running     8m1s   ready:1/1
│     └──□ rollouts-demo-789746c88d-wqcjc  Pod         ✔ Running     2m5s   ready:1/1
├──# revision:3
│  └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown  3m43s
└──# revision:1
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  • ScaledDown  12m

また完了後のRolloutは以下のようになっています。

$ kubectl describe rollout rollouts-demo
Name:         rollouts-demo
Namespace:    default
Labels:       <none>
Annotations:  rollout.argoproj.io/revision: 4
API Version:  argoproj.io/v1alpha1
Kind:         Rollout
Metadata:
  Creation Timestamp:  2020-10-10T16:00:06Z
  Generation:          63
  Resource Version:    395343
  Self Link:           /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/rollouts-demo
  UID:                 77fe4f75-920b-4286-957f-3d4dd22a6639
Spec:
  Replicas:                5
  Revision History Limit:  2
  Selector:
    Match Labels:
      App:  rollouts-demo
  Strategy:
    Canary:
      Steps:
        Set Weight:  20
        Pause:
        Set Weight:  40
        Pause:
          Duration:  10
        Set Weight:  60
        Pause:
          Duration:  10
        Set Weight:  80
        Pause:
          Duration:  10
  Template:
    Metadata:
      Creation Timestamp:  <nil>
      Labels:
        App:  rollouts-demo
    Spec:
      Containers:
        Image:  argoproj/rollouts-demo:yellow
        Name:   rollouts-demo
        Ports:
          Container Port:  8080
          Name:            http
          Protocol:        TCP
        Resources:
          Requests:
            Cpu:     5m
            Memory:  32Mi
Status:
  HPA Replicas:        5
  Available Replicas:  5
  Blue Green:
  Canary:
    Stable RS:  789746c88d
  Conditions:
    Last Transition Time:  2020-10-10T16:10:48Z
    Last Update Time:      2020-10-10T16:10:48Z
    Message:               Rollout has minimum availability
    Reason:                AvailableReason
    Status:                True
    Type:                  Available
    Last Transition Time:  2020-10-10T16:12:52Z
    Last Update Time:      2020-10-10T16:12:52Z
    Message:               ReplicaSet "rollouts-demo-789746c88d" has successfully progressed.
    Reason:                NewReplicaSetAvailable
    Status:                True
    Type:                  Progressing
  Current Pod Hash:        789746c88d
  Current Step Hash:       f64cdc9d
  Current Step Index:      8
  Observed Generation:     fcd8c79f9
  Ready Replicas:          5
  Replicas:                5
  Selector:                app=rollouts-demo
  Stable RS:               789746c88d
  Updated Replicas:        5
Events:
  Type    Reason             Age                  From                 Message
  ----    ------             ----                 ----                 -------
  Normal  SettingStableRS    15m                  rollouts-controller  Setting StableRS to CurrentPodHash: StableRS hash: 7bf84f9696
  Normal  ScalingReplicaSet  15m                  rollouts-controller  Scaled up replica set rollouts-demo-7bf84f9696 to 5
  Normal  ScalingReplicaSet  13m                  rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 1
  Normal  ScalingReplicaSet  13m                  rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 4
  Normal  ScalingReplicaSet  11m                  rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 2
  Normal  SetStepIndex       11m                  rollouts-controller  Set Step Index to 2
  Normal  ScalingReplicaSet  11m                  rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 3
  Normal  SetStepIndex       11m                  rollouts-controller  Set Step Index to 3
  Normal  SetStepIndex       10m                  rollouts-controller  Set Step Index to 4
  Normal  ScalingReplicaSet  10m                  rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 3
  Normal  ScalingReplicaSet  10m                  rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 2
  Normal  SetStepIndex       10m                  rollouts-controller  Set Step Index to 5
  Normal  SetStepIndex       10m                  rollouts-controller  Set Step Index to 6
  Normal  ScalingReplicaSet  10m                  rollouts-controller  Scaled up replica set rollouts-demo-789746c88d to 4
  Normal  ScalingReplicaSet  10m                  rollouts-controller  Scaled down replica set rollouts-demo-7bf84f9696 to 1
  Normal  SetStepIndex       10m                  rollouts-controller  Set Step Index to 7
  Normal  SettingStableRS    10m                  rollouts-controller  Completed all steps
  Normal  SetStepIndex       10m                  rollouts-controller  Set Step Index to 8
  Normal  SetStepIndex       6m23s (x2 over 13m)  rollouts-controller  Set Step Index to 1
  Normal  ScalingReplicaSet  4m46s (x6 over 10m)  rollouts-controller  (combined from similar events): Scaled down replica set rollouts-demo-6f75f48b7 to 0
  Normal  SkipSteps          2m41s                rollouts-controller  Skipping all steps because the newRS is the stableRS.