

# 创建使用服务发现的 Amazon ECS 服务
<a name="create-service-discovery"></a>

了解如何创建包含 Fargate 任务的务，该任务将服务发现和 AWS CLI 结合使用。

有关支持服务发现的 AWS 区域 的列表，请参阅 [使用服务发现连接具有 DNS 名称的 Amazon ECS 服务](service-discovery.md)。

有关支持 Fargate 的区域的信息，请参阅 [Amazon ECS 在 AWS Fargate 上的支持区域](AWS_Fargate-Regions.md)。

**注意**  
您可以使用双堆栈服务端点通过 IPv4 和 IPv6 从 AWS CLI、SDK 和 Amazon ECS API 与 Amazon ECS 进行交互。有关更多信息，请参阅 [使用 Amazon ECS 双堆栈端点](dual-stack-endpoint.md)。

## 先决条件
<a name="create-service-discovery-prereqs"></a>

在开始本教程之前，请确保满足以下先决条件：
+ 安装并配置了最新版本的 AWS CLI。有关更多信息，请参阅[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ 完成 [设置以使用 Amazon ECS](get-set-up-for-amazon-ecs.md) 中所述的步骤。
+ 您的 IAM 用户具有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 策略示例中指定的必需权限。
+ 您至少创建了一个 VPC 和一个安全组。有关更多信息，请参阅 [创建虚拟私有云](get-set-up-for-amazon-ecs.md#create-a-vpc)。

## 步骤 1：在 AWS Cloud Map 中创建服务发现资源
<a name="create-service-discovery-namespace"></a>

按照以下步骤创建服务发现命名空间和服务发现服务：

1. 创建一个私有 Cloud Map 服务发现命名空间。此示例会创建一个名为 `tutorial` 的命名空间。将 *vpc-abcd1234* 替换为现有 VPC 之一的 ID。

   ```
   aws servicediscovery create-private-dns-namespace \
         --name tutorial \
         --vpc vpc-abcd1234
   ```

   此命令的输出如下。

   ```
   {
       "OperationId": "h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e"
   }
   ```

1. 使用上一步输出中的 `OperationId`，验证私有命名空间是否已经成功创建。记下命名空间 ID，因为您在后续命令中会使用它。

   ```
   aws servicediscovery get-operation \
         --operation-id h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e
   ```

   输出如下所示。

   ```
   {
       "Operation": {
           "Id": "h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e",
           "Type": "CREATE_NAMESPACE",
           "Status": "SUCCESS",
           "CreateDate": 1519777852.502,
           "UpdateDate": 1519777856.086,
           "Targets": {
              "NAMESPACE": "ns-uejictsjen2i4eeg"
           }
       }
   }
   ```

1. 使用上一步输出中的 `NAMESPACE` ID 创建服务发现服务。此示例创建一个名为 `myapplication` 的服务。记下服务 ID 和 ARN，因为您会在后续命令中使用它们。

   ```
   aws servicediscovery create-service \
         --name myapplication \
         --dns-config "NamespaceId="ns-uejictsjen2i4eeg",DnsRecords=[{Type="A",TTL="300"}]" \
         --health-check-custom-config FailureThreshold=1
   ```

   输出如下所示。

   ```
   {
       "Service": {
          "Id": "srv-utcrh6wavdkggqtk",
           "Arn": "arn:aws:servicediscovery:region:aws_account_id:service/srv-utcrh6wavdkggqtk",
           "Name": "myapplication",
           "DnsConfig": {
               "NamespaceId": "ns-uejictsjen2i4eeg",
               "DnsRecords": [
                   {
                       "Type": "A",
                       "TTL": 300
                   }
               ]
           },
           "HealthCheckCustomConfig": {
               "FailureThreshold": 1
           },
           "CreatorRequestId": "e49a8797-b735-481b-a657-b74d1d6734eb"
       }
   }
   ```

## 步骤 2：创建 Amazon ECS 资源
<a name="create-service-discovery-cluster"></a>

使用以下步骤创建您的 Amazon ECS 集群、任务定义和服务：

1. 创建 Amazon ECS 集群。此示例会创建一个名为 `tutorial` 的集群。

   ```
   aws ecs create-cluster \
         --cluster-name tutorial
   ```

1. 注册与 Fargate 兼容的任务定义并使用 `awsvpc` 网络模式。按照以下步骤进行操作：

   1. 使用以下任务定义的内容创建名为 `fargate-task.json` 的文件。

      ```
      {
          "family": "tutorial-task-def",
              "networkMode": "awsvpc",
              "containerDefinitions": [
                  {
                      "name": "sample-app",
                      "image": "public.ecr.aws/docker/library/httpd:2.4",
                      "portMappings": [
                          {
                              "containerPort": 80,
                              "hostPort": 80,
                              "protocol": "tcp"
                          }
                      ],
                      "essential": true,
                      "entryPoint": [
                          "sh",
                          "-c"
                      ],
                      "command": [
                          "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                      ]
                  }
              ],
              "requiresCompatibilities": [
                  "FARGATE"
              ],
              "cpu": "256",
              "memory": "512"
      }
      ```

   1. 使用 `fargate-task.json` 注册任务定义。

      ```
      aws ecs register-task-definition \
            --cli-input-json file://fargate-task.json
      ```

1. 按照以下步骤创建 ECS 服务：

   1. 使用您将要创建的 ECS 服务的内容，创建名为 `ecs-service-discovery.json` 的文件。此示例会使用在上一步中创建的任务定义。由于示例任务定义使用 `awsvpc` 网络模式，`awsvpcConfiguration` 是必需的。

      创建 ECS 服务时，请指定 Fargate 和支持服务发现的 `LATEST` 平台版本。在 AWS Cloud Map 中创建服务发现服务时，`registryArn` 是返回的 ARN。`securityGroups` 和 `subnets` 必须属于用于创建 Cloud Map 命名空间的 VPC。您可以从 Amazon VPC 控制台获取安全组和子网 ID。

      ```
      {
          "cluster": "tutorial",
          "serviceName": "ecs-service-discovery",
          "taskDefinition": "tutorial-task-def",
          "serviceRegistries": [
             {
                "registryArn": "arn:aws:servicediscovery:region:aws_account_id:service/srv-utcrh6wavdkggqtk"
             }
          ],
          "launchType": "FARGATE",
          "platformVersion": "LATEST",
          "networkConfiguration": {
             "awsvpcConfiguration": {
                "assignPublicIp": "ENABLED",
                "securityGroups": [ "sg-abcd1234" ],
                "subnets": [ "subnet-abcd1234" ]
             }
          },
          "desiredCount": 1
      }
      ```

   1. 使用 `ecs-service-discovery.json` 创建 ECS 服务。

      ```
      aws ecs create-service \
            --cli-input-json file://ecs-service-discovery.json
      ```

## 步骤 3：验证 AWS Cloud Map 中的服务发现
<a name="create-service-discovery-verify"></a>

您可以通过查询您的服务发现信息来验证所有内容是否已正确创建。配置服务发现后，您可以使用 AWS Cloud Map API 操作或从 VPC 内的实例调用 `dig`。按照以下步骤进行操作：

1. 通过使用服务发现服务 ID，列出服务发现实例。记下用于资源清理的实例 ID（以粗体标记）。

   ```
    aws servicediscovery list-instances \
          --service-id srv-utcrh6wavdkggqtk
   ```

   输出如下所示。

   ```
   {
       "Instances": [
           {
               "Id": "16becc26-8558-4af1-9fbd-f81be062a266",
               "Attributes": {
                   "AWS_INSTANCE_IPV4": "172.31.87.2"
                   "AWS_INSTANCE_PORT": "80", 
                   "AVAILABILITY_ZONE": "us-east-1a", 
                   "REGION": "us-east-1", 
                   "ECS_SERVICE_NAME": "ecs-service-discovery", 
                   "ECS_CLUSTER_NAME": "tutorial", 
                   "ECS_TASK_DEFINITION_FAMILY": "tutorial-task-def"
               }
           }
       ]
   }
   ```

1. 使用服务发现命名空间、服务和 ECS 集群名称等其他参数来查询有关服务发现实例的详细信息。

   ```
   aws servicediscovery discover-instances \
         --namespace-name tutorial \
         --service-name myapplication \
         --query-parameters ECS_CLUSTER_NAME=tutorial
   ```

1. 在 Route 53 托管区域中为服务发现服务创建的 DNS 记录可使用以下 AWS CLI 命令进行查询：

   1. 使用命名空间 ID 获取有关命名空间的信息，其中包括 Route 53 托管区域 ID。

      ```
      aws servicediscovery \
            get-namespace --id ns-uejictsjen2i4eeg
      ```

      输出如下所示。

      ```
      {
          "Namespace": {
              "Id": "ns-uejictsjen2i4eeg",
              "Arn": "arn:aws:servicediscovery:region:aws_account_id:namespace/ns-uejictsjen2i4eeg",
              "Name": "tutorial",
              "Type": "DNS_PRIVATE",
              "Properties": {
                   "DnsProperties": {
                      "HostedZoneId": "Z35JQ4ZFDRYPLV"
                  }
              },
              "CreateDate": 1519777852.502,
              "CreatorRequestId": "9049a1d5-25e4-4115-8625-96dbda9a6093"
          }
      }
      ```

   1. 使用上一步中的 Route 53 托管区域 ID（请参阅粗体文本），获取托管区域的资源记录集。

      ```
      aws route53 list-resource-record-sets \
            --hosted-zone-id Z35JQ4ZFDRYPLV
      ```

1. 您还可以使用 `dig` 从 VPC 中的实例查询 DNS。

   ```
   dig +short myapplication.tutorial
   ```

## 步骤 4：清除
<a name="create-service-discovery-cleanup"></a>

完成本教程后，清除相关资源，以避免因未使用的资源产生费用。按照以下步骤进行操作：

1. 使用您之前记下的服务 ID 和实例 ID，注销服务发现服务实例。

   ```
   aws servicediscovery deregister-instance \
         --service-id srv-utcrh6wavdkggqtk \
         --instance-id 16becc26-8558-4af1-9fbd-f81be062a266
   ```

   输出如下所示。

   ```
   {
       "OperationId": "xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv"
   }
   ```

1. 使用上一步输出中的 `OperationId`，验证服务发现服务实例是否已成功注消。

   ```
   aws servicediscovery get-operation \ 
         --operation-id xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv
   ```

   ```
   {
     "Operation": {
           "Id": "xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv",
           "Type": "DEREGISTER_INSTANCE",
           "Status": "SUCCESS",
           "CreateDate": 1525984073.707,
           "UpdateDate": 1525984076.426,
           "Targets": {
               "INSTANCE": "16becc26-8558-4af1-9fbd-f81be062a266",
               "ROUTE_53_CHANGE_ID": "C5NSRG1J4I1FH",
               "SERVICE": "srv-utcrh6wavdkggqtk"
           }
       }
   }
   ```

1. 使用服务 ID 删除服务发现服务。

   ```
   aws servicediscovery delete-service \ 
         --id srv-utcrh6wavdkggqtk
   ```

1. 使用命名空间 ID 删除服务发现命名空间。

   ```
   aws servicediscovery delete-namespace \ 
         --id ns-uejictsjen2i4eeg
   ```

   输出如下所示。

   ```
   {
       "OperationId": "c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj"
   }
   ```

1. 使用上一步输出中的 `OperationId`，验证服务发现命名空间是否已成功删除。

   ```
   aws servicediscovery get-operation \ 
         --operation-id c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj
   ```

   输出如下所示。

   ```
   {
       "Operation": {
           "Id": "c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj",
           "Type": "DELETE_NAMESPACE",
           "Status": "SUCCESS",
           "CreateDate": 1525984602.211,
           "UpdateDate": 1525984602.558,
           "Targets": {
               "NAMESPACE": "ns-rymlehshst7hhukh",
               "ROUTE_53_CHANGE_ID": "CJP2A2M86XW3O"
           }
       }
   }
   ```

1. 将 Amazon ECS 服务的预期数量更新为 `0`。您必须执行此操作才能在下一步中删除该服务。

   ```
   aws ecs update-service \
         --cluster tutorial \
         --service ecs-service-discovery \
         --desired-count 0
   ```

1. 删除 Amazon ECS 服务。

   ```
   aws ecs delete-service \
         --cluster tutorial \
         --service ecs-service-discovery
   ```

1. 删除 Amazon ECS 集群。

   ```
   aws ecs delete-cluster \
         --cluster tutorial
   ```