ITのチカラで、デジタルビジネスへの変革を。

[AWS] AWS AppMeshのSample Appを用いた動作検証

#AppMesh #AWS #Kubernetes #ServiceMesh

はじめに

本稿では、先週のAWS Summit サンタクララでGAとなったAWS AppMeshを、サービスの概要や構成要素についてまとめつつ、実際にGUIベースで設定しながら動作検証をしてみたいと思います。

AWS AppMesh概要

AWS AppMesh(以下AppMesh)は、AWS上のマイクロサービス間の通信を監視&制御できるサービスメッシュです。

AppMeshと連携できるAWSのサービスは下記の通りです。

  • Amazon ECS
  • Amazon EKS
  • AWS Fargate
  • EC2上でスクラッチ起動したKubernetes

AppMeshはOSSのEnvoyプロキシと連携することで、サービス間のトラフィックをルーティングしたり、監視することが可能です。

アプリケーションが実装されたコンテナと同じTask or Pod内にサイドカーProxyとしてEnvoyを起動し、各サービスはEnvoyを介して通信を行います。

App Meshは各Task or Pod内のEnvoyに対して、Route情報などの設定パラメータを送信することで、マイクロサービス環境に対する通信制御の共通化を実現します。

また、Amazon CloudWatchやAWS X-Ray、任意のモニタリング・追跡ツールに対して、可測データを出力することで、アプリ間通信の監視、可視化を行うことも可能です。

上記により、AppMeshを用いることでマイクロサービス環境におけるアプリケーション間の通信を可視化したり、制御することが可能になります。

構成要素

AppMeshの構成には、下記5つの要素が必要となります。

  1. Service Mesh
  2. Virtual Service
  3. Virtual Routers
  4. Virtual Nodes
  5. Route

1. Service Mesh

マイクロサービス間のトラフィックを制御するための論理的なネットワークグループです。
AWS AppMeshのGUIコンソール上では”Mesh”として表示され、Mesh内にVirtual ServiceやVirtual Nodesなどの各構成要素を作成していきます。

2. Virtual Service

Virtual Serviceは、配下にぶら下がるVirtual NodeやVirtual Routerを抽象化する論理的な単位です。

各Virtual Serviceは論理名(例: my-service.default.svc.cluster.local)を持ち、各Virtual NodeがVirtual Serviceと通信を行う際には、この論理名に対してリクエストを送ります。
このリクエストを受けて、Virtual Serviceは配下にぶら下がるVirtual NodeやVirtual Routerにルーティングを行います。

3. Virtual Node

Virtual Nodeは、Amazon ECSにおけるServiceや、KubernetesにおけるDeploymentなどの特定のTask or Podグループに対する受け口となります。この際、Virtual NodeはTask or Podグループ内のEnvoyと連携します。

Virtual Nodeを作成する際には、Virtual Node宛のインバウンド or アウトバウンドトラフィックを転送できるよう、下記の設定を行う必要があります。

  • Virtual Node宛のインバウンドトラフィックは、全てListenerとして指定する必要があります。なお、Listenerに対して、ヘルスチェックを設定することも可能です。
  • Virtual Nodeから他サービスにアウトバウンドトラフィックは転送する際には、”Bakcends”に登録する必要があります。

4. Virtual Router

Virtual Routerは、Mesh内のトラフィックをハンドリングするための仮想的なリソースです。
各仮想Routerは、特定のポートでHTTPトラフィックをListenします。

5. Route

Routeは、どのURLをどのVirtual NodeにRouteingするかを定義する、その名の通りルート情報を記載する要素です。
複数のVirtual Nodeやウェイトの設定が可能なため、カナリアデプロイなどを行うことができます。

動作検証

それでは、実際にAppMeshを構築 & 動作検証してみたいと思います。
動作検証にはAWSが提供しているSample App(Colorapp)を使用します。

このSample Appは、Color Gatewayと白、黒、赤、青と各色用意されたColor Tellerというサービスで構成されています。

Color Gatewayが、ColoerTellerに対してHTTPリクエストを行い、返ってきた色の文字列と、過去取得した色の結果をjsonで返す…というシンプルなアプリになっています。 

 

このSample Appにおいて、サービス間の通信をAppMeshで制御します。
AppMeshで設定したRoute情報に従って、Color GatewayからColor Tellerへのトラフィック振り分けができるかを確認し、AppMeshの動作を確認していきます。

なお、今回は事前に構築済みのEKS環境上に上記Sample Appを構築し、AppMeshの動作検証をしてみたいと思います。

Kubernetes環境の場合、上記Sample Appの各サービスはEnvoyとAppのPodを起動するDeploymentと、Serviceによって構成されています。

検証の手順は下記の通りです。
Sample AppではAppMeshの構成要素を一発で構築できるようなシェルスクリプトが用意されていますが、今回は構成要素の確認のため、GUIでひとつひとつ設定していきたいと思います。

  1. セットアップ
  2. Meshの作成
  3. Virtual Serviceの作成
  4. Virtual Nodeの作成
  5. Virtual Routerの作成 & Routeの設定
  6. Virtual Serviceへの追加設定
  7. Appのデプロイ
  8. 通信検証

