AWS AppMeshのサンプルを試してみます

AWS AppMeshのサンプルを試してみます:


はじめに

2018/11/29に発表になったAWS App Meshのサンプルを試してみます。
https://aws.amazon.com/jp/blogs/news/reinvent2018-aws-app-mesh/

サンプルはこちらにあります。
https://github.com/awslabs/aws-app-mesh-examples/tree/master/examples

App Meshは、AWS上のマイクロサービスアプリケーション間の通信を簡単に監視、制御できるサービスメッシュを提供するサービスとなります。サービスメッシュのコントロールプレーン実装としては、OSSのIstioが有名です。また、App Meshではコンテナ間のプロキシとしてOSSとして開発されているEnvoyが使われています。


サンプルアプリケーションの概要

Gatewayに対してHTTPリクエストを送ると、バックエンドのアプリケーションから任意のカラーをJSONで返します。

返されるカラーは、White/Black/Blue/Redになります。


image.png


$ curl -s http://colorgateway.default.svc.cluster.local:9080/color 
{"color":"white", "stats": {"white":1}} 
構成としては、物理レイヤーと論理レイヤーの2つに分けて考えた方が理解しやすいと思います。

ここでは、物理レイヤーをVPCやECSクラスタとしています。論理レイヤーはサービスメッシュを構成するコンポーネントとなります。



image.png


サンプルを手順通り作成すると以下のような物理構成が作成されます。


image.png


論理構成は以下になります。


image.png


サービスメッシュを構成するコンポーネントの簡単な説明をします。

Mesh

複数のマイクロサービスをまとめたグループ
https://docs.aws.amazon.com/ja_jp/app-mesh/latest/userguide/meshes.html

Virtual Node

Amazon ECSサービスやKubernetesデプロイメントなどの特定のタスクグループへの論理的なポインタ
https://docs.aws.amazon.com/ja_jp/app-mesh/latest/userguide/virtual_nodes.html

Virtual Router

Virtual Node間のトラフィックをルーティングする仮想ルータ
https://docs.aws.amazon.com/ja_jp/app-mesh/latest/userguide/virtual_routers.html

Route

Virtual Routerに関連付けられたルーティング情報
https://docs.aws.amazon.com/ja_jp/app-mesh/latest/userguide/routes.html


(そもそも)Envoyとサービスメッシュについて

EnvoyはLyftが開発したプロキシソフトウェアです。
https://www.envoyproxy.io/docs/envoy/latest/intro/what_is_envoy

機能が多彩で以下の様なことが出来ます。

  • L3/L4 filter architecture
  • HTTP L7 filter architecture
  • First class HTTP/2 support
  • HTTP L7 routing
  • gRPC support
  • MongoDB L7 support
  • DynamoDB L7 support
  • Service discovery and dynamic configuration
  • Health checking
  • Advanced load balancing
単にEnvoyをリバプロとして使うのであれば、Envoy単体で運用も可能な場合があるが、マイクロサービス化するとEnvoyがサイドカーコンテナとして多数起動することになり、ルーティング情報などの設定情報を集中的に管理する機能が必要になってきます。

前述した、Istioが代表的なコントロールプレーンのツールです。AppMeshは、現時点(2018/12/28)ではPublic Previewのたトラフィックルーティングのみ使用可能です。


手順


前提

最新のaws-cliをインストールします。今回は1.16.67を使用します。

$ aws --version 
aws-cli/1.16.67 Python/3.5.4 Darwin/16.7.0 botocore/1.12.57 


事前

サンプルアプリケーションをダウンロードします。

$ git clone https://github.com/awslabs/aws-app-mesh-examples.git 
Cloning into 'aws-app-mesh-examples'... 
remote: Enumerating objects: 98, done. 
remote: Counting objects: 100% (98/98), done. 
remote: Compressing objects: 100% (57/57), done. 
remote: Total 321 (delta 30), reused 85 (delta 29), pack-reused 223 
Receiving objects: 100% (321/321), 83.70 KiB | 49.00 KiB/s, done. 
Resolving deltas: 100% (125/125), done 
作成する環境を定義します。

現時点(2018/12/28)でApp Meshが使えるリージョンは、Oregon,Virginia,East,Ohio,Irelandになります。

今回はオレゴンリージョンを使用します。

export AWS_PROFILE="default" 
export AWS_REGION="us-west-2" 
export AWS_DEFAULT_REGION="$AWS_REGION" 
<>内は、環境にあった値に変更をお願いします。

インスタンス数は、2台とかだとawsvpcモードでENI数が足りなくてタスクが起動できなくなります。

SERVICES_DOMAINで定義したドメイン名でサービスディスカバリや名前解決ができます。

