

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

# AWS App Mesh と Amazon EC2 の開始方法
<a name="getting-started-ec2"></a>

**重要**  
サポート終了通知: 2026 年 9 月 30 日、 AWS はサポートを終了します AWS App Mesh。2026 年 9 月 30 日以降、 AWS App Mesh コンソールまたは AWS App Mesh リソースにアクセスできなくなります。詳細については、このブログ記事[「 から Amazon ECS Service Connect AWS App Mesh への移行](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)」を参照してください。

このトピックは、Amazon EC2 で実行されている実際のサービス AWS App Mesh で を使用するのに役立ちます。このチュートリアルでは、複数の App Mesh リソースタイプのベーシックな機能について説明します。

## シナリオ
<a name="scenario"></a>

App Mesh の使用方法を説明するために、次の特性を持つアプリケーションがあると仮定します。
+ `serviceA` および `serviceB` という名前の 2 つのサービスで構成されています。
+ どちらのサービスも、`apps.local` という名前の名前空間にメンバー登録されます。
+ `ServiceA` は、HTTP/2、ポート 80 を介して `serviceB` と通信します。
+  すでに `serviceB` のバージョン 2 をデプロイし、`serviceBv2` 名前空間に `apps.local` という名前でメンバー登録しました。

次の要件があります。
+ からのトラフィックの 75% を `serviceA` に送信`serviceB`し、トラフィックの 25% を`serviceBv2`最初に に送信します。に 25% のみを送信することで`serviceBv2`、 からトラフィックの 100% を送信する前に、バグがないことを検証できます`serviceA`。
+ トラフィックの重み付けを簡単に調整して、信頼性が証明されたら、トラフィックの 100% が `serviceBv2` へ転送されるようにします。すべてのトラフィックが `serviceBv2` に送信されたら、`serviceB` を切断します。
+ 上記の要件を満たすために、実際のサービスの既存のアプリケーションコードまたはサービスディスカバリ登録を変更する必要はありません。

要件を満たすために、仮想サービス、仮想ノード、仮想ルーター、およびルートで、App Mesh サービスメッシュを作成することにします。メッシュを実装した後、サービスを更新して、Envoy プロキシを使用します。更新されると、サービスは相互に直接ではなく、Envoy プロキシを介して相互に通信します。

## 前提条件
<a name="prerequisites"></a>

App Mesh は、DNS に登録されている Linux サービス AWS Cloud Map、またはその両方をサポートしています。この「開始方法」を使用するには、DNS に既存のサービスを 3 つメンバー登録しておくようお勧めします。サービスが存在しない場合でもサービスメッシュとそのリソースを作成できますが、実際のサービスをデプロイするまでメッシュを使用することはできません。

サービスをまだ実行していない場合は、Amazon EC2 インスタンスの起動をして、それらにアプリケーションをデプロイできます。詳細については、[Amazon EC2 ユーザーガイド」の「チュートリアル: Amazon EC2 Linux インスタンスの開始方法](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html)」を参照してください。 Amazon EC2 残りのステップでは、実際のサービスが `serviceA`、`serviceB`、`serviceBv2` という名前で、すべてのサービスが `apps.local` という名前の名前空間を介して検出可能であることを前提としています。

## ステップ 1: メッシュと仮想サービスを作成する
<a name="create-mesh-and-virtual-service"></a>

サービスメッシュは、サービス間のネットワークトラフィックの論理的な境界であり、サービスはその中に存在します。詳細については、「[サービスメッシュ](meshes.md)」を参照してください。仮想サービスは、実際のサービスを抽象化したものです。詳細については、「[仮想サービス](virtual_services.md)」を参照してください。

