Amazon Web Services ブログ

マルチアカウント環境の Amazon EKS における App Mesh の活用

この記事は、Leveraging App Mesh with Amazon EKS in a Multi-Account environment を翻訳したものです。

今日、多くのお客様がマイクロサービスを採用してソフトウェア開発の高速化やイノベーションを実現し、新機能や製品の市場投入までの時間を短縮しています。マイクロサービスのアプローチは、特定のビジネスニーズに対応し、明確に定義された API を介して通信する小さな独立したソフトウェアの実装です。大きな組織ではこの開発モデルを実装するために、サービスのデプロイを変更し、複数の AWS アカウントを使用してワークロードを実行するという別の戦略を導入しています。このアプローチでは異なるチームやビジネスユニットのすべてのアプリケーションを単一の環境に持つことで発生する障害影響範囲を減らすことができますが、アカウントをまたいだマイクロサービスがお互いに会話ができるようにする必要があります。

重要なのは、マイクロサービスを実装する時に注意が必要なのものはネットワーク通信だけではないということです。大抵、時間を消費したりイノベーションのプロセス(主にクラウドのセットアップとガバナンス)をスローダウンさせる新しいタスクが発生します。AWS Organizations や AWS Control Tower などのサービスが AWS のマルチアカウント環境のガバナンスの整備を手助けします。

マイクロサービスを実装するときに重要になるのは通信を制御することです。マルチアカウントでの設定では、環境内で実行されているアプリケーション間の可視性をもたせ、ネットワークポリシーを強制する必要があります。ここで AWS App Mesh が重要になります。

AWS App Mesh は、アプリケーションレベルのネットワーキングを提供するサービスメッシュで、複数のタイプのコンピューティングインフラストラクチャだけでなく、さまざまな AWS アカウント間でサービスが相互に通信しやすくなります。App Mesh は、サービスの通信方法を標準化し、エンドツーエンドの可視性を実現し、アプリケーションの高可用性を確保します。クロスアカウントメッシュを使用すると、相互 TLS、接続のリトライ、タイムアウト処理などの機能を使用して、アプリケーションを変更することなく、相互通信サービスの信頼性とセキュリティが向上します。これは、コードの複雑さを軽減するのに役立ちます。

チュートリアル

この記事では、AWS App Mesh の機能を活用して、異なる AWS アカウントの異なる EKS クラスターで実行されているアプリケーションのさまざまなコンポーネントを統合する方法について説明します。

これは、スタック全体をゼロから作成する場合(以下に示すとおり)や、マルチアカウント環境で既に別の EKS クラスターが実行されており、それらにサービスメッシュを実装する必要がある場合に適用できます。インフラストラクチャがすでにプロビジョニングされている後者の場合は、手順 3 — App Mesh コンポーネントのインストールから進めることができます。

2つの EKS クラスターをそれぞれの AWS アカウントで作成します。また、これら2つのクラスター間のネットワーク接続は VPC Peering による接続を介して行われます。このアプローチにより、2つの環境を分離しつつ、クラスター間の接続性を提供できます。VPC Peering による接続を実装するだけでなく、AWS Resource Access Manager (AWS RAM) を使用して両方の AWS アカウントでメッシュを共有し、それぞれの EKS クラスターから参照できるようにします。

このチュートリアルでは、AWS App Mesh コンポーネントを作成し、Yelb というサンプルアプリケーションを使用してデプロイします。Yelb はユーザーがレストランを選ぶような投票を行うことができ、投票結果に基づいて円グラフが動的に更新されます。また、Yelb はページビューの数を記録し、投票やページの更新時には API リクエストを提供している yelb-appserverインスタンスのホスト名を表示します。Yelb のコンポーネントには次のようなものがあります。

  • yelb-uiと呼ばれる Frontend は、JavaScript のコードをブラウザに送信する役割を担っています。
  • yelb-appserverという名前のアプリケーションサーバは Sinatra のアプリケーションで、Redis のキャッシュサーバ(redis-server) や、Postgres のバックエンドデータベース(yelb-db) に読み書きを行います。
  • Redis はページビューの数を格納し、Postgres は投票数を保存します。

次の画像は、このチュートリアルで作成するアーキテクチャです。

Multi-Account-App-Mesh-and-Amazon-EKS

2つの EKS クラスターはそれぞれの AWS アカウント内の VPC に作成され、両方の AWS アカウントにまたがるメッシュがあります。yelb-ui コンポーネントは、Frontend アカウントである Cluster1 にデプロイされ、yelb-appserverredispostgres データベースは、Backend アカウントである Cluster2 にデプロイされます。この2つのアカウントで単一のメッシュを持つことがゴールです。

このデプロイでは、Yelb サービス間の通信を処理するロードバランサはデプロイされません。代わりに、AWS App Mesh が提供するクライアントサイドロードバランシングの機能を活用します。クライアントサイドロードバランシングを使用すると、クライアントはサービスのインスタンスに直接接続するため、余分なホップを除外することができます。クライアントはサービスレジストリを照会してサービスを検出します。サービスレジストリには、アクティブなサービスのインスタンスに対応する IP アドレス、ホスト名、ポートなどの詳細情報を保持しています。これらのサービスディスカバリの機能は、AWS App Mesh と AWS Cloud Map の統合によって提供されています。