export ENVIRONMENT_NAME="AppMeshSample" 
export MESH_NAME="default" 
export KEY_PAIR_NAME=<key-pair to access ec2 instances where apps are running> 
export ENVOY_IMAGE="111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.8.0.2-beta" 
export CLUSTER_SIZE=5 
export SERVICES_DOMAIN="default.svc.cluster.local" 


VPC作成

VPCを作成します。スクリプトを実行するとCloudFormationが実行されて以下の環境が作成されます。



image.png


$ cd aws-app-mesh-examples/examples/ 
$ ./infrastructure/vpc.sh create-stack 
+++ dirname ./infrastructure/vpc.sh 
++ cd ./infrastructure 
++ pwd 
+ DIR=/aws-app-mesh-examples/examples/infrastructure 
+ aws --profile default --region us-west-2 cloudformation deploy --stack-name AppMeshSample-vpc --capabilities CAPABILITY_IAM --template-file /aws-app-mesh-examples/examples/infrastructure/vpc.yaml --parameter-overrides EnvironmentName=AppMeshSample 
 
Waiting for changeset to be created.. 
Waiting for stack create/update to complete 
Successfully created/updated stack - AppMeshSample-vpc 


メッシュのセットアップ

スクリプトのなかでaws-cliが実行されMeshのみ作成されます。


image.png


$ ./infrastructure/mesh.sh create-mesh 
+ '[' '!' -z default ']' 
+ PROFILE_OPT='--profile default' 
+ aws --profile default appmesh create-mesh --mesh-name default 
{ 
    "mesh": { 
        "meshName": "default", 
        "status": { 
            "status": "ACTIVE" 
        }, 
        "metadata": { 
            "version": 1, 
            "lastUpdatedAt": 1545887155.41, 
            "arn": "arn:aws:appmesh:us-west-2:*****:mesh/default", 
            "createdAt": 1545887155.41, 
            "uid": "c2324ff1-7308-4be0-8a9b-c74f30ee6c62" 
        } 
    } 
} 


ECSかEKSのクラスタを作成する

今回はECSクラスタを作成します。CloudFormationが実行されます。



image.png


$ ./infrastructure/ecs-cluster.sh create-stack 
+++ dirname ./infrastructure/ecs-cluster.sh 
++ cd ./infrastructure 
++ pwd 
+ DIR=/aws-app-mesh-examples/examples/infrastructure 
+ aws --profile default --region us-west-2 cloudformation deploy --stack-name AppMeshSample-ecs-cluster --capabilities CAPABILITY_IAM --template-file /aws-app-mesh-examples/examples/infrastructure/ecs-cluster.yaml --parameter-overrides EnvironmentName=AppMeshSample KeyName=oregon-key ECSServicesDomain=default.svc.cluster.local ClusterSize=5 
 
Waiting for changeset to be created.. 
Waiting for stack create/update to complete 
Successfully created/updated stack - AppMeshSample-ecs-cluster 


アプリケーションのデプロイ

サンプルに含まれているgatewayとcolortellerというアプリケーションをデプロイします。

最初にECRのレポジトリを手動で2つ作成します。

aws ecr create-repository --repository-name "color-gateway" --region us-west-2 
aws ecr create-repository --repository-name "color-teller" --region us-west-2 
環境変数に作成したリポジトリのURIを設定する。

export COLOR_GATEWAY_IMAGE=<image location for colorapp's gateway> 
export COLOR_TELLER_IMAGE=<image location for colorapp's teller> 
以下に、サンプルアプリケーション用のDockerfileがあります

./apps/colorapp/src/gateway/Dockerfile 
./apps/colorapp/src/colorteller/Dockerfile 
デプロイ用のスクリプトが用意されてるのでこちらでECRにPushします。

GatewayアプリケーションをECRにPush

$ cd ./apps/colorapp/src/gateway/ 
$ ./deploy.sh  
+ '[' -z ******.dkr.ecr.us-west-2.amazonaws.com/color-gateway ']' 
+ docker build -t ******.dkr.ecr.us-west-2.amazonaws.com/color-gateway . 
Sending build context to Docker daemon  32.26kB 
Step 1/11 : FROM golang:1.10 AS builder 
 ---> a3e70d5ea200 
Step 2/11 : ADD https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 /usr/bin/dep 
Downloading [==================================================>]  8.499MB/8.499MB 
(略) 
da67ad63a8b3: Pushed  
latest: digest: sha256:634f329a49fd15dc1cad2b20cc694794a3340530e6041056b6b0b9923e3448d5 size: 528 
ColorTellerアプリケーションをECRにPush