次の リソースを作成します。
+ シナリオ内のすべてのサービスが `apps` 名前空間にメンバー登録されているため、`apps.local` という名前のメッシュ。
+ `serviceb.apps.local` という名前の仮想サービス。仮想サービスは、その名前で検出可能なサービスを表しているため、別の名前をリファレンスするようにコードを変更したくないためです。`servicea.apps.local` という名前の仮想サービスが、次のステップで追加されます。

 AWS マネジメントコンソール またはバージョン 1.18.116 AWS CLI 以降、または 2.0.38 以降を使用して、次のステップを完了できます。を使用する場合は AWS CLI、 `aws --version` コマンドを使用してインストールされている AWS CLI バージョンを確認します。バージョン 1.18.116 以降、または 2.0.38 以降をインストールしていない場合は、[AWS CLIをインストールまたは更新](https://docs.aws.amazon.com/cli/latest/reference/appmesh/cli-chap-install.html)する必要があります。使用するツールのタブを選択します。

------
#### [ AWS マネジメントコンソール ]

1. App Mesh コンソールの初回実行ウィザードを [https://console.aws.amazon.com/appmesh/get-started](https://console.aws.amazon.com/appmesh/get-started) で開きます。

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

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

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

------
#### [ AWS CLI ]

1. `[create-mesh](https://docs.aws.amazon.com/cli/latest/reference/appmesh/create-mesh.html)` コマンドを使用してメッシュを作成します。

   ```
   aws appmesh create-mesh --mesh-name apps
   ```

1. `[create-virtual-service](https://docs.aws.amazon.com/cli/latest/reference/appmesh/create-virtual-service.html)` コマンドを使用して仮想サービスを作成します。

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

------

## ステップ 2: 仮想ノードを作成する
<a name="create-virtual-node"></a>

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

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

------
#### [ AWS マネジメントコンソール ]

1. **[仮想ノード名]** に **serviceB** と入力します。

1. **[サービスディスカバリ]** で、**[DNS]** を選択し、**[DNS ホスト名]** に **serviceb.apps.local** と入力します。

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

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

------
#### [ 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"
   }
   ```

1. JSON ファイルを入力として使用して、[create-virtual-node](https://docs.aws.amazon.com/cli/latest/reference/appmesh/create-virtual-node.html) コマンドで仮想ノードを作成します。

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

------

## ステップ 3: 仮想ルーターとルートを作成する
<a name="create-virtual-router-and-route"></a>

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

次の リソースを作成します。
+ `serviceB` という名前の仮想ルーター。`serviceB.apps.local` 仮想サービスは、他のサービスとのアウトバウンド通信を開始しないためです。前に作成した仮想サービスは、実際の `serviceb.apps.local` サービスの抽象化であることに注意してください。仮想サービスは、仮想ルーターにトラフィックを送信します。仮想ルーターは、ポート 80 で HTTP/2 プロトコルを使用してトラフィックをリッスンします。その他のプロトコルもサポートされています。
+ `serviceB` という名前のルート。このルートはトラフィックの 100% を `serviceB` 仮想ノードにルーティングします。重み付けは、`serviceBv2` 仮想ノードを追加した後のステップで行います。このガイドでは説明しませんが、ルートにフィルタ条件を追加したり、通信の問題が発生したときに Envoy プロキシが仮想ノードへのトラフィックの送信を複数回試行する再試行ポリシーを追加したりできます。

------
#### [ AWS マネジメントコンソール ]

1. **[仮想ルーター名]** に **serviceB** と入力します。

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

1. **[ルート名]** に **serviceB** と入力します。

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

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

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

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

------
#### [ AWS CLI ]

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

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

      ```
      {
          "meshName": "apps",
          "spec": {
              "listeners": [
                  {
                      "portMapping": {
                          "port": 80,
                          "protocol": "http2"
                      }
                  }
              ]
          },
          "virtualRouterName": "serviceB"
      }
      ```

   1. JSON ファイルを入力として使用し、[create-virtual-router](https://docs.aws.amazon.com/cli/latest/reference/appmesh/create-virtual-router.html) コマンドで仮想ルーターを作成します。

      ```
      aws appmesh create-virtual-router --cli-input-json file://create-virtual-router.json
      ```

1. ルートを作成します。

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

      ```
      {
          "meshName" : "apps",
          "routeName" : "serviceB",
          "spec" : {
              "httpRoute" : {
                  "action" : {
                      "weightedTargets" : [
                          {
                              "virtualNode" : "serviceB",
                              "weight" : 100
                          }
                      ]
                  },
                  "match" : {
                      "prefix" : "/"
                  }
              }
          },
          "virtualRouterName" : "serviceB"
      }
      ```

   1. JSON ファイルを入力として使用し、[create-route](https://docs.aws.amazon.com/cli/latest/reference/appmesh/create-route.html) コマンドでルートを作成します。

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

------

## ステップ 4: 確認して作成する
<a name="review-create"></a>

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

------
#### [ AWS マネジメントコンソール ]

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

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

------
#### [ AWS CLI ]

[describe-mesh](https://docs.aws.amazon.com/cli/latest/reference/appmesh/describe-mesh.html) コマンドで作成したメッシュの設定を確認します。

```
aws appmesh describe-mesh --mesh-name apps
```

[describe-virtual-service](https://docs.aws.amazon.com/cli/latest/reference/appmesh/describe-virtual-service.html) コマンドで作成した仮想サービスの設定を確認します。

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

[describe-virtual-node](https://docs.aws.amazon.com/cli/latest/reference/appmesh/describe-virtual-node.html) コマンドで作成した仮想ノードの設定を確認します。

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

[describe-virtual-router](https://docs.aws.amazon.com/cli/latest/reference/appmesh/describe-virtual-router.html) コマンドで作成した仮想ルーターの設定を確認します。

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

[describe-route](https://docs.aws.amazon.com/cli/latest/reference/appmesh/describe-route.html) コマンドで作成したルートの設定を確認します。

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

------

## ステップ 5: 追加のリソースを作成する
<a name="create-additional-resources"></a>

このシナリオを完了するには、次のことを行う必要があります。
+ `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 マネジメントコンソール ]

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

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

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

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

