AWS App Mesh と Amazon の使用を開始する EC2 - AWS App Mesh

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

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/2 serviceBを超えるポート 80 と通信します。

  • すでに serviceB のバージョン 2 をデプロイし、serviceBv2 名前空間に apps.local という名前でメンバー登録しました。

次の要件があります。

  • トラフィックの 75% を serviceAserviceB、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残りのステップでは、実際のサービスが serviceAserviceBserviceBv2 という名前で、すべてのサービスが 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をインストールまたは更新する必要があります。使用するツールのタブを選択します。

AWS Management Console
  1. App Mesh コンソールの初回実行ウィザードをhttps://console.aws.amazon.com/appmesh/スタート時に開きます。

  2. [メッシュ名]apps と入力します。

  3. [仮想サービス名]serviceb.apps.local と入力します。

  4. 続行するには、[次へ] を選択します。

AWS CLI
  1. create-mesh コマンドを使用してメッシュを作成します。

    aws appmesh create-mesh --mesh-name apps
  2. create-virtual-service コマンドを使用して仮想サービスを作成します。

    aws appmesh create-virtual-service --mesh-name apps --virtual-service-name serviceb.apps.local --spec {}

ステップ 2: 仮想ノードを作成する

仮想ノードは、実際のサービスの論理ポインタとして機能します。詳細については、「仮想ノード」を参照してください。

仮想ノードの 1 つが serviceB という名前の実際のサービスを表すため、serviceB という名前の仮想ノードを作成します。仮想ノードが表す実際のサービスは、serviceb.apps.local というホスト名を持つ DNS を介して検出可能です。または、 AWS Cloud Mapを使用して実際のサービスを検出することもできます。仮想ノードは、ポート 80 の HTTP/2 プロトコルを使用してトラフィックをリッスンします。ヘルスチェックと同様に、その他のプロトコルもサポートされています。次のステップで、serviceA および serviceBv2 の仮想ノードを作成します。

AWS Management Console
  1. [仮想ノード名]serviceB と入力します。

  2. サービス検出メソッド では、 を選択しDNSDNSホスト名 serviceb.apps.localに を入力します。

  3. [リスナーの設定] で、[プロトコル][http2] を選択し、[ポート]80 と入力します。

  4. 続行するには、[次へ] を選択します。

AWS CLI
  1. 次の内容で、create-virtual-node-serviceb.json という名前のファイルを作成します。

    { "meshName": "apps", "spec": { "listeners": [ { "portMapping": { "port": 80, "protocol": "http2" } } ], "serviceDiscovery": { "dns": { "hostname": "serviceB.apps.local" } } }, "virtualNodeName": "serviceB" }
  2. JSON ファイルを入力として使用して、 create-virtual-node コマンドを使用して仮想ノードを作成します。

    aws appmesh create-virtual-node --cli-input-json file://create-virtual-node-serviceb.json

ステップ 3: 仮想ルーターとルートを作成する

仮想ルーターは、メッシュ内の 1 つ以上の仮想サービスのトラフィックを送信します。詳細については、「仮想ルーター」および「ルート」を参照してください。

次の リソースを作成します。

  • serviceB という名前の仮想ルーター。serviceB.apps.local 仮想サービスは、他のサービスとのアウトバウンド通信を開始しないためです。前に作成した仮想サービスは、実際の serviceb.apps.local サービスの抽象化であることに注意してください。仮想サービスは、仮想ルーターにトラフィックを送信します。仮想ルーターは、ポート 80 の HTTP/2 プロトコルを使用してトラフィックをリッスンします。その他のプロトコルもサポートされています。

  • serviceB という名前のルート。このルートはトラフィックの 100% を serviceB 仮想ノードにルーティングします。重み付けは、serviceBv2 仮想ノードを追加した後のステップで行います。このガイドでは説明しませんが、ルートにフィルタ条件を追加したり、通信の問題が発生したときに Envoy プロキシが仮想ノードへのトラフィックの送信を複数回試行する再試行ポリシーを追加したりできます。

AWS Management Console
  1. [仮想ルーター名]serviceB と入力します。

  2. [リスナーの設定] で、[プロトコル][http2] を選択して、[ポート]80 を指定します。

  3. [ルート名]serviceB と入力します。

  4. [ルートタイプ] で、[http2] を選択します。

  5. [ターゲット設定][仮想ノード名]で、[serviceB] を選択し、[重み]に 100 と入力します。

  6. [一致設定] で、[方法] を選択します。

  7. 続行するには、[次へ] を選択します。

