Flagger による k8s アプリケーションの Blue/Green デプロイ
はじめに
既に稼働しているアプリケーションのバージョンを上げる際のデプロイ方法にはいろいろありますが、特にダウンタイムの発生しないデプロイ方法としては以下のものが有名です。
- Blue/Green デプロイ (以下 B/G デプロイ)
- Canary デプロイ
k8s クラスタに deployment として展開されているアプリケーションのバージョンを変更することを考える場合、deployment リソース内のイメージタグを更新してクラスタに適用すれば RollingUpdateStrategy に基づいて既存の pod が徐々に置き換えられていきます。( kubernetes ドキュメント を参照)
この方法では常に最小限の pod が稼働していることが保証されておりダウンタイムが発生しません。なのでまあこれでも充分といえば充分ですが、上記デプロイ方法のように置き換え前後でアプリケーションの正常性確認をしたり、デプロイが失敗した際に自動でロールバックを実行したいような場合もあります。
k8s の Service を工夫することでも実現できますが、デプロイの自動化やリリース作業をより効率的に行うための Flagger という OSS ツールがあるので、今回は Flagger とサービスメッシュの linkerd を合わせた BG デプロイを試してみます。
Flagger
Flagger はサービスメッシュや Ingress Controller と組み合わせてアプリケーションの様々なデプロイ戦略を実現するツールです。CNCF graduate project である Flux の一部に位置づけられています。
flagger ではダウンタイムの発生しない以下のようなデプロイ戦略を実現することができます。
- Canary (progressive traffic shifting)
- A/B Testing (HTTP headers and cookies traffic routing)
- Blue/Green (traffic switching and mirroring)
また、デプロイ実行時や結果の slack への通知や自動ロールバック、rollout 中の負荷テストなどの機能もあります。
Linkerd
Linkerd は k8s 用の軽量サービスメッシュツールです。同様の役割を果たすツールとしては envoy が有名です。
Linkerd は監視対象の pod にマイクロプロキシと呼ばれるコンテナを注入し、pod を通過するトラフィックを監視、可視化、制御する役割を果たします。主な機能はドキュメントの Reference にまとまっており、サービスメッシュもこの機能の一つとなっています。
flagger と組み合わせた B/G デプロイにおいては HTTPRoute の機能を使っているようです。
準備
インストール
linkerd, flagger で BG デプロイを行うためにそれぞれのコンポーネントを k8s クラスタにインストールします。
Linkerd
linkerd のインストールは linkerd ドキュメントの Getting start に沿って進めます。
linkerd は CLI を通じて CRD や様々なリソースをインストールできるようになっているため、はじめに CLI をインストールします。
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
export PATH=$HOME/.linkerd2/bin:$PATH
linkerd check --pre
次に linkerd Custom Resource Definition (CRD) と linkerd 本体のインストールを行います。
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
linkerd check
これにより linkerd namespace が作成され、linkerd dataplane が作成されます。
linkerd-viz のインストール
linkerd viz install | kubectl apply -f -
これにより linkerd-viz ダッシュボード等の拡張機能がインストールされます。今回の範囲でこの中に含まれる prometheus を使用します。
flagger
flagger のインストールは Linkerd Canary Deployments の Prerequisites に従って行います。マニフェストや helm などのインストール方法が用意されていますが、今回はマニフェストからインストールします。
kubectl apply -k github.com/fluxcd/flagger//kustomize/linkerd
linkerd SMI というコンポーネントも必要なのでインストール
curl -sL https://linkerd.github.io/linkerd-smi/install | sh
linkerd smi install | kubectl apply -f -
アプリケーションの準備
B/G デプロイの動作確認にはアプリケーションを古いバージョンから新しいバージョンにアップデートする作業が必要になるので、簡単なアプリケーションとしてルートにアクセスしたら現在のバージョンを返すだけの単純な python アプリを用意します。
from flask import Flask
app = Flask(__name__)
version = "1.0"
@app.route("/")
def test():
return {"version": version}
if __name__ == "__main__":
app.run(host="0.0.0.0")
FROM python:3.11-slim
RUN pip install flask
COPY . /
ENTRYPOINT ["/python"]
CMD ["/main.py"]
この中の version = "1.0"
をそれぞれ 1.0, 2.0 としたイメージを作成し、イメージタグをそれぞれ v1, v2 とします。
アプリケーションのルートにアクセスすると現在のバージョンが取得できます。
$ curl 10.106.142.221:5000
{"version":"1.0"}
$ curl 10.106.142.221:5000
{"version":"2.0"}
k8s クラスタにアプリケーションをデプロイするために deployment を作成します。
イメージ名は linkerd-test
としてどこかのレジストリに push しておきます (今回はローカルに立てた harbor)。
apiVersion: apps/v1
kind: Deployment
metadata:
name: linkerd-test
namespace: linkerd-mysvc
spec:
replicas: 2
selector:
matchLabels:
app: linkerd-test
template:
metadata:
labels:
app: linkerd-test
spec:
containers:
- image: harbor.centre.com/k8s/linkerd-test:v1
name: flask
ports:
- containerPort: 5000
name: http
Flagger デプロイで使う用語・概念
flagger ではやや見慣れない概念や用語があるので、デプロイを試す前に確認しておきます。
canary オブジェクト
flagger ではカスタムリソースである canary オブジェクトによってデプロイ時の挙動を制御します。設定可能な項目は ドキュメントの usage に細かく書いてあります。
Deployment の種類
canary オブジェクトをクラスタ上に作成すると、デプロイ対象として設定した deployments の pod 数が 0 に設定され、代わりに同じプロパティが設定された [deployment_name]-primary
という deployment が作成されます。
デプロイを行う前後の定常状態では primary deployment の pod が外部からのトラフィックに対応し、デプロイ中の正常性試験などは元の deployment の pod が対応します。
元の deployment のイメージ等の更新作業は管理者などのユーザが行い、primary deployment のバージョンアップやロールバックは canary オブジェクトが変更に基づいて自動で更新する構成になっています。
また、canary オブジェクト作成時に外部からのトラフィックをルーティングするための 3 つの svc オブジェクトも同時に作成されます。
例えば linkerd-test
という deployment に対して canary オブジェクトを作成した場合、以下の svc が自動で作成されます。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
linkerd-test ClusterIP 10.97.84.59 <none> 5000/TCP 136m
linkerd-test-canary ClusterIP 10.109.254.145 <none> 5000/TCP 136m
linkerd-test-primary ClusterIP 10.110.50.78 <none> 5000/TCP 136m
デプロイを行う前後の定常状態ではアプリケーションのトラフィックは linkerd-test, linkerd-test-primary サービスを通じて primary deployment へルーティングされます。
デプロイ中では元の deployment の replica 数が調整され、置き換え先バージョンへの正常性確認は linkerd-test-canary サービスを通じて行われます。linkerd-test サービスには HTTPRoute オブジェクトが紐付けられ、事前定義したプロパティに応じてトラフィックを linkerd-test-canary と linkerd-test-primary に分割します (canary デプロイの場合)。このような構成によりトラフィックを置き換え先バージョンへルーティングしてテストなどを行います。
Flagger におけるデプロイ phase
flagger を使ったデプロイでは内部的にいくつかの phase を経由して新しいバージョンへの置き換えが行われます。ドキュメントの用語を使うと以下の phase に分けられます。
- 定常状態
- デプロイが行われる前、またはデプロイが完了した状態。
- Rollout
- アプリケーションのバージョンアップを行う前の段階。
- analysis に基づいてメトリクスの評価などが行われます。事前に定義した基準を満たすと rollout は成功とみなされ Promotion に移行します。
- この最中に基準を下回った場合などはデプロイに失敗したとみなされ、リソースをデプロイ前の状態に戻す rollback に移行します。
- Promotion
- Promotion では primary deployment を新しいバージョンに変更します。これにより外部からのトラフィックは新しいバージョンのアプリケーションにルーティングされます。
- Rollback
- rollback では Rollout phase で増えた deployments の replica 数を 0 に戻す等の処理を行い、リソースを deploy が始まる前の状態に戻します。これによりデプロイ中の primary への影響を最小限に抑えることができます。
これら phase の移行をざっくりと図示すると以下のようになります。
また、各 phase の前後やトラフィック移行前などに webhook を実行することができます。これを利用すると Rollout 前にアプリケーションの各 API の応答をチェックしたり、rollout の最中に負荷テストを行うことができます。
B/G デプロイの実行
ここでは実際に B/G デプロイによってアプリケーションのバージョンを v1 → v2 に更新する際の挙動を確認します。
デプロイシナリオの定義
B/G デプロイを実行する際は、どのような条件でデプロイを成功・失敗と判断するかの条件を事前に定義することが重要になります。
実際のデプロイではアプリケーションの仕様によってデプロイ前に API エンドポイントの正常性を確認したり Rollout の段階で負荷テストを行ったりしますが、今回は単純なケースとしてデプロイ成功・失敗条件を以下のように決めます。
- 1 回の判定条件について
- 30 秒毎のアプリケーションの Response 成功率が 99 % 以上で成功、それ以下で失敗。
- 5 回連続で判定に失敗したらデプロイに失敗したとみなし、前バージョンにロールバックする。
- 5 回判定に判定に成功したらデプロイに成功したとみなし、トラフィックを新しいバージョンに移行する。
- 判定は 30 秒毎に行う。
デプロイのシナリオを決めたら、この動作を実現するための canary リソースを以下のように定義します。
spec:
analysis:
interval: 30s
iterations: 5
threshold: 5
metrics:
- name: success-rate
templateRef:
name: success-rate
namespace: test
thresholdRange:
min: 99
interval: 30s
templateVariables:
direction: inbound
Rollout 中の判定条件は linkerd-viz インストール時に同時にインストールされた prometheus が取得する metrics に基づいて評価します。これは flagger CRD の MetricTemplate
オブジェクトによって行われます。
---
apiVersion: flagger.app/v1beta1
kind: MetricTemplate
metadata:
name: success-rate
namespace: test
spec:
provider:
type: prometheus
address: http://prometheus.linkerd-viz:9090
query: |
sum(
rate(
response_total{
namespace="{{ namespace }}",
deployment=~"{{ target }}",
classification!="failure",
direction="{{ variables.direction }}"
}[{{ interval }}]
)
)
/
sum(
rate(
response_total{
namespace="{{ namespace }}",
deployment=~"{{ target }}",
direction="{{ variables.direction }}"
}[{{ interval }}]
)
)
* 100
query フィールドの中身が判定条件である 30 秒毎のアプリケーションの Response 成功率
を計算するクエリ式に対応しています (数値自体は canary オブジェクト側で代入)。
この他、別の prometheus を使用する、固有のカスタムメトリクスを評価対象する、他の provider を指定するなどの手順が https://docs.flagger.app/usage/metrics にまとまっています。
実行
B/G デプロイを実行する前に、まずアプリケーションの deployment バージョン 1.0 である linkerd-test
deployment をクラスタにデプロイします。
次に上記で作成した canary オブジェクトをデプロイします。これにより元の deployment の replica が 0 に設定され、[deployment]-primary
という deployment から作成された pod が代わりに起動します。
$ kubectl get deployments.apps linkerd-test
NAME READY UP-TO-DATE AVAILABLE AGE
linkerd-test 0/0 0 0 23h
$ kubectl get deployments.apps linkerd-test-primary
NAME READY UP-TO-DATE AVAILABLE AGE
linkerd-test-primary 1/1 1 1 23h
これで準備が整ったので、アプリケーションを新しいバージョン v2 に更新します。
- - image: harbor.centre.com/k8s/linkerd-test:v1
+ - image: harbor.centre.com/k8s/linkerd-test:v2
canary オブジェクトが新しいバージョンへの更新を検知すると、version 2.0 の deployment の replica 数が増え、デプロイの Rollout が開始されます。Rollout 中は canary オブジェクトによって定期的にメトリクス評価が行われ、新しいバージョンの deployment が判定条件を満たすかどうかチェックされます。この様子は kubectl event -w
や kubectl describe canary [name]
等で確認できます。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Synced 10m flagger linkerd-test-primary.linkerd-mysvc not ready: waiting for rollout to finish: observed deployment generation less than desired generation
Warning Synced 9m9s flagger HTTPRoute .linkerd-mysvc update error: resource name may not be empty while reconciling
Normal Synced 8m9s (x3 over 10m) flagger all the metrics providers are available!
Normal Synced 8m9s flagger Initialization done! ctest.linkerd-mysvc
Normal Synced 5m9s flagger New revision detected! Scaling up linkerd-test.linkerd-mysvc
Normal Synced 4m9s flagger Starting canary analysis for linkerd-test.linkerd-mysvc
Normal Synced 4m9s flagger Advance ctest.linkerd-mysvc canary iteration 1/5
Normal Synced 3m9s flagger Advance ctest.linkerd-mysvc canary iteration 2/5
Normal Synced 2m9s flagger Advance ctest.linkerd-mysvc canary iteration 3/5
Normal Synced 69s flagger Advance ctest.linkerd-mysvc canary iteration 4/5
Normal Synced 9s flagger Advance ctest.linkerd-mysvc canary iteration 5/5
Advance ctest.linkerd-mysvc canary iteration 2/5
等のメッセージにより、 30 秒毎にメトリクの評価が行われていることが確認できます。今回設定した Response 成功率が 99 % 以上という条件はアプリケーションが正常な状態であればまず合格するため、Rollout の評価は正常に進んでいきます。
今回はデプロイ成功条件を 5 回に設定しているため、iteration が 5 回成功するとデプロイ成功と判断され、 Promotion phase に移行します。Promotion では primary deployment のイメージが v2 へと更新され、それが完了すると元の Deployment の replica 数が再度 0 に戻り、元の定常状態へと戻ります。
この辺りの元の deployment と primary deployment の pod 入れ替え動作は案外やってみないとわかづらいですが、ざっくり図示すると以下のような流れで変化していきます。
デプロイ中の deployment の動作
Canary デプロイの実行
flagger ではトラフィックを徐々に移行できる canary デプロイも実現できるため、こちらも試してみます。
準備
デプロイ方法を B/G から canary へと変更する方法は単純で、canary オブジェクトで iterations
としていた部分を削除し maxWeight
と stopWeight
を追加すれば良いです。
interval: 60s
- iterations: 5
+ maxWeight: 100
+ stepWeight: 25
この変更を行うだけでデプロイ方法が B/G → canary へと変更されます。
canary デプロイでは Rollout phase にトラフィックを徐々に新しいバージョンへと移行するため、移行の割合と移行完了の閾値をそれぞれ stepWeight, maxWeight として設定する必要があります。
上記の例では 60 秒毎に 25 % ずつトラフィックが新しいバージョンのアプリケーションへと移行し、100 % に達した時点で Rollout が完了します。すなわち、イメージタグを更新してからトラフィックの移行は以下のようになります、
経過時間 | 古いバージョンへのトラフィック | 新しいバージョンへのトラフィック |
---|---|---|
0 sec | 100 % | 0 % |
60 sec | 75 % | 25 % |
120 sec | 50 % | 50 % |
180 sec | 25 % | 75 % |
240 sec | 0 % | 100 % |
実行
B/G デプロイのときの同様に元の deployment のイメージタグを更新することで変更が検知され canary デプロイが始まります。
デプロイの進捗状況も B/G デプロイと同様に canary オブジェクトの events で確認できます。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Synced 11m flagger linkerd-test-primary.linkerd-mysvc not ready: waiting for rollout to finish: observed deployment generation less than desired generation
Warning Synced 10m flagger HTTPRoute .linkerd-mysvc update error: resource name may not be empty while reconciling
Normal Synced 9m14s (x3 over 11m) flagger all the metrics providers are available!
Normal Synced 9m14s flagger Initialization done! ctest.linkerd-mysvc
Normal Synced 8m14s flagger New revision detected! Scaling up linkerd-test.linkerd-mysvc
Normal Synced 7m14s flagger Starting canary analysis for linkerd-test.linkerd-mysvc
Normal Synced 7m14s flagger Advance ctest.linkerd-mysvc canary weight 25
Normal Synced 6m14s flagger Advance ctest.linkerd-mysvc canary weight 50
Normal Synced 5m14s flagger Advance ctest.linkerd-mysvc canary weight 75
Normal Synced 4m14s flagger Advance ctest.linkerd-mysvc canary weight 100
Normal Synced 3m14s flagger Copying linkerd-test.linkerd-mysvc template spec to linkerd-test-primary.linkerd-mysvc
Normal Synced 74s (x2 over 2m14s) flagger (combined from similar events): Promotion completed! Scaling down linkerd-test.linkerd-mysvc
canary デプロイでは Advance ctest.linkerd-mysvc canary weight
のメッセージによりトラフィックが段階的に移行していることが確認できます。
トラフィックの移行は httproutes オブジェクトの backend service への Weight が変化することに対応しています。
例えば古いバージョンへのルーティングが 75 %, 新しいバージョンへのルーティングが 25 % の段階で kubectl describe httproutes.gateway.networking.k8s.io
で httproutes を確認すると、Backend Refs の Weight がそれぞれこの値に設定されていることが確認できます。
Spec:
Parent Refs:
Group: core
Kind: Service
Name: linkerd-test
Namespace: linkerd-mysvc
Port: 5000
Rules:
Backend Refs:
Group:
Kind: Service
Name: linkerd-test-primary
Port: 5000
Weight: 75
Group:
Kind: Service
Name: linkerd-test-canary
Port: 5000
Weight: 25
Matches:
Path:
Type: PathPrefix
Value: /
linkerd-test
svc にアクセスした際に上記の割合でルーティングすることで canary デプロイを実現する構成になっています。もちろん canary デプロイの Rollout が進むにつれて httproutes の weight の割合も変化していきます。
トラフィックのルーティングについて
ところで canary デプロイではトラフィックを新旧バージョンにそれぞれルーティングできますが、デプロイ中も指定した割合で本当にトラフィックがルーティングされているのか少し気になります。これを実際に確かめるために、デプロイ中に linkerd-test
svc に継続的にアクセスし、レスポンス結果を csv に書き込むごくシンプルなスクリプトを使ってざっくりと計測しました。
#!/usr/bin/env python3
import requests
from datetime import datetime
import time
import csv
def run():
url = "http://linkerd-test.linkerd.mysvc:5000"
output = "output.csv"
with open (output, "w") as f:
print("Start")
writer = csv.writer(f)
while True:
try:
res = requests.get(url=url)
now = datetime.now().strftime("%Y/%m/%d %H:%M:%S.%f")
value = res.json()["version"]
print(now, value)
writer.writerow([now, value])
time.sleep(0.1)
except KeyboardInterrupt:
break
except:
pass
if __name__ == "__main__":
run()
今回のアプリケーションでは http request に対してアプリケーションのバージョンを response として返すように実装しているため、バージョンを見ることで新旧どちらの svc にルーティングされたか判別できます。デプロイ開始 ~ 完了まで上記のスクリプトを実行することでトラフィックルーティングの変化が見れるようになっています。
実際に計測を行い、ルーティング先を 10 秒ごとにまとめてグラフ化したものが以下になります。
これにより、デプロイ開始前では linkerd-test
svc へのアクセスはすべて旧バージョンのサービス(version 1.0 pod) にルーティングされますが、デプロイ開始から時間が経過するにつれてアクセスが徐々に新バージョンのサービス (version 2.0 の pod) にルーティングされている様子が確認できます。
ただし、canary デプロイ自体は 60 秒毎に 25 % ずつトラフィックを移行するように設定したのでグラフの version 1, 2 の割合も 3:1 → 2:2 → 1:3 のように変化することが想定されますが、図を見れば明らかなように上記の計測ではそのように変化していません。今回の計測手段や集計方法はかなりざっくりとしたものだったので、このあたりはもう少し厳密に計測することでより近い値になるかと思われます。
いずれにしても、canary デプロイの最中は新旧サービスにトラフィックが分割される動作が実際に確認できました。
その他
slack 通知
flagger の Alertprovider
カスタムリソースを使用すると、デプロイの開始時や成功時に slack にメッセージを投稿できます。
apiVersion: flagger.app/v1beta1
kind: AlertProvider
metadata:
name: on-call
namespace: linkerd-mysvc
spec:
type: slack
channel: on-call-alerts
username: bot-test
secretRef:
name: on-call-url
---
apiVersion: v1
kind: Secret
metadata:
name: on-call-url
namespace: linkerd-mysvc
data:
address: <encoded-url>
使うには canary マニフェストの analysis.alerts
に定義します。
spec:
analysis:
alerts:
- name: "on-call Slack"
severity: info
providerRef:
name: on-call
namespace: linkerd-mysvc
デプロイを実行すると、デプロイのタイプやターゲット、実行結果を slack に通知してくれます。
ただ現時点では機能はそれほど多くなく、投稿されるメッセージのカスタマイズなどはできなさそうです。Github を眺めるとメッセージのカスタマイズの機能リクエストなどの issue が見られるので今後機能が充実していくかも知れません。
自動ロールバック
flagger では新しいバージョンへの移行中に決められた基準を満たさいない場合にデプロイ前のバージョンに自動でロールバックする機能があるのでそちらも試してみます。
ロールバックの動作を試すには移行途中で正常性チェックに失敗する必要があるので、以下のように起動してから 30 秒後にアクセスできなくなるようにアプリケーションを修正します。
#!/bin/bash
/main.py &
sleep 30
pkill python
sleep 120
FROM python:3.11-slim-bookworm
RUN apt-get update && apt-get install -y procps
RUN pip install flask
COPY main.py /main.py
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x main.py entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
これを rollback
バージョンとして、v1 → rollback へのバージョンアップの際にロールバックが発生するようにします。デプロイに使用するオブジェクトや手順については B/G デプロイの実行 と同様です。
deployment 内のイメージタグを更新して Rollout phase に進んだ後、kubectl describe canaries.flagger.app
により canary オブジェクトの event を見ると、アプリケーションの停止により 3 回目の iteration に失敗してロールバックが行われたことが確認できます。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Synced 3m12s flagger linkerd-test-primary.linkerd-mysvc not ready: waiting for rollout to finish: observed deployment generation less than desired generation
Warning Synced 2m52s flagger HTTPRoute .linkerd-mysvc update error: resource name may not be empty while reconciling
Normal Synced 2m32s (x3 over 3m12s) flagger all the metrics providers are available!
Normal Synced 2m32s flagger Initialization done! ctest.linkerd-mysvc
Normal Synced 112s flagger New revision detected! Scaling up linkerd-test.linkerd-mysvc
Normal Synced 92s flagger Starting canary analysis for linkerd-test.linkerd-mysvc
Normal Synced 92s flagger Advance ctest.linkerd-mysvc canary iteration 1/5
Normal Synced 72s flagger Advance ctest.linkerd-mysvc canary iteration 2/5
Warning Synced 52s flagger Halt ctest.linkerd-mysvc advancement success-rate 10.78 < 99
Warning Synced 32s flagger Rolling back ctest.linkerd-mysvc failed checks threshold reached 1
Warning Synced 32s flagger Canary failed! Scaling down ctest.linkerd-mysvc
slack 上では iteration に失敗した際のメッセージが赤色で表示されます。
ロールバックが完了した状態では primary deployment のバージョンはデプロイ前の v1
ですが、もとの deployment では変更後の rollback
となっています (ただし pod 数は 0)。
$ kubectl get deployments.apps linkerd-test-primary -o yaml | grep image:
- image: harbor.centre.com/k8s/linkerd-test:v1
$ kubectl get deployments.apps linkerd-test -o yaml | grep image:
- image: harbor.centre.com/k8s/linkerd-test:rollback
この状態からデプロイを再実行するには flagger Q&A に書いてあるようにいくつかの方法があります。例にあるようにもとの deployment を編集して annotations.timestamp
のようなフィールドを追加のが一番手っ取り早いです。
apiVersion: apps/v1
kind: Deployment
spec:
template:
metadata:
annotations:
timestamp: "2020-03-10T14:24:48+0000
これがもとの deployment オブジェクトに対する変更とみなされデプロイが再実行されます。
イメージタグは既に変更済みなので変更してデプロイをトリガーすることはできず、オブジェクトの他のプロパティを更新する必要があるのがやや不便かと思いました。このあたりの動作を CI/CD に組み込んで自動化するには少し工夫する必要がありそうです。
まとめ
Flagger を用いた k8s 上アプリケーションの Blue/Green デプロイを試しました。
やや独特な用語や仕組みがあるので使い始めは慣れが必要ですが、様々なデプロイ戦略を実施できるため使いこなせるとアプリケーションのリリース作業がより効率的に実行できるかと思われます。シンプルなデプロイの自動化などは Argocd などの CI/CD ツールで実現できますが、デプロイ中の正常性確認や自動ロールバックを実現したい場合は Flagger と組み合わせると有効そうです。
Discussion