1. **[仮想ノード名]** に **serviceBv2** と入力し、**[サービスディスカバリ]** で **[DNS]** を選択して、**[DNS ホスト名]** に **servicebv2.apps.local** と入力します。

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

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

1. **[仮想ノードの作成]** をもう一度選択します。**[仮想ノード名]** に **serviceA** と入力してください。**[サービスディスカバリ]** で **[DNS]** を選択し、**[DNS ホスト名]** に **servicea.apps.local** と入力します。

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

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

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

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

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

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

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

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

1. **[仮想サービス名]** に **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"
      }
      ```

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

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

1. `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"
      }
      ```

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

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

1. 前のステップで作成した `serviceb.apps.local` 仮想サービスを更新して、そのトラフィックを `serviceB` 仮想ルーターに送信します。仮想サービスが最初に作成された時点では、`serviceB` 仮想ルーターがまだ作成されていないため、トラフィックはどこにも送信されませんでした。

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

      ```
      {
         "meshName" : "apps",
         "spec" : {
            "provider" : {
               "virtualRouter" : {
                  "virtualRouterName" : "serviceB"
               }
            }
         },
         "virtualServiceName" : "serviceb.apps.local"
      }
      ```

   1. [update-virtual-service](https://docs.aws.amazon.com/cli/latest/reference/appmesh/update-virtual-service.html) コマンドを使用して、仮想サービスを更新します。

      ```
      aws appmesh update-virtual-service --cli-input-json file://update-virtual-service.json
      ```

1. 前のステップで作成した `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"
      }
      ```

   1. [update-route](https://docs.aws.amazon.com/cli/latest/reference/appmesh/update-route.html) コマンドを使用してルートを更新します。

      ```
      aws appmesh update-route --cli-input-json file://update-route.json
      ```

1. `serviceA` 仮想サービスを作成します。

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

      ```
      {
         "meshName" : "apps",
         "spec" : {
            "provider" : {
               "virtualNode" : {
                  "virtualNodeName" : "serviceA"
               }
            }
         },
         "virtualServiceName" : "servicea.apps.local"
      }
      ```

   1. 仮想サービスを作成します。

      ```
      aws appmesh create-virtual-service --cli-input-json file://create-virtual-servicea.json
      ```

------

**メッシュの概要**  
サービスメッシュを作成する前に、`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: サービスを更新する
<a name="update-services"></a>