完成イメージは下図の構成です。

1. セットアップ

まずはSample Appをダウンロードします。

$ git clone https://github.com/aws/aws-app-mesh-examples.git

 

続いて、下記の環境変数を設定します。

export AWS_PROFILE=<"your aws-profile for aws-cli">
export AWS_REGION=<"your aws-region">
export MESH_NAME=default
export SERVICES_DOMAIN="default.svc.cluster.local"
export ENVOY_IMAGE="111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.9.0.0-prod"

 

2. Meshの作成

次にMeshを作成していきます。

AWSのマネジメントコンソールからAWS AppMeshを選択します。
左上のツールバーから、『Meshes』をクリックします。

 

次に『Create mesh』をクリックし、Meshを作成していきます。

 

Meshの名前となる“Mesh Name”を設定し、『Create mesh』をクリックします。

 

コンソール上部に”Successfully created mesh ‘Default'”と表示され、Meshes一覧に作成したMeshが表示されれば、Meshの作成は完了です。

 

2. Virtual Serviceの作成

次にVirtual Serviceを作成していきます。

“Meshes”画面にて、2で作成した”Default”をクリックします。

 

 

Meshの設定画面にて、『Virtual services』をクリックします。

 

『Create virtual service』をクリックします。

 

“Virtual service name”を入力します。なお、”Provider”の設定はまだVirtual Routerを作成していないため、一旦”none”を指定します。
最後にCreate virtual serviceをクリックします。

 

画面上部に”Successfully created virtual service ‘colorteller.default.svc.cluster.local’“と表示され、下記の画面が表示されれば作成完了です。

 

3. Virtual Nodeの作成

次にVirtual Nodeを作成していきます。
ここでは下記5つのVirtual Nodeを作成していきます。

  • colorteller-white-vn
  • colorteller-black-vn
  • colorteller-blue-vn
  • colorteller-red-vn
  • colorgateway-vn

①. 各色のcolorteller用Virtual Node作成

まずは各Colorteller用Virtual Nodeから作成していきます。

“Meshes”画面にて、2で作成した”Default”をクリックします。 

 

Meshの設定画面にて、『Virtual Nodes』をクリックします。

 

『Create virtual node』をクリックします。

 

まず、Virtual node configuration画面でこのVirtual Nodeの名前とService Discovery Method、DNSホスト名を設定します。

 

次に”Listener”として、このVirtual Nodeがで受け付けるインバウンドトラフィックを指定します。また、同ポートに対してヘルスチェックを行うよう設定していきます。

 

一通り入力が完了したら、『Create virtual node』をクリックします。

 

コンソール上部に”Successfully created virtual node ‘colorteller-white-vn’Virtual nodes”のメッセージが表示され、一覧に作成した”Colorteller-white-vn”が表示されていれば、作成完了です。

 

同様の手順で他のblack、blue、redのColorteller用Virtual Nodeも作成していきます。
この際、Virtual node configurationのみ、各色に書き換え、Listenerのパラメータはwhiteと同じものを入力してください。

 

②. colorgateway用Virtual Node作成

続いて、colorgateway用のVirtual Nodeを作成します。

『Create virtual node』をクリックし、Virtual node configurationを下記の通りに設定していきます。

この際、coloratewayはアウトバウンドトラフィックをColorteller用Virtual Serviceに転送するため、Backendに2で作成したVirtual Serviceをaddする必要があります。

 

 

次に”Listener”として、colorgateway Virtual Nodeがで受け付けるインバウンドトラフィックを指定します。なお、Health Checkはオフで設定します。
最後に『Create virtual node』をクリックします。

 

ここまでで5つのVirtual nodeが作成されていれば、Virtual nodeの作成は完了です。

 

5. Virtual Routerの作成 & Routeの設定

次にVirtual Routerを作成し、Routeの設定を行います。

①. Virtual Routerの作成

まず、Virtual Routerを作成します。

“Meshes”画面にて、2で作成した”Default”をクリックします。

 

Meshの設定画面にて、『Virtual Router』をクリックします。

 

『Create virtual router』をクリックします。

 

“Virtual router name”と”Listener”の各情報を入力します。
最後に『Create virtual router』をクリックします。

 

画面上部に”Successfully created virtual router ‘colorteller-vr'”と表示され、Virtual Routersの一覧に作成した”colorteller-vr”が表示されていれば、Virtual Routerの作成は完了です。

 

 

②. Routeの追加

続いて、①で作成したVirtual Routerに対して、Routeを追加していきます。
“Virtual routers”画面にて、①で作成した”colorteller-vr“をクリックします。

 

“Routes”画面にて、『Create route』をクリックします、

 

“Route Configuration”画面にて、Route名とRouteのタイプ(http)、トラフィックの振り分け先ターゲットとなるVirtual nodeとして、3色のcolertellerを登録します。なお、Weightはそれぞれ”1″を指定します。
最後に『Create route』をクリックします。

 

画面上部に”Successfully created route ‘colorteller-route’“と表示され、”Routes”一覧に作成したRouteが表示されていれば、作成完了です。