1. 環境のセットアップ

チュートリアルを進めるには、いくつかのツールを備えた環境が必要です。AWS Cloud9 インスタンスを使用して、このチュートリアルを実行できます。AWS Cloud9 インスタンスを作成する場合は、EKS Workshop の Create a Workspace から Update IAM Settings for your Workspace の手順を進めます。
インストールする必要があるツールは次のとおりです。

チュートリアルは2つの異なる AWS アカウントで進むため、~/.aws/credentials~/.aws/configにそれぞれの AWS アカウントの認証情報を設定したプロファイルがあることを確認します。以下に例を示します。

cat ~/.aws/credentials

[frontend]
aws_access_key_id = ...
aws_secret_access_key = ...
[backend]
aws_access_key_id = ...
aws_secret_access_key = ...

cat ~/.aws/config

[profile frontend]
region = us-west-2
[profile backend]
region = us-west-2

設定ファイルの作成に関する詳細は AWS CLI ユーザガイド を参照してください。

すべてをインストールしてプロファイルを設定したら、このチュートリアルで使用するスクリプトを GitHub リポジトリからクローンします。

git clone https://github.com/aws/aws-app-mesh-examples.git
cd aws-app-mesh-examples/walkthroughs/eks-app-mesh-multi-account/

CloudFormation テンプレートを使用して、2つの AWS アカウント間の VPC、セキュリティグループ、ルートテーブル、および VPC Peering による接続を作成します。テンプレートを確認したい場合は、クローンしたリポジトリ内の infrasctructure ディレクトリにあります。次のスクリプトを実行して作成します。

./infrastructure/setup.sh

環境のセットアップが完了したので、次は EKS クラスターを作成します。

2. EKS クラスターの作成

この手順では、次のスクリプトを実行することによって eksctl を使用した Frontend アカウントBackend アカウントへ EKS クラスターの作成を行います。

./eks/setup.sh

kubectl を実行して、作成したクラスターを確認できます。

kubectl config get-contexts

3. App Mesh コンポーネントのインストール

メッシュリソースを作成し、 Yelb アプリケーションをクラスターにデプロイする前に、AWS App Mesh Controller をインストールする必要があります。このコントローラーは kubectl を使用してApp Mesh のリソースを設定できるようにします。

初めに、Frontend アカウントにあるクラスターにコントローラーをインストールします。

kubectl config use-context <iam_user>@am-multi-account-1.<region>.eksctl.io
helm repo add eks https://aws.github.io/eks-charts 
kubectl create ns appmesh-system 
helm upgrade -i appmesh-controller eks/appmesh-controller --namespace appmesh-system

また、Backend アカウントにあるクラスターにコントローラーをインストールします。

kubectl config use-context <iam_user>@am-multi-account-2.<region>.eksctl.io 
kubectl create ns appmesh-system 
helm upgrade -i appmesh-controller eks/appmesh-controller --namespace appmesh-system

App Mesh コントローラーが実行されていることを確認します。

kubectl --context=<iam_user>@am-multi-account-1.<region>.eksctl.io get pods -n appmesh-system 
kubectl --context=<iam_user>@am-multi-account-2.<region>.eksctl.io get pods -n appmesh-system

次のような出力が表示されます。

NAME                                READY STATUS   RESTARTS AGE 
appmesh-controller-66b749c78b-67n68 1/1   Running  0        6s

4 – メッシュのデプロイと共有

両方のクラスターで App Mesh コントローラーをセットアップしたので、メッシュを作成して Backend アカウントと共有します。

まず、Frontend アカウントのクラスターに、メッシュのコンポーネントと Yelb アプリケーションをデプロイするための Namespace を作成します。

kubectl config use-context <iam_user>@am-multi-account-1.<region>.eksctl.io
kubectl create ns yelb

yelbという Namespace にmeshappmesh.k8s.aws/sidecarInjectorWebhookの2つのラベルを追加する必要があります。 これらのラベルは、Pod に対して Envoy プロキシを挿入して設定するようにコントローラーに指示します。

kubectl label namespace yelb mesh=am-multi-account-mesh
kubectl label namespace yelb "appmesh.k8s.aws/sidecarInjectorWebhook"=enabled

メッシュを作成して共有し、Backend アカウントに共有します。

./mesh/create_mesh.sh

AWS Resource Access Manager を使用してメッシュを共有します。

aws --profile frontend cloudformation deploy \
--template-file shared_resources/shared_mesh.yaml \
--parameter-overrides \
"BackendAccountId=$(aws --profile backend sts get-caller-identity | jq -r .Account)" \
--stack-name am-multi-account-shared-mesh \
--capabilities CAPABILITY_IAM

ここで、Backend アカウントResource Share Invitation を承認します。

