如何使用 AWS Cloud Map 为 ECS 服务设置跨账户服务发现?

4 分钟阅读
0

我想使用 AWS Cloud Map 为我的 Amazon Elastic Container Service (Amazon ECS) 服务设置跨账户服务发现。

简短描述

在 AWS Cloud Map 中创建私有命名空间,同时创建 Amazon Route 53 托管区。由于 Route 53 托管区与 Amazon Virtual Private Cloud (Amazon VPC) 相关联,因此 DNS 记录是可发现的。而其他 AWS 账户和 Amazon VPC 无法通过 DNS 发现 Amazon ECS 服务。

先决条件:

  • 两个位于相同或不同账户的 Amazon VPC,具有所需的子网、安全组和非重叠的 CIDR。
  • 两个 Amazon VPC 都使用 AmazonProvidedDNS,其属性 enableDnsHostnamesenableDnsSupport 处于启用状态。
  • 一个 Amazon ECS 集群。
  • 已安装最新版本的 AWS 命令行界面 (AWS CLI) 并配置了相应的权限。

**注意:**如果在运行 AWS CLI 时收到错误,请确认您运行的是最新版本的 AWS CLI

解决方法

**重要事项:**以下步骤使用了目标 Amazon VPC、源 Amazon VPC 和 Amazon ECS 集群的示例。在 AWS CLI 中,请将 example 值替换为您的值。

  • 示例 Amazon ECS 集群 example-cluster 位于 AWS 账户 1 中。
  • 示例目标 Amazon VPC example-target-vpc 托管 Amazon ECS 任务,位于 AWS 账户 1 中。
  • 示例源 Amazon VPC example-source-vpc 执行 DNS 查询,位于 AWS 账户 2 中。

创建命名空间和 AWS Cloud Map 服务

1.    使用账户 1 的凭证配置您的 AWS CLI。

2.    在账户 1 中创建私有 AWS Cloud Map 服务发现命名空间:

$ aws servicediscovery create-private-dns-namespace --name example-namespace  --vpc example-target-vpc

**注意:**前面的命令创建了名为 example-namespace 的命名空间,并返回 OperationID 作为 JSON 的输出。

3.    使用 OperationID 检查命名空间和命名空间 ID 的状态:

$ aws servicediscovery get-operation --operation-id <example-OperationId> --query 'Operation.{Status: Status, NamespaceID: Targets.NAMESPACE}'

4.    找到与命名空间关联的托管区 ID:

$ aws servicediscovery get-namespace --id <example-NamespaceID> --query 'Namespace.Properties.DnsProperties.{HoztedZoneId: HostedZoneId}'

5.    使用命名空间 ID 创建 AWS Cloud Map 服务:

$ aws servicediscovery create-service \
    --name myservice \
    --namespace-id  <example-NamespaceID> \
    --dns-config "NamespaceId=<example-NamespaceID>,RoutingPolicy=MULTIVALUE,DnsRecords=[{Type=A,TTL=60}]"

**注意:**前面的命令创建了名为 example-myservice 的 AWS Cloud Map 服务,并返回一个服务 ARN 作为输出。

注册使用 awsvpc 网络模式的任务定义

注册与 AWS Fargate 兼容并使用 awsvpc 网络模式的任务定义:

1.    创建名为 fargate-task.json 的文件,其中包含以下任务定义内容:

{
    "family": "tutorial-task-def",
        "networkMode": "awsvpc",
        "containerDefinitions": [
            {
                "name": "sample-app",
                "image": "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"
}

2.    使用 fargate-task.json 文件注册任务定义:

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

创建 Amazon ECS 服务

1.    创建名为 ecs-service-discovery.json 的文件,并包含您正在创建的 Amazon ECS 服务的内容:

  • launchType 指定为 FARGATE
  • platformVersion 指定为最新版本。
  • 确保 securityGroupssubnets 参数属于 example-target-vpc。您可以从 Amazon VPC 控制台获取安全组和子网 ID。

**注意:**由于任务定义使用 awsvpc 网络模式,因此需要 awsvpcConfiguration

JSON 文件示例:

{
    "cluster": "example-cluster",
    "serviceName": "ecs-service-discovery",
    "taskDefinition": "tutorial-task-def",
    "serviceRegistries": [
       {
          "registryArn": "<Cloudmap service ARN>"
       }
    ],
    "launchType": "FARGATE",
    "platformVersion": "example-latest-version",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "example-target-vpc-sg" ],
          "subnets": [ "example-target-vpc-subnet" ]
       }
    },
    "desiredCount": 1
}

2.    使用 ecs-service-discovery.json 文件创建您的 Amazon ECS 服务:

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

3.    确认服务任务是否已在 AWS Cloud Map 服务中注册为实例:

$ aws servicediscovery list-instances --service-id <example-cloud-map-service-id>

**注意:**现在,您的 Amazon ECS 服务在 example-target-vpc 中是可发现的了。

将源 Amazon VPC 关联到 Route 53 托管区

1.    如果 Amazon VPC 位于不同的账户中,请向账户 2 提交 Amazon VPC 关联授权请求:

$ aws route53 create-vpc-association-authorization --hosted-zone-id <example-HoztedZoneId>  --vpc VPCRegion=<example_VPC_region>,VPCId=<example-source-vpc>

2.    使用账户 2 的凭证配置 awscli,并将账户 2 中的 example-source-vpc 与账户 1 中的托管区相关联:

$ aws route53 associate-vpc-with-hosted-zone --hosted-zone-id <example-HoztedZoneId> --vpc VPCRegion=<example_VPC_region>,VPCId=<example-source-vpc>

3.    检查 example-source-vpc 是否已添加到托管区:

aws route53 get-hosted-zone --id <example-HoztedZoneId> --query 'VPCs'

4.    在 example-source-vpc 中检查通过 DNS 是否可发现 Amazon ECS 服务。使用 example-source-vpc 从 Amazon Elastic Compute Cloud (Amazon EC2) 实例查询 DNS:

$ dig +short example-service.example-namespace

**注意:**在前面的命令中,example-service.example-namespace 是 DNS 名称。将其替换为您的 AWS Cloud Map 服务和命名空间。

设置 Amazon VPC 对等连接

1.    使用 Amazon VPC 对等连接example-target-vpc 与 example-source-vpc 连接起来。

2.    更新路由表

3.    更新安全组

**注意:**在设置与路由表和安全组的 Amazon VPC 对等连接后,example-source-vpc 中的资源可以连接到 example-target-vpc 中的 Amazon ECS 任务。

如果在设置 Amazon VPC 对等连接时遇到问题,请参阅以下 AWS Knowledge Center 文章:

AWS 官方
AWS 官方已更新 1 年前