如何将 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 CreatePrivateDnsNamespace、CreateService (AWS Cloud Map) 和 CreateService (Amazon ECS)。在 AWS CloudFormation 中,您可以使用资源类型 AWS::ServiceDiscovery::PrivateDnsNamespace、AWS::ServiceDiscovery::Service 和 AWS::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":
},
"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": ,
"Subnets":
}
},
"ServiceName": "awsExampleService",
"TaskDefinition": "awsExampleTaskDefinition",
"ServiceRegistries":
},
"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