2020.11.10

AWS ECSにおけるBlueGreenデプロイメントの使いどころ

概要

AWS ECSでは、CodeDeployを併用することでBlueGreenデプロイメントを構成可能です。

BlueGreenデプロイメントはリリースの確実性・安全性をサポートしてくれる仕組みです。

ECSにおけるBlueGreenデプロイメントの利点と挙動、そして使いどころについて解説します。

BlueGreenデプロイメントのモチベーション

一般的なBlueGreenデプロイメント

一般的なBlueGreenデプロイメントの最大のモチベーションは「ダウンタイムの最小化」にあります。

非コンテナアーキテクチャの場合、デプロイ時にサーバ(インスタンス)内のアプリケーションの再起動が必要ですが、何も考慮せずにデプロイしてしまうとそれがダウンタイムに繋がってしまいます。

ダウンタイムを最小化(基本的に発生させない)ためには、サーバを冗長化した上で、サーバひとつずつに対して以下手順を実施します。

  1. サーバの一時切り離し (ルーティングさせない)
  2. 切り離したサーバへアプリケーションデプロイと再起動
  3. サーバをサービスへ戻す (ルーティングさせる)

genreraly motivation

コンテナ基盤はそもそもデプロイ時ダウンタイムがない

BlueGreenデプロイメントには上述のメリットがありますが、コンテナ基盤アーキテクチャについて考えると、モチベーションは変わってきます。

ECSやEKS(Kubernetes)のようなコンテナ基盤アーキテクチャでは、そもそもコンテナの更新時にダウンタイムが発生しないような仕組みが提供されています。
上記のような手順を実施することなく、ダウンタイムは回避できているのです。

では、ECSでBlueGreenデプロイメントを導入する意味はあるのでしょうか?

AWS ECSにおけるBlueGreenデプロイメント

AWS ECSのBlueGreenデプロイでは、ダウンタイム最小化以外で以下の利点があります。 ・リリース前に本番同様の環境で動確可能 ・リリース後切り戻しが簡単で高速

リリース対象バージョンのコンテナが本番環境上で起動後、本番アクセス先を切り替える前に、一時的にテスト用ポートでアクセス可能な環境が構築されます。

また、本番アクセス先を切り替えた後の一定時間、以前のバージョンのコンテナが残り続け、即座に切り戻しが可能な状態を作れます。

この挙動について、以下解説します。

構成

step0

ECSサービスで予めタスク(rev:v1.0.0)が起動しているとします。

ECSサービスにはALBが設定されており、1つのALBに対して、Listener と TargetGroup がそれぞれ2つずつ存在します。

1つはProductionポート用で、このポートがアプリケーションの正式な公開ポートで、現行稼働中のタスクへトラフィックが流れます。

もう一つはTestポート用で、通常時はProductionポートと同じ現行稼働中タスクへトラフィックを流しますが、BlueGreenデプロイを実行中のトラフィックの切り替わりがProductionポートと異なります。

ステップ1

step1

新しくデプロイするバージョンのタスク定義(rev:v1.1.0)を登録します。
この作業はGithubActionsやJenkinsのようなCICDツールで行うものとします。

タスク定義の登録後、CodeDeployにて新規デプロイを作成します。
CodeDeployへデプロイ指示する際、使用するタスク定義やロードバランサーに紐づけるコンテナの情報を指定する必要があります。 これら情報の指定に appsepc.yml を使用します。
appspec.yml 内のタスク定義の revision を v1.1.0 のものに書き換えて、CodeDeployに対してデプロイを実行します。

CodeDeployは、appspec.yml の内容に従って、新タスク(v1.1.0)を起動します。

ステップ2

step2

v1.1.0のタスクの起動が完了後、ロードバランサーのTestポートのトラフィックがv1.1.0のタスクに流れるように、ListenerおよびTargetGroupの切り替えを実施します。 この切り替えもCodeDeployが実施します。

CodeDeployで「新しいタスクへトラフィックを流す前の待機時間」を設定可能で、待機時間が設定されている場合は、Productionポートからのトラフィックはまだ切り替わりません。

この時点で、Testポートにアクセスすると v1.1.0 のアプリケーションに、Productionポートにアクセスすると v1.0.0 のアプリケーションにそれぞれアクセスできる状態となります。

この状態で、Testポートを活用して動作確認を実施します。
もし、動作確認で問題が検出されたら、デプロイをキャンセル可能です。
Testポートは元通り v1.0.0 のタスクへのトラフィックへ戻り、v1.1.0のタスクも削除されます。

ステップ3

step3

