LoginSignup
29
17

More than 1 year has passed since last update.

Amazon ECS の Blue/Green デプロイメントの動作は何が起こっているか解説したい

Posted at

はじめに

Amazon ECS は、コンテナを動かしうまく管理するためのコンテナオーケストレーションサービスです。新たなバージョンのコンテナをデプロイするときに、いろいろなデプロイの方法が取れますが、ECS 側で用意されているデプロイ戦略が3種類あります

  • Rolling Update : Service の中で稼働しているタスクを少しずつ順繰りアップデートする方式
  • Blue/Green Deployment : 新たな環境である Green 環境を用意して、LB レイヤーで切り替える方式
  • External Deployment : 外部のサードパーティの何かでデプロイをコントロールする方式

こちらの Document に記載があります。 : https://docs.aws.amazon.com/AmazonECS/latest/userguide/deployment-types.html

Blue/Green Deployment の中でも、更に詳細な方式があります。CodeDeploy 側で用意されている5つのデプロイ方式の中で自分たちに合うものをチョイスできます。

デプロイ設定 説明
CodeDeployDefault.ECSLinear10PercentEvery1Minutes すべてのトラフィックを移行するまで、1 分ごとにトラフィックの 10% を移行します。
CodeDeployDefault.ECSLinear10PercentEvery3Minutes すべてのトラフィックを移行するまで、3 分ごとにトラフィックの 10% を移行します。
CodeDeployDefault.ECSCanary10percent5Minutes 最初の増分でトラフィックの 10% を移行します。残りの 90% は 5 分後にデプロイします。
CodeDeployDefault.ECSCanary10percent15Minutes 最初の増分でトラフィックの 10% を移行します。残りの 90 パーセントは 15 分後にデプロイされます。
CodeDeployDefault.ECSAllAtOnce すべてのトラフィックを同時に更新済み Amazon ECS コンテナに移行します。

今回は、この Blue/Green の中で CodeDeployDefault.ECSAllAtOnceCodeDeployDefault.ECSLinear10PercentEvery1Minutes の動きを紹介していきます。

CodeDeployDefault.ECSAllAtOnce の動作について

まず、デプロイを行っていない、通常の状態の構成を見ていきます。細かい部分は正確ではない部分もありますので、詳細はぜひ触ってみてください。ALB と書いている Box は 正確には NLB も利用できますし、リスナーのポートは HTTPS も利用可能なので、細かい部分で違いがあるところもあります。

image-20220321150230341.png

  • ALB のリスナーについて
    • 1個の ALB に、2つのリスナーがあります。
    • 本番 Blue環境用のトラフィックが流れる Production リスナーと、バージョンアップ後の Green 環境用の Test リスナーです。
  • Target Group について
    • Blue と Green の環境をコントロールするために、Target Group が2つ用意されています
    • 通常の構成では、Target Group 1 しか使いません
    • Target Group 1 が、ECS で稼働している Task(コンテナ)に紐づいています

ここで、新たなバージョンをデプロイを開始し始めると、以下の構成になります。ECS 環境上に、新たなバージョンの Task が立ち上がり、Target Group 2 に紐づけられます。紐づけられただけだと、まだ本番環境でのトラフィックは流れないため、エンドユーザーは引き続き version 1 の Blue 環境を触っています。

image-20220321150713730.png

次に、Green 環境が立ち上がったので、ALB の Test 用のリスナーが Green 環境に紐づけられます。

デフォルトの状態だとコンテナの中のアプリケーションが正常に稼働しているかは CodeDeploy は気にしていません。アプリケーションが異常状態であっても次のプロセスに進みます。ALB の Health Check の機能自体はありますが、ALB 側の Health Check は CodeDeploy は気にしていないように見えています。正しく稼働しているか自動的に確認するために、CodeDeploy のライフサイクルフックで AfterAllowTestTraffic のフェーズで Lambda を動かす機能が使えますが、今回は取り上げません。気になる場合はこのあたりを確認してみましょう。

image-20220321151154806.png

次に、本番用の Production 用のリスナーが Green 環境に紐づきます。このタイミングで、初めて本場利用のユーザーが新しいバージョンを利用し始めます。CodeDeployDefault.ECSAllAtOnce の方式の場合は、全員のユーザーがこのタイミングで Green 環境に切り替わります。徐々に切り替えていきたい場合は、これ以外の方式を選択すると良いでしょう。

Blue 環境を削除するまで、CodeDeploy の画面上でロールバックボタンを押せます。1ボタン押すだけで Blue 環境に切り戻しもできるので、便利に利用できそうです。

image-20220321152044469.png

その後、Blue 環境が不要になった Blue 環境を削除します。Blue 環境の削除は主に以下の2つのトリガーがあります

  • 手動で削除
  • 保存期間を超えたら削除。デフォルトは1時間まで平行稼働してくれる

image-20220321152730654.png

CodeDeployDefault.ECSLinear10PercentEvery1Minutes の動作について

CodeDeployDefault.ECSAllAtOnce の動作について との差分のみ記載します。

ALB の Production リスナーを、Green 環境に切り替える部分についてです。

image-20220321153126216.png

ALB の重みづけの機能を活用して、本番環境にアクセスしにきたユーザーを徐々に Green 環境に寄せていきます。これにより、影響のでるユーザーを出来るだけ少ない状態にしておき、何か問題があればすぐに切り戻しを行うことが出来ます。CodeDeployDefault.ECSLinear10PercentEvery1Minutes の名前にもある通り、1分おきに、10% ずつ Green 環境へのアクセスが増えていく形ですね。

