こんにちは、末廣です。
最近、ECS のデプロイ方法として CodeDeploy が不要な組み込み型のデプロイができるようになりました。
これにあたり、私もサービスコネクトを使ってブルー/グリーンデプロイを試しました。
しかし、この組み込み型のデプロイでは、今まで CodeDeploy では対応していたカナリアデプロイとリニアデプロイが使えない状態でした。
それが今回のアップデートで組み込み型でも使えるようになったため、検証してみます。
デプロイの種類
まずはデプロイの種類からおさらいします。

構成は以前の私のブログの形式に対して、Service Connect を使い、backend サービスをデプロイするとします。

ローリングアップデート
現在の Desired Task をベースにする最小実行タスクと最大実行タスクの割合を設定し、コンテナを順々にアップデートしていく方法です。

Desired Task が2、最小実行タスクを 100%、最大実行タスクを 200%とすると、
- 新しいタスクを2個起動(合計4個:古い2個+新しい2個)
- 新しいタスクが「正常」になったら、古いタスクを2個停止
- 結果として、Desired Task の2個だけが残る
のような流れになります。
ブルー/グリーン
ブルーおよびグリーンという 2 つの環境を実行し、デプロイ中に新しいサービスリビジョンを検証することができる方法です。

組み込み型デプロイでは、Service Connect を用いてテストトラフィックを検証することができるようになっています。
Canary(カナリア)
カナリアという言葉は、炭鉱夫が一酸化炭素などの無臭ガス漏れを察知するカナリアを炭鉱に持ち込んだことが由来とされ、 デプロイ中の新しいバージョンのソフトウェアをテストしながら、必要に応じて安定したバージョンにロールバックできる様子を見立てているようです。
ブルー/グリーンデプロイの一種で、ブルー環境とグリーン環境それぞれに振り分けるトラフィックの割合を設定することができます。

詳しくは以下で検証していきます。
リニア(線形)
こちらもブルー/グリーンデプロイの一種で、線形(linear)という名の通り指定したパーセンテージずつ徐々にグリーン環境へトラフィックを移行していきます。

同じく詳しくは以下で検証していきます。
今までの設定
今までの CodeDeploy を使ったデプロイは以下のような事前定義された設定を使うことができました。
デプロイ設定 説明 CodeDeployDefault.ECSLinear10PercentEvery1Minutes すべてのトラフィックが移行されるまで、毎分トラフィックの 10 パーセントを移行します。 CodeDeployDefault.ECSLinear10PercentEvery3Minutes すべてのトラフィックが移行されるまで、3 分ごとにトラフィックの 10 パーセントを移行します。 CodeDeployDefault.ECSCanary10Percent5Minutes 最初の増分でトラフィックの 10 パーセントを移行します。残りの 90 パーセントは 5 分後にデプロイされます。 CodeDeployDefault.ECSCanary10Percent15Minutes 最初の増分でトラフィックの 10 パーセントを移行します。残りの 90 パーセントは 15 分後にデプロイされます。 CodeDeployDefault.ECSAllAtOnce すべてのトラフィックを同時に更新済み Amazon ECS コンテナに移行します。
今回の組み込み型でいうと…
- ブルー/グリーン → CodeDeployDefault.ECSAllAtOnce
- カナリア → CodeDeployDefault.ECSCanary10Percent5Minutes, CodeDeployDefault.ECSCanary10Percent15Minutes
- リニア → CodeDeployDefault.ECSLinear10PercentEvery1Minutes, CodeDeployDefault.ECSLinear10PercentEvery3Minutes
といった形になります。
検証
では、今までの CodeDeploy で事前定義されているデプロイ設定を例に、組み込み型で設定するためのパラメータを確認し、検証を進めてみます。
カナリアのとき
「最初の増分でトラフィックの 10 パーセントを移行します。残りの 90 パーセントは 5 分後にデプロイされます。」を例にやってみます。

