Argo Rollouts v1.0のWorkload Referencingについて

概要

Argo Rolloutsを使用するためにはKubernetesのDeploymentをRolloutに変更する必要がありますが、それに伴っていくつか問題となることがあります。

最近新しくリリースされたArgo Rollouts v1.0で、そのあたりに関連するWorkload Referencingという機能が追加されたので、試してみました。

Workload Referencingとは?

pod templateの定義をRollout specから参照できるようにする機能です。
(これまでは、Rollout specにdeployment strategyとpod templateの両方を記述する必要がありました。)

単純な機能ですが、これにより以下のような問題が解決されます。

  • Argo Rollouts導入時、DeploymentからRolloutにマイグレーションする際に、RolloutからDeploymentを参照するだけでよくなり、楽に移行できるようになる。
  • Rolloutを使用した際、kustomizeのStrategic Merge Patchが期待通りに動作しなかった問題を解決できる。

Workload Referencingを試してみる

検証環境

検証時のバージョンは以下のものを使用しています。

  • Kubernetes: v1.21.1 (kindで作成)
  • Argo Rollouts: v1.0.1がKubernetesクラスタにインストール済み
  • Kubectl argo rollouts plugin: v1.0.1がローカル環境にインストール済み

Deploymentを作成

まずは、deployment.yamlを作成し、applyします。

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/instance: rollout-canary
  name: rollout-ref-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: rollout-ref-deployment
  template:
    metadata:
      labels:
        app: rollout-ref-deployment
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:blue
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
$ kubectl apply -f deployment.yaml
$ kubectl get pods
NAME                                     READY   STATUS    RESTARTS   AGE
rollout-ref-deployment-d96c446f7-2bg6q   1/1     Running   0          29s
rollout-ref-deployment-d96c446f7-fvjr2   1/1     Running   0          29s
rollout-ref-deployment-d96c446f7-vx28t   1/1     Running   0          29s

Workload Referencingを使ってDeploymentからRolloutにマイグレーション

rollout.yamlを作成します。ここで、Workload Referencing (workloadRef) を使って、先程のDeploymentを参照しています。

# rollout.yaml
apiVersion: argoproj.io/v1alpha1 # Create a rollout resource
kind: Rollout
metadata:
  name: rollout-ref-deployment
spec:
  replicas: 5
  workloadRef: # Reference an existing Deployment using workloadRef field
    apiVersion: apps/v1
    kind: Deployment
    name: rollout-ref-deployment
  strategy:
    canary:
      steps:
        - setWeight: 20
        - pause: { duration: 30s }

RolloutによってReplicaSet (Pod) が管理されるようになるため、Deploymentのreplicas0に変更します。

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/instance: rollout-canary
  name: rollout-ref-deployment
spec:
  # replicas: 3
  replicas: 0 # Scale down existing deployment
  selector:
    matchLabels:
      app: rollout-ref-deployment
  template:
    metadata:
      labels:
        app: rollout-ref-deployment
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:blue
          imagePullPolicy: Always
          ports:
            - containerPort: 8080

rollout.yamlとdeployment.yamlをapplyします。

$ kubectl apply -f rollout.yaml
$ kubectl apply -f deployment.yaml

クラスタ内のリソースを確認してみると、RolloutとDeploymentがそれぞれ別々のReplicaSetを管理しているのがわかります。そして、Rolloutに紐づいたPodが5つ、Deploymentに紐づいたPodが0になっています。

$ kubectl get rollouts,deploy,rs,po
NAME                                         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE
rollout.argoproj.io/rollout-ref-deployment   5         5         5            5

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/rollout-ref-deployment   0/0     0            0           23m

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/rollout-ref-deployment-75bbd56864   5         5         5       3m46s
replicaset.apps/rollout-ref-deployment-d96c446f7    0         0         0       23m

NAME                                          READY   STATUS    RESTARTS   AGE
pod/rollout-ref-deployment-75bbd56864-5ckmg   1/1     Running   0          3m46s
pod/rollout-ref-deployment-75bbd56864-9v5sb   1/1     Running   0          3m46s
pod/rollout-ref-deployment-75bbd56864-c8wpc   1/1     Running   0          3m46s
pod/rollout-ref-deployment-75bbd56864-kqwcs   1/1     Running   0          3m46s
pod/rollout-ref-deployment-75bbd56864-ln84k   1/1     Running   0          3m46s

deployment.yamlを更新してロールアウトを実行

ロールアウトを実行するために、deployment.yamlimagetagを更新して、applyします。

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/instance: rollout-canary
  name: rollout-ref-deployment
spec:
  replicas: 0
  selector:
    matchLabels:
      app: rollout-ref-deployment
  template:
    metadata:
      labels:
        app: rollout-ref-deployment
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:green # Upgrade tag to green
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
$ kubectl apply -f deployment.yaml

すると、rollout.yamlで定義したstrategyに従って、ロールアウトが実行されます。

Argo RolloutsのDashboardで状態を確認してみます。
(Dashboardもv1.0で追加されました。kubectl argo rollouts dashboard を実行して、http://localhost:3100/ にアクセスすると表示されます。)

  • ロールアウト中

  • ロールアウト完了

無事ロールアウトが完了し、Rolloutによって管理されているPodが新しいRevisionに置き換わりました。

まとめ

Workload Referencingが導入されたことで、マイグレーションの問題やkustomizeとの問題が解決されました。また、deployment strategyとpod templateの定義が分離されたことで見通しがよくなったことも良かったと思います。

一方、Argo Rolloutsを導入するためには、DeploymentではなくRolloutを使ってPodなどのリソースを管理する必要がある、ということ自体は変わっていないので注意が必要です。

参考資料