如何将 Amazon ECS 服务发现与 AWS CloudFormation 一起使用?

上次更新时间:2020 年 4 月 8 日

我希望将 Amazon Elastic Container Service (Amazon ECS) 服务发现与 AWS CloudFormation 一起使用。

简短描述

与 Amazon ECS 控制台不同,AWS CloudFormation 的 AWS::ECS::Service 资源类型在服务创建期间无法创建服务发现资源。这与 Amazon ECS 控制台不同,后者让您可以在服务创建期间创建服务发现资源。

注意:Amazon ECS 控制台使用集成 API CreatePrivateDnsNamespaceCreateService (AWS Cloud Map) 和 CreateService (Amazon ECS)。在 AWS CloudFormation 中,您可以使用资源类型 AWS::ServiceDiscovery::PrivateDnsNamespaceAWS::ServiceDiscovery::ServiceAWS::ECS::Service 在单个 AWS CloudFormation 模板中实施集成。

解决方法

1.    在您的 AWS CloudFormation 模板的资源部分,在现有的 Amazon Virtual Private Cloud (Amazon VPC) 中创建私有服务发现命名空间(例如,example.com)。请参阅以下 JSON 和 YAML 示例。

JSON:

{
  "PrivateNamespace": {
    "Type": "AWS::ServiceDiscovery::PrivateDnsNamespace",
    "Properties": {
      "Name": "example.com",
      "Vpc": "vpc-xxxxxxx"
    }
  }
}

YAML:

PrivateNamespace:
    Type: AWS::ServiceDiscovery::PrivateDnsNamespace
    Properties:
        Name: example.com
        Vpc: vpc-xxxxxxx

注意:example.com 替换为您的命名空间的名称。将 vpc-xxxxxxx 替换为您账户中 VPC 的 ID。

2.    使用您在步骤 1 中创建的命名空间的命名空间 ID 创建服务发现服务。

您可以使用 AWS CloudFormation 模板中的 Ref 内部函数获取命名空间 ID 的值。请参阅以下 JSON 和 YAML 示例。

JSON:

{
  "DiscoveryService": {
    "Type": "AWS::ServiceDiscovery::Service",
    "Properties": {
      "Description": "Discovery Service for the Demo Application",
      "DnsConfig": {
        "RoutingPolicy": "MULTIVALUE",
        "DnsRecords": [
          {
            "TTL": 60,
            "Type": "A"
          },
          {
            "TTL": 60,
            "Type": "SRV"
          }
        ]
      },
      "HealthCheckCustomConfig": {
        "FailureThreshold": 1
      },
      "Name": "example-service-name",
      "NamespaceId": {
        "Ref": "PrivateNamespace"
      }
    }
  }
}

YAML:

DiscoveryService:
  Type: AWS::ServiceDiscovery::Service
  Properties: 
    Description: Discovery Service for the Demo Application
    DnsConfig:
      RoutingPolicy: MULTIVALUE
      DnsRecords:
        - TTL: 60
          Type: A
        - TTL: 60
          Type: SRV
    HealthCheckCustomConfig: 
      FailureThreshold: 1
    Name: example-service-name
    NamespaceId: !Ref PrivateNamespace

注意:example-service-name 替换为您的服务的名称

DnsConfig 属性指定在向服务发现服务注册 Amazon ECS 任务时在 Amazon Route 53 中自动创建的 DNS 记录。

注意:支持类型 A 和 SRV 的 DNS 记录。

提示:最佳实践是使用 HealthCheckCustomConfig 属性来允许 Amazon ECS 向服务发现报告任务运行状况。Amazon ECS 使用来自容器检查、运行状况检查和任务状态的信息来更新 AWS Cloud Map 的服务发现的运行状况。

3.    要创建与您先前步骤创建的服务发现命名空间和服务集成的 Amazon ECS 服务,请使用 AWS:ECS::Service 资源中的 ServiceRegistries 属性指定集成。请参阅以下 JSON 和 YAML 示例。

