

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# App Mesh 入門
<a name="getting-started"></a>

**重要**  
支援終止通知：在 2026 年 9 月 30 日， AWS 將停止對 的支援 AWS App Mesh。2026 年 9 月 30 日之後，您將無法再存取 AWS App Mesh 主控台或 AWS App Mesh 資源。如需詳細資訊，請參閱此部落格文章[從 遷移 AWS App Mesh 至 Amazon ECS Service Connect](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)。

您可以將 App Mesh 與部署到 Amazon ECS、Kubernetes （部署到自己的 Amazon EC2 執行個體或在 Amazon EKS 上執行的應用程式） 和 Amazon EC2 搭配使用。若要開始使用 App Mesh，請選取您要搭配 App Mesh 使用之應用程式部署到其中的其中一項服務。在完成其中一個入門指南後，您可以隨時啟用其他服務中的應用程式，以使用 App Mesh。

**Topics**
+ [AWS App Mesh 和 Amazon ECS 入門](getting-started-ecs.md)
+ [AWS App Mesh 和 Kubernetes 入門](getting-started-kubernetes.md)
+ [AWS App Mesh 和 Amazon EC2 入門](getting-started-ec2.md)
+ [App Mesh 範例](examples.md)

# AWS App Mesh 和 Amazon ECS 入門
<a name="getting-started-ecs"></a>

**重要**  
支援終止通知：在 2026 年 9 月 30 日， AWS 將停止對 的支援 AWS App Mesh。2026 年 9 月 30 日之後，您將無法再存取 AWS App Mesh 主控台或 AWS App Mesh 資源。如需詳細資訊，請參閱此部落格文章[從 遷移 AWS App Mesh 至 Amazon ECS Service Connect](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)。

本主題可協助您將 AWS App Mesh 與在 Amazon ECS 上執行的實際服務搭配使用。本教學課程涵蓋數種 App Mesh 資源類型的基本功能。

## 案例
<a name="scenario"></a>

若要說明如何使用 App Mesh，請假設您擁有具有下列特性的應用程式：
+ 包含兩個名為 `serviceA`和 的服務`serviceB`。
+ 這兩個服務都註冊到名稱為 `apps.local` 的命名空間。
+ `ServiceA` 與 `serviceB` 透過 HTTP/2，連接埠 80 進行通訊。
+  您已部署 `serviceB` 第 2 版，並在 `apps.local` 命名空間中將其註冊為名稱 `serviceBv2`。

您有以下要求：
+ 您想要將 75% 的流量從 `serviceA` 傳送到 ，`serviceB`並將 25% 的流量傳送到 `serviceBv2` 。透過僅將 25% 傳送到 `serviceBv2`，您可以在從 傳送 100% 的流量之前驗證其是否沒有錯誤`serviceA`。
+ 您希望能夠輕鬆地調整流量權重，以便證實流量可靠之後，能夠 100% 流入 `serviceBv2`。將所有流量傳送到 後`serviceBv2`，您想要停止 `serviceB`。
+ 您不想變更實際服務的任何現有應用程式碼或服務探索註冊，以符合先前的要求。

為了滿足您的需求，您決定建立具有虛擬服務、虛擬節點、虛擬路由器和路由的 App Mesh 服務網格。實作網格後，您會更新您的服務以使用 Envoy 代理。一旦更新，您的服務會透過 Envoy 代理彼此通訊，而非直接相互通訊。

## 先決條件
<a name="prerequisites"></a>

**重要**  
支援終止通知：在 2026 年 9 月 30 日， AWS 將停止對 的支援 AWS App Mesh。2026 年 9 月 30 日之後，您將無法再存取 AWS App Mesh 主控台或 AWS App Mesh 資源。如需詳細資訊，請參閱此部落格文章[從 遷移 AWS App Mesh 至 Amazon ECS Service Connect](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)。
+ 對 App Mesh 概念的現有了解。如需詳細資訊，請參閱[什麼是 AWS App Mesh？](what-is-app-mesh.md)。
+ 對 Amazon ECSs概念的現有理解。如需詳細資訊，請參閱《[Amazon Elastic Container Service 開發人員指南》中的什麼是 Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html)。
+ App Mesh 支援向 DNS AWS Cloud Map或兩者註冊的 Linux 服務。若要使用此入門指南，建議您擁有三個已向 DNS 註冊的現有服務。本主題中的程序假設現有服務名為 `serviceA`、 和 `serviceB`，`serviceBv2`並且所有服務都可以透過名為 的命名空間探索`apps.local`。

  即使服務不存在，您也可以建立服務網格及其資源，但在部署實際服務之前，您無法使用網格。如需 Amazon ECS 上服務探索的詳細資訊，請參閱[服務探索](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html)。若要使用服務探索建立 Amazon ECS 服務，請參閱[教學課程：使用服務探索建立服務](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-service-discovery.html)。如果您還沒有執行中的服務，則可以[使用服務探索建立 Amazon ECS 服務](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-service-discovery.html)。

## 步驟 1：建立網格和虛擬服務
<a name="create-mesh-and-virtual-service2"></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. 在 https：//[https://console.aws.amazon.com/appmesh/get-started](https://console.aws.amazon.com/appmesh/get-started) 開啟 App Mesh 主控台初次執行精靈。

1. 對於 **Mesh name (網格名稱)**，輸入 **apps**。

1. 對於 **Virtual service name (虛擬服務名稱)**，輸入 **serviceb.apps.local**。

1. 若要繼續，請選擇 **Next (下一步)**。

------
#### [ 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-node2"></a>

虛擬節點可做為實際服務的邏輯指標。如需詳細資訊，請參閱[虛擬節點](virtual_nodes.md)。

建立名稱為 `serviceB` 的虛擬節點，因為其中一個虛擬節點代表名稱為 `serviceB` 的實際服務。虛擬節點代表的實際服務可透過 `DNS` (主機名稱為 `serviceb.apps.local`) 探索。或者，您可以使用 探索實際的服務 AWS Cloud Map。虛擬節點將會在連接埠 80 上使用 HTTP/2 通訊協定來接聽流量。也支援其他通訊協定，以及運作狀態檢查。您將在稍後的步驟中為 `serviceA` 和 `serviceBv2` 建立虛擬節點。

------
#### [ AWS 管理主控台 ]

1. 對於 **Virtual node name (虛擬節點名稱)**，輸入 **serviceB**。

1. 針對**服務探索方法**，選擇 **DNS**，然後輸入 **serviceb.apps.local** **DNS 主機名稱**。

1. 在**接聽程式組態**下，為**通訊協定**選擇 **http2**，並為**連接埠**輸入 **80** 。

1. 若要繼續，請選擇 **Next (下一步)**。

------
#### [ 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>

虛擬路由器會路由網格內一或多個虛擬服務的流量。如需詳細資訊，請參閱[虛擬路由器](virtual_routers.md)及[路由](routes.md)。

建立下列資源：
+ 名為 `serviceB` 的虛擬路由器，因為 `serviceB.apps.local` 虛擬服務不會啟動與任何其他服務的對外通訊。請記住，您先前建立的虛擬服務是實際 `serviceb.apps.local` 服務的抽象。虛擬服務會將流量傳送至虛擬路由器。虛擬路由器會使用連接埠 80 上的 HTTP/2 通訊協定接聽流量。也支援其他通訊協定。
+ 名為 `serviceB` 的路由。它將 100% 的流量路由到`serviceB`虛擬節點。新增`serviceBv2`虛擬節點後，權重會進入後續步驟。雖然未涵蓋在本指南中，但您可以為路由新增其他篩選條件，並新增重試政策，使 Envoy 代理在遇到通訊問題時多次嘗試將流量傳送至虛擬節點。

------
#### [ AWS 管理主控台 ]

1. 對於 **Virtual router name (虛擬路由器名稱)**，輸入 **serviceB**。

1. 在**接聽程式組態**下，為**通訊協定**選擇 **http2**，並為**連接埠**指定 **80** 。

1. 對於 **Route name (路由名稱)**，輸入 **serviceB**。

1. 對於 **Route type (路由類型)**，選擇 **http2**。

1. 針對**目標組態**下的**虛擬節點名稱**，選取 `serviceB`並輸入 **100**表示**權重**。

1. 在**相符組態**下，選擇**方法**。

1. 若要繼續，請選擇 **Next (下一步)**。

------
#### [ 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 管理主控台 ]

如果您需要在任何區段中進行變更，請選擇 **Edit (編輯)**。對這些設定感到滿意後，請選擇 **Create mesh (建立網格)**。

**Status (狀態)** 畫面會顯示所有已建立的網格資源。選取 **View mesh (檢視網格)** 即可在主控台中檢視建立的資源。

------
#### [ 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`，將所有流量直接傳送至`serviceA`虛擬節點。
+ 更新您在上一個步驟中建立的 `serviceB` 路由，將 75% 的流量傳送到 `serviceB` 虛擬節點，以及 25% 的流量傳送到 `serviceBv2` 虛擬節點。隨著時間的推移，您可以繼續修改權重，直到 `serviceBv2` 收到 100% 的流量為止。將所有流量傳送到 後`serviceBv2`，您可以關閉並停止`serviceB`虛擬節點和實際服務。當您更改權重時，您的程式碼不需要任何修改，因為 `serviceb.apps.local` 虛擬和實際服務名稱不會變更。記住，`serviceb.apps.local` 虛擬服務會將流量傳送至虛擬路由器，接著虛擬路由器會將流量路由至虛擬節點。虛擬節點的服務探索名稱可以隨時變更。

------
#### [ AWS 管理主控台 ]

1. 在左側導覽窗格中，選取 **Meshes (網格)**。

1. 選取您在上一個步驟中建立的 `apps` 網格。

1. 在左側導覽窗格中，選取 **Virtual nodes (虛擬節點)**。

1. 選擇 **Create virtual node (建立虛擬節點)**。

1. 對於 **Virtual node name (虛擬節點名稱)** 輸入 **serviceBv2**、對於 **Service discovery method (服務探索方法)** 選擇 **DNS**，然後對於 **DNS hostname (DNS 主機名稱)** 輸入 **servicebv2.apps.local**。

1. 針對**接聽程式組態**，選取**通訊協定**的 **http2**，然後**80**針對**連接埠**輸入 。

1. 選擇 **Create virtual node (建立虛擬節點)**。

1. 再次選擇 **Create virtual node (建立虛擬節點)**。輸入 **serviceA** 做為**虛擬節點名稱**。對於 **Service discovery method (服務探索方法)**，選擇 **DNS**，並針對 **DNS hostname (DNS 主機名稱)** 輸入 **servicea.apps.local**。

1. 在**新增後端**下**輸入虛擬服務名稱**，輸入 **serviceb.apps.local**。

1. 在**接聽程式組態**下，針對**通訊協定**選擇 **http2**，**80**針對**連接埠**輸入 ，然後選擇**建立虛擬節點**。

1. 在左側導覽窗格中，選取 **Virtual routers (虛擬路由器)**，然後從清單中選取 `serviceB` 虛擬路由器。

1. 在 **Routes (路由)** 下方，選取您在上一個步驟中建立的路由 (名為 `ServiceB`)，然後選擇 **Edit (編輯)**。

1. 在**目標**、**虛擬節點名稱**下，將 的**權重**值`serviceB`變更為 **75**。

