今回は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」
となります。
具体的な機能としては、以下のようなものが挙げられます。
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を利用する前提条件は以下の通りです。
今回の検証環境は以下の通りです。
$ eksctl version
0.57.0
$ 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"}
$ 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を設定する部分。
interval
: analysisの実行間隔
threshold
: ロールバックを実行する基準となる、analysisの失敗回数
maxWeight
: Canaryへ転送する最大のトラフィック転送割合
stepWeight
: Canaryへの転送量を1回あたりに増やす割合。
metrics
: メトリックの設定箇所
thresholdRange
: request-success-rate
の場合はリクエスト成功率の最低値、 request-duration
の場合はリクエストのP99 duration最大ミリセカンド値を指定
webhooks
: Webhookの設定
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側へ切り替える
Succeeded
フェーズ: Analysisとアップデートの完了
※参考リンク: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のウォッチを開始しておきます。
$ 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
$ 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
$ 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
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Promoting 0 2021-07-21T10:19:46Z
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
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Finalising 0 2021-07-21T10:20:46Z
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Succeeded 0 2021-07-21T10:21:46Z
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が削除されます。
$ 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
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Succeeded 0 2021-07-21T10:21:46Z
podinfo Progressing 0 2021-07-21T10:55:46Z
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
podinfo Failed 0 2021-07-21T11:02:46Z
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
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
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
$ 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
$ 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
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
$ 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
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Promoting 0 2021-07-22T00:59:56Z
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
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Finalising 0 2021-07-22T01:00:56Z
$ 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
NAME STATUS WEIGHT LASTTRANSITIONTIME
podinfo Succeeded 0 2021-07-22T01:01:56Z
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
$ 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
$ 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
リソース作成時
※ コンテナイメージアップデート成功時
※ アップデート失敗時
参考ドキュメント