今回はProgressive Deliveryを実現するツールの一つであるFlaggerを試してみます。なお、Progressive Deliveryについては、以下の参考リンクなどを参照ください。
※参考リンク:
Flaggerとは
Flaggerは Progressive Dlivery Operator for Kubernetes
と打ち出されている通り、KubernetesをベースにProgressive Deliveryの実現をサポートするプロダクトです。
Flaggerを利用する環境は、以下のような構成となります。
※画像:Flagger Docより
Flaggerの実現するのは大きく3つ紹介されており、 Progressive Deliveryによる「より安全なリリース」
サービスメッシュやIngress Controllerによる「柔軟なTraffic Routing」
Progressive Deliveryに用いるメトリックをカスタムすることも可能な「拡張性のあるValidation」
となります。
具体的な機能としては、以下のようなものが挙げられます。
サービスメッシュ・Ingress Controllerと組み合わせたトラフィックコントロール
FlaggerはKubernetes CNIと組み合わせることで、単体でもトラフィックの切り替えを行うことができますが、Istio/Linkerdといったサービスメッシュ、Nginx/ContourなどのIngress Controllerとして機能するプロダクトと組み合わせることで、CanaryリリースやA/Bテストなど、より発展的なデリバリーを実現します。
GitOpsツールとの組み合わせ
FlaggerはGitOpsプロダクトと組み合わせることで、GitOps + Progressive Deliveryというデプロイ・リリースパイプラインを実現します。以前動かしてみたFluxなどと組み合わせることが可能です
4種類のデプロイ・デリバリー戦略に対応
Flaggerは Canary
というCustom Resourceの設定を変更することで、4種類のデプロイ・デリバリー戦略に対応しています。
- Canary Release: HTTPリクエスト成功率などの重要な指標(KPI、Key Performace Indicator)を計測しつつ、異なるバージョンのアプリケーションへのトラフィック量を少しずつ変更します。
- A/B Testing: Session Affinity (Sticky Session)を要求するようなフロントエンドのアプリケーションに対応するため、Canary ReleaseにHTTPヘッダーやCookieの条件一致を加えることで、同じユーザーが同一のバージョンにアクセスし続けるようトラフィックを制御し、A/Bテストを実現します。
- Blue/Green: KPIなどをベースに新しいバージョンのアプリケーションに問題がないと判断できたら、一気にトラフィックを新しいバージョンのほうへ切り替えます。
- Blue/Green with Traffic Mirroring: Canary ReleaseやBlue/Greenの前段階として利用します。インバウンドな通信をコピーして、一方は現在稼働中のServiceに、もう一方をCanary Serviceへ転送します。Canary Serviceからのレスポンスは破棄しますが、メトリックは収集し、Canaryのほうが問題ない状態かを確認することができます。
※参考リンク:Flagger Doc - Deployment Strategies
モニタリングツールへのクエリ
Flaggerはメトリックをベースにして、可用性やエラー率などのSLOを評価します。Flaggerは HTTPリクエスト成功率
とDuration
を組み込みのメトリックとして持ちますが、カスタムすることも可能です。メトリックのターゲットにはPrometheusやDataDogを利用できます。
※参考リンク:Flagger Doc - Metrics Analysis
WebhookによるAnalysisの拡張
Flaggerでは、アプリケーション切替の前後に行うテスト(Analysis)を、Webhookによって拡張することができます。Flaggerでは8種類のHookが用意されており、そのレスポンスコードによって切り替えが発生します。またFlaggerではWebhhokの設定でコマンドを指定することで、切り替え前後に負荷テストなどを実施できます。
※参考リンク:Flagger Doc - Webhooks
通知サービスへのアラート
FlaggerはSlackやMicrosoft Teamsなどの各種チャットツールへアラートを送信することができます。送信先のプロバイダーは AlertProvider
というCustom Resourceで定義します。
※参考リンク:Flagger Doc - Alerting
Flaggerを動かしてみる
ここから実際にFlaggerを動かします。Flaggerのドキュメントには、各デプロイ戦略とツールとの組み合わせごとにチュートリアルが用意されています。今回はIstioをベースに2種類のデプロイ戦略をなぞってみます。Istioについては、以前の投稿などをご参照ください。環境の用意はこちらのドキュメントをベースにしています。
※参考リンク:
前提条件
Flaggerを利用する前提条件は以下の通りです。
- Kubernetes version:
1.16
以上 - istio version:
1.5
以上
今回の検証環境は以下の通りです。
# eksctl version $ eksctl version 0.57.0 # Kubernetes / kubectl version $ kubectl version Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.0", GitCommit:"af46c47ce925f4c4ad5cc8d1fca46c7b77d13b38", GitTreeState:"clean", BuildDate:"2020-12-08T17:59:43Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"20+", GitVersion:"v1.20.7-eks-8be107", GitCommit:"8be107e517a77bde856aced857f3428e4f344969", GitTreeState:"clean", BuildDate:"2021-06-12T03:14:13Z", GoVersion:"go1.15.12", Compiler:"gc", Platform:"linux/amd64"} # Istio version $ istioctl version no running Istio pods in "istio-system" 1.10.3
Istio / Prometheus / Flaggerのデプロイ
まずはIstioのデプロイを行います。Istioは istioctl
コマンドからデプロイを行います。今回使用しているProfileはこちらから確認できます。なお、Istioインストールの際、istiodに要求されるメモリ量が多いため、nodeのスペックは十分大きいものを指定したほうが良いでしょう。今回はEC2インスタンスのsペックは t3.large
を指定しています。
$ istioctl manifest install --set profile=default This will install the Istio 1.10.3 default profile with ["Istio core" "Istiod" "Ingress gateways"] components into the cluster. Proceed? (y/N) y ✔ Istio core installed ✔ Istiod installed ✔ Ingress gateways installed ✔ Installation complete # デプロイ後の確認 $ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE istio-ingressgateway-c4d8648bc-pkm72 1/1 Running 0 59s istiod-7bd65bd549-76xgz 1/1 Running 0 71s $ kubectl get svc -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.100.230.248 a50db11ad30db428b926a77884d22fa1-1849188677.ap-northeast-1.elb.amazonaws.com 15021:30212/TCP,80:31556/TCP,443:32089/TCP 96s istiod ClusterIP 10.100.89.234 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 108s
次にPrometheusをデプロイします。
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.10/samples/addons/prometheus.yaml serviceaccount/prometheus created configmap/prometheus created clusterrole.rbac.authorization.k8s.io/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created service/prometheus created deployment.apps/prometheus created # デプロイ後の確認 $ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE istio-ingressgateway-c4d8648bc-pkm72 1/1 Running 0 3m19s istiod-7bd65bd549-76xgz 1/1 Running 0 3m31s prometheus-69f7f4d689-bz2z5 2/2 Running 0 15s $ kubectl get svc -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.100.230.248 a50db11ad30db428b926a77884d22fa1-1849188677.ap-northeast-1.elb.amazonaws.com 15021:30212/TCP,80:31556/TCP,443:32089/TCP 3m32s istiod ClusterIP 10.100.89.234 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 3m44s prometheus ClusterIP 10.100.238.59 <none> 9090/TCP 28s
最後にFlaggerをデプロイします。
$ kubectl apply -k github.com/fluxcd/flagger//kustomize/istio customresourcedefinition.apiextensions.k8s.io/alertproviders.flagger.app created customresourcedefinition.apiextensions.k8s.io/canaries.flagger.app created customresourcedefinition.apiextensions.k8s.io/metrictemplates.flagger.app created serviceaccount/flagger created clusterrole.rbac.authorization.k8s.io/flagger created clusterrolebinding.rbac.authorization.k8s.io/flagger created deployment.apps/flagger created # デプロイ後の確認 $ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE flagger-5cf787b9c8-jgdtv 1/1 Running 0 44s istio-ingressgateway-c4d8648bc-pkm72 1/1 Running 0 6m15s istiod-7bd65bd549-76xgz 1/1 Running 0 6m27s prometheus-69f7f4d689-bz2z5 2/2 Running 0 3m11s
Canary Deployment
まずはCanary Deploymentを試します。手順はこちらのドキュメントに記載されています。
前準備
まず使用するデモ用アプリが、サービスメッシュの外からアクセスできるよう Gateway
リソースをデプロイします。
ingress-gateway.yaml
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: public-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
$ kubectl apply -f ingress-gateway.yaml gateway.networking.istio.io/public-gateway created # デプロイ後の確認 $ kubectl get gateway -n istio-system NAME AGE public-gateway 9s
次にテスト用アプリを起動するNamespaceの作成と、IstioによるSidecar Proxyの注入を行うためのラベリングを行います。
$ kubectl create ns test namespace/test created $ kubectl label namespace test istio-injection=enabled namespace/test labeled # デプロイ後の確認 $ kubectl get ns --show-labels NAME STATUS AGE LABELS default Active 28m <none> istio-system Active 13m <none> kube-node-lease Active 28m <none> kube-public Active 28m <none> kube-system Active 28m <none> test Active 82s istio-injection=enabled
次にテスト用のアプリとHPAをデプロイします。なお、今回の手順ではHPAは特に利用しないため、 metrics-server
のインストールは実施しません。そのためHPAのターゲットも Unknown
状態となります。
$ kubectl apply -k https://github.com/fluxcd/flagger//kustomize/podinfo?ref=main deployment.apps/podinfo created horizontalpodautoscaler.autoscaling/podinfo created # デプロイ後の確認 $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE podinfo-99dc84b6f-bmtvv 2/2 Running 0 56s podinfo-99dc84b6f-l5pk8 2/2 Running 0 71s $ kubectl get hpa -n test NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE podinfo Deployment/podinfo <unknown>/99% 2 4 2 98s
また、Progressive DeliveryでのAnalysisで利用する loadtester
Podも合わせてデプロイします。この loadtester
は rakyll/hey / bojand/ghz という2つの負荷テストツールをベースとしています。
$ kubectl apply -k https://github.com/fluxcd/flagger//kustomize/tester?ref=main service/flagger-loadtester created deployment.apps/flagger-loadtester created # デプロイ後の確認 $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 29s podinfo-99dc84b6f-bmtvv 2/2 Running 0 4m25s podinfo-99dc84b6f-l5pk8 2/2 Running 0 4m40s $ kubectl get svc -n test NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flagger-loadtester ClusterIP 10.100.21.132 <none> 80/TCP 25s
Canary
リソースのデプロイ
Flaggerは Canary
というCustom Resourceを利用し、既存のDeploymentに対して、指定したデプロイ戦略を実行します。どのデプロイ戦略を利用するかは、 Canary
中に指定したパラメータによって変更します。
今回利用する Canary
のマニフェストファイルは以下の通りです。少しだけパラメータの説明を付け加えます。
spec.targetRef
: ターゲットとするリソース種別を指定。Deployment
DaemonSet
のいずれかを指定可能spec.progressDeadlineSeconds
: Canary Deployment実行時、ロールバック前に進行する際の最大秒数。kubectl get canary
実行時にCanary Deploymentの進行を表示する間隔。spec.analysis
: Progressive DeliveryのAnalysisを設定する部分。
podinfo-canary.yaml
apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo namespace: test spec: targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo progressDeadlineSeconds: 60 autoscalerRef: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler name: podinfo service: port: 9898 targetPort: 9898 gateways: - public-gateway.istio-system.svc.cluster.local hosts: - app.example.com trafficPolicy: tls: mode: DISABLE retries: attempts: 3 perTryTimeout: 1s retryOn: "gateway-error,connect-failure,refused-stream" analysis: interval: 1m threshold: 5 maxWeight: 50 stepWeight: 10 metrics: - name: request-success-rate thresholdRange: min: 99 interval: 1m - name: request-duration thresholdRange: max: 500 interval: 30s webhooks: - name: acceptance-test type: pre-rollout url: http://flagger-loadtester.test/ timeout: 30s metadata: type: bash cmd: "curl -sd 'test' http://podinfo-canary:9898/token | grep token" - name: load-test url: http://flagger-loadtester.test/ timeout: 5s metadata: cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"
上記マニフェストファイルをデプロイすると、先ほど作成した podinfo
Podを置き換える形で podinfo-primary
というPodが作成されます。またPod以外にも以下のリソースが作成されます。
- Deployment / Pod:
podinfo-primary
- HPA:
podinfo-primary
- Service:
podinfo
podinfo-canary
podinfo-primary
- Destination Rule:
podinfo-canary
podinfo-primary
- Virtual Service:
podinfo
$ kubectl apply -f podinfo-canary.yaml canary.flagger.app/podinfo created # デプロイ後の確認 $ kubectl get canary -n test NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Initialized 0 2021-07-21T10:02:46Z $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 30m podinfo-primary-657f8c97dd-28lbv 2/2 Running 0 2m31s podinfo-primary-657f8c97dd-z7sx6 2/2 Running 0 2m31s $ kubectl get hpa -n test NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE podinfo Deployment/podinfo <unknown>/99% 2 4 0 34m podinfo-primary Deployment/podinfo-primary <unknown>/99% 2 4 2 70s $ kubectl get service -n test NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flagger-loadtester ClusterIP 10.100.21.132 <none> 80/TCP 29m podinfo ClusterIP 10.100.172.155 <none> 9898/TCP 9s podinfo-canary ClusterIP 10.100.249.86 <none> 9898/TCP 69s podinfo-primary ClusterIP 10.100.129.195 <none> 9898/TCP 69s $ kubectl get destinationrule -n test NAME HOST AGE podinfo-canary podinfo-canary 57s podinfo-primary podinfo-primary 57s $ kubectl get virtualservice -n test NAME GATEWAYS HOSTS AGE podinfo ["public-gateway.istio-system.svc.cluster.local"] ["app.example.com","podinfo"] 43s
またこの時 Canary
リソースのログを見ると、Initializationのプロセスが確認できます。
$ kubectl describe canary podinfo -n test (中略) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning Synced 4m41s flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less then desired generation Normal Synced 3m41s (x2 over 4m41s) flagger all the metrics providers are available! Normal Synced 3m41s flagger Initialization done! podinfo.test
これでProgressive Deliveryを実行する準備ができました。
アプリケーションのアップデート
ここからCanary Deploymentを実行します。デプロイした podinfo
のイメージを更新することでアップデートを開始すると、Analysisを実行した後にPodのアップデートを行います。
Canary Deploymentの場合は以下のような構成となります。
※画像: Flagger Docより
Flaggerでは Primary
Canary
という2種類のPodを利用します。Canary
PodはAnalysisを実行する対象のPodで、アップデート中に作成し、完了後に削除されます。 Primary
Podは実際にトラフィックを流す対象のPodで、Analysisをクリアすると Primary
Podをバージョンアップすることで、アップデートが完了します。
Canary Deployment実行時のFlaggerの処理は、以下のように進行します。基本的な流れはCanary DeploymentもBlue/Green Deploymentも共通です。
Progressing
フェーズ: Analysisの実行- 新しいイメージバージョンのCanary Podを作成
- Canary Podへトラフィックを転送する。この時メトリックも収集し、評価する
- Canary Podへの転送量を
maxWeight
まで増加する
Promoting
フェーズ: Analysisの完了後、Primaryのスペックを更新- 新しいイメージタグのPrimary Podを作成する(Secret等のリソースがある場合はそれも複製する)
- 古いPrimary Podを削除する
Finalising
フェーズ: トラフィックをPrimary側へ切り替える- Primary Podへトラフィックを切り替える
Succeeded
フェーズ: Analysisとアップデートの完了- Canary Podを削除する
※参考リンク:GitHub - flux/flagger: status.go
アップデート前のイメージタグは 3.1.0
です。
$ kubectl describe pod podinfo-primary-657f8c97dd-28lbv -n test | grep 'Image:' Image: docker.io/istio/proxyv2:1.10.3 Image: stefanprodan/podinfo:3.1.0 Image: docker.io/istio/proxyv2:1.10.3
アップデート実行前に、PodとCanaryのウォッチを開始しておきます。
# watch $ kubectl get canary -n test -w $ kubectl get pods -n test -w # イメージアップデート kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
ここからフェーズごとの推移を載せておきます。
Progressing
# Progressing ## Weightが徐々に増加する $ kubectl get canary -n test -w NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Initialized 0 2021-07-21T10:02:46Z podinfo Progressing 0 2021-07-21T10:13:46Z podinfo Progressing 10 2021-07-21T10:14:46Z podinfo Progressing 20 2021-07-21T10:15:46Z podinfo Progressing 30 2021-07-21T10:16:46Z podinfo Progressing 40 2021-07-21T10:17:46Z podinfo Progressing 50 2021-07-21T10:18:46Z ## Canary Podが作成される $ kubectl get pods -n test -w NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 39m podinfo-primary-657f8c97dd-28lbv 2/2 Running 0 11m podinfo-primary-657f8c97dd-z7sx6 2/2 Running 0 11m podinfo-5f8fd4f546-vtjvl 0/2 Pending 0 0s podinfo-5f8fd4f546-vtjvl 0/2 Pending 0 0s podinfo-5f8fd4f546-vtjvl 0/2 Init:0/1 0 0s podinfo-5f8fd4f546-vtjvl 0/2 PodInitializing 0 1s podinfo-5f8fd4f546-6mqz8 0/2 Pending 0 0s podinfo-5f8fd4f546-6mqz8 0/2 Pending 0 0s podinfo-5f8fd4f546-6mqz8 0/2 Init:0/1 0 0s podinfo-5f8fd4f546-6mqz8 0/2 Init:0/1 0 1s podinfo-5f8fd4f546-6mqz8 0/2 PodInitializing 0 2s podinfo-5f8fd4f546-vtjvl 0/2 Running 0 8s podinfo-5f8fd4f546-vtjvl 1/2 Running 0 9s podinfo-5f8fd4f546-6mqz8 0/2 Running 0 7s podinfo-5f8fd4f546-6mqz8 1/2 Running 0 9s podinfo-5f8fd4f546-vtjvl 2/2 Running 0 16s podinfo-5f8fd4f546-6mqz8 2/2 Running 0 14s
Promoting
# Promoting NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Promoting 0 2021-07-21T10:19:46Z ## Primary Podを更新 NAME READY STATUS RESTARTS AGE podinfo-primary-657f8c97dd-z7sx6 2/2 Terminating 0 18m podinfo-primary-76655b74b9-cvs9z 0/2 Pending 0 0s podinfo-primary-76655b74b9-cvs9z 0/2 Pending 0 0s podinfo-primary-76655b74b9-cvs9z 0/2 Init:0/1 0 0s podinfo-primary-76655b74b9-b99lq 0/2 Pending 0 0s podinfo-primary-76655b74b9-b99lq 0/2 Pending 0 0s podinfo-primary-76655b74b9-b99lq 0/2 Init:0/1 0 0s podinfo-primary-76655b74b9-cvs9z 0/2 PodInitializing 0 2s podinfo-primary-76655b74b9-b99lq 0/2 PodInitializing 0 3s podinfo-primary-76655b74b9-cvs9z 0/2 Running 0 3s podinfo-primary-76655b74b9-b99lq 0/2 Running 0 4s podinfo-primary-76655b74b9-cvs9z 1/2 Running 0 4s podinfo-primary-76655b74b9-b99lq 1/2 Running 0 5s podinfo-primary-657f8c97dd-z7sx6 0/2 Terminating 0 18m podinfo-primary-657f8c97dd-z7sx6 0/2 Terminating 0 18m podinfo-primary-657f8c97dd-z7sx6 0/2 Terminating 0 18m podinfo-primary-76655b74b9-cvs9z 2/2 Running 0 8s podinfo-primary-76655b74b9-b99lq 2/2 Running 0 13s podinfo-primary-657f8c97dd-28lbv 2/2 Terminating 0 18m podinfo-primary-657f8c97dd-28lbv 0/2 Terminating 0 18m podinfo-primary-657f8c97dd-28lbv 0/2 Terminating 0 18m podinfo-primary-657f8c97dd-28lbv 0/2 Terminating 0 18m
Finalising
Succeeded
# Finalising NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Finalising 0 2021-07-21T10:20:46Z # Succeeded NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Succeeded 0 2021-07-21T10:21:46Z ## Canary Podの削除 NAME READY STATUS RESTARTS AGE podinfo-5f8fd4f546-6mqz8 2/2 Terminating 0 7m54s podinfo-5f8fd4f546-vtjvl 2/2 Terminating 0 8m podinfo-5f8fd4f546-6mqz8 0/2 Terminating 0 8m podinfo-5f8fd4f546-vtjvl 0/2 Terminating 0 8m6s podinfo-5f8fd4f546-vtjvl 0/2 Terminating 0 8m7s podinfo-5f8fd4f546-vtjvl 0/2 Terminating 0 8m7s podinfo-5f8fd4f546-6mqz8 0/2 Terminating 0 8m7s podinfo-5f8fd4f546-6mqz8 0/2 Terminating 0 8m7s
最終的には以下のような状態になります。
$ kubectl get canary -n test NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Succeeded 0 2021-07-21T10:21:46Z $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 52m podinfo-primary-76655b74b9-b99lq 2/2 Running 0 6m32s podinfo-primary-76655b74b9-cvs9z 2/2 Running 0 6m32s
podinfo
Canaryのログは以下の通りです。
$ kubectl describe canary -n test podinfo (中略) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning Synced 47m flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less then desired generation Normal Synced 46m (x2 over 47m) flagger all the metrics providers are available! Normal Synced 46m flagger Initialization done! podinfo.test Normal Synced 35m flagger New revision detected! Scaling up podinfo.test Normal Synced 34m flagger Starting canary analysis for podinfo.test Normal Synced 34m flagger Pre-rollout check acceptance-test passed Normal Synced 34m flagger Advance podinfo.test canary weight 10 Normal Synced 33m flagger Advance podinfo.test canary weight 20 Normal Synced 32m flagger Advance podinfo.test canary weight 30 Normal Synced 31m flagger Advance podinfo.test canary weight 40 Normal Synced 30m flagger Advance podinfo.test canary weight 50 Normal Synced 29m flagger Copying podinfo.test template spec to podinfo-primary.test Normal Synced 27m (x2 over 28m) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test
ロールバック
次にロールバックの場合を見てみます。先ほどと同様コンテナイメージを更新後、 flagger-loadtester
から特定のエンドポイント (http://podinfo-canary:9898/status/500
) を叩き、エラーを発生させます。その結果、Canary Deploymentは失敗・中断され、Canary Podが削除されます。
# watch $ kubectl get canary -n test -w $ kubectl get pods -n test -w # コンテナイメージの更新 $ kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.2
flagger-loadtester
からcurlを実行します。
$ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 85m podinfo-75459749c9-8w9tl 2/2 Running 0 3m47s podinfo-75459749c9-mqd7m 2/2 Running 0 3m51s podinfo-primary-76655b74b9-b99lq 2/2 Running 0 39m podinfo-primary-76655b74b9-cvs9z 2/2 Running 0 39m # エラーを発生させる $ kubectl exec -it flagger-loadtester-64695f854f-6mkgj -n test sh /home/app $ watch curl http://podinfo-canary:9898/status/500
Deployment Failed
# Canary NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Succeeded 0 2021-07-21T10:21:46Z podinfo Progressing 0 2021-07-21T10:55:46Z ## Analysisが成功しないためにWEIGHTの値が変化しない podinfo Progressing 10 2021-07-21T10:56:46Z podinfo Progressing 10 2021-07-21T10:57:46Z podinfo Progressing 10 2021-07-21T10:58:46Z podinfo Progressing 10 2021-07-21T10:59:46Z podinfo Progressing 10 2021-07-21T11:00:46Z podinfo Progressing 10 2021-07-21T11:01:46Z ## 最終的にはFailedとなる podinfo Failed 0 2021-07-21T11:02:46Z # Pod NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 81m podinfo-primary-76655b74b9-b99lq 2/2 Running 0 35m podinfo-primary-76655b74b9-cvs9z 2/2 Running 0 35m ## Canary Podの作成 podinfo-75459749c9-mqd7m 0/2 Pending 0 0s podinfo-75459749c9-mqd7m 0/2 Pending 0 0s podinfo-75459749c9-mqd7m 0/2 Init:0/1 0 0s podinfo-75459749c9-mqd7m 0/2 PodInitializing 0 2s podinfo-75459749c9-8w9tl 0/2 Pending 0 0s podinfo-75459749c9-8w9tl 0/2 Pending 0 0s podinfo-75459749c9-8w9tl 0/2 Init:0/1 0 0s podinfo-75459749c9-8w9tl 0/2 PodInitializing 0 2s podinfo-75459749c9-8w9tl 0/2 Running 0 8s podinfo-75459749c9-8w9tl 1/2 Running 0 10s podinfo-75459749c9-mqd7m 0/2 Running 0 15s podinfo-75459749c9-mqd7m 1/2 Running 0 16s podinfo-75459749c9-8w9tl 2/2 Running 0 19s podinfo-75459749c9-mqd7m 2/2 Running 0 24s ## Canary Podの削除 podinfo-75459749c9-mqd7m 2/2 Terminating 0 7m podinfo-75459749c9-8w9tl 2/2 Terminating 0 6m56s podinfo-75459749c9-mqd7m 0/2 Terminating 0 7m6s podinfo-75459749c9-8w9tl 0/2 Terminating 0 7m2s podinfo-75459749c9-mqd7m 0/2 Terminating 0 7m7s podinfo-75459749c9-mqd7m 0/2 Terminating 0 7m7s podinfo-75459749c9-8w9tl 0/2 Terminating 0 7m11s podinfo-75459749c9-8w9tl 0/2 Terminating 0 7m11s
最終的には以下のような状態となります。
$ kubectl get canary -n test NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Failed 0 2021-07-21T11:02:46Z $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 91m podinfo-primary-76655b74b9-b99lq 2/2 Running 0 45m podinfo-primary-76655b74b9-cvs9z 2/2 Running 0 45m
podinfo
Canaryのログは以下の通りです。
$ kubectl describe canary -n test podinfo (中略) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Synced 53m flagger Advance podinfo.test canary weight 20 Normal Synced 52m flagger Advance podinfo.test canary weight 30 Normal Synced 51m flagger Advance podinfo.test canary weight 40 Normal Synced 50m flagger Advance podinfo.test canary weight 50 Normal Synced 49m flagger Copying podinfo.test template spec to podinfo-primary.test Normal Synced 47m (x2 over 48m) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test Normal Synced 13m (x2 over 55m) flagger New revision detected! Scaling up podinfo.test Normal Synced 12m (x2 over 54m) flagger Advance podinfo.test canary weight 10 Normal Synced 12m (x2 over 54m) flagger Pre-rollout check acceptance-test passed Normal Synced 12m (x2 over 54m) flagger Starting canary analysis for podinfo.test Warning Synced 10m flagger Halt podinfo.test advancement success rate 97.50% < 99% Warning Synced 8m25s flagger Halt podinfo.test advancement success rate 97.61% < 99% Warning Synced 7m25s (x3 over 11m) flagger Halt podinfo.test advancement success rate 0.00% < 99% Warning Synced 6m25s flagger Rolling back podinfo.test failed checks threshold reached 5 Warning Synced 6m25s flagger Canary failed! Scaling down podinfo.test
Blue/Green Deployment
続いてBlue/Green Deploymentを試します。Canary Deploymentから連続して実施する場合は、まず podinfo
Canaryリソースを一度削除します。
$ kubectl delete -f podinfo-canary.yaml canary.flagger.app "podinfo" deleted
podinfo
Canaryを削除すると、作成時に一緒に作られたPodなどのリソースも合わせて削除されます。また、Canary作成時に置き換えられた podinfo
Podは、Canaryを削除しても復旧されません。
# podinfo Podは再作成されない $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 126m $ kubectl get deploy -n test NAME READY UP-TO-DATE AVAILABLE AGE flagger-loadtester 1/1 1 1 126m podinfo 0/0 0 0 130m
ここでは podinfo
Deploymentを編集して podinfo
Podを再作成します。編集したのはレプリカ数とコンテナイメージタグの2か所です。
$ kubectl edit deploy podinfo -n test deployment.apps/podinfo edited # Deployment編集後 $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-h9jdv 2/2 Running 0 33m podinfo-99dc84b6f-svnvg 2/2 Running 0 25s podinfo-99dc84b6f-vmv7n 2/2 Running 0 25s
Canary
リソースのデプロイ
次に新しいCanaryリソースをデプロイします。Canary Deploymentの際に利用したものと比べ、Analysis部分に maxWeight
stepWeight
がありません。Weightの設定がないため、Canary Podへトラフィックを流すことなく、spec.analysis.iterations
の回数だけAnalysisを実行、チェックを通過したら新しいバージョンのPrimary Podを作成してトラフィックを切り替えます。
podinfo-bg.yaml
apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo namespace: test spec: targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo progressDeadlineSeconds: 60 autoscalerRef: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler name: podinfo service: port: 9898 targetPort: 9898 gateways: - public-gateway.istio-system.svc.cluster.local hosts: - app.example.com trafficPolicy: tls: mode: DISABLE retries: attempts: 3 perTryTimeout: 1s retryOn: "gateway-error,connect-failure,refused-stream" analysis: interval: 1m threshold: 5 iterations: 10 metrics: - name: request-success-rate thresholdRange: min: 99 interval: 1m - name: request-duration thresholdRange: max: 500 interval: 30s webhooks: - name: acceptance-test type: pre-rollout url: http://flagger-loadtester.test/ timeout: 30s metadata: type: bash cmd: "curl -sd 'test' http://podinfo-canary:9898/token | grep token" - name: load-test url: http://flagger-loadtester.test/ timeout: 5s metadata: cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"
まずは上記マニフェストファイルをデプロイします。
$ kubectl apply -f podinfo-bg.yaml canary.flagger.app/podinfo created # デプロイ後の確認 $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-h9jdv 2/2 Running 0 38m podinfo-primary-7b67c7fbc4-4fhm6 2/2 Running 0 82s podinfo-primary-7b67c7fbc4-w5jpt 2/2 Running 0 82s $ kubectl get canary -n test NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Initialized 0 2021-07-22T00:46:56Z
アプリケーションのアップデート
次にアプリケーションを更新します。
Canary Deploymentと同様、イメージタグの更新を行います。
$ kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1 deployment.apps/podinfo image updated
PodとCanaryの経過を見てみます。Canary Deploymentと異なり、こちらのログからは経過が確認できませんが、 kubectl describe canary
でのEventsにはAnalysisが進行している様子が確認できます。
Progressing
# Progressing $ kubectl get canary -n test -w NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Initialized 0 2021-07-22T00:46:56Z podinfo Progressing 0 2021-07-22T00:47:56Z $ kubectl get pods -n test -w NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-h9jdv 2/2 Running 0 38m podinfo-primary-7b67c7fbc4-4fhm6 2/2 Running 0 93s podinfo-primary-7b67c7fbc4-w5jpt 2/2 Running 0 93s ## Canary Podの作成 podinfo-5f8fd4f546-5tbmv 0/2 Pending 0 0s podinfo-5f8fd4f546-5tbmv 0/2 Pending 0 0s podinfo-5f8fd4f546-5tbmv 0/2 Init:0/1 0 0s podinfo-5f8fd4f546-5tbmv 0/2 PodInitializing 0 2s podinfo-5f8fd4f546-5tbmv 0/2 Running 0 3s podinfo-5f8fd4f546-5tbmv 1/2 Running 0 3s podinfo-5f8fd4f546-bkxbz 0/2 Pending 0 0s podinfo-5f8fd4f546-bkxbz 0/2 Pending 0 1s podinfo-5f8fd4f546-bkxbz 0/2 Init:0/1 0 1s podinfo-5f8fd4f546-bkxbz 0/2 PodInitializing 0 3s podinfo-5f8fd4f546-bkxbz 0/2 Running 0 4s podinfo-5f8fd4f546-bkxbz 1/2 Running 0 5s podinfo-5f8fd4f546-bkxbz 2/2 Running 0 9s podinfo-5f8fd4f546-5tbmv 2/2 Running 0 16s ## Iterationが進行している $ kubectl describe canary podinfo -n test | tail -10 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning Synced 3m24s flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less then desired generation Normal Synced 2m24s (x2 over 3m24s) flagger all the metrics providers are available! Normal Synced 2m24s flagger Initialization done! podinfo.test Normal Synced 84s flagger New revision detected! Scaling up podinfo.test Normal Synced 24s flagger Starting canary analysis for podinfo.test Normal Synced 24s flagger Pre-rollout check acceptance-test passed Normal Synced 24s flagger Advance podinfo.test canary iteration 1/10 $ kubectl describe canary podinfo -n test | tail -10 Normal Synced 11m (x2 over 12m) flagger all the metrics providers are available! Normal Synced 11m flagger Initialization done! podinfo.test Normal Synced 10m flagger New revision detected! Scaling up podinfo.test Normal Synced 9m26s flagger Starting canary analysis for podinfo.test Normal Synced 9m26s flagger Pre-rollout check acceptance-test passed Normal Synced 9m26s flagger Advance podinfo.test canary iteration 1/10 Normal Synced 8m26s flagger Advance podinfo.test canary iteration 2/10 Normal Synced 7m26s flagger Advance podinfo.test canary iteration 3/10 Normal Synced 6m26s flagger Advance podinfo.test canary iteration 4/10 Normal Synced 26s (x6 over 5m26s) flagger (combined from similar events): Advance podinfo.test canary iteration 10/10
Promoting
# Promoting NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Promoting 0 2021-07-22T00:59:56Z ## Primary Podの更新 NAME READY STATUS RESTARTS AGE podinfo-primary-7b67c7fbc4-w5jpt 2/2 Terminating 0 14m podinfo-primary-666bd89c86-s8pkg 0/2 Pending 0 0s podinfo-primary-666bd89c86-s8pkg 0/2 Pending 0 0s podinfo-primary-666bd89c86-s8pkg 0/2 Init:0/1 0 0s podinfo-primary-666bd89c86-vqhm5 0/2 Pending 0 0s podinfo-primary-666bd89c86-vqhm5 0/2 Pending 0 0s podinfo-primary-666bd89c86-vqhm5 0/2 Init:0/1 0 0s podinfo-primary-666bd89c86-s8pkg 0/2 PodInitializing 0 2s podinfo-primary-666bd89c86-vqhm5 0/2 PodInitializing 0 2s podinfo-primary-666bd89c86-s8pkg 0/2 Running 0 3s podinfo-primary-666bd89c86-vqhm5 0/2 Running 0 3s podinfo-primary-666bd89c86-s8pkg 1/2 Running 0 4s podinfo-primary-666bd89c86-vqhm5 1/2 Running 0 4s podinfo-primary-7b67c7fbc4-w5jpt 0/2 Terminating 0 14m podinfo-primary-7b67c7fbc4-w5jpt 0/2 Terminating 0 14m podinfo-primary-7b67c7fbc4-w5jpt 0/2 Terminating 0 14m podinfo-primary-666bd89c86-vqhm5 2/2 Running 0 16s podinfo-primary-666bd89c86-s8pkg 2/2 Running 0 16s podinfo-primary-7b67c7fbc4-4fhm6 2/2 Terminating 0 14m podinfo-primary-7b67c7fbc4-4fhm6 0/2 Terminating 0 14m podinfo-primary-7b67c7fbc4-4fhm6 0/2 Terminating 0 14m podinfo-primary-7b67c7fbc4-4fhm6 0/2 Terminating 0 14m $ kubectl describe canary podinfo -n test | tail -10 Normal Synced 13m (x2 over 14m) flagger all the metrics providers are available! Normal Synced 13m flagger Initialization done! podinfo.test Normal Synced 12m flagger New revision detected! Scaling up podinfo.test Normal Synced 11m flagger Starting canary analysis for podinfo.test Normal Synced 11m flagger Pre-rollout check acceptance-test passed Normal Synced 11m flagger Advance podinfo.test canary iteration 1/10 Normal Synced 10m flagger Advance podinfo.test canary iteration 2/10 Normal Synced 9m5s flagger Advance podinfo.test canary iteration 3/10 Normal Synced 8m5s flagger Advance podinfo.test canary iteration 4/10 Normal Synced 5s (x8 over 7m5s) flagger (combined from similar events): Copying podinfo.test template spec to podinfo-primary.test
Finalising
# Finalising NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Finalising 0 2021-07-22T01:00:56Z ## Primary Podへトラフィックを流す $ kubectl describe canary podinfo -n test | tail -10 Normal Synced 14m (x2 over 15m) flagger all the metrics providers are available! Normal Synced 14m flagger Initialization done! podinfo.test Normal Synced 13m flagger New revision detected! Scaling up podinfo.test Normal Synced 12m flagger Starting canary analysis for podinfo.test Normal Synced 12m flagger Pre-rollout check acceptance-test passed Normal Synced 12m flagger Advance podinfo.test canary iteration 1/10 Normal Synced 11m flagger Advance podinfo.test canary iteration 2/10 Normal Synced 10m flagger Advance podinfo.test canary iteration 3/10 Normal Synced 9m15s flagger Advance podinfo.test canary iteration 4/10 Normal Synced 15s (x9 over 8m15s) flagger (combined from similar events): Routing all traffic to primary
Succeeded
# Succeeded NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Succeeded 0 2021-07-22T01:01:56Z ## Canary Podの削除 NAME READY STATUS RESTARTS AGE podinfo-5f8fd4f546-5tbmv 2/2 Terminating 0 14m podinfo-5f8fd4f546-bkxbz 2/2 Terminating 0 13m podinfo-5f8fd4f546-5tbmv 0/2 Terminating 0 14m podinfo-5f8fd4f546-bkxbz 0/2 Terminating 0 14m podinfo-5f8fd4f546-5tbmv 0/2 Terminating 0 14m podinfo-5f8fd4f546-5tbmv 0/2 Terminating 0 14m podinfo-5f8fd4f546-bkxbz 0/2 Terminating 0 14m podinfo-5f8fd4f546-bkxbz 0/2 Terminating 0 14m $ kubectl describe canary podinfo -n test | tail -10 Normal Synced 15m (x2 over 16m) flagger all the metrics providers are available! Normal Synced 15m flagger Initialization done! podinfo.test Normal Synced 14m flagger New revision detected! Scaling up podinfo.test Normal Synced 13m flagger Starting canary analysis for podinfo.test Normal Synced 13m flagger Pre-rollout check acceptance-test passed Normal Synced 13m flagger Advance podinfo.test canary iteration 1/10 Normal Synced 12m flagger Advance podinfo.test canary iteration 2/10 Normal Synced 11m flagger Advance podinfo.test canary iteration 3/10 Normal Synced 10m flagger Advance podinfo.test canary iteration 4/10 Normal Synced 0s (x10 over 9m) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test
ロールバック
ロールバックも試してみます。やることはCanary Deploymentとまったく同じです。
# コンテナイメージの更新 $ kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.2 deployment.apps/podinfo image updated # Canary/Podのウォッチを開始 $ kubectl get canary -n test -w NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Succeeded 0 2021-07-22T01:01:56Z $ kubectl get pods -n test -w NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-h9jdv 2/2 Running 0 66m podinfo-primary-666bd89c86-s8pkg 2/2 Running 0 15m podinfo-primary-666bd89c86-vqhm5 2/2 Running 0 15m
# flagger-loadtesterから500ステータスコードの実行 $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-6mkgj 2/2 Running 0 85m podinfo-75459749c9-8w9tl 2/2 Running 0 3m47s podinfo-75459749c9-mqd7m 2/2 Running 0 3m51s podinfo-primary-76655b74b9-b99lq 2/2 Running 0 39m podinfo-primary-76655b74b9-cvs9z 2/2 Running 0 39m $ kubectl exec -it -n test flagger-loadtester-64695f854f-6mkgj sh /home/app $ watch curl http://podinfo-canary.test:9898/status/500
Deployment Proceeding (Failed)
$ kubectl describe canary podinfo -n test | tail -10 Normal Synced 31m flagger Advance podinfo.test canary iteration 2/10 Normal Synced 30m flagger Advance podinfo.test canary iteration 3/10 Normal Synced 29m flagger Advance podinfo.test canary iteration 4/10 Normal Synced 19m (x10 over 28m) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test Normal Synced 5m4s (x2 over 33m) flagger New revision detected! Scaling up podinfo.test Normal Synced 4m4s (x2 over 32m) flagger Advance podinfo.test canary iteration 1/10 Normal Synced 4m4s (x2 over 32m) flagger Pre-rollout check acceptance-test passed Normal Synced 4m4s (x2 over 32m) flagger Starting canary analysis for podinfo.test Warning Synced 64s (x2 over 3m4s) flagger Halt podinfo.test advancement success rate 0.00% < 99% Warning Synced 4s (x2 over 2m4s) flagger Halt podinfo.test advancement success rate 97.51% < 99%
Deployment Failed
NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Failed 0 2021-07-22T01:22:56Z NAME READY STATUS RESTARTS AGE podinfo-75459749c9-w8vx8 2/2 Terminating 0 7m podinfo-75459749c9-7qbvd 2/2 Terminating 0 7m podinfo-75459749c9-w8vx8 0/2 Terminating 0 7m6s podinfo-75459749c9-7qbvd 0/2 Terminating 0 7m6s podinfo-75459749c9-7qbvd 0/2 Terminating 0 7m13s podinfo-75459749c9-7qbvd 0/2 Terminating 0 7m13s podinfo-75459749c9-w8vx8 0/2 Terminating 0 7m15s podinfo-75459749c9-w8vx8 0/2 Terminating 0 7m15s $ kubectl describe canary podinfo -n test | tail -10 Normal Synced 32m flagger Advance podinfo.test canary iteration 4/10 Normal Synced 22m (x10 over 31m) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test Normal Synced 8m32s (x2 over 36m) flagger New revision detected! Scaling up podinfo.test Normal Synced 7m32s (x2 over 35m) flagger Pre-rollout check acceptance-test passed Normal Synced 7m32s (x2 over 35m) flagger Advance podinfo.test canary iteration 1/10 Normal Synced 7m32s (x2 over 35m) flagger Starting canary analysis for podinfo.test Warning Synced 3m32s (x2 over 5m32s) flagger Halt podinfo.test advancement success rate 97.51% < 99% Warning Synced 2m32s (x3 over 6m32s) flagger Halt podinfo.test advancement success rate 0.00% < 99% Warning Synced 92s flagger Rolling back podinfo.test failed checks threshold reached 5 Warning Synced 92s flagger Canary failed! Scaling down podinfo.test
Slackへのメッセージ送信
次にSlackへメッセージを送信する場合を試してみます。Flaggerでは AlertProvider
というリソースで、メッセージの送信先となるプロバイダーやWebhooknURLを設定します。
※参考リンク:Flagger Doc - Alerting
今回は以下のような AlertProvider
マニフェストを利用します。前提として、SlackのIncoming Webhookを取得しておきます。
※参考リンク:SlackでのIncoming Webhookの利用
podinfo-alert.yaml
apiVersion: flagger.app/v1beta1 kind: AlertProvider metadata: name: on-call namespace: test spec: type: slack channel: on-call-alerts username: flagger secretRef: name: on-call-url --- apiVersion: v1 kind: Secret metadata: name: on-call-url namespace: test data: address: <encoded webhook URL>
上記マニフェストを使ってリソースをデプロイします。
$ kubectl apply -f podinfo-alert.yaml alertprovider.flagger.app/on-call created secret/on-call-url created # デプロイ後の確認 $ kubectl get alertprovider -n test NAME TYPE on-call slack
AlertProvider
を利用するには Canary
リソースのほうも修正が必要です。以下のマニフェストのように、 spec.analysis.alerts
にて、利用する AlertProvider
とログレベルを指定します。
podinfo-canary-alert.yaml
apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo namespace: test spec: targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo progressDeadlineSeconds: 60 autoscalerRef: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler name: podinfo service: port: 9898 targetPort: 9898 gateways: - public-gateway.istio-system.svc.cluster.local hosts: - app.example.com trafficPolicy: tls: mode: DISABLE retries: attempts: 3 perTryTimeout: 1s retryOn: "gateway-error,connect-failure,refused-stream" analysis: alerts: - name: "on-call Slack" severity: info providerRef: name: on-call namespace: test interval: 1m threshold: 5 maxWeight: 50 stepWeight: 10 metrics: - name: request-success-rate thresholdRange: min: 99 interval: 1m - name: request-duration thresholdRange: max: 500 interval: 30s webhooks: - name: acceptance-test type: pre-rollout url: http://flagger-loadtester.test/ timeout: 30s metadata: type: bash cmd: "curl -sd 'test' http://podinfo-canary:9898/token | grep token" - name: load-test url: http://flagger-loadtester.test/ timeout: 5s metadata: cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"
上記マニフェストから Canary
リソースをデプロイします。
$ kubectl apply -f podinfo-canary-alert.yaml canary.flagger.app/podinfo created $ kubectl get pods -n test NAME READY STATUS RESTARTS AGE flagger-loadtester-64695f854f-h9jdv 2/2 Running 0 104m podinfo-primary-df5797b7c-bj86k 2/2 Running 0 90s podinfo-primary-df5797b7c-xgf4v 2/2 Running 0 90s $ kubectl get canary -n test NAME STATUS WEIGHT LASTTRANSITIONTIME podinfo Initialized 0 2021-07-22T01:53:06Z
Slackとの連携が成功していれば、以下の画像のようなメッセージが送られます。
※ Canary
リソース作成時
※ コンテナイメージアップデート成功時
※ アップデート失敗時