$ cd ../ 
$ cd colorteller/ 
$ ./deploy.sh  
+ '[' -z ******.dkr.ecr.us-west-2.amazonaws.com/color-teller ']' 
+ docker build -t ******.dkr.ecr.us-west-2.amazonaws.com/color-teller . 
Sending build context to Docker daemon  8.192kB 
Step 1/11 : FROM golang:1.10 AS builder 
 ---> a3e70d5ea200 
Step 2/11 : ADD https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 /usr/bin/dep 
Downloading [==================================================>]  8.499MB/8.499MB 
(略) 
8c7a1b9b5ec0: Pushed  
latest: digest: sha256:c4b21221d55272295ddce74eb891451d34714d7c09ad826deba3b1eb3db14fad size: 528 
ここまでで以下のような環境が作成されます。



image.png



サービスメッシュのセットアップ

Virtual Node,Virtual Router,Routeを作成します。aws-cliが実行されます。



image.png


$ cd ../../ 
$ pwd 
/aws-app-mesh-examples/examples/apps/colorapp 
$ ./servicemesh/deploy.sh  
[MESH] [Thu Dec 27 15:53:37 JST 2018] : Creating virtual nodes 
[MESH] [Thu Dec 27 15:53:37 JST 2018] : ====================== 
[MESH] [Thu Dec 27 15:53:37 JST 2018] : cli_input={ 
    "spec": { 
        "listeners": [ 
(略) 
[MESH] [Thu Dec 27 15:54:09 JST 2018] : --> a529b027-6176-4324-9e56-423e6ada8c94 
[MESH] [Thu Dec 27 15:54:09 JST 2018] : --> a529b027-6176-4324-9e56-423e6ada8c94 


ECSにアプリケーションをデプロイ

CloudFormationが実行されて、ECRからコンテナイメージがECSクラスタにデプロイされます。



image.png


$ ./ecs/ecs-colorapp.sh  
+++ dirname ./ecs/ecs-colorapp.sh 
++ cd ./ecs 
++ pwd 
+ DIR=/aws-app-mesh-examples/examples/apps/colorapp/ecs 
+ aws --profile default --region us-west-2 cloudformation deploy --stack-name AppMeshSample-ecs-colorapp --capabilities CAPABILITY_IAM --template-file /aws-app-mesh-examples/examples/apps/colorapp/ecs/ecs-colorapp.yaml --parameter-overrides EnvironmentName=AppMeshSample EnvoyImage=111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.8.0.2-beta ECSServicesDomain=default.svc.cluster.local AppMeshMeshName=default ColorGatewayImage=******.dkr.ecr.us-west-2.amazonaws.com/color-gateway ColorTellerImage=******.dkr.ecr.us-west-2.amazonaws.com/color-teller 
 
Waiting for changeset to be created.. 
Waiting for stack create/update to complete 
Successfully created/updated stack - AppMeshSample-ecs-colorapp 


動作確認

踏み台サーバを準備するかSession ManagerでECSクラスタ用のEC2インスタンスにログインする。

Gatewayに対してcurlしてみる。

$ curl -s http://colorgateway.default.svc.cluster.local:9080/color 
{"color":"white", "stats": {"white":1}} 
Whiteが返される。これはルーティング設定(Route)でvirtualNodeがcolorteller-vnのみ設定してあり、colorteller-vnは「White」を返すコンテナになります。

$ cat servicemesh/config/routes/colorteller-route.json  
{ 
    "routeName": "colorteller-route", 
    "spec": { 
        "httpRoute": { 
            "action": { 
                "weightedTargets": [ 
                    { 
                        "virtualNode": "colorteller-vn", 
                        "weight": 1 
                    } 
                ] 
            }, 
            "match": { 
                "prefix": "/" 
            } 
        } 
    }, 
    "virtualRouterName": "colorteller-vr" 
} 
Blueを返すように変更してみます。まずは、Virtual Nodeを確認します。

$ aws appmesh list-virtual-nodes --mesh-name default 
{ 
    "virtualNodes": [ 
        { 
            "arn": "arn:aws:appmesh:us-east-1:******:mesh/default/virtualNode/colorteller-vn", 
            "meshName": "default", 
            "virtualNodeName": "colorteller-vn" 
        }, 
        { 
            "arn": "arn:aws:appmesh:us-east-1:******:mesh/default/virtualNode/colorteller-red-vn", 
            "meshName": "default", 
            "virtualNodeName": "colorteller-red-vn" 
        }, 
        { 
            "arn": "arn:aws:appmesh:us-east-1:******:mesh/default/virtualNode/colorteller-blue-vn", 
            "meshName": "default", 
            "virtualNodeName": "colorteller-blue-vn" 
        }, 
        { 
            "arn": "arn:aws:appmesh:us-east-1:******:mesh/default/virtualNode/colorteller-black-vn", 
            "meshName": "default", 
            "virtualNodeName": "colorteller-black-vn" 
        }, 
        { 
            "arn": "arn:aws:appmesh:us-east-1:******:mesh/default/virtualNode/colorgateway-vn", 
            "meshName": "default", 
            "virtualNodeName": "colorgateway-vn" 
        } 
    ] 
} 
Blueですが、virtualNodeNameがcolorteller-blue-vnになりますので、colorteller-route.jsonを編集します。

$ emacs servicemesh/config/routes/colorteller-route.json  
{ 
    "routeName": "colorteller-route", 
    "spec": { 
        "httpRoute": { 
            "action": { 
                "weightedTargets": [ 
                    { 
                        "virtualNode": "colorteller-blue-vn", 
                        "weight": 1 
                    } 
                ] 
            }, 
            "match": { 
                "prefix": "/" 
            } 
        } 
    }, 
    "virtualRouterName": "colorteller-vr" 
} 
更新します。

$ aws appmesh update-route --mesh-name default --cli-input-json file://servicemesh/config/routes/colorteller-route.json  
virtualNodeがcolorteller-blue-vnとなっていることを確認する。

$ aws appmesh describe-route --mesh-name default  --route-name colorteller-route --virtual-router-name colorteller-vr 
{ 
    "route": { 
        "meshName": "default", 
        "spec": { 
            "httpRoute": { 
                "action": { 
                    "weightedTargets": [ 
                        { 
                            "weight": 1, 
                            "virtualNode": "colorteller-blue-vn" 
curlコマンドで確認すると、blueが返ってきます。

sh-4.2$ curl -s http://colorgateway.default.svc.cluster.local:9080/color 
{"color":"blue", "stats": {"blue":0,"white":1}}sh-4.2$ 
トラフィックの30%をBlackのマイクロサービス、70%をRedのマイクロサービスといったようにルーティングすることも可能です。


落ち穂拾い

GatewayのEnvoyコンテナにログインして設定情報を確認してみます。

GatewayのEnvoyコンテナが起動しているEC2インスタンスにログイン via SSM or 踏み台経由してSSH

コンテナIDを確認

sh-4.2$ sudo su - 
Last login: Fri Dec 28 05:10:11 UTC 2018 on pts/6 
[root@ip-10-0-126-201 ~]# docker ps 
CONTAINER ID        IMAGE                                                                          COMMAND                  CREATED             STATUS              PORTS               NAMES 
13591540c2b5        111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.8.0.2-beta   "/bin/sh -c /usr/bin…"   24 hours ago        Up 24 hours                             ecs-AppMeshSample-ecs-colorapp-ColorGatewayTaskDefinition-1P2K347XVMJFW-1-envoy-fec5ebb5a1fbec900a00 
コンテナにログイン

root@ip-10-0-126-201 ~]# 
[root@ip-10-0-126-201 ~]# docker exec -it 13591540c2b5 /bin/bash 
bash-4.2$ 
Envoyの設定情報確認

Virtual Nodeがcolorgateway-vn|colorteller-blue-vnになっていることが確認できます。

bash-4.2$ curl localhost:9901/config_dump 
{ 
 "configs": [ 
  { 
   "@type": "type.googleapis.com/envoy.admin.v2alpha.BootstrapConfigDump", 
 
(略) 
  { 
   "@type": "type.googleapis.com/envoy.admin.v2alpha.RoutesConfigDump", 
   "dynamic_route_configs": [ 
    { 
     "version_info": "61077530", 
     "route_config": { 
      "name": "rds|egress|default|colorgateway-vn|http|9080|61077530", 
      "virtual_hosts": [ 
       { 
        "name": "rds|egress|default|colorgateway-vn|http|9080|colorteller.default.svc.cluster.local|61077530", 
        "domains": [ 
         "colorteller.default.svc.cluster.local", 
         "colorteller.default.svc.cluster.local:9080" 
        ], 
        "routes": [ 
         { 
          "match": { 
           "prefix": "/" 
          }, 
          "route": { 
           "weighted_clusters": { 
            "clusters": [ 
             { 
              "name": "cds|egress|default|colorgateway-vn|colorteller-blue-vn|http|9080|59827320", 
              "weight": 1 
             } 
            ], 
            "total_weight": 1 
           } 
          } 
         } 
        ] 
       } 
      ] 
     }, 
     "last_updated": "2018-12-28T04:19:28.852Z" 
    }, 


お約束

投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)