初めは、Blue 環境へのアクセスが 100% で、Green 環境へのアクセスが 0% となっています。1分ごとにこの重みづけが 10% ずつ偏りが変わっていく形ですね。最終的には、Green 環境に完全に切り替わります。

  • 100% : 0%
  • 90% : 10%
  • 80% : 20%
  • 70% : 30%

more....

Blue/Green Deployment : 環境作成

ここまで概念的な話でした。これからは、実際に環境を作成してみる手順を紹介していきます。手順に興味がない場合は、この部分は無視してもらって大丈夫です。

ALB 作成

まず、ECS Service を作成する前に、紐づける ALB を作成しておく必要があります。

Create Load Balancer を押します。

image-20220321080700552.png

ALB を選択します。

image-20220321080730130.png

名前を指定

image-20220321080822035.png

Listener は適当に指定しないといけないので、Dummy のものを指定

image-20220321080919251.png

Create

image-20220321080933331.png

ALB が作成できました。Dummy で作成した Listener は削除しておきます。

image-20220321081010361.png

ECS Service 作成

次に、ECS Service を作成していきます。Blue/Green Deployment の方式は、2022年3月現在、旧コンソールでないと設定できませんでした。

Service Create

image-20220321081050189.png

  • Task Definition
  • Service name

image-20220321092358650.png

Deployment Type を指定可能

  • Blue/green deployment を選択

image-20220321081321062.png

VPC や Subnet を指定

image-20220321081415124.png

連携する ALB を指定

image-20220321081452581.png

Load Balancer に対して、2つのリスナーを用意する

  • Blue 環境用の Production listener
  • Green 環境用の Test listener

image-20220321081643682.png

2 つの Target Group の指定。デフォルトのままにしておく。

image-20220321081804799.png

Service の作成

image-20220321081847206.png

Service が作成されました

image-20220321082157288.png

自動設定 : ALB

ALB には 2 つの Listener が自動設定されています

image-20220321082259938.png

ALB にアクセスすることも出来ます

image-20220321092424396.png

自動設定 : Target Group

Target Group1 には、2つの Task が紐づいています

image-20220321082418446.png

Target Group 2 には、なにも Task は居ません

image-20220321082456152.png

自動設定 : CodeDeploy

CodeDeploy の Application の定義が1個作成されています

image-20220321083718914.png

Application の中に、Deployment Group が作成されています

image-20220321083815184.png

詳細な中身を確認するために、Edit を押します

image-20220321083850359.png

2つの設定値を確認できます。

  • Traffic rerouting : Blue 環境から Green 環境にトラフィックを切り替えるときの猶予時間についての設定。デフォルトの設定は、Reroute traffic immediately なので、すぐに切り替える設定になっている。
  • Original revision termination : Blue 環境から Green 環境に切り替えたあとに、Blue 環境をどれくらいの時間残しておくかの指定。この指定した時間は手動でロールバックボタンを押すことが出来る。

image-20220321083950323.png

なお、自動ロールバックについても設定があり、デプロイメントに失敗したときは自動的にロールバックされる

image-20220321084211021.png

動作確認 : Blue/Green を試す

対象の Service を選択して、Update を押す

image-20220321084931004.png

Task Definition を Revision 9 から 10 に変更します

image-20220321092806532.png

CodeDeploy に対する動作を指定できます。このままデフォルトでいきます。Deployment configuration でデプロイ方式を選択できるので、そのときの状況に合わせて最適なものを選びましょう。

image-20220321085148379.png

Next Step

image-20220321085229594.png

Next Step

image-20220321085250033.png

Update Service

image-20220321085310128.png

Service のアップデートを開始したので、Blue/Green Deployment が始まりました。

image-20220321085324851.png

ECS Task が 2 個から 4 個に増えている

image-20220321085542484.png

CodeDeploy では、Deployment が進んでいることがわかる

image-20220321085400815.png

Green 用の Target Group に新たな Task が登録される

image-20220321085447396.png

CodeDeploy 上では、Reroute が切り替わっている。切り替わってから1時間は Blue 環境を残す設定にしているので、Blue 環境が残っている。Terminate original task set を手動で押すことで、Blue 環境の手動削除が可能。

image-20220321085646435.png

ALB の HTTP 80 Listener の宛先 Target Group が切り替わっている

image-20220321093449522.png

CodeDeploy 上では、何にどれくらいの時間が掛かっていたかを確認可能

image-20220321093645451.png

わかったこと

  • CodeDeploy の Appllication 配下にある Deployment Group の設定 Original revision termination は、Blue から Green に切り替え終わった後に、Blue の環境をどれだけ保持しておくかの設定となっている。

  • Blue の環境を保持している期間は、新たなデプロイが出来ない。新たにデプロイしたい場合は、手動で Terminate ボタンを押す必要がある
    image-20220321095818846.png

  • 重みづけをした場合は、Target Group の重みづけが入る

    • CodeDeployDefault.ECSLinear10PercentEvery1Minutes
    • 90 : 10 → 80 : 20 → 70 : 30 と徐々に切り替わっていく
      image-20220321101233371.png
  • Blue/Green Deployment の場合、ALB の Health Check にある Interval や、Healthy threshold など設定値は、影響しない。Interval をいくら伸ばしても、Healthy threshold の回数を増やしても、Deployment の時間には影響しなかった。CodeDeploy は、ALB の Health Check は無視しているのだと思われる。

  • CodeDeploy による Blue/Green デプロイは、Green 環境が正常に稼働しているかは気にしないで切り替えを行う。これを検証して、異常な場合は自動ロールバックするために、CodeDeploy のライフサイクルフックを利用可能

参考URL

29
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
17