次のコマンドを実行して、招待を承認します。

RESOURCE_SHARE_ARN=$(aws --profile backend ram get-resource-share-invitations \
| jq -r '.resourceShareInvitations[] | select(.resourceShareName=="mesh-share") | .resourceShareInvitationArn')

aws --profile backend ram accept-resource-share-invitation \
--resource-share-invitation-arn $RESOURCE_SHARE_ARN

Backend アカウントにはサービスロールが必要です。これにより、App Mesh は AWS Cloud Map を使用してyelb-appserverの仮想ノードの IP アドレスを検出します。これは次のように作成できます。

aws --profile backend iam create-service-linked-role \
--aws-service-name appmesh.amazonaws.com

5 – メッシュリソースとアプリケーションのデプロイ

Backend アカウントのリソースは Frontend アカウントのリソースへの依存関係であるため、それらを作成することから始めましょう。

Backend アカウントのクラスターコンテキストに切り替えます。

kubectl config use-context <iam_user>@am-multi-account-2.<region>.eksctl.io

すでにメッシュは作成および共有されていますが、Backend アカウントのクラスター内の App Mesh コントローラーがそれを認識する必要があるため、次のスクリプトを実行しましょう。

kubectl create ns yelb
kubectl label namespace yelb mesh=am-multi-account-mesh
kubectl label namespace yelb "appmesh.k8s.aws/sidecarInjectorWebhook"=enabled
./mesh/create_mesh.sh

ここで、Backend アカウントにメッシュコンポーネントを作成します。これにより、yelb-appserveryelb-db、およびyelb-redisのための仮想ノード、仮想サービス、および仮想ルーターが作成されます。

kubectl apply -f mesh/yelb-redis.yaml
kubectl apply -f mesh/yelb-db.yaml
kubectl apply -f mesh/yelb-appserver.yaml

yelb-appserveryelb-db、およびyelb-redisをデプロイします。

kubectl apply -f yelb/resources_backend.yaml

yelb-appserverの 仮想サービスの ARN を取得して、それに応じてmesh/yelb-ui.yamlのバックエンド設定を変更します。 これは手動プロセスです。スキップすると、yelb-ui の仮想ノードの作成は失敗します。

kubectl -n yelb get virtualservice yelb-appserver

# mesh/yelb-ui.yaml 内の <yelb-appserver virtualServiceARN> を
# お好みのエディタで、上記コマンドで出力されたARNに置き換えてください。

すべての Backend アカウントコンポーネントがデプロイされたので、Frontend アカウントのクラスターに切り替えます。

kubectl config use-context <iam_user>@am-multi-account-1.<region>.eksctl.io

Frontend アカウントでメッシュコンポーネントを作成します。これにより、yelb-uiの仮想ノード、仮想サービス、および仮想ルーターが作成されます。

kubectl apply -f mesh/yelb-ui.yaml

yelb-uiをデプロイします。

kubectl apply -f yelb/resources_frontend.yaml

ロードバランサーの URL を取得して、ブラウザでアプリケーションをテストします。

kubectl get service yelb-ui -n yelb

次のようにアプリケーションが表示されます。先に進んでテストします。

yelb-ui

AWS コンソール を使用して、App Mesh リソースが AWS Resource Access Manager を使用してアーキテクチャにシームレスに統合されていることを確認してください。 仮想サービス、仮想ルーター、仮想ノードの所有者は簡単に識別できます。

Mesh-view

6. クリーンアップ

このチュートリアルの実行中に作成されたすべてのリソースをクリーンアップするには、次のコマンドを使用してクリーンアップスクリプトを実行します。

./cleanup.sh

このクリーンアップスクリプトは、このチュートリアル用に作成された AWS アカウントは削除せず、前の手順でプロビジョニングされたリソースのみを削除することに注意してください。

まとめ

この投稿では、2つの(それぞれが独自のアカウントと VPC に作成された) EKS クラスターを作成し、一方のクラスターにフロントエンドサービス、もう一方のクラスターにバックエンドリソースを作成しました。 両方のクラスターにまたがるメッシュを使用し、相互 TLS、接続のリトライ、タイムアウト処理などの機能をアプリケーションコードを変更せずに追加すると同時に、これらのサービス間の通信を簡素化できました。 このアプローチにより、マルチアカウントおよびマルチクラスター戦略をとるお客様は、これらの環境間の接続をより適切に管理し、サービスメッシュによって提供されるすべての利点を活用できるようになります。

マルチアカウントは App Mesh の機能の1つにすぎません。App Mesh を使用して、カナリアデプロイを実行でき、CI/CD パイプライン分散トレースサービス間トラフィックの暗号化 を実装することができます。その他の特徴についてはこちらを参照してください。 AWS App Mesh の詳細をさらに詳しく学びたい場合は、AWS App Mesh Workshop を実施してください。

App Mesh の新しい機能を試してみたい場合は、App Mesh Preview Channel にサインアップしてください。フィードバックをお待ちしております。

翻訳はソリューションアーキテクト加治が担当しました。原文はこちらです。