JSON:

{
  "EcsService": {
    "Type": "AWS::ECS::Service",
    "Properties": {
      "Cluster": "awsExampleCluster",
      "DesiredCount": 4,
      "LaunchType": "FARGATE",
      "NetworkConfiguration": {
        "AwsvpcConfiguration": {
          "SecurityGroups": [
            "sg-xxxxxxx"
          ],
          "Subnets": [
            "subnet-xxxxxxx"
          ]
        }
      },
      "ServiceName": "awsExampleService",
      "TaskDefinition": "awsExampleTaskDefinition",
      "ServiceRegistries": [
        {
          "RegistryArn": {
            "Fn::GetAtt": [
              "DiscoveryService",
              "Arn"
            ]
          },
          "Port": 80
        }
      ]
    }
  }
}

YAML:

EcsService:
  Type: AWS::ECS::Service
  Properties:
    Cluster: awsExampleCluster
    DesiredCount: 4
    LaunchType: FARGATE
    NetworkConfiguration:
      AwsvpcConfiguration:
        SecurityGroups:
          - sg-xxxxxxx
        Subnets:
          - subnet-xxxxxxx
    ServiceName: awsExampleService
    TaskDefinition: awsExampleTaskDefinition
    ServiceRegistries:
      - RegistryArn: !GetAtt DiscoveryService.Arn
        Port: 80

注意:awsExampleCluster 替换为您的集群,将 awsExampleService 替换为您的服务,将 awsExampleTaskDefinition 替换为您的任务定义,将 sg-xxxxxxx 替换为您的安全组 ID,并将 subnet-xxxxxxx 替换为您的子网 ID。

对于 RegistryArn 属性,将值设置为要与 Amazon ECS 服务集成的服务发现服务的 Amazon 资源名称 (ARN)。使用内部函数 Fn::GetAtt 从 AWS CloudFormation 模板中获取此值。

如果使用 awsvpc 模式,请将值设置为 Port ContainerPort ContainerName 的组合(如任务定义中所指定)。如果使用 host bridge 模式,请将值设置为 ContainerPort ContainerName (如任务定义中所指定)。

4.    打开 AWS CloudFormation 控制台,然后选择创建堆栈以根据更新的模板部署资源。

5.    要验证是否可以从 VPC 中解析您的任务,请运行以下命令:

$ dig awsExampleService.awsExampleNamespace. +short
$ dig srv awsExampleService.awsExampleNamespace. +short
$ curl awsExampleService.awsExampleNamespace. -I

注意:awsExampleService 的值是 AWS::ECS::Service 资源的名称。awsExampleNamespace 的值是 AWS::ServiceDiscovery::PrivateDnsNamespace 资源的名称。

命令将返回类似于以下内容的输出:

对于 $ dig awsExampleService.awsExampleNamespace. +short

172.31.182.0
172.31.160.124
172.31.137.81
172.31.149.244

对于 $ dig srv awsExampleService.awsExampleNamespace. +short

1 1 80 ffe95d27ea8d4f7aba0dfed87297fc5a.awsExampleService.awsExampleNamespace.
1 1 80 44a17fa781974a93bb563bc1826a8697.awsExampleService.awsExampleNamespace.
1 1 80 d640ecb3d283421bb2d1318caf4b0d66.awsExampleService.awsExampleNamespace.
1 1 80 65aff6fff33144b2ad79d283ab52cfe9.awsExampleService.awsExampleNamespace.

对于 $ curl awsExampleService.awsExampleNamespace. -I

HTTP/1.1 200 OK
Server: nginx/1.15.12
Date: Wed, 15 May 2019 02:25:19 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Apr 2019 13:08:19 GMT
Connection: keep-alive
ETag: "5cb5d3c3-264"
Accept-Ranges: bytes

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?