Amazon Web Services ブログ
AWS Load Balancer Controller を使った Blue/Green デプロイメント、カナリアデプロイメント、A/B テスト
これまで AWS をお使いのみなさまは、一般的に Flagger やサービスメッシュ、CI/CD などのソリューションを使用して、Blue/Green デプロイメント、A/B テスト、トラフィック管理をしてきました。AWS Load Balancer Controller ( 旧称:ALB Ingress Controller ) がリリースされたことで、EKS ユーザーは AWS Application Load Balancer をネイティブサポートした Kubernetes Ingress リソースを介して Blue/Green デプロイメント、A/B テスト、カナリアデプロイをすることが可能になりました。
このブログでは、AWS Application Load Balancer の加重ターゲットグループの概念、高度なリクエストルーティング、そして Kubernetes Ingress リソースを介してそれらの設定を管理する方法を紹介します。
ソリューション概要
加重ターゲットグループ
AWS ユーザーが Blue/Green デプロイやカナリアデプロイ、A/B テスト戦略を採用できるように、AWS は 2019/11 に Application Load Balancer の加重ターゲットグループを発表しました。複数のターゲットグループが、あるリスナールールの同じ転送アクションに関連づけられ、各ターゲットグループの重みを指定できます。これにより、開発者がアプリケーションの異なるバージョンに対して通信をどのように分散するかコントロールできます。例えば、8 対 2 の重み付けがされた 2 つのターゲットグループを持つリスナールールを定義した場合、ロードバランサーは通信を 80 %対 20 %の割合で各ターゲットグループにルーティングします。
高度なリクエストルーティング
加えて、加重ターゲットグループに関して、AWS は 2019 年に高度なリクエストルーティング機能を発表しています。高度なリクエストルーティングでは、開発者が標準 及び カスタム HTTP ヘッダーやメソッド、リクエストパス、クエリ文字列、ソース IP アドレスに基づいてルール ( 及びトラフィックルーティング ) を作成することができます。この新機能により、ルーティングのためのプロキシフリートが不要になるためアプリケーションを簡素化し、ロードバランサーで不要なトラフィックをブロックし、A/B テストの実装が可能になります。
AWS Load Balancer Controller
AWS Load Balancer Controller は Kubernetes クラスターが Elastic Load Balancing を管理するのを助けるコントローラーです。Kubernetes Ingress リソースに従い、Application Load Balancer のプロビジョニングします。プロビジョニングされた Application Load Balancer の動作をカスタマイズするため、アノテーションを Kubernetes Ingress オブジェクトに追加します。これにより、開発者は Application Load Balancer を構成し、Kubernetes のネイティブセマンティックスを用い、Blue/Green デプロイメント、カナリアデプロイメント、A/B デプロイメントを実現します。例えば、下記の Ingress アノテーションは、2 つのアプリケーションバージョン間で通信を分散するための Application Load Balancer の設定です。
ウォークスルー
前提条件
- AWS Application Load Balancer、Amazon EKS、Kubernetes に対する十分な理解
- Amazon EKS コマンドラインツールである eksctl
- Kubernetes コマンドラインツールである kubectl 及び helm
eksclt を用いたEKSクラスターの作成
下記のコマンドを利用して Amazon EKS クラスターを作成します。クラスター名 dev
を独自の名前に書き換えることは可能です。region-code
を Amazon EKS がサポートされる他のリージョンに書き換えることもできます。
より詳細は、こちらを参照ください。
AWS Load Balancer Controller のインストール
本ドキュメントに記載されているように、最新バージョンの AWS Load Balancer Controller をインストールします。
AWS Load Balancer Controller がデプロイされたことを確認してください。
サンプルアプリケーションバージョン 1 とバージョン 2 のデプロイ
使用するサンプルアプリケーションは、hello-kubernetes です。カスタムメッセージを含む 2 つのバージョンのアプリケーションをデプロイし、サービスタイプを ClusterIP
に設定します。
Ingress のデプロイと Blue/Green デプロイメントのテスト
Ingress のアノテーション(alb.ingress.kubernetes.io/actions.${action-name}
) は、Application Load Balancer のリスナーに対するカスタムアクションを構成する方法を提供します。例えば、リダイレクトアクションやフォワードアクションなどです。フォワードアクションの場合、異なる重みを持つ複数のターゲットグループがアノテーションで定義されます。AWS Load Balancer Controller は、ターゲットグループをプロビジョニングし、通信を転送するためにアノテーションに従ってリスナールールを設定します。例えば、下記の Ingress リソースは 全通信を hello-kubernetes-v1
サービス ( 重み: 100 対 0 ) にフォワードする Application Load Balancer を構成します。
アノテーションの action-name
は Ingress ルール内の serviceName
に一致する必要があり、servicePort
は前のコードスニペットと同様に use-annotation
と記載する必要がある点に注意してください。
下記の Ingress リソースをデプロイし、AWS Load Balancer Controller によって Application Load Balancer が作成と設定がされるまで 2 分程度待ちます。
ロードバランサーエンドポイントからのレスポンスが、常にアプリケーションバージョン 1 からであることを確認してください。
Blue/Green デプロイメント
Blue/Green デプロイメントをするために、すべての通信がバージョン 2 に流れるように Ingress のアノテーションをアップデートします。
下記の Ingress リソースをデプロイします。
ロードバランサーエンドポイントからのレスポンスが、常にアプリケーションバージョン 2 からであることを確認してください。
Ingress のデプロイとカナリアデプロイメントのテスト
すべての通信をバージョン 2 へ向ける代わりに、バージョン 2 の重みを段階的に増やすことで、通信を緩やかにバージョン 2 へシフトできます。これにより、より多くの通信をバージョン 2 に流す前に、プロダクションの通信の一部でバージョン 2 を検証できます。下記の例では、通信の 10 %がバージョン 2 へ、残りの 90 %がバージョン1へ流れています。
下記の Ingress リソースをデプロイします。
ロードバランサーからのレスポンスを確認してください。
Argo Rolluots
プロダクション環境でカナリアデプロイメントをする時、通常、少しずつ通信を切り替えます。その際、ある程度の自動化が施されます。このプロセスには、さまざまなパフォーマンス監視システムも組み込まれ、各ステップでエラーが発生してないか、またエラーが許容閾値以下であるか確認します。これを実現するためには、Argo Rollouts などのプログレッシブデリバリーの仕組みが非常に有益です。
Argo Rollouts は、AWS Load Balancer Controller のアノテーションベースのトラフィックシェーピング機能を利用して、更新中に徐々に通信を新しいバージョンのアプリケーションにシフトするためのファーストクラスのサポートを提供します。加えて、Argo Rollouts は、主要な KPI を検証するためにさまざまなプロバイダーからのメトリックを照会して解釈し、更新中の自動プロモーションまたはロールバックを促進できます。より詳細な情報は、こちらをご参照ください。
Ingress のデプロイとA/Bテスト
Ingress の spec で設定するホストやパスのルーティング条件に加え、Ingress アノテーション alb.ingress.kubernetes.io/conditions.${conditions-name}
を用い、ルーティング条件を設定できます。また、http-header
, http-request-method
, query-string
及び source-ip
を基準としたルーティングを設定することもできます。これによって開発者は、サービスメッシュ等の個別のルーティング機構をセットアップ 及び 管理する必要なく、A/B テストを実装するためにこれらのルーティングオプションを利用することができます。
AWS Load Balancer Controller は、特定のバックエンドへの通信の一部を転送するために、アノテーションに従ってリスナールールを設定します。下記の例では、全てのリクエストがデフォルトでアプリケーションバージョン 1 へ転送されます。リクエストのカスタム HTTP ヘッダーに HeaderName=HeaderValue1
が含まれる場合、下記の Ingress リソースは、アプリケーションバージョン 2 へ通信を転送します。
下記の Ingress リソースをデプロイしてください。
ロードバランサーエンドポイントからのレスポンスを確認してください。
クリーンアップ
VPC 削除を妨げる VPC 内の孤立したリソースが発生しない様、Ingress リソースを削除する必要があります。これにより最初に Application Load Balancer が削除されます。
まとめ
Blue/Green デプロイメント、カナリアデプロイメント、A/B テストを採用するためのさまざまな方法があります。このブログでは、AWS Load Balancer Controller を使用して Kubernetes Ingress リソースを管理することにより、AWS Application Load Balancer で同様のデプロイメント戦略の実現する方法にを示しました。
翻訳はソリューションアーキテクト祖父江が担当しました。原文はこちらです。