AWS CLI
  1. 仮想ルーターを作成します。

    1. 次の内容で、create-virtual-router.json という名前のファイルを作成します。

      { "meshName": "apps", "spec": { "listeners": [ { "portMapping": { "port": 80, "protocol": "http2" } } ] }, "virtualRouterName": "serviceB" }
    2. JSON ファイルを入力として使用して、 create-virtual-router コマンドを使用して仮想ルーターを作成します。

      aws appmesh create-virtual-router --cli-input-json file://create-virtual-router.json
  2. ルートを作成します。

    1. 次の内容で、create-route.json という名前のファイルを作成します。

      { "meshName" : "apps", "routeName" : "serviceB", "spec" : { "httpRoute" : { "action" : { "weightedTargets" : [ { "virtualNode" : "serviceB", "weight" : 100 } ] }, "match" : { "prefix" : "/" } } }, "virtualRouterName" : "serviceB" }
    2. ファイルを入力JSONとして使用して create-route コマンドでルートを作成します。

      aws appmesh create-route --cli-input-json file://create-route.json

ステップ 4: 確認して作成する

前のステップと照らし合わせて設定を確認します。

AWS Management Console

いずれかのセクションに変更を加える必要がある場合は、[編集] を選択します。設定が完了したら、[メッシュの作成] を選択します。

[ステータス] 画面には、作成されたすべてのメッシュリソースが表示されます。作成したリソースをコンソールに表示するには、[メッシュの表示] を選択します。

AWS CLI

describe-mesh コマンドで作成したメッシュの設定を確認します。

aws appmesh describe-mesh --mesh-name apps

describe-virtual-service コマンドで作成した仮想サービスの設定を確認します。

aws appmesh describe-virtual-service --mesh-name apps --virtual-service-name serviceb.apps.local

describe-virtual-node コマンドで作成した仮想ノードの設定を確認します。

aws appmesh describe-virtual-node --mesh-name apps --virtual-node-name serviceB

describe-virtual-router コマンドで作成した仮想ルーターの設定を確認します。

aws appmesh describe-virtual-router --mesh-name apps --virtual-router-name serviceB

describe-route コマンドで作成したルートの設定を確認します。

aws appmesh describe-route --mesh-name apps \ --virtual-router-name serviceB --route-name serviceB

ステップ 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 仮想サービスは仮想ルーターにトラフィックを送信し、仮想ルーターはトラフィックを仮想ノードにルーティングすることに注意してください。仮想ノードのサービスディスカバリ名は、いつでも変更できます。

AWS Management Console
  1. 左のナビゲーションペインで [メッシュ] を選択します。

  2. 前のステップで作成した apps メッシュを選択します。

  3. 左側のナビゲーションペインで、[仮想ノード] を選択します。

  4. [仮想ノードの作成] を選択します。

  5. 仮想ノード名 には serviceBv2を入力し、サービス検出メソッド には を選択しDNSDNSホスト名 には を入力しますservicebv2.apps.local

  6. [リスナーの設定] で、[プロトコル][http2] を選択し、[ポート]80 を入力します。

  7. [仮想ノードの作成] を選択します。

  8. [仮想ノードの作成] をもう一度選択します。[仮想ノード名]serviceA と入力してください。サービス検出メソッド で を選択しDNSDNSホスト名 で と入力しますservicea.apps.local

  9. [新しいバックエンド] の下の [仮想サービス名の入力]serviceb.apps.local と入力します。

  10. [リスナーの設定] で、[プロトコル][http2] を選択し、[ポート]80 を入力して、[仮想ノードの作成] を選択します。

  11. 左側のナビゲーションペインで [仮想ルーター] を選択し、リストから [serviceB] 仮想ルーターを選択します。

  12. [ルート] で、前のステップで作成した ServiceB という名前のルートを選択し、[編集] を選択します。

  13. [ターゲット]仮想ノード名で、serviceB[重み] の値を 75 に変更します。

  14. [ターゲットの追加] を選択し、ドロップダウンリストから serviceBv2を選択して、[重み] の値を 25 に設定します。

  15. [保存] を選択します。

  16. 左側のナビゲーションペインで、[仮想サービス] を選択し、[仮想サービスの作成] を選択します。

  17. [仮想サービス名]servicea.apps.local と入力し、[プロバイダー][仮想ノード] を選択し、[仮想ノード]serviceA を選択し、[仮想サービスの作成]を選択します。

