このページではprogressive deliveryの動きを目で見て確認しようというものになります。
※ このドキュメントでは、progressive delivery = canary releaseのことを指しています。
Flaggerの動作確認はistioをベースに動作させます。
Note
こちらのドキュメントを参考に全ての手順を踏んでから実施してください。(サービスメッシュの概要)
ref: link
Note
このドキュメントで負荷試験ツールを利用する場合には、locustをinstallする必要があります。
ref: link
Flaggerは、IstioなどのService Meshツールと連携してCanaryリリースやブルー/グリーンデプロイメントといったprogressive deliveryの自動化を実現するオペレーターです。Istioを例にあげると、Flaggerは指定されたアプリケーションに基づいて、Service、VirtualService、DestinationRuleなどのIstioリソースを自動生成します。このプロセスは、resource:canaryに基づいて行われ、アプリケーションのリリース管理が簡素化されます。
progressive deliveryが開始されると、Flaggerは事前に定義されたMetricTemplateを使用して、各モニタリングプロバイダー(PrometheusやDatadogなど)にクエリを送信し、リリースの健全性を監視します。モニタリングの結果に基づいて、問題がなければIstioのweightを調整し、トラフィックの割合を段階的にCanary環境へ移行させます。万が一、異常が検知された場合は、リリースを自動的に停止またはロールバックします。
※ これは個人的な考え方なので、もっと良い表現の仕方があったら教えてください...
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: flexiblemockserver
spec:
service:
# Wrapping Service Resources
port: 8080
name: canary-test-flexiblemockserver
# Wrapping VirtualService Resource
#retries:
# attempts: 3
# perTryTimeout: 1s
# retryOn: "5xx"
詳細はFlaggerのCanary Resourceのschemaを確認してください。
ref: CRD
ref: schema
構成を簡略化させた図
progressive deliveryが開始されると、Flaggerは事前に定義されたMetricTemplateを使用して、各モニタリングプロバイダー(PrometheusやDatadogなど)にクエリを送信し、リリースの健全性を監視します。モニタリングの結果に基づいて、問題がなければIstioのweightを調整し、トラフィックの割合を段階的にCanary環境へ移行させます。万が一、異常が検知された場合は、リリースを自動的に停止またはロールバックします。
ここについてさらに詳細について図を用いて解説します。
図で書くとこんな感じ
ref: link
❯ kubectl apply -k sample_manifest/kubernetes/flagger/
❯ kubectl apply -f https://raw.githubusercontent.com/fluxcd/flagger/main/artifacts/flagger/crd.yaml
ref: link
❯ kubectl apply -k sample_manifest/kubernetes/flagger/canary-test-flexiblemockserver
TBU
labelに差分を入れて、動作を確認してみる。
TBU
❯ kubectl apply -k sample_manifest/kubernetes/flagger/canary-test-flexiblemockserver
実際にapplicationが実行されたら、負荷試験ツールを用いてリクエストを流してみる。
❯ kubectl apply -k sample_manifest/kubernetes/locust/sample/
実行されると、weightがあがります。
ここのweightはistioのweightと一致しています。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2024-09-25T05:11:56Z"
generation: 28
name: canary-test-flexiblemockserver
namespace: mockserver
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: canary-test-flexiblemockserver
uid: 83ec2230-110d-4f02-98fe-ecd6f07b9b82
resourceVersion: "583895"
uid: efa1d284-9c2c-4c41-844f-be07387e789e
spec:
gateways:
- mesh
hosts:
- canary-test-flexiblemockserver
http:
- route:
- destination:
host: canary-test-flexiblemockserver-primary
weight: 90
- destination:
host: canary-test-flexiblemockserver-canary
weight: 10
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2024-09-25T05:11:56Z"
generation: 38
name: canary-test-flexiblemockserver
namespace: mockserver
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: canary-test-flexiblemockserver
uid: 83ec2230-110d-4f02-98fe-ecd6f07b9b82
resourceVersion: "587738"
uid: efa1d284-9c2c-4c41-844f-be07387e789e
spec:
gateways:
- mesh
hosts:
- canary-test-flexiblemockserver
http:
- route:
- destination:
host: canary-test-flexiblemockserver-primary
weight: 50
- destination:
host: canary-test-flexiblemockserver-canary
weight: 50
promoteフェイズになると、VirtualServiceをcanary:primaryを50:5050にしてDeploymentのミラーリング(canaryからprimaryに昇格)を行います。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2024-09-25T05:11:56Z"
generation: 39
name: canary-test-flexiblemockserver
namespace: mockserver
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: canary-test-flexiblemockserver
uid: 83ec2230-110d-4f02-98fe-ecd6f07b9b82
resourceVersion: "588295"
uid: efa1d284-9c2c-4c41-844f-be07387e789e
spec:
gateways:
- mesh
hosts:
- canary-test-flexiblemockserver
http:
- route:
- destination:
host: canary-test-flexiblemockserver-primary
weight: 100
- destination:
host: canary-test-flexiblemockserver-canary
weight: 0
canaryからprimaryにミラーリングを完了させると、VirtualServiceのweightをcanary:primaryを0:100にしてProgressiveDeliveryを完了させます。
eventも載せておきます。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Synced 9m38s (x7 over 8h) flagger Starting canary analysis for canary-test-flexiblemockserver.mockserver
Normal Synced 9m38s (x6 over 8h) flagger Advance canary-test-flexiblemockserver.mockserver canary weight 10
Normal Synced 8m38s (x6 over 8h) flagger Advance canary-test-flexiblemockserver.mockserver canary weight 20
Normal Synced 7m38s (x6 over 8h) flagger Advance canary-test-flexiblemockserver.mockserver canary weight 30
Normal Synced 6m38s (x6 over 8h) flagger Advance canary-test-flexiblemockserver.mockserver canary weight 40
Normal Synced 5m38s (x5 over 8h) flagger Advance canary-test-flexiblemockserver.mockserver canary weight 50
Normal Synced 2m39s (x12 over 8h) flagger (combined from similar events): Promotion completed! Scaling down canary-test-flexiblemockserver.mockserver
試験が終わったらlocust
を削除しましょう。
❯ kubectl delete -k sample_manifest/kubernetes/locust/sample/
labelに差分を入れて、動作を確認してみる。
TBU
❯ kubectl apply -k sample_manifest/kubernetes/flagger/canary-test-flexiblemockserver
実際にcanary podが実行されたら、負荷試験ツールを用いてリクエストを流してみる。
❯ kubectl apply -k sample_manifest/kubernetes/locust/sample2/
今回はk9sの画面を表示していますが、SUSPENDED
の数が増えていることがわかります。
これは、metric_templateで定義した値がcanaryで設定してる閾値を満たしていないまたは、超えているためです。
今回はk9sの画面を表示していますが、SUSPENDED
の数が設定している数を超えたため失敗したことがわかります。
イベントは以下のように表示されています。
Warning Synced 10m flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 91.57 > 10
Warning Synced 9m38s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 133.65 > 10
Warning Synced 8m24s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 74.69 > 10
Warning Synced 7m38s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 55.80 > 10
Warning Synced 6m38s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 65.24 > 10
Warning Synced 5m38s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 91.61 > 10
Warning Synced 4m38s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 170.53 > 10
Warning Synced 3m38s flagger Halt canary-test-flexiblemockserver.mockserver advancement my metric 94.74 > 10
Warning Synced 38s (x4 over 2m38s) flagger (combined from similar events): Canary failed! Scaling down canary-test-flexiblemockserver.mockserver
試験が終わったらlocust
を削除しましょう。
❯ kubectl delete -k sample_manifest/kubernetes/locust/sample2/
apiVersion: flagger.app/v1beta1
kind: MetricTemplate
metadata:
name: my-metric
spec:
provider:
type: prometheus
address: http://prometheus-operated.monitoring:9090
query: |
sum(rate(traces_spanmetrics_calls_total{service_name="canary-test-flexiblemockserver", http_status_code!~"20*"}[1m])) * 60 or vector(0)
現状のQueryだと、primaryとcanaryの両方のデータを足した値が表示されます。 ただ、本来canary releaseとはcanary側がデグレーションを起こしてないかを確認するものなのでcanaryとprimaryにどのような差があるか、もしくは、canary側に絞るといったような対応をしてあるとさらに良い対応ができるでしょう。
修正版(canary側に絞る例)
apiVersion: flagger.app/v1beta1
kind: MetricTemplate
metadata:
name: my-metric
spec:
provider:
type: prometheus
address: http://prometheus-operated.monitoring:9090
query: |
sum(rate(traces_spanmetrics_calls_total{service_name="canary-test-flexiblemockserver", http_status_code!~"20*",k8s_deployment_name="canary-test-flexiblemockserve"}[1m])) * 60 or vector(0)
dashboardによる可視化
TBU
FlaggerはPrometheusタイプのメトリクスを公開してるのでPrometheusで取得を行うと、可視化、monitorの作成を行うことができる。
ref: flaggerのmetric取得部分(Prometheus pod_monitor)
ref: ドキュメント
sample)
TBU