6. Virtual Serviceへの追加設定

次に2で作成したVirtual Serviceに対して、ProviderとしてVirtual RouterをProviderとして追加します。

“Meshes”画面にて、2で作成した”Default”をクリックします。

 

Meshの設定画面にて、『Virtual services』をクリックします。

 

“Virtual services”の一覧から、2で作成した “colorteller.default.svc.cluster.local”をクリックします。

 

“colorteller.default.svc.cluster.local”の設定画面で『Edit』をクリックします。

 

“Edit virtual service”の設定画面で、”Provider”に”Virtual router”を指定し、5で作成した”colorteller-vr”を指定します。
最後に『Save』をクリックします。

 

画面上部に”Successfully edited virtual service ‘colorteller.default.svc.cluster.local’“とメッセージが表示され、Routes一覧に5で”colorteller-vr”に登録したRoute “colorteller-route”が表示されていれば、設定完了です。

 

ここまでで、Service Mesh側の設定は完了です。

 

7. Appのデプロイ

続いて、Color AppをEKS上にデプロイしていきます。

①. Docker ImageをリポジトリにPush

まずは、ColorGatewayおよびColorTellerのDocker ImageをリポジトリにPushします。
今回はAWSのリポジトリサービス、ECRを使用します。
下記のawsコマンドでECRにリポジトリを作成します。

$ aws ecr create-repository --repository-name "color-gateway" --region us-east-1
$ aws ecr create-repository --repository-name "color-teller" --region us-east-1

 

作成した各リポジトリのURIを環境変数に設定します。

$ export COLOR_GATEWAY_IMAGE=<"<youraccountnumber>.dkr.ecr.amazonaws.com/gateway:latest">
$ export COLOR_TELLER_IMAGE=<"<youraccountnumber>.dkr.ecr.amazonaws.com/colorteller:latest">

 

SampleApp内のデプロイ用スクリプトを用いて、ECRにDocker Imageをプッシュします。

## GatewayアプリをECRにPush
$ cd examples/apps/colorapp/src/gateway/
$ ./deploy.sh

## ColorTellerアプリをECRにPush
$ cd examples/apps/colorapp/src/colorteller/
$ ./deploy.sh

 

②. EKS上にSample Appをデプロイ

EKS環境にSample Appをデプロイします。
下記コマンドでデプロイを実行します。

$ cd examples/apps/colorapp/kubernetes/
$ ./generate-templates.sh && kubectl apply -f colorapp.yaml

実行後、Kuberenetes上に各リソースが作成されていることを確認します。それぞれ起動していれば成功です。

$ kubectl get svc
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
colorgateway        ClusterIP   10.100.94.235   <none>        9080/TCP   1m
colorteller         ClusterIP   10.100.247.17   <none>        9080/TCP   1m
colorteller-black   ClusterIP   10.100.160.0    <none>        9080/TCP   1m
colorteller-blue    ClusterIP   10.100.93.160   <none>        9080/TCP   1m
colorteller-red     ClusterIP   10.100.59.36    <none>        9080/TCP   1m
tcpecho             ClusterIP   10.100.202.50   <none>        2701/TCP   1m

$ kubectl get deployment
NAME                DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
colorgateway        1         1         1            1           5m
colorteller-black   1         1         1            1           4m
colorteller-blue    1         1         1            1           4m
colorteller-red     1         1         1            1           4m
colorteller-white   1         1         1            1           5m
tcpecho             1         1         1            1           4m

$ kubectl get pod
NAME                                        READY     STATUS    RESTARTS   AGE
colorgateway-69c4f4996f-k79rb               2/2       Running   0          5m
colorteller-black-545fcd87f6-24k46          2/2       Running   0          5m
colorteller-blue-86b98484cc-6ctvd           2/2       Running   0          5m
colorteller-red-679846fc84-zq4lx            2/2       Running   0          5m
colorteller-white-5cdfcfdbf4-x5nzv          2/2       Running   0          5m
tcpecho-779c75f5d7-st4mw                    1/1       Running   0          5m

8. 動作確認

それでは、実際にAppMeshによるトラフィック分散を確認してみたいと思います。

Kubernetes上にテスト用のPodを構築し、同PodからVirtual service “Colorgateway”のDNS名に対してCurlを実行してみます。

$ kubectl run -it curler --image=tutum/curl --env="SERVICES_DOMAIN=${SERVICES_DOMAIN}" bash

root@curler-549bd98668-h7zth:/# curl -s --connect-timeout 2 http://colorgateway.${SERVICES_DOMAIN}:9080/color
{"color":"white", "stats": {"white":1}}

root@curler-549bd98668-h7zth:/# curl -s --connect-timeout 2 http://colorgateway.${SERVICES_DOMAIN}:9080/color
{"color":"blue", "stats": {"blue":0.5,"white":0.5}}

何度か実行し、5のRoute情報で設定したターゲットVirtual Nodeにトラフィックが分散されていることを確認できたら成功です。

 

Mafuyu Miyano

この記事を書いた人

Mafuyu Miyano