メッシュを作成したら、次のタスクを完了する必要があります。
+ 各サービスでデプロイする Envoy プロキシに、1つ以上の仮想ノードの設定を読み取りすることを許可します。プロキシを承認する方法の詳細については、[Envoy プロキシの認可](proxy-authorization.md) を参照してください。
+ 既存のサービスを更新するには、次のステップを実行します。

**Amazon EC2 インスタンスを仮想ノードメンバーとして設定するには**

1. IAM ロールを作成します。

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

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ```

------

   1. 次のコマンドを使用して IAM ロールを作成します。

      ```
      aws iam create-role --role-name mesh-virtual-node-service-b --assume-role-policy-document file://ec2-trust-relationship.json
      ```

1. IAM ポリシーを、Amazon ECR からの読み取りと特定のApp Mesh 仮想ノードの設定のみを許可するロールに添付します。

   1. 次の内容の `virtual-node-policy.json` という名前のファイルを作成します。`apps` は [ステップ 1: メッシュと仮想サービスを作成する](#create-mesh-and-virtual-service) で作成したメッシュの名前で、`serviceB` は [ステップ 2: 仮想ノードを作成する](#create-virtual-node) で作成した仮想ノードの名前です。*111122223333* をアカウント ID に置き換え、*us-west-2* をメッシュを作成したリージョンに置き換えます。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "appmesh:StreamAggregatedResources",
                  "Resource": [
                      "arn:aws:appmesh:us-west-2:111122223333:mesh/apps/virtualNode/serviceB"
                  ]
              }
          ]
      }
      ```

------

   1. 次のコマンドを使用してポリシーを作成します。

      ```
      aws iam create-policy --policy-name virtual-node-policy --policy-document file://virtual-node-policy.json
      ```

   1. 前のステップで作成したポリシーをロールに添付して、ロールが AppMesh からの `serviceB` 仮想ノードの設定のみを読み取れるようにします。

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::111122223333:policy/virtual-node-policy --role-name mesh-virtual-node-service-b
      ```

   1. `AmazonEC2ContainerRegistryReadOnly` マネージドポリシーをロールに添付して、Amazon ECR から Envoy コンテナイメージをプルできるようにします。

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --role-name mesh-virtual-node-service-b
      ```

1. 作成した [IAM ロールを使用して Amazon EC2 インスタンスの起動](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role)を行います。

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

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

1. 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` を除く[サポートされているリージョン](https://docs.aws.amazon.com/general/latest/gr/appmesh.html)に置き換えることができます。

     ```
     $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
     ```

1. 次のいずれかのコマンドを実行して、イメージをプルするリージョンに応じて、インスタンスで 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` リージョンを除く、[サポートされている任意のリージョン](https://docs.aws.amazon.com/general/latest/gr/appmesh.html)に置き換えることができます。`1337` は、`0` と `2147483647` の間の任意の値に置き換えることができます。

     ```
     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.34.13.0-prod
     ```
   + `me-south-1` リージョン `1337` は、`0` と `2147483647` の間の任意の値に置き換えることができます。

     ```
     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.34.13.0-prod
     ```
   + `ap-east-1` リージョン `1337` は、`0` と `2147483647` の間の任意の値に置き換えることができます。

     ```
     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.34.13.0-prod
     ```
**注記**  
`APPMESH_RESOURCE_ARN` プロパティは、バージョン `1.15.0` またはそれ以降のEnvoy イメージを必要とします 詳細については、「[Envoy イメージ](envoy.md)」を参照してください。
**重要**  
App Mesh での使用は、バージョン v1.9.0.0-prod 以降のみでサポートされています。

1. 次の `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
   ```

1. アプリケーショントラフィックを Envoy プロキシにルーティングする `iptables` ルールを設定するには、前のステップで作成したスクリプトを実行します。

   ```
   sudo ./envoy-networking.sh
   ```

1. 仮想ノードのアプリケーションコードを開始します。

**注記**  
App Mesh のその他の例とチュートリアルについては、[App Mesh サンプルリポジトリ](https://github.com/aws/aws-app-mesh-examples)を参照してください。