ArgoCDのCanary Deploymentを試す

MicroK8sにArgoCDをインストールするでMicroK8sにArgoCDをインストールしたので機能を試しています。その一貫として、今日はCanary Deployment(カナリアデプロイメント)を試したいと思います。

  • Argo Rolloutsをインストールする
  • Rolloutを作成する
    • カナリアデプロイ用のRolloutを作成する
    • Serviceを作成する
  • カナリアデプロイを実行する

Argo Rolloutsをインストールする


カナリアデプロイをするにはRolloutというリソースが必要になるので、以下のURLを参考にそのArgo Rolloutsをインストールします。

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin/

ArgoCDによるBlueGreenデプロイを試すでインストール済みなので、今回はスキップします。

Rolloutを作成する


以下の記事を参考に、カナリアデプロイ用のRolloutを作成します。

https://argoproj.github.io/argo-rollouts/features/canary/

カナリアリリース用のRolloutを作成する


IstioのSubsetでバージョン毎に流量制御を行うで作成したhelloaアプリケーションのv1/v2を利用して、カナリアリリース用のRolloutを作成します。

以下のyamlを使って、レプリカ数 4個のhelloa:v1アプリケーションを実行するhelloa-canaryを作成します。helloa-canaryは、アプリケーションアップデート時に25%分だけ新しいバージョンをデプロイし、その10秒後に50%になるようデプロイします。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: helloa-canary
spec:
  replicas: 4
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: helloa
  template:
    metadata:
      labels:
        app: helloa
    spec:
      containers:
      - name: helloa
        image: localhost:32147/helloa:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    canary:
      steps:
      - setWeight: 25
      - pause:
          duration: 10 # 10 seconds
      - setWeight: 50
      - pause: {} # pause indefinitely

spec.strategy.canaryブロックでカナリアデプロイの設定が行えます。詳細なオプションについては、以下のURLを参照してください。

https://argoproj.github.io/argo-rollouts/features/canary/

作成すると、以下のようにPodとReplicaSetが作成されます。

ubuntu@microk8s-vm:~$ microk8s.kubectl create -f rollout.yaml 
rollout.argoproj.io/helloa-canary created
ubuntu@microk8s-vm:~$ microk8s.kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
helloa-canary-5d86bb8b54   4         4         4       23s
ubuntu@microk8s-vm:~$ microk8s.kubectl get pods 
NAME                             READY   STATUS    RESTARTS   AGE
helloa-canary-5d86bb8b54-2djjc   1/1     Running   0          7s
helloa-canary-5d86bb8b54-hr8kf   1/1     Running   0          7s
helloa-canary-5d86bb8b54-nzdcl   1/1     Running   0          7s
helloa-canary-5d86bb8b54-spzcb   1/1     Running   0          7s

Serviceを作成する


上記で作成したhelloaを公開するため、NodePort 32000ポートで公開するcanary Serviceを作成します。

kind: Service
apiVersion: v1
metadata:
  name: canary
spec:
  selector:
    app: helloa
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
    nodePort: 32000

上記のyamlファイルを使い、以下のコマンドでcanary Serviceを作成します。

ubuntu@microk8s-vm:~/argocd/canary$ microk8s.kubectl create -f service.yaml 
service/canary created
ubuntu@microk8s-vm:~/argocd/canary$ microk8s.kubectl get svc canary
NAME     TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
canary   NodePort   10.152.183.151   <none>        8080:32000/TCP   9s

httpリクエストを送ると、以下の結果が返ってきます。

$ curl 192.168.64.2:32000
Hello A

カナリアデプロイを実行する


helloaのタグをv2にして、カナリアデプロイを実行します。

以下のコマンドで、helloaのタグをv1からv2に変更します。

ubuntu@microk8s-vm:~/argocd/canary$ microk8s.kubectl patch rollout helloa-canary --type merge -p '{"spec": {"template": {"spec": {"containers": [{"name":"helloa","image":"localhost:32147/helloa:v2"}]}}}}'
rollout.argoproj.io/helloa-canary patched

若干のタイムラグはあるのですが、以下のコマンドでデプロイ状況を確認しました。最初は3割v2に割り振られ、その10秒後に5割v2に割り振られているので、指定した割合と近しい値が出ていることを確認できました。

$ while true; do  date "+TIME: %H:%M:%S"; curl 192.168.64.2:32000; sleep 1; done
TIME: 20:54:19←setWeight 25%
Hello A
TIME: 20:54:20
Hello A v2
TIME: 20:54:21
Hello A
TIME: 20:54:22
Hello A
TIME: 20:54:23
Hello A
TIME: 20:54:24
Hello A
TIME: 20:54:25
Hello A v2
TIME: 20:54:26
Hello A
TIME: 20:54:27
Hello A
TIME: 20:54:28
Hello A v2
TIME: 20:54:29←setWeight 50%
Hello A
TIME: 20:54:30
Hello A
TIME: 20:54:31
Hello A
TIME: 20:54:32
Hello A v2
TIME: 20:54:33
Hello A v2
TIME: 20:54:34
Hello A v2
TIME: 20:54:35
Hello A
TIME: 20:54:36
Hello A
TIME: 20:54:37
Hello A v2
TIME: 20:54:38
Hello A v2

Podの状況を確認すると、指定した通りv1, v2のPodが2個ずつデプロイされて止まっていました。

ubuntu@microk8s-vm:~$ microk8s.kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
helloa-canary-5695f95f6b   2         2         2       80s
helloa-canary-5d86bb8b54   2         2         2       15m
ubuntu@microk8s-vm:~$ microk8s.kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
helloa-canary-5695f95f6b-9mlh9   1/1     Running   0          76s
helloa-canary-5695f95f6b-9ppnk   1/1     Running   0          64s
helloa-canary-5d86bb8b54-hr8kf   1/1     Running   0          15m
helloa-canary-5d86bb8b54-spzcb   1/1     Running   0          15m

以上です。