AWS App Mesh 和 Amazon 入門 EC2 - AWS 應用程式網格

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

AWS App Mesh 和 Amazon 入門 EC2

重要

支援終止通知:2026 年 9 月 30 日 AWS 將停止對 的支援 AWS App Mesh。2026 年 9 月 30 日後,您將無法再存取 AWS App Mesh 主控台或 AWS App Mesh 資源。如需詳細資訊,請造訪此部落格文章,從 遷移 AWS App Mesh 至 Amazon ECS Service Connect

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

案例

若要說明如何使用 App Mesh,請假設您有具有下列特性的應用程式:

  • 由兩個名為 serviceA和 的服務組成serviceB

  • 這兩個服務都註冊到名稱為 apps.local 的命名空間。

  • ServiceAserviceB超過 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 代理彼此通訊,而非直接相互通訊。

必要條件

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

如果您尚未執行服務,您可以啟動 Amazon EC2執行個體,並將應用程式部署到這些執行個體。如需詳細資訊,請參閱 Amazon 使用者指南中的教學課程:Amazon EC2 Linux 執行個體入門。 EC2其餘步驟假設實際服務名稱為 serviceAserviceBserviceBv2,而且所有服務皆可透過名稱為 apps.local 的命名空間探索。

步驟 1:建立網格和虛擬服務

服務網格是在它之內各服務之間網路流量的邏輯邊界。如需詳細資訊,請參閱服務網格。虛擬服務是實際服務的抽象化。如需詳細資訊,請參閱虛擬服務

建立下列資源:

  • 名稱為 apps 的網格,因為案例中的所有服務皆註冊到 apps.local 命名空間。

  • 名稱為 serviceb.apps.local 的虛擬服務,因為虛擬服務代表可使用該名稱探索的服務,而且您不想將程式碼變更為參照其他名稱。稍後的步驟會新增名稱為 servicea.apps.local 的虛擬服務。

您可以使用 AWS Management Console 或 1.18 AWS CLI .116 或更新版本或 2.0.38 或更新版本來完成下列步驟。如果使用 AWS CLI,請使用 aws --version命令來檢查已安裝的 AWS CLI 版本。如果您沒有安裝 1.18.116 或更新版本或 2.0.38 或更新版本,則必須安裝或更新 AWS CLI。為您要使用的工具選取索引標籤。

AWS Management Console
  1. https://console.aws.amazon.com/appmesh/入門 開啟 App Mesh 主控台首次執行精靈。

  2. 對於 Mesh name (網格名稱),輸入 apps

  3. 對於 Virtual service name (虛擬服務名稱),輸入 serviceb.apps.local

  4. 若要繼續,請選擇 Next (下一步)

AWS CLI
  1. 使用 create-mesh 命令建立網格。

    aws appmesh create-mesh --mesh-name apps
  2. 使用 create-virtual-service 命令建立虛擬服務。

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

步驟 2:建立虛擬節點

虛擬節點可做為實際服務的邏輯指標。如需詳細資訊,請參閱虛擬節點

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

AWS Management Console
  1. 對於 Virtual node name (虛擬節點名稱),輸入 serviceB

  2. 針對服務探索方法 ,選擇 DNS並輸入serviceb.apps.localDNS主機名稱

  3. 接聽程式組態 下,針對通訊協定選擇 http2,並80針對連接埠 輸入

  4. 若要繼續,請選擇 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" }
  2. 使用 JSON 檔案作為輸入,使用 create-virtual-node命令建立虛擬節點。

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

步驟 3:建立虛擬路由器和路由

虛擬路由器會路由網格內一或多個虛擬服務的流量。如需詳細資訊,請參閱 虛擬路由器路由