Testポートでの動作確認に問題がなければ、Productionポートのトラフィックをv1.1.0のタスクに切り替えます。

CodeDeployで「元のタスクを残しておく時間」を設定可能で、この時間が設定されている場合、v1.0.0のタスクが指定時間残ります。

Productionポートを切り替えた後で不具合が発覚して、急いでロールバックするケースで役立ちます。

ステップ4

step4

リリースに問題がなければ、v1.0.0のタスクを終了します。

リリース作業が完了です。

インプレースデプロイメント(ローリング更新)

ECSでは、BlueGreenデプロイメントの他にインプレースデプロイメントを選択できます。

インプレースデプロイメントには、テストポートが存在せず、デプロイ処理の中で即座にアクセス先が切り替わります。

上述したとおり、インプレースデプロイメントであってもダウンタイムは発生しません。

ECSにおけるBlueGreenデプロイメントの使いどころ

簡易ステージング環境として活用する

BlueGreenデプロイメントは、リリース直前に本番アプリケーションの手作業によるテストを実施可能なため、より安全なリリースが可能です。 個人的な見解では「リリース直前に作成される一時的な簡易ステージング環境」としての用途にメリットがあると考えています。

アプリケーション数が1つだけ、もしくは関連するアプリケーション数が少ない場合に効果的です。 例えば、LaravelやRailsのようなモノリシックなアプリケーションを運用する場合です。

しかし、マイクロサービスのように、アプリケーション数が多くなってくると、ちょっと活用しにくいかなと思います。 例えば SPAフロントエンド + APIバックエンド の二つのECSサービスがあるとして、APIバックエンドをリリースする際にも、フロントエンドからの結合テストを行いたいはずです。 このためには、SPAフロントエンドからAPIバックエンドへアクセスする際に、production と test のどちらのポートを使用するのかなどの判定が必要になります。 これは、サービスが2つ程度であればできそうな気もしますが、さらにサービスが増えた際にどんどん複雑化しそうな気がします。

サービス結合数が多くなる場合は、BlueGreenデプロイメントではなく、インプレースデプロイメントを選択した上で、ステージング環境を別途専用に構築するのが良いと考えてます。

アークテクチャの複雑度が上がることを考慮する

BlueGreenデプロイメントは、インプレースデプロイメントに比べて、アーキテクチャの複雑度が高くなります。

また、サービスごとに必ずロードバランサーが必要です。 ECSではサービスディスカバリがサポートされており、ロードバランサーがなくてもサービスの名前解決が可能なのですが、BlueGreenデプロイメントを選択した場合はロードバランサーが必須です。 ロードバランサーには稼働時間やトラフィック量に応じた料金も発生します。

これらの事柄も予め考慮した方が良さそうです。 構成がシンプルであるということは、それだけでメリットです。

ECSサービスのデプロイメントコントローラについての注意点

ECSサービスのデプロイでは、内部的にデプロイメントコントローラというものが設定されており、それぞれ以下の対応となります。

インプレースデプロイメント: ECS
BlueGreenデプロイメント: CodeDeploy

デプロイメントコントローラは、ECSサービスの作成時にしか設定することができません。

すなわち、デプロイタイプを後から変更することはできず、変更したい場合はサービスの作り直しが必要です。

この際、ダウンタイムを回避するために色々と作業が必要なので、デプロイタイプについては最初によく検討して決定するべきです。

未検証の気になる点

以下ページに制約事項が記載されています。 https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html

ここに以下の記載があります

*「Blue/Green デプロイタイプを使用する場合、Amazon ECS サービスの Auto Scaling はサポートされません。」

しかし、BlueGreenデプロイメントを設定したECSサービスに対して、AutoScalingの設定自体はコンソールからできてしまうようで、この辺の検証ができていません。

いずれ検証したいと思います。

まとめ

AWS ECSにおけるBlueGreenデプロイメントを導入するモチベーション、挙動と使いどころについて解説しました。

ECSでは、BlueGreenデプロイメントによってリリース時の確実性・安全性の向上が期待できます。

BlueGreenデプロイメントの挙動を理解し使いこなすことで、リリース前の動作確認や不測の事態によるリリース後の切り戻しなどを容易になります。

シンプルなアプリケーションやアプリケーション個別の簡易ステージング環境が欲しい場合は、BlueGreenデプロイメントの導入価値がありそうです。

ECSのBlueGreenデプロイメントの特性を知り、状況に応じて使い分けましょう。

参考

PublicKey: 「Blue-Green Deployment」とは何か、マーチン・ファウラー氏の解説

martinfowler.com: BlueGreenDeployment