1. 選擇**新增目標**，`serviceBv2`從下拉式清單中選擇，並將**權重**的值設定為 **25**。

1. 選擇**儲存**。

1. 在左側瀏覽窗格中，選取 **Virtual services (虛擬服務)**，然後選擇 **Create virtual service (建立虛擬服務)**。

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` 的實際服務。除了實際服務以外，您目前擁有包含代表實際服務之下列資源的服務網格：
+ 兩個虛擬服務。代理會透過虛擬路由器將 `servicea.apps.local` 虛擬服務的所有流量傳送至 `serviceb.apps.local` 虛擬服務。
+ 名稱為 `serviceA`、`serviceB` 和 `serviceBv2` 的三個虛擬節點。Envoy 代理會使用針對虛擬節點設定的服務探索資訊，來查詢實際服務的 IP 地址。
+ 具有單一路由的虛擬路由器，其指示 Envoy 代理將 75% 的傳入流量路由到 `serviceB` 虛擬節點，將 25% 的流量路由到 `serviceBv2` 虛擬節點。

## 步驟 6：更新服務
<a name="update-services"></a>

在建立網格之後，您需要完成下列任務：
+ 授權您使用每個 Amazon ECS 任務部署的 Envoy 代理程式，以讀取一或多個虛擬節點的組態。如需如何授權代理的詳細資訊，請參閱[代理授權](https://docs.aws.amazon.com/app-mesh/latest/userguide/proxy-authorization.html)。
+ 更新每個現有的 Amazon ECS 任務定義，以使用 Envoy 代理。

**憑證**  
Envoy 容器需要 AWS Identity and Access Management 登入資料，才能簽署傳送到 App Mesh 服務的請求。對於使用 Amazon EC2 啟動類型部署的 Amazon ECS 任務，憑證可以來自[執行個體角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html)或[任務 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)。在 Linux 容器上使用 Fargate 部署的 Amazon ECS 任務無法存取提供執行個體 IAM 設定檔憑證的 Amazon EC2 中繼資料伺服器。若要提供登入資料，您必須將 IAM 任務角色連接至使用 Fargate on Linux 容器類型部署的任何任務。

如果使用 Amazon EC2 啟動類型部署任務，且 Amazon EC2 中繼資料伺服器的存取遭到封鎖，如[任務 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)中*的重要*註釋中所述，則任務 IAM 角色也必須連接至任務。您指派給執行個體或任務的角色必須連接 IAM 政策，如 [Proxy 授權](https://docs.aws.amazon.com/app-mesh/latest/userguide/proxy-authorization.html)中所述。



**使用 更新您的任務定義 AWS CLI**  
您可以使用 Amazon ECS AWS CLI 命令 [https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html](https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html)。以下任務定義範例說明如何為您的服務設定 App Mesh。

**注意**  
透過主控台設定 Amazon ECS 的 App Mesh 無法使用。

### 任務定義 json
<a name="getting-started-ecs-json"></a>

**代理組態**  
若要將 Amazon ECS 服務設定為使用 App Mesh，您服務的任務定義必須具有下列代理組態區段。將代理組態 `type` 設為 `APPMESH`，將 `containerName` 設為 `envoy`。相應地設定下列屬性值。

`IgnoredUID`  
對於使用此使用者 ID 的程序，Envoy 代理不會路由來自這些程序的流量。您可以為此屬性值選擇您想要的任何使用者 ID，但此 ID 必須與任務定義中 Envoy 容器的 `user` ID 相同。這配對可讓 Envoy 忽略自己的流量，而不使用代理。我們的範例是基於歷史用途使用 `1337`。

`ProxyIngressPort`  
這是 Envoy 代理容器的傳入連接埠。將此值設為 `15000`。

`ProxyEgressPort`  
這是 Envoy 代理容器的傳出連接埠。將此值設為 `15001`。

`AppPorts`  
指定應用程式容器接聽的任何傳入連接埠。在這個範例中，應用程式容器會接聽連接埠 `9080`。您指定的連接埠必須符合在虛擬節點接聽程式上設定的連接埠。

`EgressIgnoredIPs`  
Envoy 不會代理將流量送往這些 IP 地址。將此值設定為 `169.254.170.2,169.254.169.254`，這會忽略 Amazon EC2 中繼資料伺服器和 Amazon ECS 任務中繼資料端點。中繼資料端點提供任務登入資料的 IAM 角色。您可以新增其他地址。

`EgressIgnoredPorts`  
您可以新增以逗號分隔的連接埠清單。Envoy 不會代理將流量送往這些連接埠。即使您沒有列出連接埠，連接埠 22 也會被忽略。  
可忽略的傳出連接埠數目上限為 15。

```
"proxyConfiguration": {
	"type": "APPMESH",
	"containerName": "envoy",
	"properties": [{
			"name": "IgnoredUID",
			"value": "1337"
		},
		{
			"name": "ProxyIngressPort",
			"value": "15000"
		},
		{
			"name": "ProxyEgressPort",
			"value": "15001"
		},
		{
			"name": "AppPorts",
			"value": "9080"
		},
		{
			"name": "EgressIgnoredIPs",
			"value": "169.254.170.2,169.254.169.254"
		},
		{
			"name": "EgressIgnoredPorts",
			"value": "22"
		}
	]
}
```

**應用程式容器 Envoy 相依性**  
任務定義中的應用程式容器必須等待 Envoy 代理引導並啟動之後才能啟動。為了確保發生這種情況，您可以在每個應用程式容器定義中設定一個`dependsOn`區段，以等待 Envoy 容器報告為 `HEALTHY`。以下程式碼顯示具有此相依性的應用程式容器定義範例。以下範例中的所有屬性都是必要的。某些屬性值也是必要的，但有些是*可取代的*。

```
{
	"name": "appName",
	"image": "appImage",
	"portMappings": [{
		"containerPort": 9080,
		"hostPort": 9080,
		"protocol": "tcp"
	}],
	"essential": true,
	"dependsOn": [{
		"containerName": "envoy",
		"condition": "HEALTHY"
	}]
}
```

**Envoy 容器定義**

您的 Amazon ECS 任務定義必須包含 App Mesh Envoy 容器映像。

所有[支援](https://docs.aws.amazon.com/general/latest/gr/appmesh.html)的區域都可以將*區域碼*取代為 `me-south-1`、`ap-east-1`、`ap-southeast-3`、`eu-south-1`、 `il-central-1`和 以外的任何區域`af-south-1`。  
標準  

```
840364872350.dkr.ecr.region-code.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```
符合 FIPS 規範  

```
840364872350.dkr.ecr.region-code.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod-fips
```

`me-south-1`  
標準  

```
772975370895.dkr.ecr.me-south-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```

`ap-east-1`  
標準  

```
856666278305.dkr.ecr.ap-east-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```

`ap-southeast-3`  
標準  

```
909464085924.dkr.ecr.ap-southeast-3.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```

`eu-south-1`  
標準  

```
422531588944.dkr.ecr.eu-south-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```

`il-central-1`  
標準  

```
564877687649.dkr.ecr.il-central-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```

`af-south-1`  
標準  

```
924023996002.dkr.ecr.af-south-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
```

`Public repository`  
標準  

```
public.ecr.aws/appmesh/aws-appmesh-envoy:v1.34.13.0-prod
```
符合 FIPS 規範  

```
public.ecr.aws/appmesh/aws-appmesh-envoy:v1.34.13.0-prod-fips
```

**重要**  
只有 v1.9.0.0 版或更新版本支援與 App Mesh 搭配使用。

您必須使用 App Mesh Envoy 容器映像，直到 Envoy 專案團隊合併支援 App Mesh 的變更。如需其他詳細資訊，請參閱 [GitHub 藍圖問題](https://github.com/aws/aws-app-mesh-roadmap/issues/10)。

以下範例中的所有屬性都是必要的。某些屬性值也是必要的，但有些是*可取代的*。

**注意**  
Envoy 容器定義必須標示為 `essential`。
我們建議將 `512` CPU 單位和至少 `64` MiB 的記憶體配置到 Envoy 容器。在 Fargate 上，您可以設定的最低記憶體為 `1024` MiB。
Amazon ECS 服務的虛擬節點名稱必須設定為 `APPMESH_RESOURCE_ARN` 屬性的值。此屬性需要版本 `1.15.0`或更新版本的 Envoy 映像。如需詳細資訊，請參閱[Envoy 影像](envoy.md)。
`user` 設定的值必須與任務定義代理組態中的 `IgnoredUID` 值相符。在此範例中，我們使用 `1337`.
此處顯示的運作狀態檢查會等待 Envoy 容器正確引導，然後再向 Amazon ECS 報告 Envoy 容器運作狀態良好，並準備好啟動應用程式容器。
根據預設，當 Envoy 在指標和追蹤方面參照本身時，App Mesh 會使用您在 `APPMESH_RESOURCE_ARN` 中指定的資源名稱。您可以藉由使用自己的名稱設定 `APPMESH_RESOURCE_CLUSTER` 環境變數，以覆寫此行為。此屬性需要版本 `1.15.0`或更新版本的 Envoy 映像。如需詳細資訊，請參閱[Envoy 影像](envoy.md)。

下列程式碼顯示 Envoy 容器定義範例。

```
{
	"name": "envoy",
	"image": "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod",
	"essential": true,
	"environment": [{
		"name": "APPMESH_RESOURCE_ARN",
		"value": "arn:aws:appmesh:us-west-2:111122223333:mesh/apps/virtualNode/serviceB"
	}],
	"healthCheck": {
		"command": [
			"CMD-SHELL",
			"curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
		],
		"startPeriod": 10,
		"interval": 5,
		"timeout": 2,
		"retries": 3
	},
	"user": "1337"
}
```

**任務定義範例**  
下列範例 Amazon ECS 任務定義示範如何將上述範例合併為 的任務定義`taskB`。提供使用 或不使用 為這兩種 Amazon ECS 啟動類型建立任務的範例 AWS X-Ray。視需要變更*可取代*值，以從案例中建立名為 `taskBv2` 和 `taskA` 的任務定義。以您的網格名稱和虛擬節點名稱代替 `APPMESH_RESOURCE_ARN` 值，以您的應用程式監聽的連接埠清單代替代理組態 `AppPorts` 值。根據預設，當 Envoy 在指標和追蹤方面參照本身時，App Mesh 會使用您在 `APPMESH_RESOURCE_ARN` 中指定的資源名稱。您可以藉由使用自己的名稱設定 `APPMESH_RESOURCE_CLUSTER` 環境變數，以覆寫此行為。下列範例中的所有屬性都是必要的。某些屬性值也是必要的，但有些是*可取代的*。

如果您依照登入資料章節所述執行 Amazon ECS 任務，則需要將現有的[任務 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)新增至範例。

**重要**  
Fargate 必須使用大於 1024 的連接埠值。

**Example Amazon ECS 任務定義的 JSON - Linux 容器上的 Fargate**  

```
{
   
   "family" : "taskB",
   "memory" : "1024",
   "cpu" : "0.5 vCPU",
   "proxyConfiguration" : {
      "containerName" : "envoy",
      "properties" : [
         {
            "name" : "ProxyIngressPort",
            "value" : "15000"
         },
         {
            "name" : "AppPorts",
            "value" : "9080"
         },
         {
            "name" : "EgressIgnoredIPs",
            "value" : "169.254.170.2,169.254.169.254"
         },
         {
            "name": "EgressIgnoredPorts",
            "value": "22"
         },
         {
            "name" : "IgnoredUID",
            "value" : "1337"
         },
         {
            "name" : "ProxyEgressPort",
            "value" : "15001"
         }
      ],
      "type" : "APPMESH"
   },
   "containerDefinitions" : [
      {
         "name" : "appName",
         "image" : "appImage",
         "portMappings" : [
            {
               "containerPort" : 9080,
               "protocol" : "tcp"
            }
         ],
         "essential" : true,
         "dependsOn" : [
            {
               "containerName" : "envoy",
               "condition" : "HEALTHY"
            }
         ]
      },
      {         
         "name" : "envoy",
         "image" : "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod",
         "essential" : true,
         "environment" : [
            {
               "name" : "APPMESH_VIRTUAL_NODE_NAME",
               "value" : "mesh/apps/virtualNode/serviceB"
            }
         ],
         "healthCheck" : {
            "command" : [
               "CMD-SHELL",
               "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
            ],
            "interval" : 5,
            "retries" : 3,
            "startPeriod" : 10,
            "timeout" : 2
         },
         "memory" : 500,
         "user" : "1337"
      }
   ],
   "requiresCompatibilities" : [ "FARGATE" ],
   "taskRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskRole",
   "executionRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
   "networkMode" : "awsvpc"
}
```

**Example JSON for Amazon ECS 任務定義 AWS X-Ray - Linux 容器上的 Fargate**  
X-Ray 可讓您收集應用程式提供的請求相關資料，並提供可用來視覺化流量的工具。使用適用於 Envoy 的 X-Ray 驅動程式可讓 Envoy 向 X-Ray 報告追蹤資訊。您可以使用 [Envoy 組態](https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html)啟用 X-Ray 追蹤。根據組態，Envoy 會將追蹤資料傳送至做為[附屬](https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon-ecs.html)容器執行的 X-Ray 協助程式，而協助程式會將追蹤轉送至 X-Ray 服務。一旦追蹤發佈到 X-Ray，您可以使用 X-Ray 主控台來視覺化服務呼叫圖表並請求追蹤詳細資訊。下列 JSON 代表啟用 X-Ray 整合的任務定義。  

```
{
   
   
   "family" : "taskB",
   "memory" : "1024",
   "cpu" : "512",
   "proxyConfiguration" : {
      "containerName" : "envoy",
      "properties" : [
         {
            "name" : "ProxyIngressPort",
            "value" : "15000"
         },
         {
            "name" : "AppPorts",
            "value" : "9080"
         },
         {
            "name" : "EgressIgnoredIPs",
            "value" : "169.254.170.2,169.254.169.254"
         },
         {
            "name": "EgressIgnoredPorts",
            "value": "22"
         },
         {
            "name" : "IgnoredUID",
            "value" : "1337"
         },
         {
            "name" : "ProxyEgressPort",
            "value" : "15001"
         }
      ],
      "type" : "APPMESH"
   },
   "containerDefinitions" : [
      {
         "name" : "appName",
         "image" : "appImage",
         "portMappings" : [
            {
               "containerPort" : 9080,
               "protocol" : "tcp"
            }
         ],
         "essential" : true,
         "dependsOn" : [
            {
               "containerName" : "envoy",
               "condition" : "HEALTHY"
            }
         ]
      },
      {
         
         "name" : "envoy",
         "image" : "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod",
         "essential" : true,
         "environment" : [
            {
               "name" : "APPMESH_VIRTUAL_NODE_NAME",
               "value" : "mesh/apps/virtualNode/serviceB"
            },
            {
               "name": "ENABLE_ENVOY_XRAY_TRACING",
               "value": "1"
            }
         ],
         "healthCheck" : {
            "command" : [
               "CMD-SHELL",
               "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
            ],
            "interval" : 5,
            "retries" : 3,
            "startPeriod" : 10,
            "timeout" : 2
         },
         "memory" : 500,
         "user" : "1337"
      },
      {
         "name" : "xray-daemon",
         "image" : "amazon/aws-xray-daemon",
         "user" : "1337",
         "essential" : true,
         "cpu" : "32",
         "memoryReservation" : "256",
         "portMappings" : [
            {
               "containerPort" : 2000,
               "protocol" : "udp"
            }
         ]
      }
   ],
   "requiresCompatibilities" : [ "FARGATE" ],
   "taskRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskRole",
   "executionRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
   "networkMode" : "awsvpc"
}
```

**Example Amazon ECS 任務定義的 JSON - EC2 啟動類型**  

```
{
  "family": "taskB",
  "memory": "256",
  "proxyConfiguration": {
    "type": "APPMESH",
    "containerName": "envoy",
    "properties": [
      {
        "name": "IgnoredUID",
        "value": "1337"
      },
      {
        "name": "ProxyIngressPort",
        "value": "15000"
      },
      {
        "name": "ProxyEgressPort",
        "value": "15001"
      },
      {
        "name": "AppPorts",
        "value": "9080"
      },
      {
        "name": "EgressIgnoredIPs",
        "value": "169.254.170.2,169.254.169.254"
      },
      {
        "name": "EgressIgnoredPorts",
        "value": "22"
      }
    ]
  },
  "containerDefinitions": [
    {
      "name": "appName",
      "image": "appImage",
      "portMappings": [
        {
          "containerPort": 9080,
          "hostPort": 9080,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "dependsOn": [
        {
          "containerName": "envoy",
          "condition": "HEALTHY"
        }
      ]
    },
    {
      "name": "envoy",
      "image": "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod",
      "essential": true,
      "environment": [
        {
          "name": "APPMESH_VIRTUAL_NODE_NAME",
          "value": "mesh/apps/virtualNode/serviceB"
        }
      ],
      "healthCheck": {
        "command": [
          "CMD-SHELL",
          "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
        ],
        "startPeriod": 10,
        "interval": 5,
        "timeout": 2,
        "retries": 3
      },
      "user": "1337"
    }
  ],
  "requiresCompatibilities" : [ "EC2" ],
  "taskRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskRole",
  "executionRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc"
}
```

**Example JSON for Amazon ECS 任務定義搭配 AWS X-Ray EC2 啟動類型**  

```
{
  "family": "taskB",
  "memory": "256",
   "cpu" : "1024",
  "proxyConfiguration": {
    "type": "APPMESH",
    "containerName": "envoy",
    "properties": [
      {
        "name": "IgnoredUID",
        "value": "1337"
      },
      {
        "name": "ProxyIngressPort",
        "value": "15000"
      },
      {
        "name": "ProxyEgressPort",
        "value": "15001"
      },
      {
        "name": "AppPorts",
        "value": "9080"
      },
      {
        "name": "EgressIgnoredIPs",
        "value": "169.254.170.2,169.254.169.254"
      },
      {
        "name": "EgressIgnoredPorts",
        "value": "22"
      }
    ]
  },
  "containerDefinitions": [
    {
      "name": "appName",
      "image": "appImage",
      "portMappings": [
        {
          "containerPort": 9080,
          "hostPort": 9080,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "dependsOn": [
        {
          "containerName": "envoy",
          "condition": "HEALTHY"
        }
      ]
    },
    {
      "name": "envoy",
      "image": "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod",
      "essential": true,
      "environment": [
        {
          "name": "APPMESH_VIRTUAL_NODE_NAME",
          "value": "mesh/apps/virtualNode/serviceB"
        },
        {
         "name": "ENABLE_ENVOY_XRAY_TRACING",
         "value": "1"
        }
      ],
      "healthCheck": {
        "command": [
          "CMD-SHELL",
          "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
        ],
        "startPeriod": 10,
        "interval": 5,
        "timeout": 2,
        "retries": 3
      },
      "user": "1337"
    },
    {
      "name": "xray-daemon",
      "image": "amazon/aws-xray-daemon",
      "user": "1337",
      "essential": true,
      "cpu": 32,
      "memoryReservation": 256,
      "portMappings": [
        {
          "containerPort": 2000,
          "protocol": "udp"
        }
      ]
    }
  ],
  "requiresCompatibilities" : [ "EC2" ],
  "taskRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskRole",
  "executionRoleArn" : "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc"
}
```

## 進階主題
<a name="advanced-topics-ecs"></a>

### 使用 App Mesh 的 Canary 部署
<a name="canary-appmesh-ecs"></a>

Canary 部署和版本可協助您在舊版本的應用程式與新部署的版本之間切換流量。它也會監控新部署版本的運作狀態。如果新版本有任何問題，Canary 部署可以自動將流量切換回舊版本。Canary 部署可讓您使用更多控制在應用程式版本之間切換流量。

如需如何使用 App Mesh 為 Amazon ECS 實作 Canary 部署的詳細資訊，請參閱[使用 App Mesh 為 Amazon ECS 建立具有 Canary 部署的管道](https://aws.amazon.com/blogs/containers/create-a-pipeline-with-canary-deployments-for-amazon-ecs-using-aws-app-mesh/)

**注意**  
如需 App Mesh 的更多範例和逐步解說，請參閱 [App Mesh 範例儲存庫](https://github.com/aws/aws-app-mesh-examples)。

# AWS App Mesh 和 Kubernetes 入門
<a name="getting-started-kubernetes"></a>

**重要**  
支援終止通知：在 2026 年 9 月 30 日， AWS 將停止對 的支援 AWS App Mesh。2026 年 9 月 30 日之後，您將無法再存取 AWS App Mesh 主控台或 AWS App Mesh 資源。如需詳細資訊，請參閱此部落格文章[從 遷移 AWS App Mesh 至 Amazon ECS Service Connect](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)。

當您使用適用於 Kubernetes 的 App Mesh 控制器 AWS App Mesh 與 Kubernetes 整合時，您可以管理 App Mesh 資源，例如網格、虛擬服務、虛擬節點、虛擬路由器，以及透過 Kubernetes 的路由。您也可以自動將 App Mesh 附屬容器映像新增至 Kubernetes Pod 規格。本教學課程會逐步引導您安裝適用於 Kubernetes 的 App Mesh 控制器，以啟用此整合。

控制器隨附下列 Kubernetes 自訂資源定義的部署：`meshes`、`virtual services`、`virtual nodes` 和 `virtual routers`。控制器會監控自訂資源的建立、修改和刪除，並透過 App Mesh API 變更對應的 App Mesh [服務網格](meshes.md)、[虛擬服務](virtual_services.md)[虛擬節點](virtual_nodes.md)[虛擬閘道](virtual_gateways.md)[閘道路由](gateway-routes.md)、、 [虛擬路由器](virtual_routers.md)（包括 [路由](routes.md)) 資源。若要進一步了解或為控制器提供貢獻，請參閱 [GitHub 專案](https://github.com/aws/aws-app-mesh-controller-for-k8s)。

控制器也會安裝 webhook，將下列容器注入到標示為您指定名稱的 Kubernetes Pod 中。
+ **App Mesh Envoy 代理** – Envoy 使用 App Mesh 控制平面中定義的組態來判斷傳送應用程式流量的位置。
+ **App Mesh 代理路由管理器 **– 更新 Pod 網路命名空間中的`iptables`規則，以透過 Envoy 路由傳入和傳出流量。此容器會在 Pod 內以 Kubernetes 初始化容器執行。

## 先決條件
<a name="mesh-k8s-integration-prerequisites"></a>
+ 對 App Mesh 概念的現有了解。如需詳細資訊，請參閱[什麼是 AWS App Mesh？](what-is-app-mesh.md)。
+ Kubernetes 概念的現有理解。如需詳細資訊，請參閱 [Kubernetes 文件中的什麼是](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/) Kubernetes。
+ 現有 Kubernetes 叢集。如果您沒有現有的叢集，請參閱《[Amazon EKS 使用者指南](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)*》中的 Amazon EKS *入門。如果您在 Amazon EC2 上執行自己的 Kubernetes 叢集，請確保 Docker 已向 Envoy 映像所在的 Amazon ECR 儲存庫進行身分驗證。如需詳細資訊，請參閱《Amazon Elastic Container Registry 使用者指南》中的 [Envoy 映像](https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html)、[登錄檔身分驗證](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html#registry_auth)，以及《Kubernetes 文件》中的[從私有登錄檔提取映像](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)。
+ App Mesh 支援向 DNS AWS Cloud Map或兩者註冊的 Linux 服務。若要使用此入門指南，建議您擁有三個已向 DNS 註冊的現有服務。本主題中的程序假設現有服務名為 `serviceA`、 和 `serviceB`，`serviceBv2`並且所有服務都可以透過名為 的命名空間探索`apps.local`。

  即使服務不存在，您也可以建立服務網格及其資源，但在部署實際服務之前，您無法使用網格。
+  AWS CLI 已安裝 1.18.116 版或更新版本，或 2.0.38 版或更新版本。若要安裝或升級 AWS CLI，請參閱[安裝 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)。
+ 已設定為與您的 Kubernetes 叢集通訊的 `kubectl` 用戶端。如果您使用的是 Amazon Elastic Kubernetes Service，您可以使用安裝`[kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html)`和設定`[kubeconfig](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html)`檔案的指示。
+ 已安裝 Helm 3.0 版或更新版本。如果您尚未安裝 Helm，請參閱《[Amazon EKS 使用者指南》中的搭配使用 Helm 與](https://docs.aws.amazon.com/eks/latest/userguide/helm.html) *Amazon EKS*。
+ Amazon EKS 目前僅支援 `IPv4_ONLY`和 `IPv6_ONLY` IP 偏好設定，因為 Amazon EKS 目前僅支援能夠僅提供`IPv4`流量或僅提供`IPv6`流量的 Pod。

其餘步驟假設實際服務名稱為 `serviceA`、`serviceB` 和 `serviceBv2`，而且所有服務皆可透過名稱為 `apps.local` 的命名空間探索。

## 步驟 1：安裝整合元件
<a name="install-controller"></a>

將整合元件安裝到託管您要與 App Mesh 搭配使用之 Pod 的每個叢集中一次。

**安裝整合元件**

1. 此程序的其餘步驟需有已安裝預先發行版本控制器的叢集。如果您已安裝發行前版本，或不確定您是否擁有 ，您可以下載並執行指令碼，檢查叢集上是否已安裝發行前版本。

   ```
   curl -o pre_upgrade_check.sh https://raw.githubusercontent.com/aws/eks-charts/master/stable/appmesh-controller/upgrade/pre_upgrade_check.sh
   sh ./pre_upgrade_check.sh
   ```

   如果指令碼傳回 `Your cluster is ready for upgrade. Please proceed to the installation instructions`，您可以繼續進行下個步驟。如果傳回不同的訊息，則您必須先完成升級步驟，才能繼續進行。如需升級發行前版本的詳細資訊，請參閱在 GitHub 上的 [Upgrade (升級)](https://github.com/aws/eks-charts/blob/master/stable/appmesh-controller/README.md#upgrade)。

1. 將 `eks-charts` 儲存庫新增到 Helm。

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

1. 安裝 App Mesh Kubernetes 自訂資源定義 (CRD)。

   ```
   kubectl apply -k "https://github.com/aws/eks-charts/stable/appmesh-controller/crds?ref=master"
   ```

1. 為控制器建立 Kubernetes 命名空間。

   ```
   kubectl create ns appmesh-system
   ```

1. 設定下列變數，以便在稍後步驟中使用。以現有叢集的數值取代 `cluster-name` 和 `Region-code`。

   ```
   export CLUSTER_NAME=cluster-name
   export AWS_REGION=Region-code
   ```

1. (選用) 如果您要在 Fargate 上執行控制器，則必須建立 Fargate 設定檔。如果您尚未`eksctl`安裝 ，請參閱《*Amazon EKS 使用者指南*》中的[安裝或升級`eksctl`](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl)。如果您想要使用主控台建立設定檔，請參閱《*Amazon EKS 使用者指南*》中的[建立 Fargate 設定檔](https://docs.aws.amazon.com/eks/latest/userguide/fargate-profile.html#create-fargate-profile)。

   ```
   eksctl create fargateprofile --cluster $CLUSTER_NAME --name appmesh-system --namespace appmesh-system
   ```

1. 為您的叢集建立 OpenID Connect (OIDC) 身分識別提供者。如果您尚未`eksctl`安裝 ，您可以使用《*Amazon EKS 使用者指南*》中的[安裝或升級`eksctl`](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl)說明進行安裝。如果您想要使用主控台建立提供者，請參閱《*Amazon EKS 使用者指南*》中的[為叢集上的服務帳戶啟用 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)。

   ```
   eksctl utils associate-iam-oidc-provider \
       --region=$AWS_REGION \
       --cluster $CLUSTER_NAME \
       --approve
   ```

1. 建立 IAM 角色，將 [https://console.aws.amazon.com/iam/home?#policies/arn:aws:iam::aws:policy/AWSAppMeshFullAccess$jsonEditor](https://console.aws.amazon.com/iam/home?#policies/arn:aws:iam::aws:policy/AWSAppMeshFullAccess$jsonEditor)和 [https://console.aws.amazon.com/iam/home?#policies/arn:aws:iam::aws:policy/AWSCloudMapFullAccess$jsonEditor](https://console.aws.amazon.com/iam/home?#policies/arn:aws:iam::aws:policy/AWSCloudMapFullAccess$jsonEditor) AWS 受管政策連接至該角色，並將其繫結至 Kubernetes `appmesh-controller` 服務帳戶。該角色可讓控制器新增、移除和變更 App Mesh 資源。
**注意**  
命令會建立具有自動產生名稱的 AWS IAM 角色。您無法指定所建立的 IAM 角色名稱。

   ```
   eksctl create iamserviceaccount \
       --cluster $CLUSTER_NAME \
       --namespace appmesh-system \
       --name appmesh-controller \
       --attach-policy-arn  arn:aws:iam::aws:policy/AWSCloudMapFullAccess,arn:aws:iam::aws:policy/AWSAppMeshFullAccess \
       --override-existing-serviceaccounts \
       --approve
   ```

   如果您想要使用 AWS 管理主控台 或 建立服務帳戶 AWS CLI，請參閱《*Amazon EKS 使用者指南*》中的[為您的服務帳戶建立 IAM 角色和政策](https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html#create-service-account-iam-role)。如果您使用 AWS 管理主控台 或 AWS CLI 來建立帳戶，您也需要將角色對應至 Kubernetes 服務帳戶。如需詳細資訊，請參閱《*Amazon EKS 使用者指南*》中的[為您的服務帳戶指定 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html)。

1. 

**部署 App Mesh 控制器。如需所有組態選項的清單，請參閱 GitHub 上的[組態](https://github.com/aws/eks-charts/blob/master/stable/appmesh-controller/README.md#configuration) 。**

   1. 若要部署私有叢集的 App Mesh 控制器，您必須先將 App Mesh 和服務探索 Amazon VPC 端點啟用至連結的私有子網路。您也需要設定 `accountId`。

      ```
      --set accountId=$AWS_ACCOUNT_ID
      ```

      若要在私有叢集中啟用 X-Ray 追蹤，請啟用 X-Ray 和 Amazon ECR Amazon VPC 端點。根據`public.ecr.aws/xray/aws-xray-daemon:latest`預設，控制器會使用 ，因此請將此映像提取至本機，並將其[推送至您的個人 ECR 儲存庫](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html)。
**注意**  
[Amazon VPC 端點](https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html)目前不支援 Amazon ECR 公有儲存庫。

      下列範例顯示使用 X-Ray 組態部署控制器。

      ```
      helm upgrade -i appmesh-controller eks/appmesh-controller \
          --namespace appmesh-system \
          --set region=$AWS_REGION \
          --set serviceAccount.create=false \
          --set serviceAccount.name=appmesh-controller \
          --set accountId=$AWS_ACCOUNT_ID \
          --set log.level=debug \
          --set tracing.enabled=true \
          --set tracing.provider=x-ray \
          --set xray.image.repository=your-account-id.dkr.ecr.your-region.amazonaws.com/your-repository \
          --set xray.image.tag=your-xray-daemon-image-tag
      ```

      使用虛擬節點或閘道繫結應用程式部署時，請確認 X-Ray 協助程式是否已成功注入。

      如需詳細資訊，請參閱《*Amazon EKS 使用者指南*[》中的私有叢集](https://docs.aws.amazon.com/eks/latest/userguide/private-clusters.html)。

   1. 部署其他叢集的 App Mesh 控制器。如需所有組態選項的清單，請參閱 GitHub 上的[組態](https://github.com/aws/eks-charts/blob/master/stable/appmesh-controller/README.md#configuration) 。

      ```
      helm upgrade -i appmesh-controller eks/appmesh-controller \
          --namespace appmesh-system \
          --set region=$AWS_REGION \
          --set serviceAccount.create=false \
          --set serviceAccount.name=appmesh-controller
      ```
**注意**  
如果您的 Amazon EKS 叢集系列是 `IPv6`，請在部署 App Mesh 控制器時將下列選項新增至先前的命令 ，以設定叢集名稱`--set clusterName=$CLUSTER_NAME`。
**重要**  
如果您的叢集位於 `me-south-1`、`ap-east-1`、`il-central-1`、、 `ap-southeast-3` `eu-south-1`或 `af-south-1`區域，則需要將下列選項新增至先前的命令：  
將 *account-id* 和 *region-code* 取代為一組適當的值。  

       ```
        --set image.repository=account-id.dkr.ecr.Region-code.amazonaws.com/amazon/appmesh-controller
       ```
772975370895.dkr.ecr.me-south-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
856666278305.dkr.ecr.ap-east-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
909464085924.dkr.ecr.ap-southeast-3.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
422531588944.dkr.ecr.eu-south-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
564877687649.dkr.ecr.il-central-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
924023996002.dkr.ecr.af-south-1.amazonaws.com/aws-appmesh-envoy:v1.34.13.0-prod
您可以在 GitHub 的變更[日誌](https://github.com/aws/aws-app-mesh-controller-for-k8s/releases)中找到較舊的影像 URIs。版本 中影像所在的 AWS 帳戶已變更`v1.5.0`。舊版映像託管在 AWS Amazon Elastic Kubernetes Service [Amazon 容器映像登錄檔](https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html)中找到的帳戶上。

       ```
       --set sidecar.image.repository=account-id.dkr.ecr.Region-code.amazonaws.com/aws-appmesh-envoy
       ```
772975370895.dkr.ecr.me-south-1.amazonaws.com/amazon/appmesh-controller:v1.13.1
856666278305.dkr.ecr.ap-east-1.amazonaws.com/amazon/appmesh-controller:v1.13.1
909464085924.dkr.ecr.ap-southeast-3.amazonaws.com/amazon/appmesh-controller:v1.13.1
422531588944.dkr.ecr.eu-south-1.amazonaws.com/amazon/appmesh-controller:v1.13.1
564877687649.dkr.ecr.il-central-1.amazonaws.com/amazon/appmesh-controller:v1.13.1
924023996002.dkr.ecr.af-south-1.amazonaws.com/amazon/appmesh-controller:v1.13.1

       ```
       --set sidecar.image.repository=account-id.dkr.ecr.Region-code.amazonaws.com/aws-appmesh-envoy
       ```
772975370895.dkr.ecr.me-south-1.amazonaws.com/aws-appmesh-proxy-route-manager:v7-prod
856666278305.dkr.ecr.ap-east-1.amazonaws.com/aws-appmesh-proxy-route-manager:v7-prod
909464085924.dkr.ecr.ap-southeast-3.amazonaws.com/aws-appmesh-proxy-route-manager:v7-prod
422531588944.dkr.ecr.eu-south-1.amazonaws.com/aws-appmesh-proxy-route-manager:v7-prod
564877687649.dkr.ecr.il-central-1.amazonaws.com/aws-appmesh-proxy-route-manager:v7-prod
924023996002.dkr.ecr.af-south-1.amazonaws.com/aws-appmesh-proxy-route-manager:v7-prod
**重要**  
只有 v1.9.0.0 版或更新版本支援與 App Mesh 搭配使用。

1. 確認控制器版本為 `v1.4.0` 或更新版本。您可以在 GitHub 上查看 [change log (變更日誌)](https://github.com/aws/aws-app-mesh-controller-for-k8s/releases)。

   ```
   kubectl get deployment appmesh-controller \
       -n appmesh-system \
       -o json  | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'
   ```
**注意**  
如果您檢視執行中容器的日誌，您應該會看到一行文字，其中包含下列文字，而您可以放心忽略此內容。  

   ```
   Neither -kubeconfig nor -master was specified. Using the inClusterConfig. This might not work.
   ```

## 步驟 2：部署 App Mesh 資源
<a name="configure-app-mesh"></a>

在 Kubernetes 中部署應用程式時，您也可以建立 Kubernetes 自訂資源，讓控制器可以建立對應的 App Mesh 資源。下列程序可協助您部署 App Mesh 資源及其部分功能。您可以在 GitHub 上 App Mesh 演練中列出的許多功能資料夾的`v1beta2`子資料夾中，找到部署其他 App Mesh 資源功能的範例資訊清單。 [https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs)

**重要**  
控制器建立 App Mesh 資源後，建議您只使用控制器變更或刪除 App Mesh 資源。如果您使用 App Mesh 變更或刪除資源，控制器預設不會在十小時內變更或重新建立變更或刪除的 App Mesh 資源。您可以將此持續時間設定為較短。如需詳細資訊，請參閱 GitHub 上的 [Configuration (組態)](https://github.com/aws/eks-charts/blob/master/stable/appmesh-controller/README.md#configuration)。

**部署 App Mesh 資源**

1. 建立 Kubernetes 命名空間以部署 App Mesh 資源。

   1. 將下列內容儲存到電腦上名為 `namespace.yaml` 的檔案中。

      ```
      apiVersion: v1
      kind: Namespace
      metadata:
        name: my-apps
        labels:
          mesh: my-mesh
          appmesh.k8s.aws/sidecarInjectorWebhook: enabled
      ```

   1. 建立命名空間。

      ```
      kubectl apply -f namespace.yaml
      ```

1. 建立 App Mesh 服務網格。

   1. 將下列內容儲存到電腦上名為 `mesh.yaml` 的檔案中。檔案用於建立名為 的網格資源`my-mesh`。服務網格是在它之內各服務之間網路流量的邏輯邊界。

      ```
      apiVersion: appmesh.k8s.aws/v1beta2
      kind: Mesh
      metadata:
        name: my-mesh
      spec:
        namespaceSelector:
          matchLabels:
            mesh: my-mesh
      ```

   1. 建立網格。

      ```
      kubectl apply -f mesh.yaml
      ```

   1. 檢視已建立 Kubernetes 網格資源的詳細資料。

      ```
      kubectl describe mesh my-mesh
      ```

      Output

      ```
      Name:         my-mesh
      Namespace:
      Labels:       <none>
      Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"Mesh","metadata":{"annotations":{},"name":"my-mesh"},"spec":{"namespaceSelector":{"matchLa...
      API Version:  appmesh.k8s.aws/v1beta2
      Kind:         Mesh
      Metadata:
        Creation Timestamp:  2020-06-17T14:51:37Z
        Finalizers:
          finalizers.appmesh.k8s.aws/mesh-members
          finalizers.appmesh.k8s.aws/aws-appmesh-resources
        Generation:        1
        Resource Version:  6295
        Self Link:         /apis/appmesh.k8s.aws/v1beta2/meshes/my-mesh
        UID:               111a11b1-c11d-1e1f-gh1i-j11k1l111m711
      Spec:
        Aws Name:  my-mesh
        Namespace Selector:
          Match Labels:
            Mesh:  my-mesh
      Status:
        Conditions:
          Last Transition Time:  2020-06-17T14:51:37Z
          Status:                True
          Type:                  MeshActive
        Mesh ARN:                arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh
        Observed Generation:     1
      Events:                    <none>
      ```

   1. 檢視控制器建立之 App Mesh 服務網格的詳細資訊。

      ```
      aws appmesh describe-mesh --mesh-name my-mesh
      ```

      Output

      ```
      {
          "mesh": {
              "meshName": "my-mesh",
              "metadata": {
                  "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh",
                  "createdAt": "2020-06-17T09:51:37.920000-05:00",
                  "lastUpdatedAt": "2020-06-17T09:51:37.920000-05:00",
                  "meshOwner": "111122223333",
                  "resourceOwner": "111122223333",
                  "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711",
                  "version": 1
              },
              "spec": {},
              "status": {
                  "status": "ACTIVE"
              }
          }
      }
      ```

1. 建立 App Mesh 虛擬節點。虛擬節點會充當 Kubernetes 部署的邏輯指標。

   1. 將下列內容儲存到電腦上名為 `virtual-node.yaml` 的檔案中。檔案用於在 *`my-apps`* 命名空間`my-service-a`中建立名為 的 App Mesh 虛擬節點。該虛擬節點代表在稍後的步驟中建立的 Kubernetes 服務。`hostname` 的值是此虛擬節點所代表之實際服務的完整 DNS 主機名稱。

      ```
      apiVersion: appmesh.k8s.aws/v1beta2
      kind: VirtualNode
      metadata:
        name: my-service-a
        namespace: my-apps
      spec:
        podSelector:
          matchLabels:
            app: my-app-1
        listeners:
          - portMapping:
              port: 80
              protocol: http
        serviceDiscovery:
          dns:
            hostname: my-service-a.my-apps.svc.cluster.local
      ```

      虛擬節點具有本教學未涵蓋的功能，例如端對端加密和運作狀態檢查。如需詳細資訊，請參閱[虛擬節點](virtual_nodes.md)。若要查看您可以為上述規格中的虛擬節點設定的所有可用設定，請執行下列命令。

      ```
      aws appmesh create-virtual-node --generate-cli-skeleton yaml-input
      ```

   1. 部署虛擬節點。

      ```
      kubectl apply -f virtual-node.yaml
      ```

   1. 檢視所建立之 Kubernetes 虛擬節點資源的詳細資料。

      ```
      kubectl describe virtualnode my-service-a -n my-apps
      ```

      Output

      ```
      Name:         my-service-a
      Namespace:    my-apps
      Labels:       <none>
      Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"VirtualNode","metadata":{"annotations":{},"name":"my-service-a","namespace":"my-apps"},"s...
      API Version:  appmesh.k8s.aws/v1beta2
      Kind:         VirtualNode
      Metadata:
        Creation Timestamp:  2020-06-17T14:57:29Z
        Finalizers:
          finalizers.appmesh.k8s.aws/aws-appmesh-resources
        Generation:        2
        Resource Version:  22545
        Self Link:         /apis/appmesh.k8s.aws/v1beta2/namespaces/my-apps/virtualnodes/my-service-a
        UID:               111a11b1-c11d-1e1f-gh1i-j11k1l111m711
      Spec:
        Aws Name:  my-service-a_my-apps
        Listeners:
          Port Mapping:
            Port:      80
            Protocol:  http
        Mesh Ref:
          Name:  my-mesh
          UID:   111a11b1-c11d-1e1f-gh1i-j11k1l111m711
        Pod Selector:
          Match Labels:
            App:  nginx
        Service Discovery:
          Dns:
            Hostname:  my-service-a.my-apps.svc.cluster.local
      Status:
        Conditions:
          Last Transition Time:  2020-06-17T14:57:29Z
          Status:                True
          Type:                  VirtualNodeActive
        Observed Generation:     2
        Virtual Node ARN:        arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps
      Events:                    <none>
      ```

   1. 檢視控制器在 App Mesh 中建立之虛擬節點的詳細資訊。
**注意**  
即使在 Kubernetes 中建立的虛擬節點名稱是 `my-service-a`，但在 App Mesh 中建立的虛擬節點名稱為 `my-service-a_my-apps`。控制器會在建立 App Mesh 資源時，將 Kubernetes 命名空間名稱附加至 App Mesh 虛擬節點名稱。命名空間名稱會新增，因為在 Kubernetes 中，您可以在不同的命名空間中建立具有相同名稱的虛擬節點，但在 App Mesh 中，虛擬節點名稱在網格中必須是唯一的。

      ```
      aws appmesh describe-virtual-node --mesh-name my-mesh --virtual-node-name my-service-a_my-apps
      ```

      Output

      ```
      {
          "virtualNode": {
              "meshName": "my-mesh",
              "metadata": {
                  "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps",
                  "createdAt": "2020-06-17T09:57:29.840000-05:00",
                  "lastUpdatedAt": "2020-06-17T09:57:29.840000-05:00",
                  "meshOwner": "111122223333",
                  "resourceOwner": "111122223333",
                  "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711",
                  "version": 1
              },
              "spec": {
                  "backends": [],
                  "listeners": [
                      {
                          "portMapping": {
                              "port": 80,
                              "protocol": "http"
                          }
                      }
                  ],
                  "serviceDiscovery": {
                      "dns": {
                          "hostname": "my-service-a.my-apps.svc.cluster.local"
                      }
                  }
              },
              "status": {
                  "status": "ACTIVE"
              },
              "virtualNodeName": "my-service-a_my-apps"
          }
      }
      ```

1. 建立 App Mesh 虛擬路由器。虛擬路由器會處理網格內一或多個虛擬服務的流量。

   1. 將下列內容儲存到電腦上名為 `virtual-router.yaml` 的檔案中。檔案用於建立虛擬路由器，將流量路由到上一個步驟中建立且名為 `my-service-a` 的虛擬節點。控制器會建立 App Mesh 虛擬路由器和路由資源。您可以為路由指定更多功能，並使用除 `http` 以外的通訊協定。如需詳細資訊，請參閱[虛擬路由器](virtual_routers.md)及[路由](routes.md)。請注意，參考的虛擬節點名稱是 Kubernetes 虛擬節點名稱，而不是控制器在 App Mesh 中建立的 App Mesh 虛擬節點名稱。

      ```
      apiVersion: appmesh.k8s.aws/v1beta2
      kind: VirtualRouter
      metadata:
        namespace: my-apps
        name: my-service-a-virtual-router
      spec:
        listeners:
          - portMapping:
              port: 80
              protocol: http
        routes:
          - name: my-service-a-route
            httpRoute:
              match:
                prefix: /
              action:
                weightedTargets:
                  - virtualNodeRef:
                      name: my-service-a
                    weight: 1
      ```

      （選用） 若要查看您可以在上述規格中設定的虛擬路由器的所有可用設定，請執行下列命令。

      ```
      aws appmesh create-virtual-router --generate-cli-skeleton yaml-input
      ```

      若要查看您可以在上述規格中設定的路由的所有可用設定，請執行下列命令。

      ```
      aws appmesh create-route --generate-cli-skeleton yaml-input
      ```

   1. 部署虛擬路由器。

      ```
      kubectl apply -f virtual-router.yaml
      ```

   1. 檢視已建立的 Kubernetes 的虛擬路由器資源。

      ```
      kubectl describe virtualrouter my-service-a-virtual-router -n my-apps
      ```

      縮寫輸出

      ```
      Name:         my-service-a-virtual-router
      Namespace:    my-apps
      Labels:       <none>
      Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"VirtualRouter","metadata":{"annotations":{},"name":"my-service-a-virtual-router","namespac...
      API Version:  appmesh.k8s.aws/v1beta2
      Kind:         VirtualRouter
      ...
      Spec:
        Aws Name:  my-service-a-virtual-router_my-apps
        Listeners:
          Port Mapping:
            Port:      80
            Protocol:  http
        Mesh Ref:
          Name:  my-mesh
          UID:   111a11b1-c11d-1e1f-gh1i-j11k1l111m711
        Routes:
          Http Route:
            Action:
              Weighted Targets:
                Virtual Node Ref:
                  Name:  my-service-a
                Weight:  1
            Match:
              Prefix:  /
          Name:        my-service-a-route
      Status:
        Conditions:
          Last Transition Time:  2020-06-17T15:14:01Z
          Status:                True
          Type:                  VirtualRouterActive
        Observed Generation:     1
        Route AR Ns:
          My - Service - A - Route:  arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps/route/my-service-a-route
        Virtual Router ARN:          arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps
      Events:                        <none>
      ```

   1. 檢視控制器在 App Mesh 中建立的虛擬路由器資源。您`my-service-a-virtual-router_my-apps`為 指定 `name`，因為當控制器在 App Mesh 中建立虛擬路由器時，會將 Kubernetes 命名空間名稱附加至虛擬路由器的名稱。

      ```
      aws appmesh describe-virtual-router --virtual-router-name my-service-a-virtual-router_my-apps --mesh-name my-mesh
      ```

      Output

      ```
      {
          "virtualRouter": {
              "meshName": "my-mesh",
              "metadata": {
                  "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps",
                  "createdAt": "2020-06-17T10:14:01.547000-05:00",
                  "lastUpdatedAt": "2020-06-17T10:14:01.547000-05:00",
                  "meshOwner": "111122223333",
                  "resourceOwner": "111122223333",
                  "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711",
                  "version": 1
              },
              "spec": {
                  "listeners": [
                      {
                          "portMapping": {
                              "port": 80,
                              "protocol": "http"
                          }
                      }
                  ]
              },
              "status": {
                  "status": "ACTIVE"
              },
              "virtualRouterName": "my-service-a-virtual-router_my-apps"
          }
      }
      ```

   1. 檢視控制器在 App Mesh 中建立的路由資源。因為路由是 Kubernetes 中虛擬路由器組態的一部分，所以並未在 Kubernetes 中建立路由資源。路由資訊會顯示在 Kubernetes 資源詳情的子步驟 `c` 中。控制器在 App Mesh 中建立路由時，並未將 Kubernetes 命名空間名稱附加至 App Mesh 路由名稱，因為路由名稱對虛擬路由器是唯一的。

      ```
      aws appmesh describe-route \
          --route-name my-service-a-route \
          --virtual-router-name my-service-a-virtual-router_my-apps \
          --mesh-name my-mesh
      ```

      Output

      ```
      {
          "route": {
              "meshName": "my-mesh",
              "metadata": {
                  "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps/route/my-service-a-route",
                  "createdAt": "2020-06-17T10:14:01.577000-05:00",
                  "lastUpdatedAt": "2020-06-17T10:14:01.577000-05:00",
                  "meshOwner": "111122223333",
                  "resourceOwner": "111122223333",
                  "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711",
                  "version": 1
              },
              "routeName": "my-service-a-route",
              "spec": {
                  "httpRoute": {
                      "action": {
                          "weightedTargets": [
                              {
                                  "virtualNode": "my-service-a_my-apps",
                                  "weight": 1
                              }
                          ]
                      },
                      "match": {
                          "prefix": "/"
                      }
                  }
              },
              "status": {
                  "status": "ACTIVE"
              },
              "virtualRouterName": "my-service-a-virtual-router_my-apps"
          }
      }
      ```

1. 建立 App Mesh 虛擬服務。虛擬服務是實際服務的抽象化，由虛擬節點直接提供，或透過虛擬路由器間接提供。相依服務會依其名稱呼叫您的虛擬服務。雖然名稱與 App Mesh 無關，但我們建議將虛擬服務命名為虛擬服務所代表之實際服務的完整網域名稱。透過這種方式命名您的虛擬服務，您不需要變更應用程式程式碼來參考不同的名稱。請求會路由傳送到指定為虛擬服務之提供者的虛擬節點或虛擬路由器。

   1. 將下列內容儲存到電腦上名為 `virtual-service.yaml` 的檔案中。檔案用於建立虛擬服務，該服務使用虛擬路由器供應商將流量路由到在上一個步驟中建立的名為 `my-service-a` 的虛擬節點。`spec` 中的 `awsName` 數值是此虛擬服務所抽象之實際 Kubernetes 服務的完整格式網域名稱 (FQDN)。在 [步驟 3：建立或更新服務](#create-update-services) 中建立 Kubernetes 服務。如需詳細資訊，請參閱[虛擬服務](virtual_services.md)。

      ```
      apiVersion: appmesh.k8s.aws/v1beta2
      kind: VirtualService
      metadata:
        name: my-service-a
        namespace: my-apps
      spec:
        awsName: my-service-a.my-apps.svc.cluster.local
        provider:
          virtualRouter:
            virtualRouterRef:
              name: my-service-a-virtual-router
      ```

      若要查看您可以為上述規格中的虛擬服務設定的所有可用設定，請執行下列命令。

      ```
      aws appmesh create-virtual-service --generate-cli-skeleton yaml-input
      ```

   1. 建立虛擬服務。

      ```
      kubectl apply -f virtual-service.yaml
      ```

   1. 檢視所建立之 Kubernetes 虛擬服務資源的詳細資料。

      ```
      kubectl describe virtualservice my-service-a -n my-apps
      ```

      Output

      ```
      Name:         my-service-a
      Namespace:    my-apps
      Labels:       <none>
      Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"VirtualService","metadata":{"annotations":{},"name":"my-service-a","namespace":"my-apps"}...
      API Version:  appmesh.k8s.aws/v1beta2
      Kind:         VirtualService
      Metadata:
        Creation Timestamp:  2020-06-17T15:48:40Z
        Finalizers:
          finalizers.appmesh.k8s.aws/aws-appmesh-resources
        Generation:        1
        Resource Version:  13598
        Self Link:         /apis/appmesh.k8s.aws/v1beta2/namespaces/my-apps/virtualservices/my-service-a
        UID:               111a11b1-c11d-1e1f-gh1i-j11k1l111m711
      Spec:
        Aws Name:  my-service-a.my-apps.svc.cluster.local
        Mesh Ref:
          Name:  my-mesh
          UID:   111a11b1-c11d-1e1f-gh1i-j11k1l111m711
        Provider:
          Virtual Router:
            Virtual Router Ref:
              Name:  my-service-a-virtual-router
      Status:
        Conditions:
          Last Transition Time:  2020-06-17T15:48:40Z
          Status:                True
          Type:                  VirtualServiceActive
        Observed Generation:     1
        Virtual Service ARN:     arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualService/my-service-a.my-apps.svc.cluster.local
      Events:                    <none>
      ```

   1. 檢視控制器在 App Mesh 中建立的虛擬服務資源詳細資訊。Kubernetes 控制器在 App Mesh 中建立虛擬服務時，並未將 Kubernetes 命名空間名稱附加至 App Mesh 虛擬服務名稱，因為虛擬服務的名稱是唯一的 FQDN。

      ```
      aws appmesh describe-virtual-service --virtual-service-name my-service-a.my-apps.svc.cluster.local --mesh-name my-mesh
      ```

      Output

      ```
      {
          "virtualService": {
              "meshName": "my-mesh",
              "metadata": {
                  "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualService/my-service-a.my-apps.svc.cluster.local",
                  "createdAt": "2020-06-17T10:48:40.182000-05:00",
                  "lastUpdatedAt": "2020-06-17T10:48:40.182000-05:00",
                  "meshOwner": "111122223333",
                  "resourceOwner": "111122223333",
                  "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711",
                  "version": 1
              },
              "spec": {
                  "provider": {
                      "virtualRouter": {
                          "virtualRouterName": "my-service-a-virtual-router_my-apps"
                      }
                  }
              },
              "status": {
                  "status": "ACTIVE"
              },
              "virtualServiceName": "my-service-a.my-apps.svc.cluster.local"
          }
      }
      ```

雖然本教學未涵蓋，但控制器也可以部署 App Mesh [虛擬閘道](virtual_gateways.md)和 [閘道路由](gateway-routes.md)。如需使用控制器部署這些資源的逐步解說，請參閱[設定傳入閘道](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-ingress-gateway)，或包含 GitHub 上資源[的範例資訊](https://github.com/aws/aws-app-mesh-examples/blob/main/walkthroughs/howto-k8s-ingress-gateway/v1beta2/manifest.yaml.template)清單。

## 步驟 3：建立或更新服務
<a name="create-update-services"></a>

您想要與 App Mesh 搭配使用的任何 Pod 都必須新增 App Mesh 附屬容器。注入器會自動將附屬容器新增至部署您指定命名空間的任何 Pod 中。

1. 啟用代理伺服器授權。我們建議您讓每個 Kubernetes 部署僅串流其 App Mesh 虛擬節點的組態。

   1. 將下列內容儲存到電腦上名為 `proxy-auth.json` 的檔案中。請務必用您自己的*替代顏色值*取代。

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

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "appmesh:StreamAggregatedResources",
                  "Resource": [
                      "arn:aws:appmesh:us-east-1:111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps"
                  ]
              }
          ]
      }
      ```

------

   1. 建立政策。

      ```
      aws iam create-policy --policy-name my-policy --policy-document file://proxy-auth.json
      ```

   1. 建立 IAM 角色、將您在上一個步驟中建立的政策連接至該角色、建立 Kubernetes 服務帳戶，並將政策繫結至 Kubernetes 服務帳戶。該角色可讓控制器新增、移除和變更 App Mesh 資源。

      ```
      eksctl create iamserviceaccount \
          --cluster $CLUSTER_NAME \
          --namespace my-apps \
          --name my-service-a \
          --attach-policy-arn  arn:aws:iam::111122223333:policy/my-policy \
          --override-existing-serviceaccounts \
          --approve
      ```

      如果您想要使用 AWS 管理主控台 或 建立服務帳戶 AWS CLI，請參閱《*Amazon EKS 使用者指南*》中的[為您的服務帳戶建立 IAM 角色和政策](https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html#create-service-account-iam-role)。如果您使用 AWS 管理主控台 或 AWS CLI 來建立帳戶，您也需要將角色對應至 Kubernetes 服務帳戶。如需詳細資訊，請參閱《*Amazon EKS 使用者指南*》中的[為您的服務帳戶指定 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html)。

1. (選用) 如果您要將您的部署內容部署到 Fargate Pod，則需要建立 Fargate 設定檔。如果您尚未`eksctl`安裝 ，您可以使用 *Amazon EKS 使用者指南*中的[安裝或升級`eksctl`](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl)中的指示進行安裝。如果您想要使用主控台建立設定檔，請參閱《*Amazon EKS 使用者指南*》中的[建立 Fargate 設定檔](https://docs.aws.amazon.com/eks/latest/userguide/fargate-profile.html#create-fargate-profile)。

   ```
   eksctl create fargateprofile --cluster my-cluster --region Region-code --name my-service-a --namespace my-apps
   ```

1. 建立 Kubernetes 服務和部署。如果您有要與 App Mesh 搭配使用的現有部署，則需要部署虛擬節點，就像在 `3`的子步驟一樣[步驟 2：部署 App Mesh 資源](#configure-app-mesh)。更新您的部署，以確保其標籤符合您在虛擬節點上設定的標籤，以便附屬容器自動新增至 Pod，並重新部署 Pod。

   1. 將下列內容儲存到電腦上名為 `example-service.yaml` 的檔案中。如果您變更命名空間名稱並使用 Fargate Pod，請確定命名空間名稱符合您在 Fargate 設定檔中定義的命名空間名稱。

      ```
      apiVersion: v1
      kind: Service
      metadata:
        name: my-service-a
        namespace: my-apps
        labels:
          app: my-app-1
      spec:
        selector:
          app: my-app-1
        ports:
          - protocol: TCP
            port: 80
            targetPort: 80
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-service-a
        namespace: my-apps
        labels:
          app: my-app-1
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: my-app-1
        template:
          metadata:
            labels:
              app: my-app-1
          spec:
            serviceAccountName: my-service-a
            containers:
            - name: nginx
              image: nginx:1.19.0
              ports:
              - containerPort: 80
      ```
**重要**  
規範中的 `app` `matchLabels` `selector` 值必須與您在 [步驟 2：部署 App Mesh 資源](#configure-app-mesh) 的子步驟 `3` 中建立虛擬節點時指定的值相符，否則附屬容器將不會注入到 Pod 中。在上一個範例中，標籤的值為 `my-app-1`。如果您部署虛擬閘道，而不是虛擬節點，則`Deployment`資訊清單應該只包含 Envoy 容器。如需要使用之映像的詳細資訊，請參閱 [Envoy 影像](envoy.md)。如需範例 Manfest，請參閱 GitHub 上的[部署範例](https://github.com/aws/aws-app-mesh-examples/blob/main/walkthroughs/howto-k8s-ingress-gateway/v1beta2/manifest.yaml.template#L585)。

   1. 部署服務。

      ```
      kubectl apply -f example-service.yaml
      ```

   1. 檢視服務和部署。

      ```
      kubectl -n my-apps get pods
      ```

      Output

      ```
      NAME                            READY   STATUS    RESTARTS   AGE
      my-service-a-54776556f6-2cxd9   2/2     Running   0          10s
      my-service-a-54776556f6-w26kf   2/2     Running   0          18s
      my-service-a-54776556f6-zw5kt   2/2     Running   0          26s
      ```

   1. 檢視已部署之其中一個 pod 的詳細資訊。

      ```
      kubectl -n my-apps describe pod my-service-a-54776556f6-2cxd9
      ```

      縮寫輸出

      ```
      Name:         my-service-a-54776556f6-2cxd9
      Namespace:    my-app-1
      Priority:     0
      Node:         ip-192-168-44-157.us-west-2.compute.internal/192.168.44.157
      Start Time:   Wed, 17 Jun 2020 11:08:59 -0500
      Labels:       app=nginx
                    pod-template-hash=54776556f6
      Annotations:  kubernetes.io/psp: eks.privileged
      Status:       Running
      IP:           192.168.57.134
      IPs:
        IP:           192.168.57.134
      Controlled By:  ReplicaSet/my-service-a-54776556f6
      Init Containers:
        proxyinit:
          Container ID:   docker://e0c4810d584c21ae0cb6e40f6119d2508f029094d0e01c9411c6cf2a32d77a59
          Image:          111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager:v2
          Image ID:       docker-pullable://111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager
          Port:           <none>
          Host Port:      <none>
          State:          Terminated
            Reason:       Completed
            Exit Code:    0
            Started:      Fri, 26 Jun 2020 08:36:22 -0500
            Finished:     Fri, 26 Jun 2020 08:36:22 -0500
          Ready:          True
          Restart Count:  0
          Requests:
            cpu:     10m
            memory:  32Mi
          Environment:
            APPMESH_START_ENABLED:         1
            APPMESH_IGNORE_UID:            1337
            APPMESH_ENVOY_INGRESS_PORT:    15000
            APPMESH_ENVOY_EGRESS_PORT:     15001
            APPMESH_APP_PORTS:             80
            APPMESH_EGRESS_IGNORED_IP:     169.254.169.254
            APPMESH_EGRESS_IGNORED_PORTS:  22
            AWS_ROLE_ARN:                  arn:aws:iam::111122223333:role/eksctl-app-mesh-addon-iamserviceaccount-my-a-Role1-NMNCVWB6PL0N
            AWS_WEB_IDENTITY_TOKEN_FILE:   /var/run/secrets/eks.amazonaws.com/serviceaccount/token
          ...
      Containers:
        nginx:
          Container ID:   docker://be6359dc6ecd3f18a1c87df7b57c2093e1f9db17d5b3a77f22585ce3bcab137a
          Image:          nginx:1.19.0
          Image ID:       docker-pullable://nginx
          Port:           80/TCP
          Host Port:      0/TCP
          State:          Running
            Started:      Fri, 26 Jun 2020 08:36:28 -0500
          Ready:          True
          Restart Count:  0
          Environment:
            AWS_ROLE_ARN:                 arn:aws:iam::111122223333:role/eksctl-app-mesh-addon-iamserviceaccount-my-a-Role1-NMNCVWB6PL0N
            AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
          ...
        envoy:
          Container ID:   docker://905b55cbf33ef3b3debc51cb448401d24e2e7c2dbfc6a9754a2c49dd55a216b6
          Image:          840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.4.0-prod
          Image ID:       docker-pullable://840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy
          Port:           9901/TCP
          Host Port:      0/TCP
          State:          Running
            Started:      Fri, 26 Jun 2020 08:36:36 -0500
          Ready:          True
          Restart Count:  0
          Requests:
            cpu:     10m
            memory:  32Mi
          Environment:
            APPMESH_RESOURCE_ARN:         arn:aws:iam::111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps
            APPMESH_PREVIEW:              0
            ENVOY_LOG_LEVEL:              info
            AWS_REGION:                   us-west-2
            AWS_ROLE_ARN:                 arn:aws:iam::111122223333:role/eksctl-app-mesh-addon-iamserviceaccount-my-a-Role1-NMNCVWB6PL0N
            AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
      ...
      Events:
        Type    Reason     Age   From                                                   Message
        ----    ------     ----  ----                                                   -------
        Normal  Pulling    30s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Pulling image "111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager:v2"
        Normal  Pulled     23s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Successfully pulled image "111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager:v2"
        Normal  Created    21s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Created container proxyinit
        Normal  Started    21s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Started container proxyinit
        Normal  Pulling    20s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Pulling image "nginx:1.19.0"
        Normal  Pulled     16s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Successfully pulled image "nginx:1.19.0"
        Normal  Created    15s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Created container nginx
        Normal  Started    15s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Started container nginx
        Normal  Pulling    15s   kubelet, ip-192-168-44-157.us-west-2.compute.internal  Pulling image "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.4.0-prod"
        Normal  Pulled     8s    kubelet, ip-192-168-44-157.us-west-2.compute.internal  Successfully pulled image "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.4.0-prod"
        Normal  Created    7s    kubelet, ip-192-168-44-157.us-west-2.compute.internal  Created container envoy
        Normal  Started    7s    kubelet, ip-192-168-44-157.us-west-2.compute.internal  Started container envoy
      ```

      在前面的輸出中，您可以看到 `proxyinit` 和 `envoy` 容器已新增至 pod 中。如果您已將範例服務部署至 Fargate，則控制器會將`envoy`容器新增至 Pod，但容器`proxyinit`並未如此。

1. （選用） 安裝附加元件，例如 Prometheus、Grafana AWS X-Ray、Jaeger 和 Datadog。如需詳細資訊，請參閱 GitHub 上的 [App Mesh 附加元件](https://github.com/aws/eks-charts#app-mesh-add-ons)和《App Mesh 使用者指南》中的[可觀測性](https://docs.aws.amazon.com/app-mesh/latest/userguide/observability.html)一節。

**注意**  
如需 App Mesh 的更多範例和逐步解說，請參閱 [App Mesh 範例儲存庫](https://github.com/aws/aws-app-mesh-examples)。

## 步驟 4：清理
<a name="remove-integration"></a>

移除本教學中建立的所有範例資源。控制器也會移除在 `my-mesh` App Mesh 服務網格中建立的資源。

```
kubectl delete namespace my-apps
```

如果您已為範例服務建立 Fargate 設定檔，請將其移除。

```
eksctl delete fargateprofile --name my-service-a --cluster my-cluster --region Region-code
```

刪除網格。

```
kubectl delete mesh my-mesh
```

(選擇性) 您可以移除 Kubernetes 整合元件。

```
helm delete appmesh-controller -n appmesh-system
```

（選用） 如果您將 Kubernetes 整合元件部署至 Fargate，請刪除 Fargate 設定檔。

```
eksctl delete fargateprofile --name appmesh-system --cluster my-cluster --region Region-code
```

# 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 資源。如需詳細資訊，請參閱此部落格文章[從 遷移 AWS App Mesh 至 Amazon ECS Service Connect](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)。

本主題可協助您將 AWS App Mesh 與在 Amazon EC2 上執行的實際服務搭配使用。本教學課程涵蓋數種 App Mesh 資源類型的基本功能。

## 案例
<a name="scenario"></a>

若要說明如何使用 App Mesh，請假設您擁有具有下列特性的應用程式：
+ 包含兩個名為 `serviceA`和 的服務`serviceB`。
+ 這兩個服務都註冊到名稱為 `apps.local` 的命名空間。
+ `ServiceA` 與 `serviceB` 透過 HTTP/2，連接埠 80 進行通訊。
+  您已部署 `serviceB` 第 2 版，並在 `apps.local` 命名空間中將其註冊為名稱 `serviceBv2`。

您有以下要求：
+ 您想要將 75% 的流量從 `serviceA` 傳送到 ，`serviceB`並將 25% 的流量傳送到 `serviceBv2` 。透過僅將 25% 傳送到 `serviceBv2`，您可以在從 傳送 100% 的流量之前驗證其是否沒有錯誤`serviceA`。
+ 您希望能夠輕鬆地調整流量權重，以便證實流量可靠之後，能夠 100% 流入 `serviceBv2`。將所有流量傳送到 後`serviceBv2`，您想要停止 `serviceB`。
+ 您不想變更實際服務的任何現有應用程式碼或服務探索註冊，以符合先前的要求。

為了滿足您的需求，您決定建立具有虛擬服務、虛擬節點、虛擬路由器和路由的 App Mesh 服務網格。實作網格後，您會更新您的服務以使用 Envoy 代理。一旦更新，您的服務會透過 Envoy 代理彼此通訊，而非直接相互通訊。

## 先決條件
<a name="prerequisites"></a>

App Mesh 支援向 DNS AWS Cloud Map或兩者註冊的 Linux 服務。若要使用此入門指南，建議您擁有三個已向 DNS 註冊的現有服務。即使服務不存在，您也可以建立服務網格及其資源，但在部署實際服務之前，您無法使用網格。

如果您還沒有執行中的服務，您可以啟動 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. 在 https：//[https://console.aws.amazon.com/appmesh/get-started](https://console.aws.amazon.com/appmesh/get-started) 開啟 App Mesh 主控台初次執行精靈。

1. 對於 **Mesh name (網格名稱)**，輸入 **apps**。

1. 對於 **Virtual service name (虛擬服務名稱)**，輸入 **serviceb.apps.local**。

1. 若要繼續，請選擇 **Next (下一步)**。

------
#### [ 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)。

建立名稱為 `serviceB` 的虛擬節點，因為其中一個虛擬節點代表名稱為 `serviceB` 的實際服務。虛擬節點代表的實際服務可透過 `DNS` (主機名稱為 `serviceb.apps.local`) 探索。或者，您可以使用 AWS Cloud Map探索實際服務。虛擬節點會使用連接埠 80 上的 HTTP/2 通訊協定接聽流量。也支援其他通訊協定，以及運作狀態檢查。您可以在後續步驟`serviceBv2`中為 `serviceA`和 建立虛擬節點。

------
#### [ AWS 管理主控台 ]

1. 對於 **Virtual node name (虛擬節點名稱)**，輸入 **serviceB**。

1. 針對**服務探索方法**，選擇 **DNS**，然後輸入 **serviceb.apps.local** **DNS 主機名稱**。

1. 在**接聽程式組態**下，為**通訊協定**選擇 **http2**，並為**連接埠**輸入 **80** 。

1. 若要繼續，請選擇 **Next (下一步)**。

------
#### [ 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>

虛擬路由器會路由網格內一或多個虛擬服務的流量。如需詳細資訊，請參閱[虛擬路由器](virtual_routers.md)及[路由](routes.md)。

建立下列資源：
+ 名為 `serviceB` 的虛擬路由器，因為 `serviceB.apps.local` 虛擬服務不會啟動與任何其他服務的對外通訊。請記住，您先前建立的虛擬服務是實際 `serviceb.apps.local` 服務的抽象。虛擬服務會將流量傳送至虛擬路由器。虛擬路由器會使用連接埠 80 上的 HTTP/2 通訊協定接聽流量。也支援其他通訊協定。
+ 名為 `serviceB` 的路由。它將 100% 的流量路由到`serviceB`虛擬節點。新增`serviceBv2`虛擬節點後，權重會進入後續步驟。雖然未涵蓋在本指南中，但您可以為路由新增其他篩選條件，並新增重試政策，使 Envoy 代理在遇到通訊問題時多次嘗試將流量傳送至虛擬節點。

------
#### [ AWS 管理主控台 ]

1. 對於 **Virtual router name (虛擬路由器名稱)**，輸入 **serviceB**。

1. 在**接聽程式組態**下，為**通訊協定**選擇 **http2**，並為**連接埠**指定 **80** 。

1. 對於 **Route name (路由名稱)**，輸入 **serviceB**。

1. 對於 **Route type (路由類型)**，選擇 **http2**。

1. 針對**目標組態**下的**虛擬節點名稱**，選取 `serviceB`並輸入 **100**表示**權重**。

1. 在**相符組態**下，選擇**方法**。

1. 若要繼續，請選擇 **Next (下一步)**。

------
#### [ 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 管理主控台 ]

如果您需要在任何區段中進行變更，請選擇 **Edit (編輯)**。對這些設定感到滿意後，請選擇 **Create mesh (建立網格)**。

**Status (狀態)** 畫面會顯示所有已建立的網格資源。選取 **View mesh (檢視網格)** 即可在主控台中檢視建立的資源。

------
#### [ 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`，將所有流量直接傳送至`serviceA`虛擬節點。
+ 更新您在上一個步驟中建立的 `serviceB` 路由，將 75% 的流量傳送到 `serviceB` 虛擬節點，以及 25% 的流量傳送到 `serviceBv2` 虛擬節點。隨著時間的推移，您可以繼續修改權重，直到 `serviceBv2` 收到 100% 的流量為止。將所有流量傳送到 後`serviceBv2`，您可以關閉並停止`serviceB`虛擬節點和實際服務。當您更改權重時，您的程式碼不需要任何修改，因為 `serviceb.apps.local` 虛擬和實際服務名稱不會變更。記住，`serviceb.apps.local` 虛擬服務會將流量傳送至虛擬路由器，接著虛擬路由器會將流量路由至虛擬節點。虛擬節點的服務探索名稱可以隨時變更。

------
#### [ AWS 管理主控台 ]

1. 在左側導覽窗格中，選取 **Meshes (網格)**。

1. 選取您在上一個步驟中建立的 `apps` 網格。

1. 在左側導覽窗格中，選取 **Virtual nodes (虛擬節點)**。

1. 選擇 **Create virtual node (建立虛擬節點)**。

1. 對於 **Virtual node name (虛擬節點名稱)** 輸入 **serviceBv2**、對於 **Service discovery method (服務探索方法)** 選擇 **DNS**，然後對於 **DNS hostname (DNS 主機名稱)** 輸入 **servicebv2.apps.local**。

1. 針對**接聽程式組態**，選取**通訊協定**的 **http2**，然後**80**針對**連接埠**輸入 。

1. 選擇 **Create virtual node (建立虛擬節點)**。

1. 再次選擇 **Create virtual node (建立虛擬節點)**。輸入 **serviceA** 做為**虛擬節點名稱**。對於 **Service discovery method (服務探索方法)**，選擇 **DNS**，並針對 **DNS hostname (DNS 主機名稱)** 輸入 **servicea.apps.local**。

1. 在**新增後端**下**輸入虛擬服務名稱**，輸入 **serviceb.apps.local**。

1. 在**接聽程式組態**下，針對**通訊協定**選擇 **http2**，**80**針對**連接埠**輸入 ，然後選擇**建立虛擬節點**。

1. 在左側導覽窗格中，選取 **Virtual routers (虛擬路由器)**，然後從清單中選取 `serviceB` 虛擬路由器。

1. 在 **Routes (路由)** 下方，選取您在上一個步驟中建立的路由 (名為 `ServiceB`)，然後選擇 **Edit (編輯)**。

1. 在**目標**、**虛擬節點名稱**下，將 的**權重**值`serviceB`變更為 **75**。

1. 選擇**新增目標**，`serviceBv2`從下拉式清單中選擇，並將**權重**的值設定為 **25**。

1. 選擇**儲存**。

1. 在左側瀏覽窗格中，選取 **Virtual services (虛擬服務)**，然後選擇 **Create virtual service (建立虛擬服務)**。

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` 的實際服務。除了實際服務以外，您目前擁有包含代表實際服務之下列資源的服務網格：
+ 兩個虛擬服務。代理會透過虛擬路由器將 `servicea.apps.local` 虛擬服務的所有流量傳送至 `serviceb.apps.local` 虛擬服務。
+ 名稱為 `serviceA`、`serviceB` 和 `serviceBv2` 的三個虛擬節點。Envoy 代理會使用針對虛擬節點設定的服務探索資訊，來查詢實際服務的 IP 地址。
+ 具有單一路由的虛擬路由器，其指示 Envoy 代理將 75% 的傳入流量路由到 `serviceB` 虛擬節點，將 25% 的流量路由到 `serviceBv2` 虛擬節點。

## 步驟 6：更新服務
<a name="update-services"></a>

在建立網格之後，您需要完成下列任務：
+ 授權您隨每個服務一起部署的 Envoy 代理，以讀取一或多個虛擬節點的組態。如需如何授權代理的詳細資訊，請參閱 [Envoy Proxy 授權](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. 將您在上一個步驟中建立的政策連接至角色，讓角色只能從 App Mesh 讀取`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`、、`il-central-1`、 `ap-southeast-3` `eu-south-1`和 以外的所有區域`af-south-1`。您可以將 *us-west-2* 取代為任何[支援的 區域](https://docs.aws.amazon.com/general/latest/gr/appmesh.html)，但 `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
     ```

1. 執行下列其中一個命令來啟動執行個體上的 App Mesh Envoy 容器，視您要從哪個區域提取映像而定。*apps* 和 *serviceB* 值是案例中定義的網格和虛擬節點名稱。此資訊會告知代理程式要從 App Mesh 讀取哪些虛擬節點組態。若要完成案例，您也需要為託管 `serviceBv2`和`serviceA`虛擬節點所代表服務的 Amazon EC2 執行個體完成這些步驟。對於您自己的應用程式，將這些值取代為您自己的值。
   + 除了 `me-south-1`、`ap-east-1`、、`il-central-1`、 `ap-southeast-3` `eu-south-1`和 以外的所有區域`af-south-1`。您可以將*區域碼*取代為 `me-south-1`、`ap-east-1`、、`il-central-1`、 `ap-southeast-3` `eu-south-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)。
**重要**  
只有 v1.9.0.0 版或更新版本支援與 App Mesh 搭配使用。

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. 若要設定 `iptables` 規則以將應用程式流量路由至 Envoy 代理，請執行您在上一個步驟中建立的指令碼。

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

1. 啟動您的虛擬節點應用程式程式碼。

**注意**  
如需 App Mesh 的更多範例和逐步解說，請參閱 [App Mesh 範例儲存庫](https://github.com/aws/aws-app-mesh-examples)。

# App Mesh 範例
<a name="examples"></a>

**重要**  
支援終止通知：2026 年 9 月 30 日， AWS 將停止支援 AWS App Mesh。2026 年 9 月 30 日之後，您將無法再存取 AWS App Mesh 主控台或 AWS App Mesh 資源。如需詳細資訊，請參閱此部落格文章[從 遷移 AWS App Mesh 至 Amazon ECS Service Connect](https://aws.amazon.com/blogs/containers/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect)。

您可以在下列儲存庫中找到end-to-end演練 AWS App Mesh ，顯示與各種 AWS 服務整合的動作和程式碼範例：

[應用程式網格範例](https://github.com/aws/aws-app-mesh-examples)