AWS CLI
  1. serviceBv2 仮想ノードを作成します。

    1. 次の内容で、create-virtual-node-servicebv2.json という名前のファイルを作成します。

      { "meshName": "apps", "spec": { "listeners": [ { "portMapping": { "port": 80, "protocol": "http2" } } ], "serviceDiscovery": { "dns": { "hostname": "serviceBv2.apps.local" } } }, "virtualNodeName": "serviceBv2" }
    2. 仮想ノードを作成します。

      aws appmesh create-virtual-node --cli-input-json file://create-virtual-node-servicebv2.json
  2. serviceA 仮想ノードを作成します。

    1. 次の内容で、create-virtual-node-servicea.json という名前のファイルを作成します。

      { "meshName" : "apps", "spec" : { "backends" : [ { "virtualService" : { "virtualServiceName" : "serviceb.apps.local" } } ], "listeners" : [ { "portMapping" : { "port" : 80, "protocol" : "http2" } } ], "serviceDiscovery" : { "dns" : { "hostname" : "servicea.apps.local" } } }, "virtualNodeName" : "serviceA" }
    2. 仮想ノードを作成します。

      aws appmesh create-virtual-node --cli-input-json file://create-virtual-node-servicea.json
  3. 前のステップで作成した serviceb.apps.local 仮想サービスを更新して、そのトラフィックを serviceB 仮想ルーターに送信します。仮想サービスが最初に作成された時点では、serviceB 仮想ルーターがまだ作成されていないため、トラフィックはどこにも送信されませんでした。

    1. 次の内容で、update-virtual-service.json という名前のファイルを作成します。

      { "meshName" : "apps", "spec" : { "provider" : { "virtualRouter" : { "virtualRouterName" : "serviceB" } } }, "virtualServiceName" : "serviceb.apps.local" }
    2. update-virtual-service コマンドを使用して仮想サービスを更新します。

      aws appmesh update-virtual-service --cli-input-json file://update-virtual-service.json
  4. 前のステップで作成した serviceB ルートを更新します。

    1. 次の内容で、update-route.json という名前のファイルを作成します。

      { "meshName" : "apps", "routeName" : "serviceB", "spec" : { "http2Route" : { "action" : { "weightedTargets" : [ { "virtualNode" : "serviceB", "weight" : 75 }, { "virtualNode" : "serviceBv2", "weight" : 25 } ] }, "match" : { "prefix" : "/" } } }, "virtualRouterName" : "serviceB" }
    2. update-route コマンドを使用してルートを更新します。

      aws appmesh update-route --cli-input-json file://update-route.json
  5. serviceA 仮想サービスを作成します。

    1. 次の内容で、create-virtual-servicea.json という名前のファイルを作成します。

      { "meshName" : "apps", "spec" : { "provider" : { "virtualNode" : { "virtualNodeName" : "serviceA" } } }, "virtualServiceName" : "servicea.apps.local" }
    2. 仮想サービスを作成します。

      aws appmesh create-virtual-service --cli-input-json file://create-virtual-servicea.json
メッシュの概要

サービスメッシュを作成する前に、servicea.apps.localserviceb.apps.local、および servicebv2.apps.local という 3 つの実際のサービスがありました。実際のサービスに加えて、実際のサービスを表す次のリソースを含むサービスメッシュが作成されました。

  • 2 つの仮想サービス。プロキシは、仮想ルーターを経由して、servicea.apps.local 仮想サービスからのすべてのトラフィックを serviceb.apps.local 仮想サービスに送信します。

  • serviceAserviceB、および serviceBv2 という名前の 3 つの仮想ノード。Envoy プロキシは、仮想ノードに対して設定されたサービスディスカバリ情報を使用して、実際のサービスの IP アドレスを検索します。

  • Envoy プロキシがインバウンドトラフィックの 75% を serviceB 仮想ノードに、25% を serviceBv2 仮想ノードにルーティングするように指定する 1 つのルートを持つ仮想ルーター。

ステップ 6: サービスを更新する