建立下列資源:

  • 名為 serviceB 的虛擬路由器,因為 serviceB.apps.local 虛擬服務不會啟動與任何其他服務的對外通訊。請記住,您先前建立的虛擬服務是實際 serviceb.apps.local 服務的抽象。虛擬服務會將流量傳送至虛擬路由器。虛擬路由器會使用連接埠 80 上的 HTTP/2 通訊協定接聽流量。也支援其他通訊協定。

  • 名為 serviceB 的路由。它將 100% 的流量路由到serviceB虛擬節點。新增serviceBv2虛擬節點後,權重會進入後續步驟。雖然未涵蓋在本指南中,但您可以為路由新增其他篩選條件,並新增重試政策,使 Envoy 代理在遇到通訊問題時多次嘗試將流量傳送至虛擬節點。

AWS Management Console
  1. 對於 Virtual router name (虛擬路由器名稱),輸入 serviceB

  2. 接聽程式組態 下,為通訊協定選擇 http2,並為80連接埠 指定 。

  3. 對於 Route name (路由名稱),輸入 serviceB

  4. 對於 Route type (路由類型),選擇 http2

  5. 針對目標組態 下的虛擬節點名稱,選取 serviceB並輸入 100表示權重

  6. 相符組態 下,選擇方法

  7. 若要繼續,請選擇 Next (下一步)

AWS CLI
  1. 建立虛擬路由器。

    1. 使用下列內容建立名為 create-virtual-router.json 的檔案:

      { "meshName": "apps", "spec": { "listeners": [ { "portMapping": { "port": 80, "protocol": "http2" } } ] }, "virtualRouterName": "serviceB" }
    2. 使用 JSON 檔案作為輸入,使用 create-virtual-router命令建立虛擬路由器。

      aws appmesh create-virtual-router --cli-input-json file://create-virtual-router.json
  2. 建立路由。

    1. 使用下列內容建立名為 create-route.json 的檔案:

      { "meshName" : "apps", "routeName" : "serviceB", "spec" : { "httpRoute" : { "action" : { "weightedTargets" : [ { "virtualNode" : "serviceB", "weight" : 100 } ] }, "match" : { "prefix" : "/" } } }, "virtualRouterName" : "serviceB" }
    2. 使用 create-route 命令,使用 JSON 檔案作為輸入來建立路由。

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

步驟 4:檢閱和建立

依照先前的指示檢閱設定。

AWS Management Console

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

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

AWS CLI

檢閱您使用 describe-mesh 命令建立的網格設定。

aws appmesh describe-mesh --mesh-name apps

檢閱您使用 describe-virtual-service命令建立的虛擬服務設定。

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

檢閱您使用 describe-virtual-node命令建立的虛擬節點設定。

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

檢閱您使用 describe-virtual-router命令建立的虛擬路由器設定。

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

檢閱您使用 describe-route 命令建立的路由設定。

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

步驟 5:建立其他資源

若要完成案例,您必須:

  • 建立一個名為 serviceBv2 的虛擬節點,以及另一個名為 serviceA 的虛擬節點。兩個虛擬節點都會接聽 HTTP/2 連接埠 80 上的請求。針對serviceA虛擬節點,設定後端的 serviceb.apps.local。來自serviceA虛擬節點的所有傳出流量都會傳送至名為 的虛擬服務serviceb.apps.local。雖然未涵蓋在本指南中,但您也可以指定將虛擬節點的存取日誌寫入其中的檔案路徑。

  • 建立名為 的其他虛擬服務servicea.apps.local,將所有流量直接傳送至serviceA虛擬節點。

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

