Amazon Web Services ブログ
EC2 Container ServiceのBlue/Greenデプロイメント
この投稿と付随するコードの作成には、下記3名による多大な貢献がありました。
Jeremy Cowan Solutions Architect |
Anuj Sharma DevOps Cloud Architect |
Peter Dalbhanjan Solutions Architect |
コンテナ化されていないトラディショナルな環境にソフトウェアアップデートを展開するのは難しく、リスクを伴います。デプロイパッケージまたはスクリプトを記述するときは、ターゲットマシンが特定の状態にあると仮定する必要があります。ステージング環境が本番環境の正確なミラーイメージでない場合、デプロイは失敗する可能性があります。デプロイが失敗すると、アプリケーションの最後の正常なバージョンを再デプロイするまでサービス停止が起きることがあります。あなたが運用管理者だとしたら、サービス停止があると夜間に起きていなければいけないでしょう。
リリース内容の審査が終わるまでユーザーに新しいバージョンをさらすことなく、本番環境でテストをおこないたいと考えているお客様が増えています。人によっては、新機能が多くの人たちに公開される前に少数の顧客に対してのみ公開し、フィードバックを集めることもあるでしょう。これは、カナリア分析またはカナリアテストと呼ばれる手法です。この記事では、Application Load Balancersとtarget groupsを使用してBlue/Greenとカナリアデプロイを実装するパターンを紹介します。
もし実際にこのアプローチを試したい場合、オープンソースのコードとAWS CloudFormationテンプレートをecs-blue-green-deployment GitHubリポジトリに公開しています。
このワークフローでは、サービスをECSクラスタにデプロイする自動化されたCI / CDパイプラインが構築され、コードの最新バージョンを本番環境に昇格する準備が整ったらターゲットグループをスワップする制御されたプロセスが提供されます。環境は3つのステップで簡単に設定でき、Blue/Greenのスワップが動作することを確認できます。ぜひ試してみてフィードバックを送ってください!
Blue/Greenの利点
Blue/Greenデプロイメントは、ソフトウェア更新を低リスクでおこなうことができるイミュータブルデプロイメントの1つのパターンです。現在の実行中の “Blue”バージョンのアプリケーションと新しい “Green”バージョンのアプリケーションを別々の環境で作成することで、リスクが軽減されます。
このデプロイメント方法では、アプリケーションの現在の実行中のバージョンに影響を与えずに、Greenの環境で機能をテストすることができます。Greenバージョンが正常に動作していることが確認できたら、DNSを変更して古いBlue環境から新しい環境にトラフィックを徐々にルーティングすることができます。この方法に従うことで、ほぼゼロダウンタイムで機能更新とロールバックをおこなうことができます。
2つの異なる環境感でトラフィックをシフトする典型的なBlue/Greenデプロイメント |
このように運用中のBlue環境に素早くトラフィックを戻すことできることは、Blue/Greenデプロイメントの主要メリットの1つです。Blue/Greenデプロイメントでは、デプロイメントプロセスのどのタイミングでもBlue環境にロールバックすることが可能です。ダウンタイムはGreen環境に問題があることを認識してから、Blue環境にトラフィックを切り戻すまでの時間に制限されます。さらに、停止の影響はすべてのトラフィックではなく、Green環境に振り分けられたトラフィックに限定されます。デプロイエラーの規模が縮小されると、全体的なデプロイのリスクも低下します。
コンテナでBlue/Greenをシンプルに実現する
複数環境の管理およびプロビジョニングの複雑さとコストのために、従来のオンプレミスでのソフトウェア更新にはBlue/Greenデプロイメントはあまり導入されていませんでした。代わりに、アプリケーションはin-placeでアップグレードされていました。
このアプローチは有効でしたが、障害時のロールバックの迅速性などいくつかの欠陥がありました。ロールバックには通常、以前のバージョンのアプリケーションの再デプロイメントをおこなっていましたが、再デプロイメントは良くないリリースがあった場合の停止時間を長期化させる可能性があります。
コンテナは、簡単にパッケージ化でき、環境間を移動しても一貫して動作するため、Blue/Greenデプロイメントの導入を容易にします。この一貫性のひとつの要因は、コンテナのもつ不変性です。コンテナの設定を変更するには、In-Placeでソフトウェアを更新するのではなく、Dockerfileを更新してコンテナを再構築、再デプロイする必要があります。
コンテナは、アプリケーションのプロセスと名前空間の分離も提供します。これにより、複数のバージョンのアプリケーションを同じDockerホスト上で競合することなく並行して実行できます。仮想マシンに比べてサイズが小さいため、ホストあたりにVMに比べて多くのコンテナを詰め込むことができます。これにより、コンピューティングリソースをより効率的に使用できるようになり、Blue/Greenデプロイメントのコストを削減できます。
Amazon ECSのフルマネージド更新
Amazon EC2 Container Service (ECS) は、既存のAmazon ECSサービスを更新すると、ローリングアップデートを実行します。ローリングアップデートでは、現在実行中のバージョンのコンテナを最新バージョンに置き換えます。ローリングアップデート中にAmazon ECSがサービスに追加または削除するコンテナの数は、サービスのデプロイ時に許可される健全なタスクの最小数と最大数を調整することによって制御されます。
最新バージョンのコンテナイメージを利用するようにサービスのタスク定義を更新すると、Amazon ECSによってコンテナの古いバージョンが自動的に最新バージョンに置き換えられます。デプロイメント中、Amazon ECSは現在実行中のバージョンから接続を切断し、新しいコンテナがオンラインになるとApplication Load Balancer に登録します。
Target groups
ターゲットグループは、同じApplication Load Balancerの背後に複数のサービスを実行できるようにする論理構造です。これは、ターゲットグループごとにリスナーを持つことで実現されています。
Application Load Balancerを前に置くECSサービスを作成する時は、サービスのターゲットグループを指定する必要があります。通常はECSサービスごとにターゲットグループを作成しますが、ここでご紹介するアプローチでは、BlueのサービスとGreenのサービスの2つのターゲットグループを作成します。Blueサービスと同じパスを使用してGreenサービスをテストできるように、ターゲットグループごとに異なるリスナーポートを使用しています。
この構成では、Greenサービスに切り替える準備が整うまで、両方の環境を並行して実行できます。セキュリティグループルールや配置制約を使用して、社内ネットワーク上のテスターからにのみGreenバージョンへのアクセスを制限することも可能です。たとえば、サービスのGreenバージョンを、企業ネットワークからアクセス可能なインスタンスでのみ実行するように設定することができます。
切り替え
古いBlueサービスを新しいGreenサービスに置き換える準備ができたら、ModifyListener APIを呼び出して、対象のターゲットグループのリスナールールを入れ替えます。変更は即座に反映されます。その後、Greenサービスはポート80のリスナーを使用してターゲットグループで実行され、Greenサービスはポート8080のリスナーを使用してターゲットグループで実行されています。下の図は、このアプローチを示しています。
シナリオ
2つのサービスが定義されており、それぞれのターゲットグループが同じApplication Load Balancerに登録され、異なるポートで待機しています。 2つのターゲットグループ間でリスナールールを入れ替えることでデプロイが完了します。
Blueサービスへのリクエストはポート80リスナーを持つターゲットグループに向けられ、Greenサービスへのリクエストはポート8080リスナーを持つターゲットグループに向けられています。
テストの後で、Application Load Balancerでリスナールールをスワップし、Greenサービスにトラフィックを送信することで、デプロイメントを完了します。
留意事項
このアプローチを使用する際に注意すべきポイントがいくつかあります。
- アプリケーションコードが完全にステートレスである必要があります。ステート情報はコンテナの外部に格納してください。
- コネクションドレイニングはグレースフルには実行されません。ターゲットグループのスワップは突然実行されます。そのため、実行時間が長いトランザクションがあるサービスの場合は注意が必要です。
- カナリアデプロイメントは実行できません。この方法では、サービスの異なるバージョン間をすばやく切り替えることができますが、本番トラフィックの一部をカナリアに流したり、サービスがクラスタ全体に展開される速度を制御したりすることはできません。
カナリアテスト
標準のAmazon ECSデプロイを使用したデプロイメント方法では、ローリングデプロイメントに伴う重労働の多くが自動化されますが、問題を発見した場合にデプロイメントを途中で中断することはできません。ロールバックしたい場合は、最後の正常なコンテナバージョンにサービスのタスク定義を更新し、Amazon ECSがクラスタ全体にデプロイを実行するのを待つ必要があります。最新のバージョンでテスト中に発見されなかった問題のある変更が導入されてしまった場合、このロールバック方法では遅すぎる可能性があります。
カナリアテストでは、Green環境が期待どおりに動作していないことがわかった場合、Blue環境に影響はありません。トラフィックを元の環境に戻すことができるため、問題のある操作やダウンタイムを最小限に抑え、影響範囲を制限します。
このタイプのデプロイメントは、一部分のユーザーに新しい機能を公開して広く利用できるようにする前にフィードバックを得るA/Bテストに特に役立ちます。
カナリアスタイルのデプロイメントでは、同じターゲットグループにBlueサービスとGreenサービスを配備します。この方法はスワップ方式ほど高速ではありませんが、各サービスのタスク数を調整することで、コンテナの交換レートを制御することができます。さらに、BlueとGreenのサービスのタスク数をそれぞれ調整することでロールバックすることができます。上記のスワップアプローチとは異なり、コンテナへの接続はグレースフルに終了します。我々はAmazon ECSのカナリアスタイルのデプロイメントについてのブログも投稿する計画を立てています。
まとめ
AWSでは、Amazon ECS、Application Load Balancer、およびターゲットグループを使用して、Blue/Greenデプロイメントの操作が可能になります。 ecs-blue-green-deployment GitHubリポジトリに公開されているコードをお客様のユースケースに合わせてカスタマイズすることをお勧めします。
より詳細に興味がある場合、 Blue/Green Deployments on AWSおよびPracticing Continuous Integration and Continuous Delivery on AWSというホワイトペーパーをお読みください。 ご質問やご提案がありましたら、ぜひご意見をお寄せください。あなたのフィードバックを楽しみにしています。
(翻訳はSA千葉が担当しました。原文はこちら)