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
以上です。