AWS Management Console
  1. 在左側導覽窗格中,選取 Meshes (網格)

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

  3. 在左側導覽窗格中,選取 Virtual nodes (虛擬節點)

  4. 選擇 Create virtual node (建立虛擬節點)

  5. 對於虛擬節點名稱 ,輸入 serviceBv2;對於服務探索方法 ,選擇 DNS;對於DNS主機名稱 ,輸入 servicebv2.apps.local

  6. 針對接聽程式組態 ,針對通訊協定選取 http2,並80針對連接埠 輸入

  7. 選擇 Create virtual node (建立虛擬節點)

  8. 再次選擇 Create virtual node (建立虛擬節點)serviceA虛擬節點名稱 輸入 。對於服務探索方法 ,選擇 DNS,對於DNS主機名稱 ,請輸入 servicea.apps.local

  9. 對於在新後端 下輸入虛擬服務名稱,請輸入 serviceb.apps.local

  10. 接聽程式組態 下,為通訊協定 選擇 http280連接埠 輸入 ,然後選擇建立虛擬節點

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

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

  13. 目標 虛擬節點名稱 下,將 的權重值變更為 serviceB 75

  14. 選擇新增目標 serviceBv2從下拉式清單中選擇 ,並將 Weight 的值設定為 25

  15. 選擇 Save (儲存)。

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

  17. 輸入servicea.apps.local虛擬服務名稱 ,選取提供者 虛擬節點,選取serviceA虛擬節點 ,然後選取建立虛擬服務。

AWS CLI
  1. 建立 serviceBv2 虛擬節點。

    1. 使用下列內容建立名為 create-virtual-node-servicebv2.json 的檔案:

      { "meshName": "apps", "spec": { "listeners": [ { "portMapping": { "port": 80, "protocol": "http2" } } ], "serviceDiscovery": { "dns": { "hostname": "serviceBv2.apps.local" } } }, "virtualNodeName": "serviceBv2" }
    2. 建立虛擬節點。

      aws appmesh create-virtual-node --cli-input-json file://create-virtual-node-servicebv2.json
  2. 建立 serviceA 虛擬節點。

    1. 使用下列內容建立名為 create-virtual-node-servicea.json 的檔案:

      { "meshName" : "apps", "spec" : { "backends" : [ { "virtualService" : { "virtualServiceName" : "serviceb.apps.local" } } ], "listeners" : [ { "portMapping" : { "port" : 80, "protocol" : "http2" } } ], "serviceDiscovery" : { "dns" : { "hostname" : "servicea.apps.local" } } }, "virtualNodeName" : "serviceA" }
    2. 建立虛擬節點。

      aws appmesh create-virtual-node --cli-input-json file://create-virtual-node-servicea.json
  3. 更新您在上一個步驟中建立的 serviceb.apps.local 虛擬服務,將其流量傳送至 serviceB 虛擬路由器。最初建立虛擬服務時,它不會傳送流量到任何地方,因為 serviceB 虛擬路由器尚未建立。

    1. 使用下列內容建立名為 update-virtual-service.json 的檔案:

      { "meshName" : "apps", "spec" : { "provider" : { "virtualRouter" : { "virtualRouterName" : "serviceB" } } }, "virtualServiceName" : "serviceb.apps.local" }
    2. 使用 update-virtual-service命令更新虛擬服務。

      aws appmesh update-virtual-service --cli-input-json file://update-virtual-service.json
  4. 更新您在上一個步驟中建立的 serviceB 路由。

    1. 使用下列內容建立名為 update-route.json 的檔案:

      { "meshName" : "apps", "routeName" : "serviceB", "spec" : { "http2Route" : { "action" : { "weightedTargets" : [ { "virtualNode" : "serviceB", "weight" : 75 }, { "virtualNode" : "serviceBv2", "weight" : 25 } ] }, "match" : { "prefix" : "/" } } }, "virtualRouterName" : "serviceB" }
    2. 使用 update-route 命令更新路由。

      aws appmesh update-route --cli-input-json file://update-route.json
  5. 建立 serviceA 虛擬服務。

    1. 使用下列內容建立名為 create-virtual-servicea.json 的檔案:

      { "meshName" : "apps", "spec" : { "provider" : { "virtualNode" : { "virtualNodeName" : "serviceA" } } }, "virtualServiceName" : "servicea.apps.local" }
    2. 建立虛擬服務。

      aws appmesh create-virtual-service --cli-input-json file://create-virtual-servicea.json
網格摘要

