AWS App MeshのサンプルをECS(EC2)からECS(Fargate)に差し替えてみた

私が想定している設計の検証のために、ECS(Fargate)で新規に構築したかったので、aws/aws-app-mesh-examplesをforkして一部を変更し、EC2からFargateに差し替えてみました。
2019.07.07

こんにちは。 分散システム大好きなshoitoです。

もうAWS App Meshは試されてますか? AWSからAWS App Meshを試せる公式サンプルが提供されています。

aws/aws-app-mesh-examples https://github.com/aws/aws-app-mesh-examples

このサンプルでは、Amazon ECS(EC2)、またはAmazon EKSに環境構築をするCloudFormationテンプレートとシェルスクリプトが同梱されています。 さらに、ウォークスルーではECS(EC2)で構築した後に、新規サービスをECS(Fargate)で構築し、連携する手順もあります。

私が想定している設計の検証のために、ECS(Fargate)で新規に構築したかったので、forkして一部を変更し、EC2からFargateに差し替えてみました。 https://github.com/shoito/aws-app-mesh-examples

すべての差分はこちらで確認できます。 https://github.com/aws/aws-app-mesh-examples/compare/master...shoito:feature-ecs-launch-type-to-fargate

最終的には、ECS(Fargate) + App Mesh(Envoy)環境にマイクロサービスのサンプルアプリケーション(aws-app-mesh-examples/examples/apps/colorapp)がデプロイされ、X-Rayのサービスマップとトレースビューなどにより、リクエストの分析が行えるようになります。

App Meshについては、Developers.IOでも既に取り上げられていますので、それ自体の紹介は今回しません。

[速報] マイクロサービス向けの新しい監視サービス!AWS App Meshが登場 #reinvent

マイクロサービス時代のインフラ連携手段「Cloud Map」「App Mesh」について喋りました #reinvent

取り扱うCloudFormationテンプレート

インフラストラクチャテンプレート

アプリケーションリソーステンプレート

EC2からFargateへの変更に伴う修正箇所

ECSタスク定義の変更

colortellerサービスとcolorgatewayサービスのタスク定義です。

https://github.com/aws/aws-app-mesh-examples/compare/master...shoito:feature-ecs-launch-type-to-fargate#diff-d190b1711d482be1d72b78d58a160795R79

// 追加
"requiresCompatibilities": [
"FARGATE"
],
// 追加。Fargateではmemoryだけでなく、cpuの指定が必須のため。
"cpu": "256",

testerサービスとechoサービスのタスク定義です。 https://github.com/aws/aws-app-mesh-examples/compare/master...shoito:feature-ecs-launch-type-to-fargate#diff-a6da4a916690bf7598a2a76d9ad9b1f4R291

# 追加。Fargateではmemoryだけでなく、cpuの指定が必須のため。
RequiresCompatibilities:
- FARGATE
Cpu: 256

ECSサービス定義の変更

Fargateを使いたいので、LaunchTypeをEC2からFARGATEに変更します。 https://github.com/aws/aws-app-mesh-examples/compare/master...shoito:feature-ecs-launch-type-to-fargate#diff-a6da4a916690bf7598a2a76d9ad9b1f4R79

# 変更前
LaunchType: EC2

# 変更後
LaunchType: FARGATE

EC2関連の削除

EC2からFargateにLaunchTypeを変更しているため、EC2関連は不要になります。 https://github.com/aws/aws-app-mesh-examples/compare/master...shoito:feature-ecs-launch-type-to-fargate#diff-3e1b407163dd6122334a47f6f7ce314bL50

構築してみる

構築先のAWSアカウントに合わせて、環境変数を設定します。 ここの手順はサンプルのREADMEとほとんど変わりません。 KEY_PAIR_NAMECLUSTER_SIZE はFargateにすると不要なため削除しています。 https://github.com/aws/aws-app-mesh-examples/tree/master/examples

export AWS_PROFILE=XXX
export AWS_DEFAULT_REGION=ap-northeast-1
export AWS_ACCOUNT_ID=123456789

export ENVIRONMENT_NAME=AppMeshSample
export MESH_NAME=sample-local
export ENVOY_IMAGE=111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.9.1.0-prod
export SERVICES_DOMAIN=sample.local
export COLOR_GATEWAY_IMAGE=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/gateway:latest
export COLOR_TELLER_IMAGE=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/colorteller:latest
$ git clone https://github.com/shoito/aws-app-mesh-examples
$ cd examples
# VPCの構築 3min
$ ./infrastructure/vpc.sh
# App Meshの構築 15s
$ ./infrastructure/appmesh-mesh.sh
# ECSクラスタの構築 1m
$ ./infrastructure/ecs-cluster.sh

# ECRにリポジトリ作成
$ aws ecr create-repository --repository-name colorteller
$ aws ecr create-repository --repository-name gateway

# colortellerコンテナイメージのビルドとPush
$ cd apps/colorapp/src/colorteller/
$ ./deploy.sh
$ cd -
# gatewayコンテナイメージのビルドとPush
$ cd apps/colorapp/src/gateway
$ ./deploy.sh
$ cd -

# colorappのApp Mesh構築 40s
$ ./apps/colorapp/servicemesh/appmesh-colorapp.sh
# colorappをECSへデプロイ 4m30s
$ ./apps/colorapp/ecs/ecs-colorapp.sh

サンプルアプリケーションの環境構築は以上になります。 次に、テストしてみましょう。

$ colorapp=$(aws cloudformation describe-stacks --stack-name=$ENVIRONMENT_NAME-ecs-colorapp --query="Stacks[0].Outputs[?OutputKey=='ColorAppEndpoint'].OutputValue" --output=text); echo $colorapp
$ curl $colorapp/color
{"color":"white", "stats": {"white":1}}

$ for ((n=0;n<200;n++)); do echo "$n: $(curl -s $colorapp/color)"; done
0: {"color":"white", "stats": {"white":1}}
1: {"color":"red", "stats": {"red":0.33,"white":0.67}}
2: {"color":"white", "stats": {"red":0.25,"white":0.75}}
3: {"color":"red", "stats": {"red":0.4,"white":0.6}}
4: {"color":"red", "stats": {"red":0.5,"white":0.5}}
5: {"color":"red", "stats": {"red":0.57,"white":0.43}}
6: {"color":"blue", "stats": {"blue":0.13,"red":0.5,"white":0.38}}
7: {"color":"blue", "stats": {"blue":0.22,"red":0.44,"white":0.33}}
8: {"color":"red", "stats": {"blue":0.2,"red":0.5,"white":0.3}}
9: {"color":"blue", "stats": {"blue":0.27,"red":0.45,"white":0.27}}
10: {"color":"red", "stats": {"blue":0.25,"red":0.5,"white":0.25}}
...
199: {"color":"white", "stats": {"blue":0.28,"red":0.36,"white":0.36}}

これで、構築したサンプルアプリケーションへ200回のHTTPリクエストを送り、正常に動作していることが確認できました。 X-Rayのサービスマップでもこのように確認できます。

念の為、ECSの画面から、Fargateが使われていることを確認します。

さいごに

AWS App Meshを試せる公式サンプルをはじめからFargateを使うように変更し、実際に環境構築・動作確認を行いました。 ECS, App Mesh, Cloud Map, X-Ray, ALB, ...など、検証のためゼロから設計・構築するのは大変なので、今回利用したサンプルはとても助かりました。 提供されているウォークスルーで、まだ試していないものもあるので、これから時間を作って試してみようと思います。