メッシュを作成したら、次のタスクを完了する必要があります。

  • 各サービスでデプロイする Envoy プロキシに、1つ以上の仮想ノードの設定を読み取りすることを許可します。プロキシを承認する方法の詳細については、Envoy プロキシの認可 を参照してください。

  • 既存のサービスを更新するには、次のステップを実行します。

Amazon EC2インスタンスを仮想ノードメンバーとして設定するには
  1. IAM ロールを作成します。

    1. 次の内容で、ec2-trust-relationship.json という名前のファイルを作成します。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
    2. 次のコマンドを使用してIAMロールを作成します。

      aws iam create-role --role-name mesh-virtual-node-service-b --assume-role-policy-document file://ec2-trust-relationship.json
  2. Amazon からの読み取りを許可するロールにIAMポリシーをアタッチECRし、特定の App Mesh 仮想ノードの設定のみを行います。

    1. 次の内容の 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" ] } ] }
    2. 次のコマンドを使用してポリシーを作成します。

      aws iam create-policy --policy-name virtual-node-policy --policy-document file://virtual-node-policy.json
    3. 前のステップで作成したポリシーをロールに添付して、ロールが AppMesh からの serviceB 仮想ノードの設定のみを読み取れるようにします。

      aws iam attach-role-policy --policy-arn arn:aws:iam::111122223333:policy/virtual-node-policy --role-name mesh-virtual-node-service-b
    4. AmazonEC2ContainerRegistryReadOnly マネージドポリシーをロールにアタッチして、Amazon から Envoy コンテナイメージをプルできるようにしますECR。

      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --role-name mesh-virtual-node-service-b
  3. 作成したIAMロールを使用して Amazon EC2インスタンスを起動します。

  4. 経由でインスタンスに接続しますSSH。

  5. オペレーティングシステムのドキュメントに従って、インスタンス AWS CLI に Docker と をインストールします。

  6. Docker クライアントがイメージをプルするリージョンの Envoy Amazon ECRリポジトリに認証します。

    • me-south-1ap-east-1ap-southeast-3eu-south-1il-central-1af-south-1 を除くすべてのリージョン。を置き換えることができます。us-west-2me-south-1ap-east-1ap-southeast-3eu-south-1il-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
  7. 次のいずれかのコマンドを実行して、イメージをプルするリージョンに応じて、インスタンスで App Mesh Envoy コンテナを起動します。- apps また、serviceB 値は、シナリオで定義されるメッシュノード名と仮想ノード名です。この情報は、App Mesh から読み取りする仮想ノード設定をプロキシに指示します。シナリオを完了するには、 serviceBv2serviceA仮想ノードで表されるサービスをホストする Amazon EC2インスタンスについても、これらのステップを完了する必要があります。独自のアプリケーションでは、これらの値を独自の値に置き換えます。

    • me-south-1ap-east-1ap-southeast-3eu-south-1il-central-1af-south-1 を除くすべてのリージョン。を置き換えることができます。Region-codeme-south-1ap-east-1、、、および リージョンを除くap-southeast-3eu-south-1il-central-1サポートされているすべての af-south-1 リージョン。1337 は、02147483647 の間の任意の値に置き換えることができます。

      sudo docker run --detach --env APPMESH_RESOURCE_ARN=mesh/apps/virtualNode/serviceB \ -u 1337 --network host 840364872350.dkr.ecr.region-code.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod
    • me-south-1 リージョン 1337 は、02147483647 の間の任意の値に置き換えることができます。

      sudo docker run --detach --env APPMESH_RESOURCE_ARN=mesh/apps/virtualNode/serviceB \ -u 1337 --network host 772975370895.dkr.ecr.me-south-1.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod
    • ap-east-1 リージョン 1337 は、02147483647 の間の任意の値に置き換えることができます。

      sudo docker run --detach --env APPMESH_RESOURCE_ARN=mesh/apps/virtualNode/serviceB \ -u 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 以降のみでサポートされています。

  8. 次の 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
  9. アプリケーショントラフィックを Envoy プロキシにルーティングする iptables ルールを設定するには、前のステップで作成したスクリプトを実行します。

    sudo ./envoy-networking.sh
  10. 仮想ノードのアプリケーションコードを開始します。

注記

App Mesh のその他の例とチュートリアルについては、App Mesh サンプルリポジトリを参照してください。