パラメータ
Canary パーセント
カナリアフェーズ中にグリーン環境へ移行するトラフィックの割合です。 今回は、トラフィックの10%をグリーン環境、残り90%をそのままのブルー環境に送信するようにします。
Canary ベイク時間
Canary パーセントで設定したトラフィックの振り分けで、ブルー/グリーン環境が並行稼働しているカナリアフェーズの時間です。 分単位で5 で設定します。
デプロイベイク時間
ブルー/グリーンの環境が並行稼働しているが、トラフィックは全てグリーン環境に向き、ブルー環境を終了するまで待機する時間です 分単位で設定し、CodeDeploy の時はデフォルトで 60分間になっていました。
デプロイしてみる
カナリアで新しいリビジョンをデプロイしてみます。

以下シェルスクリプトで curl コマンドを打ってトラフィックの状態を確認すると
#!/bin/bash URL="http://ecs-service-connect-alb-xxx.ap-northeast-1.elb.amazonaws.com" COUNT=100 for i in $(seq 1 $COUNT); do curl -s "$URL" echo done
$ ./curl.sh | sort | uniq -c | sort -nr 86 Hello from BACKEND BLUE 14 Hello from BACKEND GREEN (v2.0)
大体 10%がグリーン環境へトラフィックが流れています。 そして、Canary ベイク時間が経過した後は、全てグリーン環境へトラフィックが流れています。
$ ./curl.sh | sort | uniq -c | sort -nr 100 Hello from BACKEND GREEN (v2.0)
デプロイベイク時間の間、何かしらエラーが発生した時はロールバックを実行することもできます。

全体の流れを図で表すと、以下のようになります。

リニアのとき
「すべてのトラフィックが移行されるまで、毎分トラフィックの 10 パーセントを移行します。」を例にやってみます。

パラメータ
リニアステップ割合
リニアデプロイメントの各ステップで移行するトラフィックの割合です。ブルー環境からグリーン環境へ、何%ずつ移行していくかを指定します。10%ずつ移行させます。
リニアステップベイク時間
リニアステップ割合が増える時間の間隔です。何分ごとに10%ずつ増加させるかを指定します。 毎分トラフィックを増加させるため、1で設定します。
デプロイベイク時間
カナリアデプロイと同様です。
デプロイしてみる
リニアで新しいリビジョンをデプロイしてみます。 デプロイタブの「リクエストされたプロダクショントラフィックウェイト」をみることで、現在リニアステップのどの段階かを確認することができます。




curl でのトラフィックも確認します
$ ./curl.sh | sort | uniq -c | sort -nr 88 Hello from BACKEND BLUE 12 Hello from BACKEND GREEN (v2.0)
$ ./curl.sh | sort | uniq -c | sort -nr 79 Hello from BACKEND BLUE 21 Hello from BACKEND GREEN (v2.0)
$ ./curl.sh | sort | uniq -c | sort -nr 71 Hello from BACKEND GREEN (v2.0) 29 Hello from BACKEND BLUE
徐々にグリーン環境へトラフィックが移行していることがわかります。 全体の流れを図で表すと、以下のようになります。

使い分け
それぞれの向いているケースを考えてみます。
カナリア
万が一バグが含まれていたとしても、影響範囲をトラフィックの 10% といった少数に留められるため、アプリケーションの不具合(バグ)が心配な場合に有力な選択肢となります。
リニア
トラフィックを段階的に移行させることで、DB 接続数やメモリ使用量の推移を徐々に確認できます。そのため、インフラ構成やキャッシュ戦略の変更など、負荷変動(パフォーマンス)が心配なリリースに最適です。
まとめ
今回のアップデートにより、組み込みデプロイでもカナリアとリニアデプロイが選択できるようになりました。 CodeDeploy の時は、ベイク時間を細かく設定したい時は自身で定義する必要があるなど、一手間必要だったのがパラメータ一つでできるようになり、 さらにロードバランサー配下のサービスでなくともService Connect を使うことでカナリア、リニアの選択肢を選ぶことができるようになったいいアップデートだと感じました。
末廣 満希(執筆記事の一覧)
2022年新卒入社です。ここに何かかっこいい一言を書くことができるエンジニアになれるように頑張ります。