在您建立服務網格之前,您有三個名稱為 servicea.apps.localserviceb.apps.localservicebv2.apps.local 的實際服務。除了實際服務以外,您目前擁有包含代表實際服務之下列資源的服務網格:

  • 兩個虛擬服務。代理會透過虛擬路由器將 servicea.apps.local 虛擬服務的所有流量傳送至 serviceb.apps.local 虛擬服務。

  • 名稱為 serviceAserviceBserviceBv2 的三個虛擬節點。Envoy 代理會使用針對虛擬節點設定的服務探索資訊,來查詢實際服務的 IP 地址。

  • 具有單一路由的虛擬路由器,其指示 Envoy 代理將 75% 的傳入流量路由到 serviceB 虛擬節點,將 25% 的流量路由到 serviceBv2 虛擬節點。

步驟 6:更新服務

在建立網格之後,您需要完成下列任務:

  • 授權您隨每個服務一起部署的 Envoy 代理,以讀取一或多個虛擬節點的組態。如需如何授權代理的詳細資訊,請參閱 Envoy Proxy 授權

  • 若要更新現有的服務,請完成下列步驟。

將 Amazon EC2執行個體設定為虛擬節點成員
  1. 建立 IAM 角色。

    1. 使用下列內容建立名為 ec2-trust-relationship.json 的檔案。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
    2. 使用下列命令建立IAM角色。

      aws iam create-role --role-name mesh-virtual-node-service-b --assume-role-policy-document file://ec2-trust-relationship.json
  2. 將IAM政策連接至角色,允許其從 Amazon 讀取,ECR並只讀取特定 App Mesh 虛擬節點的組態。

    1. 使用下列內容建立名為 virtual-node-policy.json 的檔案。apps 是您在 步驟 1:建立網格和虛擬服務 建立的網格名稱,而 serviceB 是您在 步驟 2:建立虛擬節點 建立的虛擬節點名稱。Replace (取代) 111122223333 使用您的帳戶 ID 和 us-west-2 您建立網格的區域。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "appmesh:StreamAggregatedResources", "Resource": [ "arn:aws:appmesh:us-west-2:111122223333:mesh/apps/virtualNode/serviceB" ] } ] }
    2. 使用下列命令建立政策。

      aws iam create-policy --policy-name virtual-node-policy --policy-document file://virtual-node-policy.json
    3. 將您在上一個步驟中建立的政策連接到角色,以便角色只能從 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
    4. AmazonEC2ContainerRegistryReadOnly受管政策連接至角色,以便從 Amazon 提取 Envoy 容器映像ECR。

      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --role-name mesh-virtual-node-service-b
  3. 使用您建立IAM的角色啟動 Amazon EC2執行個體

  4. 透過 連線至您的執行個體SSH。

  5. 根據您的作業系統文件,在執行個體 AWS CLI 上安裝 Docker 和 。

  6. 驗證至您希望 Docker 用戶端從中提取映像的區域中的 Envoy Amazon ECR儲存庫。

    • 除了 me-south-1ap-east-1、、ap-southeast-3eu-south-1il-central-1和 以外的所有區域af-south-1。您可以取代 us-west-2 除了 me-south-1ap-east-1、、ap-southeast-3eu-south-1il-central-1和 以外的任何支援區域af-south-1

      $aws ecr get-login-password \ --region us-west-2 \ | docker login \ --username AWS \ --password-stdin 840364872350.dkr.ecr.us-west-2.amazonaws.com
    • me-south-1 區域

      $aws ecr get-login-password \ --region me-south-1 \ | docker login \ --username AWS \ --password-stdin 772975370895.dkr.ecr.me-south-1.amazonaws.com
    • ap-east-1 區域

      $aws ecr get-login-password \ --region ap-east-1 \ | docker login \ --username AWS \ --password-stdin 856666278305.dkr.ecr.ap-east-1.amazonaws.com
  7. 執行下列其中一個命令,以啟動執行個體上的 App Mesh Envoy 容器,視您要從哪個區域提取映像而定。所以此 apps 以及 serviceB 值是案例中定義的網格和虛擬節點名稱。此資訊會告訴代理程式要從 App Mesh 讀取哪些虛擬節點組態。若要完成案例,您也需要為託管 serviceBv2serviceA虛擬節點所代表之服務的 Amazon EC2執行個體完成這些步驟。對於您自己的應用程式,將這些值取代為您自己的值。

    • 除了 me-south-1ap-east-1、、ap-southeast-3eu-south-1il-central-1和 以外的所有區域af-south-1。您可以取代 Region-code 除了 me-south-1ap-east-1ap-southeast-3、、 eu-south-1il-central-1和 區域以外的任何支援af-south-1區域。您可以將 1337 換成 02147483647 之間的任何值。

      sudo docker run --detach --env APPMESH_RESOURCE_ARN=mesh/apps/virtualNode/serviceB \ -u 1337 --network host 840364872350.dkr.ecr.region-code.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod
    • me-south-1 區域。您可以將 1337 換成 02147483647 之間的任何值。

      sudo docker run --detach --env APPMESH_RESOURCE_ARN=mesh/apps/virtualNode/serviceB \ -u 1337 --network host 772975370895.dkr.ecr.me-south-1.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod
    • ap-east-1 區域。您可以將 1337 換成 02147483647 之間的任何值。

      sudo docker run --detach --env APPMESH_RESOURCE_ARN=mesh/apps/virtualNode/serviceB \ -u 1337 --network host 856666278305.dkr.ecr.ap-east-1.amazonaws.com/aws-appmesh-envoy:v1.29.9.0-prod
    注意

    APPMESH_RESOURCE_ARN 屬性需要版本 1.15.0或更新版本的 Envoy 映像。如需詳細資訊,請參閱Envoy 映像

    重要

    僅支援 v1.9.0.0 版或更新版本搭配 App Mesh 使用。

  8. 請在下方選取 Show more。使用下列命令在您的執行個體上建立名為 envoy-networking.sh 的檔案。Replace (取代) 8000 您的應用程式程式碼用於傳入流量的連接埠。您可以變更 APPMESH_IGNORE_UID 的值,但值必須與您在上一個步驟中指定的值相同;例如 1337。如有必要,您可以新增其他地址到 APPMESH_EGRESS_IGNORED_IP。請勿修改任何其他行。

    #!/bin/bash -e # # Start of configurable options # #APPMESH_START_ENABLED="0" APPMESH_IGNORE_UID="1337" APPMESH_APP_PORTS="8000" APPMESH_ENVOY_EGRESS_PORT="15001" APPMESH_ENVOY_INGRESS_PORT="15000" APPMESH_EGRESS_IGNORED_IP="169.254.169.254,169.254.170.2" # Enable routing on the application start. [ -z "$APPMESH_START_ENABLED" ] && APPMESH_START_ENABLED="0" # Enable IPv6. [ -z "$APPMESH_ENABLE_IPV6" ] && APPMESH_ENABLE_IPV6="0" # Egress traffic from the processess owned by the following UID/GID will be ignored. if [ -z "$APPMESH_IGNORE_UID" ] && [ -z "$APPMESH_IGNORE_GID" ]; then echo "Variables APPMESH_IGNORE_UID and/or APPMESH_IGNORE_GID must be set." echo "Envoy must run under those IDs to be able to properly route it's egress traffic." exit 1 fi # Port numbers Application and Envoy are listening on. if [ -z "$APPMESH_ENVOY_EGRESS_PORT" ]; then echo "APPMESH_ENVOY_EGRESS_PORT must be defined to forward traffic from the application to the proxy." exit 1 fi # If an app port was specified, then we also need to enforce the proxies ingress port so we know where to forward traffic. if [ ! -z "$APPMESH_APP_PORTS" ] && [ -z "$APPMESH_ENVOY_INGRESS_PORT" ]; then echo "APPMESH_ENVOY_INGRESS_PORT must be defined to forward traffic from the APPMESH_APP_PORTS to the proxy." exit 1 fi # Comma separated list of ports for which egress traffic will be ignored, we always refuse to route SSH traffic. if [ -z "$APPMESH_EGRESS_IGNORED_PORTS" ]; then APPMESH_EGRESS_IGNORED_PORTS="22" else APPMESH_EGRESS_IGNORED_PORTS="$APPMESH_EGRESS_IGNORED_PORTS,22" fi # # End of configurable options # function initialize() { echo "=== Initializing ===" if [ ! -z "$APPMESH_APP_PORTS" ]; then iptables -t nat -N APPMESH_INGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ip6tables -t nat -N APPMESH_INGRESS fi fi iptables -t nat -N APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ip6tables -t nat -N APPMESH_EGRESS fi } function enable_egress_routing() { # Stuff to ignore [ ! -z "$APPMESH_IGNORE_UID" ] && \ iptables -t nat -A APPMESH_EGRESS \ -m owner --uid-owner $APPMESH_IGNORE_UID \ -j RETURN [ ! -z "$APPMESH_IGNORE_GID" ] && \ iptables -t nat -A APPMESH_EGRESS \ -m owner --gid-owner $APPMESH_IGNORE_GID \ -j RETURN [ ! -z "$APPMESH_EGRESS_IGNORED_PORTS" ] && \ for IGNORED_PORT in $(echo "$APPMESH_EGRESS_IGNORED_PORTS" | tr "," "\n"); do iptables -t nat -A APPMESH_EGRESS \ -p tcp \ -m multiport --dports "$IGNORED_PORT" \ -j RETURN done if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then # Stuff to ignore ipv6 [ ! -z "$APPMESH_IGNORE_UID" ] && \ ip6tables -t nat -A APPMESH_EGRESS \ -m owner --uid-owner $APPMESH_IGNORE_UID \ -j RETURN [ ! -z "$APPMESH_IGNORE_GID" ] && \ ip6tables -t nat -A APPMESH_EGRESS \ -m owner --gid-owner $APPMESH_IGNORE_GID \ -j RETURN [ ! -z "$APPMESH_EGRESS_IGNORED_PORTS" ] && \ for IGNORED_PORT in $(echo "$APPMESH_EGRESS_IGNORED_PORTS" | tr "," "\n"); do ip6tables -t nat -A APPMESH_EGRESS \ -p tcp \ -m multiport --dports "$IGNORED_PORT" \ -j RETURN done fi # The list can contain both IPv4 and IPv6 addresses. We will loop over this list # to add every IPv4 address into `iptables` and every IPv6 address into `ip6tables`. [ ! -z "$APPMESH_EGRESS_IGNORED_IP" ] && \ for IP_ADDR in $(echo "$APPMESH_EGRESS_IGNORED_IP" | tr "," "\n"); do if [[ $IP_ADDR =~ .*:.* ]] then [ "$APPMESH_ENABLE_IPV6" == "1" ] && \ ip6tables -t nat -A APPMESH_EGRESS \ -p tcp \ -d "$IP_ADDR" \ -j RETURN else iptables -t nat -A APPMESH_EGRESS \ -p tcp \ -d "$IP_ADDR" \ -j RETURN fi done # Redirect everything that is not ignored iptables -t nat -A APPMESH_EGRESS \ -p tcp \ -j REDIRECT --to $APPMESH_ENVOY_EGRESS_PORT # Apply APPMESH_EGRESS chain to non local traffic iptables -t nat -A OUTPUT \ -p tcp \ -m addrtype ! --dst-type LOCAL \ -j APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then # Redirect everything that is not ignored ipv6 ip6tables -t nat -A APPMESH_EGRESS \ -p tcp \ -j REDIRECT --to $APPMESH_ENVOY_EGRESS_PORT # Apply APPMESH_EGRESS chain to non local traffic ipv6 ip6tables -t nat -A OUTPUT \ -p tcp \ -m addrtype ! --dst-type LOCAL \ -j APPMESH_EGRESS fi } function enable_ingress_redirect_routing() { # Route everything arriving at the application port to Envoy iptables -t nat -A APPMESH_INGRESS \ -p tcp \ -m multiport --dports "$APPMESH_APP_PORTS" \ -j REDIRECT --to-port "$APPMESH_ENVOY_INGRESS_PORT" # Apply AppMesh ingress chain to everything non-local iptables -t nat -A PREROUTING \ -p tcp \ -m addrtype ! --src-type LOCAL \ -j APPMESH_INGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then # Route everything arriving at the application port to Envoy ipv6 ip6tables -t nat -A APPMESH_INGRESS \ -p tcp \ -m multiport --dports "$APPMESH_APP_PORTS" \ -j REDIRECT --to-port "$APPMESH_ENVOY_INGRESS_PORT" # Apply AppMesh ingress chain to everything non-local ipv6 ip6tables -t nat -A PREROUTING \ -p tcp \ -m addrtype ! --src-type LOCAL \ -j APPMESH_INGRESS fi } function enable_routing() { echo "=== Enabling routing ===" enable_egress_routing if [ ! -z "$APPMESH_APP_PORTS" ]; then enable_ingress_redirect_routing fi } function disable_routing() { echo "=== Disabling routing ===" iptables -t nat -F APPMESH_INGRESS iptables -t nat -F APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ip6tables -t nat -F APPMESH_INGRESS ip6tables -t nat -F APPMESH_EGRESS fi } function dump_status() { echo "=== iptables FORWARD table ===" iptables -L -v -n echo "=== iptables NAT table ===" iptables -t nat -L -v -n if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then echo "=== ip6tables FORWARD table ===" ip6tables -L -v -n echo "=== ip6tables NAT table ===" ip6tables -t nat -L -v -n fi } function clean_up() { disable_routing ruleNum=$(iptables -L PREROUTING -t nat --line-numbers | grep APPMESH_INGRESS | cut -d " " -f 1) iptables -t nat -D PREROUTING $ruleNum ruleNum=$(iptables -L OUTPUT -t nat --line-numbers | grep APPMESH_EGRESS | cut -d " " -f 1) iptables -t nat -D OUTPUT $ruleNum iptables -t nat -X APPMESH_INGRESS iptables -t nat -X APPMESH_EGRESS if [ "$APPMESH_ENABLE_IPV6" == "1" ]; then ruleNum=$(ip6tables -L PREROUTING -t nat --line-numbers | grep APPMESH_INGRESS | cut -d " " -f 1) ip6tables -t nat -D PREROUTING $ruleNum ruleNum=$(ip6tables -L OUTPUT -t nat --line-numbers | grep APPMESH_EGRESS | cut -d " " -f 1) ip6tables -t nat -D OUTPUT $ruleNum ip6tables -t nat -X APPMESH_INGRESS ip6tables -t nat -X APPMESH_EGRESS fi } function main_loop() { echo "=== Entering main loop ===" while read -p '> ' cmd; do case "$cmd" in "quit") clean_up break ;; "status") dump_status ;; "enable") enable_routing ;; "disable") disable_routing ;; *) echo "Available commands: quit, status, enable, disable" ;; esac done } function print_config() { echo "=== Input configuration ===" env | grep APPMESH_ || true } print_config initialize if [ "$APPMESH_START_ENABLED" == "1" ]; then enable_routing fi main_loop
  9. 若要設定 iptables 規則以將應用程式流量路由至 Envoy 代理,請執行您在上一個步驟中建立的指令碼。

    sudo ./envoy-networking.sh
  10. 啟動您的虛擬節點應用程式程式碼。

注意

如需 App Mesh 的更多範例和逐步解說,請參閱 App Mesh 範例儲存庫