翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
AWS App Mesh と Amazon の使用を開始する EC2
重要
サポート終了通知: 2026 年 9 月 30 日、 は のサポートを中止 AWS します AWS App Mesh。2026 年 9 月 30 日以降、 AWS App Mesh コンソールまたは AWS App Mesh リソースにアクセスできなくなります。詳細については、このブログ記事の「 から Amazon ECS Service Connect AWS App Mesh への移行
このトピックは、Amazon で実行されている実際のサービス AWS App Mesh で を使用するのに役立ちますEC2。このチュートリアルでは、複数の App Mesh リソースタイプのベーシックな機能について説明します。
シナリオ
App Mesh の使用方法を説明するために、次の特性を持つアプリケーションがあると仮定します。
-
serviceA
およびserviceB
という名前の 2 つのサービスで構成されています。 -
どちらのサービスも、
apps.local
という名前の名前空間にメンバー登録されます。 -
ServiceA
は HTTP/2serviceB
を超えるポート 80 と通信します。 -
すでに
serviceB
のバージョン 2 をデプロイし、serviceBv2
名前空間にapps.local
という名前でメンバー登録しました。
次の要件があります。
-
トラフィックの 75% を
serviceA
にserviceB
、25% をserviceBv2
最初に に送信します。に 25% のみを送信することでserviceBv2
、 からトラフィックを 100% 送信する前に、バグがないことを検証できますserviceA
。 -
トラフィックの重み付けを簡単に調整して、信頼性が証明されたら、トラフィックの 100% が
serviceBv2
へ転送されるようにします。すべてのトラフィックがserviceBv2
に送信されたら、serviceB
を切断します。 -
上記の要件を満たすために、実際のサービスの既存のアプリケーションコードまたはサービスディスカバリ登録を変更する必要はありません。
要件を満たすために、仮想サービス、仮想ノード、仮想ルーター、およびルートで、App Mesh サービスメッシュを作成することにします。メッシュを実装した後、サービスを更新して、Envoy プロキシを使用します。更新されると、サービスは相互に直接ではなく、Envoy プロキシを介して相互に通信します。
前提条件
App Mesh は、DNS、 AWS Cloud Map、またはその両方に登録されている Linux サービスをサポートしています。この入門ガイドを使用するには、 に登録されている 3 つの既存のサービスがあることをお勧めしますDNS。サービスが存在しない場合でもサービスメッシュとそのリソースを作成できますが、実際のサービスをデプロイするまでメッシュを使用することはできません。
サービスがまだ実行されていない場合は、Amazon EC2インスタンスを起動してアプリケーションをデプロイできます。詳細については、「Amazon ユーザーガイド」の「チュートリアル: Amazon EC2 Linux インスタンスの開始方法」を参照してください。 EC2残りのステップでは、実際のサービスが serviceA
、serviceB
、serviceBv2
という名前で、すべてのサービスが apps.local
という名前の名前空間を介して検出可能であることを前提としています。
ステップ 1: メッシュと仮想サービスを作成する
サービスメッシュは、サービス間のネットワークトラフィックの論理的な境界であり、サービスはその中に存在します。詳細については、「サービスメッシュ」を参照してください。仮想サービスは、実際のサービスを抽象化したものです。詳細については、「仮想サービス」を参照してください。
次の リソースを作成します。
-
シナリオ内のすべてのサービスが
apps
名前空間にメンバー登録されているため、apps.local
という名前のメッシュ。 -
serviceb.apps.local
という名前の仮想サービス。仮想サービスは、その名前で検出可能なサービスを表しているため、別の名前をリファレンスするようにコードを変更したくないためです。servicea.apps.local
という名前の仮想サービスが、次のステップで追加されます。
AWS Management Console または AWS CLI バージョン 1.18.116 以降、または 2.0.38 以降を使用して、次のステップを完了できます。を使用する場合は AWS CLI、 aws --version
コマンドを使用してインストールされている AWS CLI バージョンを確認します。バージョン 1.18.116 以降、または 2.0.38 以降をインストールしていない場合は、AWS CLIをインストールまたは更新する必要があります。使用するツールのタブを選択します。
ステップ 2: 仮想ノードを作成する
仮想ノードは、実際のサービスの論理ポインタとして機能します。詳細については、「仮想ノード」を参照してください。
仮想ノードの 1 つが serviceB
という名前の実際のサービスを表すため、serviceB
という名前の仮想ノードを作成します。仮想ノードが表す実際のサービスは、serviceb.apps.local
というホスト名を持つ DNS
を介して検出可能です。または、 AWS Cloud Mapを使用して実際のサービスを検出することもできます。仮想ノードは、ポート 80 の HTTP/2 プロトコルを使用してトラフィックをリッスンします。ヘルスチェックと同様に、その他のプロトコルもサポートされています。次のステップで、serviceA
および serviceBv2
の仮想ノードを作成します。
ステップ 3: 仮想ルーターとルートを作成する
仮想ルーターは、メッシュ内の 1 つ以上の仮想サービスのトラフィックを送信します。詳細については、「仮想ルーター」および「ルート」を参照してください。
次の リソースを作成します。
-
serviceB
という名前の仮想ルーター。serviceB.apps.local
仮想サービスは、他のサービスとのアウトバウンド通信を開始しないためです。前に作成した仮想サービスは、実際のserviceb.apps.local
サービスの抽象化であることに注意してください。仮想サービスは、仮想ルーターにトラフィックを送信します。仮想ルーターは、ポート 80 の HTTP/2 プロトコルを使用してトラフィックをリッスンします。その他のプロトコルもサポートされています。 -
serviceB
という名前のルート。このルートはトラフィックの 100% をserviceB
仮想ノードにルーティングします。重み付けは、serviceBv2
仮想ノードを追加した後のステップで行います。このガイドでは説明しませんが、ルートにフィルタ条件を追加したり、通信の問題が発生したときに Envoy プロキシが仮想ノードへのトラフィックの送信を複数回試行する再試行ポリシーを追加したりできます。
ステップ 4: 確認して作成する
前のステップと照らし合わせて設定を確認します。
ステップ 5: 追加のリソースを作成する
このシナリオを完了するには、次のことを行う必要があります。
-
serviceBv2
という名前の仮想ノードと、serviceA
という名前の別の仮想ノードを作成します。両方の仮想ノードは HTTP/2 ポート 80 を超えるリクエストをリッスンします。serviceA
仮想ノードには、serviceb.apps.local
のバックエンドを設定します。serviceA
仮想ノードからのすべてのアウトバウンドトラフィックは、serviceb.apps.local
という名前の仮想サービスに送信されます。このガイドでは説明しませんが、仮想ノードのアクセスログを書き込むファイルパスを指定することもできます。 -
servicea.apps.local
という名前の追加の仮想サービスを 1 つ作成します。これにより、すべてのトラフィックがserviceA
仮想ノードに直接送信されます。 -
前のステップで作成した
serviceB
ルートを更新して、トラフィックの 75% をserviceB
仮想ノードに送信し、25% をserviceBv2
仮想ノードに送信します。時間の経過とともに、serviceBv2
が 100% のトラフィックを受信するまで、継続して重みを変更することができます。すべてのトラフィックがserviceBv2
に送信されたら、serviceB
仮想ノードと実際のサービスをシャットダウンして中止することができます。重みを変更しても、serviceb.apps.local
仮想サービス名および実際のサービス名は変更されないため、コードを変更する必要はありません。serviceb.apps.local
仮想サービスは仮想ルーターにトラフィックを送信し、仮想ルーターはトラフィックを仮想ノードにルーティングすることに注意してください。仮想ノードのサービスディスカバリ名は、いつでも変更できます。
メッシュの概要
サービスメッシュを作成する前に、servicea.apps.local
、serviceb.apps.local
、および servicebv2.apps.local
という 3 つの実際のサービスがありました。実際のサービスに加えて、実際のサービスを表す次のリソースを含むサービスメッシュが作成されました。
-
2 つの仮想サービス。プロキシは、仮想ルーターを経由して、
servicea.apps.local
仮想サービスからのすべてのトラフィックをserviceb.apps.local
仮想サービスに送信します。 -
serviceA
、serviceB
、およびserviceBv2
という名前の 3 つの仮想ノード。Envoy プロキシは、仮想ノードに対して設定されたサービスディスカバリ情報を使用して、実際のサービスの IP アドレスを検索します。 -
Envoy プロキシがインバウンドトラフィックの 75% を
serviceB
仮想ノードに、25% をserviceBv2
仮想ノードにルーティングするように指定する 1 つのルートを持つ仮想ルーター。
ステップ 6: サービスを更新する
メッシュを作成したら、次のタスクを完了する必要があります。
-
各サービスでデプロイする Envoy プロキシに、1つ以上の仮想ノードの設定を読み取りすることを許可します。プロキシを承認する方法の詳細については、Envoy プロキシの認可 を参照してください。
-
既存のサービスを更新するには、次のステップを実行します。
Amazon EC2インスタンスを仮想ノードメンバーとして設定するには
-
IAM ロールを作成します。
-
次の内容で、
ec2-trust-relationship.json
という名前のファイルを作成します。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
-
次のコマンドを使用してIAMロールを作成します。
aws iam create-role --role-name
mesh-virtual-node-service-b
--assume-role-policy-document file://ec2-trust-relationship.json
-
-
Amazon からの読み取りを許可するロールにIAMポリシーをアタッチECRし、特定の App Mesh 仮想ノードの設定のみを行います。
-
次の内容の
virtual-node-policy.json
という名前のファイルを作成します。apps
は ステップ 1: メッシュと仮想サービスを作成する で作成したメッシュの名前で、serviceB
は ステップ 2: 仮想ノードを作成する で作成した仮想ノードの名前です。置換111122223333
アカウント ID とus-west-2
メッシュを作成したリージョン。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "appmesh:StreamAggregatedResources", "Resource": [ "arn:aws:appmesh:
us-west-2
:111122223333
:mesh/apps
/virtualNode/serviceB
" ] } ] } -
次のコマンドを使用してポリシーを作成します。
aws iam create-policy --policy-name
virtual-node-policy
--policy-document file://virtual-node-policy.json -
前のステップで作成したポリシーをロールに添付して、ロールが AppMesh からの
serviceB
仮想ノードの設定のみを読み取れるようにします。aws iam attach-role-policy --policy-arn arn:aws:iam::
111122223333
:policy/virtual-node-policy --role-namemesh-virtual-node-service-b
-
AmazonEC2ContainerRegistryReadOnly
マネージドポリシーをロールにアタッチして、Amazon から Envoy コンテナイメージをプルできるようにしますECR。aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --role-name
mesh-virtual-node-service-b
-
-
作成したIAMロールを使用して Amazon EC2インスタンスを起動します。
-
経由でインスタンスに接続しますSSH。
-
オペレーティングシステムのドキュメントに従って、インスタンス AWS CLI に Docker と をインストールします。
-
Docker クライアントがイメージをプルするリージョンの Envoy Amazon ECRリポジトリに認証します。
-
me-south-1
、ap-east-1
、ap-southeast-3
、eu-south-1
、il-central-1
、af-south-1
を除くすべてのリージョン。を置き換えることができます。us-west-2
、me-south-1
、ap-east-1
、ap-southeast-3
、eu-south-1
il-central-1
、 を除くサポートされているリージョン。af-south-1
$
aws ecr get-login-password \ --region
us-west-2
\ | docker login \ --username AWS \ --password-stdin 840364872350.dkr.ecr.us-west-2
.amazonaws.com -
me-south-1
リージョン$
aws ecr get-login-password \ --region me-south-1 \ | docker login \ --username AWS \ --password-stdin 772975370895.dkr.ecr.me-south-1.amazonaws.com
-
ap-east-1
リージョン$
aws ecr get-login-password \ --region ap-east-1 \ | docker login \ --username AWS \ --password-stdin 856666278305.dkr.ecr.ap-east-1.amazonaws.com
-
-
次のいずれかのコマンドを実行して、イメージをプルするリージョンに応じて、インスタンスで App Mesh Envoy コンテナを起動します。-
apps
また、serviceB
値は、シナリオで定義されるメッシュノード名と仮想ノード名です。この情報は、App Mesh から読み取りする仮想ノード設定をプロキシに指示します。シナリオを完了するには、serviceBv2
とserviceA
仮想ノードで表されるサービスをホストする Amazon EC2インスタンスについても、これらのステップを完了する必要があります。独自のアプリケーションでは、これらの値を独自の値に置き換えます。-
me-south-1
、ap-east-1
、ap-southeast-3
、eu-south-1
、il-central-1
、af-south-1
を除くすべてのリージョン。を置き換えることができます。Region-code
、me-south-1
、ap-east-1
、、、および リージョンを除くap-southeast-3
eu-south-1
il-central-1
、サポートされているすべてのaf-south-1
リージョン。
は、1337
0
と2147483647
の間の任意の値に置き換えることができます。sudo docker run --detach --env APPMESH_RESOURCE_ARN=
mesh/
\ -uapps
/virtualNode/serviceB
1337
--network host 840364872350.dkr.ecr.region-code
.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod -
me-south-1
リージョン
は、1337
0
と2147483647
の間の任意の値に置き換えることができます。sudo docker run --detach --env APPMESH_RESOURCE_ARN=
mesh/
\ -uapps
/virtualNode/serviceB
1337
--network host 772975370895.dkr.ecr.me-south-1.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod -
ap-east-1
リージョン
は、1337
0
と2147483647
の間の任意の値に置き換えることができます。sudo docker run --detach --env APPMESH_RESOURCE_ARN=
mesh/
\ -uapps
/virtualNode/serviceB
1337
--network host 856666278305.dkr.ecr.ap-east-1.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod
注記
APPMESH_RESOURCE_ARN
プロパティは、バージョン1.15.0
またはそれ以降のEnvoy イメージを必要とします 詳細については、「Envoy イメージ」を参照してください。重要
App Mesh での使用は、バージョン v1.9.0.0-prod 以降のみでサポートされています。
-
次の
Show more
を選択します。インスタンスで、次の内容のenvoy-networking.sh
という名前のファイルを作成します。置換8000
アプリケーションコードが受信トラフィックに使用するポート。APPMESH_IGNORE_UID
の値は変更できますが、値は前のステップで指定した値と同じである必要があります (例:1337
)。必要に応じて、アドレスをAPPMESH_EGRESS_IGNORED_IP
に追加できます。他の行は変更しないでください。#!/bin/bash -e # # Start of configurable options # #APPMESH_START_ENABLED="0" APPMESH_IGNORE_UID="
1337
" APPMESH_APP_PORTS="8000
" APPMESH_ENVOY_EGRESS_PORT="15001" APPMESH_ENVOY_INGRESS_PORT="15000" APPMESH_EGRESS_IGNORED_IP="169.254.169.254,169.254.170.2" # Enable routing on the application start. [ -z "$APPMESH_START_ENABLED" ] && APPMESH_START_ENABLED="0" # Enable IPv6. [ -z "$APPMESH_ENABLE_IPV6" ] && APPMESH_ENABLE_IPV6="0" # Egress traffic from the processess owned by the following UID/GID will be ignored. if [ -z "$APPMESH_IGNORE_UID" ] && [ -z "$APPMESH_IGNORE_GID" ]; then echo "Variables APPMESH_IGNORE_UID and/or APPMESH_IGNORE_GID must be set." echo "Envoy must run under those IDs to be able to properly route it's egress traffic." exit 1 fi # Port numbers Application and Envoy are listening on. if [ -z "$APPMESH_ENVOY_EGRESS_PORT" ]; then echo "APPMESH_ENVOY_EGRESS_PORT must be defined to forward traffic from the application to the proxy." exit 1 fi # If an app port was specified, then we also need to enforce the proxies ingress port so we know where to forward traffic. if [ ! -z "$APPMESH_APP_PORTS" ] && [ -z "$APPMESH_ENVOY_INGRESS_PORT" ]; then echo "APPMESH_ENVOY_INGRESS_PORT must be defined to forward traffic from the APPMESH_APP_PORTS to the proxy." exit 1 fi # Comma separated list of ports for which egress traffic will be ignored, we always refuse to route SSH traffic. if [ -z "$APPMESH_EGRESS_IGNORED_PORTS" ]; then APPMESH_EGRESS_IGNORED_PORTS="22" else APPMESH_EGRESS_IGNORED_PORTS="$APPMESH_EGRESS_IGNORED_PORTS,22" fi # # End of configurable options # function initialize() { echo "=== Initializing ===" if [ ! -z "$APPMESH_APP_PORTS" ]; then iptables -t nat -N APPMESH_INGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ip6tables -t nat -N APPMESH_INGRESS fi fi iptables -t nat -N APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ip6tables -t nat -N APPMESH_EGRESS fi } function enable_egress_routing() { # Stuff to ignore [ ! -z "$APPMESH_IGNORE_UID" ] && \ iptables -t nat -A APPMESH_EGRESS \ -m owner --uid-owner $APPMESH_IGNORE_UID \ -j RETURN [ ! -z "$APPMESH_IGNORE_GID" ] && \ iptables -t nat -A APPMESH_EGRESS \ -m owner --gid-owner $APPMESH_IGNORE_GID \ -j RETURN [ ! -z "$APPMESH_EGRESS_IGNORED_PORTS" ] && \ for IGNORED_PORT in $(echo "$APPMESH_EGRESS_IGNORED_PORTS" | tr "," "\n"); do iptables -t nat -A APPMESH_EGRESS \ -p tcp \ -m multiport --dports "$IGNORED_PORT" \ -j RETURN done if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then # Stuff to ignore ipv6 [ ! -z "$APPMESH_IGNORE_UID" ] && \ ip6tables -t nat -A APPMESH_EGRESS \ -m owner --uid-owner $APPMESH_IGNORE_UID \ -j RETURN [ ! -z "$APPMESH_IGNORE_GID" ] && \ ip6tables -t nat -A APPMESH_EGRESS \ -m owner --gid-owner $APPMESH_IGNORE_GID \ -j RETURN [ ! -z "$APPMESH_EGRESS_IGNORED_PORTS" ] && \ for IGNORED_PORT in $(echo "$APPMESH_EGRESS_IGNORED_PORTS" | tr "," "\n"); do ip6tables -t nat -A APPMESH_EGRESS \ -p tcp \ -m multiport --dports "$IGNORED_PORT" \ -j RETURN done fi # The list can contain both IPv4 and IPv6 addresses. We will loop over this list # to add every IPv4 address into `iptables` and every IPv6 address into `ip6tables`. [ ! -z "$APPMESH_EGRESS_IGNORED_IP" ] && \ for IP_ADDR in $(echo "$APPMESH_EGRESS_IGNORED_IP" | tr "," "\n"); do if [[ $IP_ADDR =~ .*:.* ]] then [ "$APPMESH_ENABLE_IPV6" == "1" ] && \ ip6tables -t nat -A APPMESH_EGRESS \ -p tcp \ -d "$IP_ADDR" \ -j RETURN else iptables -t nat -A APPMESH_EGRESS \ -p tcp \ -d "$IP_ADDR" \ -j RETURN fi done # Redirect everything that is not ignored iptables -t nat -A APPMESH_EGRESS \ -p tcp \ -j REDIRECT --to $APPMESH_ENVOY_EGRESS_PORT # Apply APPMESH_EGRESS chain to non local traffic iptables -t nat -A OUTPUT \ -p tcp \ -m addrtype ! --dst-type LOCAL \ -j APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then # Redirect everything that is not ignored ipv6 ip6tables -t nat -A APPMESH_EGRESS \ -p tcp \ -j REDIRECT --to $APPMESH_ENVOY_EGRESS_PORT # Apply APPMESH_EGRESS chain to non local traffic ipv6 ip6tables -t nat -A OUTPUT \ -p tcp \ -m addrtype ! --dst-type LOCAL \ -j APPMESH_EGRESS fi } function enable_ingress_redirect_routing() { # Route everything arriving at the application port to Envoy iptables -t nat -A APPMESH_INGRESS \ -p tcp \ -m multiport --dports "$APPMESH_APP_PORTS" \ -j REDIRECT --to-port "$APPMESH_ENVOY_INGRESS_PORT" # Apply AppMesh ingress chain to everything non-local iptables -t nat -A PREROUTING \ -p tcp \ -m addrtype ! --src-type LOCAL \ -j APPMESH_INGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then # Route everything arriving at the application port to Envoy ipv6 ip6tables -t nat -A APPMESH_INGRESS \ -p tcp \ -m multiport --dports "$APPMESH_APP_PORTS" \ -j REDIRECT --to-port "$APPMESH_ENVOY_INGRESS_PORT" # Apply AppMesh ingress chain to everything non-local ipv6 ip6tables -t nat -A PREROUTING \ -p tcp \ -m addrtype ! --src-type LOCAL \ -j APPMESH_INGRESS fi } function enable_routing() { echo "=== Enabling routing ===" enable_egress_routing if [ ! -z "$APPMESH_APP_PORTS" ]; then enable_ingress_redirect_routing fi } function disable_routing() { echo "=== Disabling routing ===" iptables -t nat -F APPMESH_INGRESS iptables -t nat -F APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ip6tables -t nat -F APPMESH_INGRESS ip6tables -t nat -F APPMESH_EGRESS fi } function dump_status() { echo "=== iptables FORWARD table ===" iptables -L -v -n echo "=== iptables NAT table ===" iptables -t nat -L -v -n if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then echo "=== ip6tables FORWARD table ===" ip6tables -L -v -n echo "=== ip6tables NAT table ===" ip6tables -t nat -L -v -n fi } function clean_up() { disable_routing ruleNum=$(iptables -L PREROUTING -t nat --line-numbers | grep APPMESH_INGRESS | cut -d " " -f 1) iptables -t nat -D PREROUTING $ruleNum ruleNum=$(iptables -L OUTPUT -t nat --line-numbers | grep APPMESH_EGRESS | cut -d " " -f 1) iptables -t nat -D OUTPUT $ruleNum iptables -t nat -X APPMESH_INGRESS iptables -t nat -X APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ruleNum=$(ip6tables -L PREROUTING -t nat --line-numbers | grep APPMESH_INGRESS | cut -d " " -f 1) ip6tables -t nat -D PREROUTING $ruleNum ruleNum=$(ip6tables -L OUTPUT -t nat --line-numbers | grep APPMESH_EGRESS | cut -d " " -f 1) ip6tables -t nat -D OUTPUT $ruleNum ip6tables -t nat -X APPMESH_INGRESS ip6tables -t nat -X APPMESH_EGRESS fi } function main_loop() { echo "=== Entering main loop ===" while read -p '> ' cmd; do case "$cmd" in "quit") clean_up break ;; "status") dump_status ;; "enable") enable_routing ;; "disable") disable_routing ;; *) echo "Available commands: quit, status, enable, disable" ;; esac done } function print_config() { echo "=== Input configuration ===" env | grep APPMESH_ || true } print_config initialize if [ "$APPMESH_START_ENABLED" == "1" ]; then enable_routing fi main_loop-
アプリケーショントラフィックを Envoy プロキシにルーティングする
iptables
ルールを設定するには、前のステップで作成したスクリプトを実行します。sudo ./envoy-networking.sh
-
仮想ノードのアプリケーションコードを開始します。
注記
App Mesh のその他の例とチュートリアルについては、App Mesh サンプルリポジトリ