

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

# 使用 設定 Amazon ECS Service Connect AWS CLI
<a name="create-service-connect"></a>

您可以搭配 AWS CLI使用 Service Connect，來建立包含 Fargate 任務的 Amazon ECS 服務。

**注意**  
您可以使用雙堆疊服務端點，透過 IPv4 和 IPv6 AWS CLI從 、 SDKs 和 Amazon ECS API 與 Amazon ECS 互動。如需詳細資訊，請參閱[使用 Amazon ECS 雙堆疊端點](dual-stack-endpoint.md)。

## 先決條件
<a name="create-service-connect-prereqs"></a>

下列是使用 Service Connect 的先決條件：
+ 確認 AWS CLI 已安裝並設定最新版本的 。如需詳細資訊，請參閱 [Installing or updating to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ 您的 IAM 使用者擁有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 政策範例中指定的所需許可。
+ 您已建立要使用的 VPC、子網路、路由表和安全群組。如需詳細資訊，請參閱[建立 Virtual Private Cloud](get-set-up-for-amazon-ecs.md#create-a-vpc)。
+ 您具有名為 `ecsTaskExecutionRole` 的任務執行角色，且 `AmazonECSTaskExecutionRolePolicy` 受管政策已附加至該角色。此角色允許 Fargate 將 NGINX 應用程式日誌和 Service Connect Proxy 日誌寫入 Amazon CloudWatch Logs。如需詳細資訊，請參閱[建立任務執行角色](task_execution_IAM_role.md#create-task-execution-role)。

## 步驟 1：建立叢集
<a name="create-service-connect-cluster"></a>

使用下列步驟建立 Amazon ECS 叢集和命名空間。

**建立 Amazon ECS 叢集和 AWS Cloud Map 命名空間**

1. 建立要使用的名為 `tutorial` 的 Amazon ECS 叢集。參數 `--service-connect-defaults` 會設定叢集的預設命名空間。在範例輸出中，名稱的 AWS Cloud Map 命名空間`service-connect`不存在於此帳戶中 AWS 區域，因此命名空間是由 Amazon ECS 建立。該命名空間是在帳戶的 AWS Cloud Map 中建立，並且對所有其他命名空間都可見，因此請使用可指示此用途的名稱。

   ```
   aws ecs create-cluster --cluster-name tutorial --service-connect-defaults namespace=service-connect
   ```

   輸出：

   ```
   {
       "cluster": {
           "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
           "clusterName": "tutorial",
           "serviceConnectDefaults": {
               "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
           },
           "status": "PROVISIONING",
           "registeredContainerInstancesCount": 0,
           "runningTasksCount": 0,
           "pendingTasksCount": 0,
           "activeServicesCount": 0,
           "statistics": [],
           "tags": [],
           "settings": [
               {
                   "name": "containerInsights",
                   "value": "disabled"
               }
           ],
           "capacityProviders": [],
           "defaultCapacityProviderStrategy": [],
           "attachments": [
               {
                   "id": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
                   "type": "sc",
                   "status": "ATTACHING",
                   "details": []
               }
           ],
           "attachmentsStatus": "UPDATE_IN_PROGRESS"
       }
   }
   }
   ```

1. 確認已建立叢集：

   ```
   aws ecs describe-clusters --clusters tutorial
   ```

   輸出：

   ```
   {
       "clusters": [
           {
               "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
               "clusterName": "tutorial",
               "serviceConnectDefaults": {
                   "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
               },
               "status": "ACTIVE",
               "registeredContainerInstancesCount": 0,
               "runningTasksCount": 0,
               "pendingTasksCount": 0,
               "activeServicesCount": 0,
               "statistics": [],
               "tags": [],
               "settings": [],
               "capacityProviders": [],
               "defaultCapacityProviderStrategy": []
           }
       ],
       "failures": []
   }
   ```

1. （選用） 確認已在其中建立命名空間 AWS Cloud Map。您可以在建立時，使用 AWS 管理主控台 或正常 AWS CLI 組態 AWS Cloud Map。

   例如，使用 AWS CLI：

   ```
   aws servicediscovery get-namespace --id ns-EXAMPLE
   ```

   輸出：

   ```
   {
       "Namespace": {
           "Id": "ns-EXAMPLE",
           "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE",
           "Name": "service-connect",
           "Type": "HTTP",
           "Properties": {
               "DnsProperties": {
                   "SOA": {}
               },
               "HttpProperties": {
                   "HttpName": "service-connect"
               }
           },
           "CreateDate": 1661749852.422,
           "CreatorRequestId": "service-connect"
       }
   }
   ```

## 步驟 2：為伺服器建立服務
<a name="create-service-connect-nginx-server"></a>

Service Connect 功能適用於在 Amazon ECS 上進行多個應用程式的互連線。這些應用程式中至少有一個需要提供要連線的 Web 服務。在此步驟中，您要建立如下項目：
+ 會使用未修改的官方 NGINX 容器映像且包含 Service Connect 組態的任務定義。
+ Amazon ECS 服務定義，將 Service Connect 設定為針對此服務的流量提供服務探索與服務網格代理。此組態會重複使用叢集組態中的預設命名空間，以減少您為每個服務所做的服務組態數量。
+ Amazon ECS 服務。該服務會使用任務定義執行一項任務，並為 Service Connect Proxy 插入額外的容器。Proxy 會在任務定義中容器連接埠映射的連接埠上接聽。在 Amazon ECS 中執行的用戶端應用程式中，用戶端任務中的 Proxy 會接聽任務定義連接埠名稱、服務探索名稱或服務用戶端別名名稱的輸出連線，以及來自用戶端別名的連接埠號碼。

**使用 Service Connect 建立 Web 服務**

1. 註冊與 Fargate 相容的任務定義，並使用 `awsvpc` 網路模式。請遵循下列步驟：

   1. 使用以下任務定義的內容，建立名為 `service-connect-nginx.json` 的檔案：

      此任務定義透過將 `name` 和 `appProtocol` 參數新增至連接埠映射來設定 Service Connect。使用多個連接埠時，連接埠名稱有助於您識別服務組態中的此連接埠。依預設，連接埠名稱也會用作可探索的名稱，以供命名空間中的其他應用程式使用。

      任務定義包含任務 IAM 角色，因為服務已啟用 ECS Exec。
**重要**  
此任務定義使用 `logConfiguration`，將 nginx 輸出從 `stdout` 和 `stderr` 傳送到 Amazon CloudWatch Logs。此任務執行角色沒有所需的額外許可，無法建立 CloudWatch Logs 日誌群組。使用 AWS 管理主控台 或 在 CloudWatch Logs 中建立日誌群組 AWS CLI。如果不想將 nginx 日誌傳送到 CloudWatch Logs，您可以移除 `logConfiguration`。  
將任務執行角色中的 AWS 帳戶 ID 取代為您的 AWS 帳戶 ID。

      ```
      {
          "family": "service-connect-nginx",
          "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
          "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
          "networkMode": "awsvpc",
          "containerDefinitions": [
              {
              "name": "webserver",
              "image": "public.ecr.aws/docker/library/nginx:latest",
              "cpu": 100,
              "portMappings": [
                  {
                      "name": "nginx",
                      "containerPort": 80,
                      "protocol": "tcp", 
                      "appProtocol": "http"
                  }
              ],
              "essential": true,
              "logConfiguration": {
                  "logDriver": "awslogs",
                  "options": {
                      "awslogs-group": "/ecs/service-connect-nginx",
                      "awslogs-region": "region", 
                      "awslogs-stream-prefix": "nginx"
                  }
              }
              }
          ],
          "cpu": "256",
          "memory": "512"
      }
      ```

   1. 使用 `service-connect-nginx.json` 檔案註冊任務定義：

      ```
      aws ecs register-task-definition --cli-input-json file://service-connect-nginx.json
      ```

1. 建立服務：

   1. 使用您要建立的 Amazon ECS 服務的內容，建立名為 `service-connect-nginx-service.json` 的檔案。此範例使用上個步驟中建立的任務定義。需要 `awsvpcConfiguration`，因為任務定義範例使用 `awsvpc` 網路模式。

      建立 ECS 服務時，請指定 Fargate 以及支援 Service Connect 的 `LATEST` 平台版本。`securityGroups` 和 `subnets` 所屬的 VPC 必須具有使用 Amazon ECS 的需求。您可以從 Amazon VPC 主控台取得安全群組和子網路識別碼。

      此服務透過新增 `serviceConnectConfiguration` 參數來設定 Service Connect。不需要命名空間，因為叢集已設定預設命名空間。在命名空間的 ECS 中執行的用戶端應用程式使用 `portName` 和 `clientAliases` 中的連接埠連線至此服務。例如，由於 nginx 在根位置 `/` 提供歡迎頁面，因此可以使用 `http://nginx:80/` 連上此服務。未在 Amazon ECS 中執行或不在相同命名空間中的外部應用程式，可以使用任務的 IP 地址和任務定義中的連接埠號碼，透過 Service Connect Proxy 連上此應用程式。對於 `tls` 組態，請為 `awsPcaAuthorityArn`、`kmsKey` 與 IAM 角色的 `roleArn` 新增憑證 `arn`。

      此服務會使用 `logConfiguration`，將 Service Connect Proxy 輸出從 `stdout` 和 `stderr` 傳送至 Amazon CloudWatch Logs。此任務執行角色沒有所需的額外許可，無法建立 CloudWatch Logs 日誌群組。使用 AWS 管理主控台 或 在 CloudWatch Logs 中建立日誌群組 AWS CLI。我們建議您建立此日誌群組，並將 Proxy 日誌儲存在 CloudWatch Logs 中。如果不想將 Proxy 日誌傳送到 CloudWatch Logs，您可以移除 `logConfiguration`。

      ```
      {
          "cluster": "tutorial",
          "deploymentConfiguration": {
              "maximumPercent": 200,
              "minimumHealthyPercent": 0
          },
          "deploymentController": {
              "type": "ECS"
          },
          "desiredCount": 1,
          "enableECSManagedTags": true,
          "enableExecuteCommand": true,
          "launchType": "FARGATE",
          "networkConfiguration": {
              "awsvpcConfiguration": {
                  "assignPublicIp": "ENABLED",
                  "securityGroups": [
                      "sg-EXAMPLE"
                  ],
                  "subnets": [
                      "subnet-EXAMPLE",
                      "subnet-EXAMPLE",
                      "subnet-EXAMPLE"
                  ]
                 }
          },
          "platformVersion": "LATEST",
          "propagateTags": "SERVICE",
          "serviceName": "service-connect-nginx-service",
          "serviceConnectConfiguration": {
              "enabled": true,
              "services": [
                  {
                      "portName": "nginx",
                      "clientAliases": [
                          {
                              "port": 80
                          }
                      ],
                      "tls": {
                         "issuerCertificateAuthority": {
                            "awsPcaAuthorityArn": "certificateArn"
                         }, 
                         "kmsKey": "kmsKey", 
                         "roleArn": "iamRoleArn"
                      }
                  }
              ],
              "logConfiguration": {
                  "logDriver": "awslogs",
                  "options": {
                      "awslogs-group": "/ecs/service-connect-proxy",
                      "awslogs-region": "region",
                      "awslogs-stream-prefix": "service-connect-proxy"
                  }
              }
          },
          "taskDefinition": "service-connect-nginx"
      }
      ```

   1. 使用 `service-connect-nginx-service.json` 檔案建立服務：

      ```
      aws ecs create-service --cluster tutorial --cli-input-json file://service-connect-nginx-service.json
      ```

      輸出：

      ```
      {
          "service": {
              "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/tutorial/service-connect-nginx-service",
              "serviceName": "service-connect-nginx-service",
              "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
              "loadBalancers": [],
              "serviceRegistries": [],
              "status": "ACTIVE",
              "desiredCount": 1,
              "runningCount": 0,
              "pendingCount": 0,
              "launchType": "FARGATE",
              "platformVersion": "LATEST",
              "platformFamily": "Linux",
              "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
              "deploymentConfiguration": {
                  "deploymentCircuitBreaker": {
                      "enable": false,
                      "rollback": false
                  },
                  "maximumPercent": 200,
                  "minimumHealthyPercent": 0
              },
              "deployments": [
                  {
                      "id": "ecs-svc/3763308422771520962",
                      "status": "PRIMARY",
                      "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
                      "desiredCount": 1,
                      "pendingCount": 0,
                      "runningCount": 0,
                      "failedTasks": 0,
                      "createdAt": 1661210032.602,
                      "updatedAt": 1661210032.602,
                      "launchType": "FARGATE",
                      "platformVersion": "1.4.0",
                      "platformFamily": "Linux",
                      "networkConfiguration": {
                          "awsvpcConfiguration": {
                              "assignPublicIp": "ENABLED",
                              "securityGroups": [
                                  "sg-EXAMPLE"
                              ],
                              "subnets": [
                                  "subnet-EXAMPLEf",
                                  "subnet-EXAMPLE",
                                  "subnet-EXAMPLE"
                              ]
                          }
                      },
                      "rolloutState": "IN_PROGRESS",
                      "rolloutStateReason": "ECS deployment ecs-svc/3763308422771520962 in progress.",
                      "failedLaunchTaskCount": 0,
                      "replacedTaskCount": 0,
                      "serviceConnectConfiguration": {
                          "enabled": true,
                          "namespace": "service-connect",
                          "services": [
                              {
                                  "portName": "nginx",
                                  "clientAliases": [
                                      {
                                          "port": 80
                                      }
                                  ]
                              }
                          ],
                          "logConfiguration": {
                              "logDriver": "awslogs",
                              "options": {
                                  "awslogs-group": "/ecs/service-connect-proxy",
                                  "awslogs-region": "us-west-2",
                                  "awslogs-stream-prefix": "service-connect-proxy"
                              },
                              "secretOptions": []
                          }
                      },
                      "serviceConnectResources": [
                          {
                              "discoveryName": "nginx",
                              "discoveryArn": "arn:aws:servicediscovery:us-west-2:123456789012:service/srv-EXAMPLE"
                          }
                      ]
                  }
              ],
              "roleArn": "arn:aws:iam::123456789012:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
              "version": 0,
              "events": [],
              "createdAt": 1661210032.602,
              "placementConstraints": [],
              "placementStrategy": [],
              "networkConfiguration": {
                  "awsvpcConfiguration": {
                      "assignPublicIp": "ENABLED",
                      "securityGroups": [
                          "sg-EXAMPLE"
                      ],
                      "subnets": [
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE"
                      ]
                  }
              },
              "schedulingStrategy": "REPLICA",
              "enableECSManagedTags": true,
              "propagateTags": "SERVICE",
              "enableExecuteCommand": true
          }
      }
      ```

      您提供的 `serviceConnectConfiguration` 會出現在輸出的第一個*部署*中。當您以需要對任務進行變更的方式對 ECS 服務進行變更時，Amazon ECS 會建立新的部署。

## 步驟 3：確認您是否可以連線
<a name="create-service-connect-verify"></a>

若要確認 Service Connect 已設定且正常運作，請依照下列步驟從外部應用程式連線至 Web 服務。然後，查看 CloudWatch 中由 Service Connect Proxy 建立的其他指標。

**從外部應用程式連線至 Web 服務**
+ 使用任務 IP 地址連線至任務 IP 地址和容器連接埠

  使用 AWS CLI 取得任務 ID，方法是使用 `aws ecs list-tasks --cluster tutorial`。

  如果子網路和安全群組允許任務定義的連接埠上來自公用網際網路的流量，您可以從電腦連線到公用 IP。不過，公有 IP 無法從 `describe-tasks` 取得，因此這些步驟涉及前往 Amazon EC2 AWS 管理主控台 或 AWS CLI 以取得彈性網路界面的詳細資訊。

  在此範例中，相同 VPC 中的 Amazon EC2 執行個體使用的是任務的私有 IP。該應用程式是 nginx，但 `server: envoy` 標題顯示使用的是 Service Connect Proxy。Service Connect Proxy 正在任務定義中容器連接埠上接聽。

  ```
  $ curl -v 10.0.19.50:80/
  *   Trying 10.0.19.50:80...
  * Connected to 10.0.19.50 (10.0.19.50) port 80 (#0)
  > GET / HTTP/1.1
  > Host: 10.0.19.50
  > User-Agent: curl/7.79.1
  > Accept: */*
  >
  * Mark bundle as not supporting multiuse
  < HTTP/1.1 200 OK
  < server: envoy
  < date: Tue, 23 Aug 2022 03:53:06 GMT
  < content-type: text/html
  < content-length: 612
  < last-modified: Tue, 16 Apr 2019 13:08:19 GMT
  < etag: "5cb5d3c3-264"
  < accept-ranges: bytes
  < x-envoy-upstream-service-time: 0
  <
  <!DOCTYPE html>
  <html>
  <head>
  <title>Welcome to nginx!</title>
  <style>
      body {
          width: 35em;
          margin: 0 auto;
          font-family: Tahoma, Verdana, Arial, sans-serif;
      }
  </style>
  </head>
  <body>
  <h1>Welcome to nginx!</h1>
  <p>If you see this page, the nginx web server is successfully installed and
  working. Further configuration is required.</p>
  
  <p>For online documentation and support please refer to
  <a href="http://nginx.org/">nginx.org</a>.<br/>
  Commercial support is available at
  <a href="http://nginx.com/">nginx.com</a>.</p>
  
  <p><em>Thank you for using nginx.</em></p>
  </body>
  </html>
  ```

**檢視 Service Connect 指標**  
Service Connect Proxy 會在 CloudWatch 指標中建立應用程式 (HTTP、HTTP2、gRPC 或 TCP 連線) 指標。使用 CloudWatch 主控台時，請參閱 Amazon ECS 命名空間下的 **DiscoveryName**、(**DiscoveryName、ServiceName、ClusterName**)、**TargetDiscoveryName** 與 (**TargetDiscoveryName、ServiceName、ClusterName**) 的其他指標維度。如需有關這些指標與維度的詳細資訊，請參閱 Amazon CloudWatch Logs User Guide 中的 [View Available Metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/viewing_metrics_with_cloudwatch.html)。