

# 互连 Amazon ECS 服务
<a name="interconnecting-services"></a>

在 Amazon ECS 任务中运行的应用程序通常需要接收来自互联网的连接或连接到在 Amazon ECS 服务中运行的其他应用程序。如果您需要来自互联网的外部连接，我们建议您使用 Elastic Load Balancing。有关集成负载均衡的更多信息，请参阅 [使用负载均衡分配 Amazon ECS 服务流量](service-load-balancing.md)。

如果您需要一个应用程序来连接到在 Amazon ECS 服务中运行的其他应用程序，Amazon ECS 会提供以下无需负载均衡器的方法来实现此目的：
+ *Amazon ECS Service Connect*

  建议使用 Service Connect，它为服务发现、连接和流量监控提供 Amazon ECS 配置。借助 Service Connect，您的应用程序可以使用短名称和标准端口连接到同一集群中的 Amazon ECS 服务，也可以连接到其他集群（包括同一 AWS 区域 的不同 VPC 中）中的 Amazon ECS 服务。

  当您使用 Service Connect 时，Amazon ECS 会管理服务发现的所有部分：创建可发现的名称，在任务开始和停止时动态管理每个任务的条目，在配置为发现名称的每个任务中运行代理。您的应用程序可以通过使用 DNS 名称的标准功能，并建立连接来查找这些名称。如果您的应用程序已执行此操作，则您无需修改应用程序即可使用 Service Connect。

  您在每项服务和任务定义中都提供完整的配置。Amazon ECS 在每个服务部署中管理对该配置的更改，以确保部署中的所有任务以相同的方式运行。例如，DNS 作为服务发现的一个常见问题是控制迁移。如果您将 DNS 名称更改为指向新的替换 IP 地址，则在所有客户端开始使用新服务之前，可能需要最大的 TTL 时间。使用 Service Connect，客户端部署将通过替换客户端任务来更新配置。您可以像配置任何其他部署一样配置部署断路器和其他部署配置，以对 Service Connect 更改造成影响。

  有关更多信息，请参阅 [使用 Service Connect 连接具有短名称的 Amazon ECS 服务](service-connect.md)。
+ *Amazon ECS 服务发现*

  服务间通信的另一种方法是使用服务发现进行直接通信。在这种方法中，您可以使用与 Amazon ECS 的 AWS Cloud Map 服务发现集成。使用服务发现，Amazon ECS 将已启动的任务列表同步到 AWS Cloud Map，后者将维护一个 DNS 主机名，该主机名解析为来自该特定服务的一个或多个任务的内部 IP 地址。Amazon VPC 中的其他服务可以使用此 DNS 主机名，以通过其内部 IP 地址将流量直接发送到另一个容器。

  这种服务间的通信方法可实现低延迟。容器之间没有额外的组件。流量直接从一个容器传递到另一个容器。

  这种方法适用于使用 `awsvpc` 网络模式时，在这种模式下，每项任务都有自己唯一的 IP 地址。大多数软件仅支持使用 DNS `A` 记录，这些记录可直接解析为 IP 地址。使用 `awsvpc` 网络模式时，每项任务的 IP 地址都是一个 `A` 记录。但是，如果您使用 `bridge` 网络模式，则多个容器可能会共享相同的 IP 地址。此外，动态端口映射会导致容器在该单个 IP 地址上被随机分配端口号。此时，`A` 记录已不足以进行服务发现。您还必须使用 `SRV` 记录。这种类型的记录可以同时跟踪 IP 地址和端口号，但需要您相应地配置应用程序。您使用的某些预建应用程序可能不支持 `SRV` 记录。

  `awsvpc` 网络模式的另一个优点是，您的每项服务都有一个唯一的安全组。您可以将此安全组配置为只允许来自需要与该服务通信的特定上游服务的传入连接。

  使用服务发现进行服务间直接通信的主要缺点是，您必须实现额外的逻辑才能进行重试和处理连接失败。DNS 记录具有生存时间（TTL），可控制其缓存时长。更新 DNS 记录和缓存过期需要一些时间，这样您的应用程序可以获取 DNS 记录的最新版本。因此，您的应用程序最终可能会将 DNS 记录解析为指向另一个不再存在的容器。您的应用程序需要处理重试，并具有忽略不良后端的逻辑。

  有关更多信息，请参阅 [使用服务发现连接具有 DNS 名称的 Amazon ECS 服务](service-discovery.md)。
+ *Amazon VPC Lattice*

  Amazon VPC Lattice 是一项托管应用程序联网服务，Amazon ECS 客户无需修改其代码即可观察、保护和监控在不同 AWS 计算服务、VPC 和账户之间构建的应用程序。

  VPC Lattice 使用目标组，即计算资源的集合。这些目标可以运行您的应用程序或服务，可以是 Amazon EC2 实例、IP 地址、Lambda 函数和应用程序负载均衡器。通过将其使用的 Amazon ECS 服务与 VPC Lattice 目标组相关联，客户现在可以在 VPC Lattice 中启用 Amazon ECS 任务作为 IP 目标。启动注册服务的任务时，Amazon ECS 会自动向 VPC Lattice 目标组注册任务。

  有关更多信息，请参阅 [使用 Amazon VPC Lattice 连接、观察和保护 Amazon ECS 服务](ecs-vpc-lattice.md)。

## 网络模式兼容性表
<a name="interconnect-network-mode-compatibility-table"></a>

下表介绍了这些选项与任务网络模式之间的兼容性。在表中，“客户端”是指从 Amazon ECS 任务内部建立连接的应用程序。


****  

| 互连选项 | 已进行桥接 | `awsvpc` | 主机 | 
| --- | --- | --- | --- | 
| 服务发现 | 是的，但要求客户端知道 DNS 中没有 hostPort 的 SRV 记录。 | 是 | 是的，但要求客户端知道 DNS 中没有 hostPort 的 SRV 记录。 | 
| Service Connect  | 是 | 是 | 否 | 
| VPC Lattice | 是 | 是 | 是 | 

# 使用 Service Connect 连接具有短名称的 Amazon ECS 服务
<a name="service-connect"></a>

Amazon ECS Service Connect 以 Amazon ECS 配置的形式提供服务间通信的管理。它在 Amazon ECS 中同时构建服务发现和服务网格。这让您可以通过服务部署控制您管理的每个服务内部的全面配置，使用不依赖 VPC DNS 配置的统一方式在命名空间中引用您的服务，以及使用标准化的指标和日志来监控您的所有应用程序。Service Connect 仅会互连服务。

下图显示了一个示例 Service Connect 网络，其具有 VPC 中的 2 个子网和有 2 个服务。一种运行 WordPress 的客户端服务，其在每个子网中有 1 个任务。一种运行 MySQL 的服务器服务，其在每个子网中有 1 个任务。这两项服务都具有很高的可用性，可以弹性应对任务和可用区问题，因为每项服务都运行分布在 2 个子网中的多个任务。实心箭头会显示从 WordPress 到 MySQL 的连接。例如，使用 IP 地址 `172.31.16.1` 在任务中从 WordPress 容器内部运行的 `mysql --host=mysql` CLI 命令。该命令在 MySQL 的默认端口上使用简称 `mysql`。此名称和端口会在同一任务中连接到 Service Connect 代理。WordPress 任务中的代理使用轮询负载均衡和异常值检测中的任何先前失败信息来选择要连接到的 MySQL 任务。如图中的实心箭头所示，代理使用 IP 地址 `172.31.16.2` 连接到 MySQL 任务中的第二个代理。第二个代理会在同一任务中连接到本地 MySQL 服务器。这两个代理均会报告连接性能，这些性能在 Amazon ECS 和 Amazon CloudWatch 控制台的图表中可见，因此您可以用相同的方式从各种应用程序中获取性能指标。

![\[显示最少 HA 服务的 Service Connect 网络示例\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/serviceconnect.png)


以下服务可与 Service Connect 一起使用：

**端口名称**  
为特定端口映射分配名称的 Amazon ECS 任务定义配置。此配置仅供 Amazon ECS Service Connect 使用。

**客户端别名**  
分配端点中使用的端口号的 Amazon ECS 服务配置。此外，客户端别名可以分配端点的 DNS 名称，覆盖发现名称。如果 Amazon ECS 服务中未提供发现名称，则客户端别名将覆盖端口名称作为端点名称。有关端点示例，请参阅*端点*的定义。可以为一项 Amazon ECS 服务分配多个客户端别名。此配置仅供 Amazon ECS Service Connect 使用。

**发现名称**  
可以为任务定义中的指定端口创建的可选中间名称。此名称用于创建 AWS Cloud Map 服务。如果此名称未提供，则使用任务定义中的端口名称。可以为 Amazon ECS 服务的特定端口分配多个发现名称。此配置仅供 Amazon ECS Service Connect 使用。  
AWS Cloud Map 服务名称在命名空间中必须是唯一的。由于此限制，对于每个命名空间中的特定任务定义，您只能有一个 Service Connect 配置，而没有发现名称。

**端点**  
连接到 API 或网站的 URL。URL 包含协议、DNS 名称和端口。有关一般端点的更多信息，请参阅《Amazon Web Services 一般参考》中的 *AWS 词汇表*中的[端点](https://docs.aws.amazon.com/glossary/latest/reference/glos-chap.html#endpoint)。  
Service Connect 创建连接到 Amazon ECS 服务的端点，并在 Amazon ECS 服务中配置任务以连接到端点。URL 包含协议、DNS 名称和端口。您可以在任务定义中选择协议和端口名称，因为该端口必须与容器映像内的应用程序匹配。在服务中，您可以按名称选择每个端口，可以分配 DNS 名称。如果您未在 Amazon ECS 服务配置中指定 DNS 名称，则默认使用任务定义中的端口名称。例如，Service Connect 端点可以是 `http://blog:80`、`grpc://checkout:8080` 或 `http://_db.production.internal:99`。

**Service Connect 服务**  
Amazon ECS 服务中单一端点的配置。这是 Service Connect 配置的一部分，由控制台中的 **Service Connect 和发现名称配置**中的单行组成，或由 Amazon ECS 服务的 JSON 配置中的 `services` 列表中的一个对象组成。此配置仅供 Amazon ECS Service Connect 使用。  
有关更多信息，请参阅《Amazon Elastic Container Service API 参考》中的 [ServiceConnectService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceConnectService.html)。

**命名空间**  
与 Service Connect 结合使用的 AWS Cloud Map 命名空间的 Amazon 资源名称（ARN）短名称或全称。命名空间必须与 Amazon ECS 服务和集群在同一个 AWS 区域 内。AWS Cloud Map 中的命名空间类型不影响 Service Connect。命名空间可以是在 AWS RAM 可用的 AWS 区域中使用 AWS Resource Access Manager（AWS RAM）与您的 AWS 账户共享的命名空间。有关共享命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)。  
Service Connect 将 AWS Cloud Map 命名空间用作相互对话的 Amazon ECS 任务的逻辑分组。每个 Amazon ECS 服务所属的命名空间只能是唯一的。命名空间内的服务可以分布在同一 AWS 区域内的不同 Amazon ECS 集群中。如果命名空间是共享命名空间，则服务可以分布在命名空间所有者和命名空间使用者 AWS 账户之间。您可以根据任何标准自由地组织服务。

**客户端服务**  
一种运行网络客户端应用程序的服务。此服务必须配置命名空间。服务中的每项任务都可以通过 Service Connect 代理容器发现并连接到命名空间中的所有端点。  
如果任务中的任何容器需要从命名空间中的服务连接到端点，请选择客户端服务。如果前端、反向代理或负载均衡器应用程序通过其他方法（例如从 Elastic Load Balancing 中）接收外部流量，则它可以使用这种类型的 Service Connect 配置。

**客户端-服务器服务**  
一种运行网络或 Web 服务应用程序的 Amazon ECS 服务。此服务必须配置命名空间和至少一个端点。使用端点即可访问服务中的每项任务。Service Connect 代理容器侦听端点名称和端口，将流量引导到任务中的应用程序容器。  
如果有任何容器公开并侦听端口上的网络流量，请选择客户端-服务器服务。这些应用程序无需连接到同一命名空间中的其他客户端-服务器服务，但需要客户端配置。后端、中间件、业务层或大多数微服务都可以使用这种类型的 Service Connect 配置。如果您希望前端、反向代理或负载均衡器应用程序接收来自在相同命名空间中的使用 Service Connect 进行配置的其他服务的流量，则这些服务应使用此类 Service Connect 配置。

Service Connect 功能可创建相关服务的虚拟网络。可以在多个不同的命名空间中使用相同的服务配置，以运行独立但相同的应用程序集。Service Connect 定义了 Amazon ECS 服务中的代理容器。通过这种方式，就可以使用相同的任务定义在具有不同 Service Connect 配置的不同命名空间中运行相同的应用程序。服务制造的每项任务都会在任务中运行一个代理容器。

Service Connect 适用于同一命名空间内的 Amazon ECS 服务之间的连接。对于以下应用程序，您需要使用其他互连方法连接到配置了 Service Connect 的 Amazon ECS 服务：
+ 在其他命名空间中配置的任务
+ 未针对 Service Connect 配置的任务
+ Amazon ECS 之外的其他应用程序

这些应用程序可以通过 Service Connect 代理进行连接，但无法解析 Service Connect 端点名称。

若要让这些应用程序解析 Amazon ECS 任务的 IP 地址，则需使用另一种互连方法。

**Topics**
+ [定价](#service-connect-pricing)
+ [Amazon ECS Service Connect 组件](service-connect-concepts-deploy.md)
+ [Amazon ECS Service Connect 配置概述](service-connect-concepts.md)
+ [使用共享 AWS Cloud Map 命名空间的 Amazon ECS Service Connect](service-connect-shared-namespaces.md)
+ [Amazon ECS Service Connect 访问日志](service-connect-envoy-access-logs.md)
+ [加密 Amazon ECS Service Connect 流量](service-connect-tls.md)
+ [使用 AWS CLI 配置 Amazon ECS Service Connect](create-service-connect.md)

## 定价
<a name="service-connect-pricing"></a>
+ Amazon ECS Service Connect 的定价取决于您是使用 AWS Fargate 还是 Amazon EC2 基础设施来托管您的容器化工作负载。在 AWS Outposts 上使用 Amazon ECS 时，则定价采用与您直接使用 Amazon EC2 时相同的模式。有关更多信息，请参阅 [Amazon ECS 定价](https://aws.amazon.com/ecs/pricing)。
+ 使用 Amazon ECS Service Connect 不收取任何额外费用。
+ 通过 Service Connect 使用 AWS Cloud Map 时，无需支付额外费用。
+ 客户为 Amazon ECS Service Connect 使用的计算资源（包括 vCPU 和内存）支付费用。由于 Amazon ECS Service Connect 代理在客户任务中运行，因此运行该任务无需额外付费。任务资源在客户工作负载和 Amazon ECS Service Connect 代理之间共享。
+ 将 Amazon ECS Service Connect 流量加密功能与 AWS 私有 CA 一起使用时，客户需要为他们创建的私有证书颁发机构以及颁发的每个 TLS 证书支付费用。有关更多详细信息，请参阅 [AWS 私有证书颁发机构 定价](https://aws.amazon.com/private-ca/pricing/)。要估算 TLS 证书的每月费用，客户需要了解启用了 TLS 的 Amazon ECS 服务的数量，将其乘以证书成本，然后再乘以六。由于 Amazon ECS Service Connect 每五天自动轮换一次 TLS 证书，因此每个 Amazon ECS 服务平均每月会颁发六个证书。

# Amazon ECS Service Connect 组件
<a name="service-connect-concepts-deploy"></a>

使用 Amazon ECS Service Connect 时，可以将每项 Amazon ECS 服务配置为运行接收网络请求的服务器应用程序（客户端-服务器服务），或者配置为运行发出请求的客户端应用程序（客户端服务）。

准备开始使用 Service Connect 时，从客户端-服务器服务开始。您可以向新服务或现有服务添加 Service Connect 配置。Amazon ECS 会在命名空间中创建一个 Service Connect 端点。此外，Amazon ECS 在服务中创建新部署以替换当前正在运行的任务。

现有任务和其他应用程序可以继续连接到现有端点和外部应用程序。如果客户端-服务器服务通过横向扩展来添加任务，则来自客户端的新连接将在所有任务之间保持平衡。如果客户端-服务器服务已更新，则来自客户端的新连接将在新版本的任务之间保持平衡。

现有任务无法解析并连接到新端点。只有在同一命名空间中具有 Service Connect 配置且在此部署之后开始运行的新任务才能解析并连接到此端点。

这意味着客户端应用程序的操作员可以决定其应用程序的配置何时更改，即使服务器应用程序的操作员可以随时更改其配置。每次部署命名空间中的任何服务时，命名空间中的端点列表都可能发生变化。现有任务和替换任务的行为将继续与最近部署后的行为相同。

考虑以下示例。

首先，假设您正在创建可在单个 AWS CloudFormation 模板和单个 CloudFormation 堆栈中供公有互联网使用的应用程序。公共发现和可访问性应最后由 CloudFormation 创建，包括前端客户端服务。服务需要按此顺序创建，以防止前端客户端服务运行并向公众开放，但后端不会。这样可以避免在此期间向公众发送错误消息。在 AWS CloudFormation 中，您必须使用 `dependsOn`，用于向 CloudFormation 指示多个 Amazon ECS 服务不能并行或同时进行。对于客户端任务连接到的每个后端客户端-服务器服务，您都应将 `dependsOn` 添加到前端客户端服务中。

其次，假设存在没有 Service Connect 配置的前端服务。任务正在连接到现有的后端服务。首先使用 **DNS** 中的相同名称或前端所用的 `clientAlias`，将客户端-服务器服务连接配置添加到后端服务。这会创建一个新部署，因此所有部署回滚检测或 AWS 管理控制台、AWS CLI、AWS 开发工具包和其他方法将后端服务回滚并恢复到先前的部署和配置。如果您对后端服务的性能和行为感到满意，请向前端服务添加客户端或客户端-服务器 Service Connect 配置。只有新部署中的任务使用添加到这些新任务中的 Service Connect 代理。如果此配置有问题，通过使用部署回滚检测或 AWS 管理控制台、AWS CLI、AWS 开发工具包和其他方法将后端服务回滚并恢复到先前的部署和配置，您可以回滚和恢复到以前的配置。如果您使用其他基于 DNS（而非 Service Connect）的服务发现系统，则在本地 DNS 缓存到期后，任何前端或客户端应用程序都会开始使用新端点并更改端点配置，这通常需要数小时。

## Networking
<a name="service-connect-concepts-network"></a>

默认情况下，Service Connect 代理从任务定义端口映射中侦听 `containerPort`。您的安全组规则必须允许从运行客户端的子网传入（进入）流量到此端口。

即使您在 Service Connect 服务配置中设置了端口号，这也不会更改 Service Connect 代理侦听的客户端-服务器服务的端口。当您设置此端口号时，Amazon ECS 会在这些任务内的 Service Connect 代理上更改客户端服务所连接的端点的端口。客户端服务中的代理使用 `containerPort` 连接到客户端-服务器服务中的代理。

如果要更改 Service Connect 代理侦听的端口，请更改客户端服务器服务的 Service Connect 配置中的 `ingressPortOverride`。如果您更改此端口号，则必须允许此端口上的入站流量，该端口由通往此服务的流量使用。

您的应用程序发送到为 Service Connect 配置的 Amazon ECS 服务的流量要求 Amazon VPC 和子网具有允许您使用的 `containerPort` 和 `ingressPortOverride` 端口号的路由表规则和网络 ACL 规则。

 您可以使用 Service Connect 在 VPC 之间发送流量。对路由表规则、网络 ACL 和安全组的相同要求同时适用于两种 VPC。

例如，两个集群在不同的 VPC 中创建任务。每个集群中的服务都配置为使用相同的命名空间。这两个服务中的应用程序无需任何 VPC DNS 配置即可解析命名空间中的每个端点。但是，除非 VPC 对等、VPC 或子网路由表以及 VPC 网络 ACL 允许 `containerPort` 和 `ingressPortOverride` 端口号上的流量，否则代理无法进行连接。

对于使用 `bridge` 联网模式的任务，您必须创建一个带有入站规则的安全组，该规则允许上动态端口范围内的流量。然后，将安全组分配给 Service Connect 集群中的所有 EC2 实例。

## Service Connect 代理
<a name="service-connect-concepts-proxy"></a>

如果使用 Service Connect 配置创建或更新服务，Amazon ECS 则会在每个新任务启动时为其添加一个新容器。这种使用单独容器的模式称为 `sidecar`。此容器不存在于任务定义中，您无法对其进行配置。Amazon ECS 在服务中管理容器配置。这允许您在多个服务、命名空间和任务之间重复使用相同的任务定义，而无需 Service Connect。

**代理资源**
+ 对于任务定义，您必须设置 CPU 和内存参数。

  我们建议为 Service Connect 代理容器的任务 CPU 和内存额外添加 256 个 CPU 单元和至少 64MiB 的内存。在 AWS Fargate 上，可以设置的最低内存量为 512 MiB 内存。在 Amazon EC2 上，任务定义内存是必需的。
+ 对于该服务，您可以在 Service Connect 配置中设置日志配置。
+ 如果您希望此服务中的任务在峰值负载时每秒收到超过 500 个请求，我们建议在此 Service Connect 代理容器的任务定义中向您的任务 CPU 添加 512 个 CPU 单元。
+ 如果您希望在命名空间中创建 100 个以上的 Service Connect 服务，或者在命名空间内的所有 Amazon ECS 服务中总共创建 2000 个任务，我们建议在 Service Connect 代理容器的任务内存中添加 128 MiB 的内存。在命名空间中的所有 Amazon ECS 服务使用的每个任务定义中，您都应该执行此操作。

**代理配置**  
您的应用程序通过与应用程序相同的任务连接到 sidecar 容器中的代理。Amazon ECS 会配置任务和容器，以便只有当应用程序连接到同一命名空间中的端点名称时，应用程序才会连接到代理。所有其他流量都不使用此代理。其他流量包括同一 VPC 中的 IP 地址、AWS 服务端点和外部流量。

**负载均衡**  
Service Connect 将代理配置为使用轮询策略在 Service Connect 端点中的任务之间进行负载均衡。连接所在任务中的本地代理在提供端点的客户端-服务器服务中挑选其中一个任务。  
例如，考虑一个在名为 *local* 的命名空间中配置为*客户端服务*的服务中运行 WordPress 的任务。还有另一项包含运行 MySQL 数据库的 2 个任务的服务。此服务配置为在同一命名空间中通过 Service Connect 提供一个称为 `mysql` 的端点。在 WordPress 任务中，WordPress 应用程序会使用端点名称连接到数据库。与该名称的连接会转到在同一个任务中在 sidecar 容器中运行的代理。然后，代理可以使用轮询策略连接到任一 MySQL 任务。  
负载均衡策略：轮询

**异常检测**  
此功能使用代理拥有的有关先前失败连接的数据，以避免向已连接失败的主机发送新连接。Service Connect 配置代理的异常检测功能以提供被动运行状况检查。  
使用上一个示例，代理可以连接到任一 MySQL 任务。如果代理与特定 MySQL 任务建立了多个连接，并且在过去 30 秒内有 5 个或以上的连接失败，则代理会在 30 到 300 秒内避开该 MySQL 任务。

** 重试**  
Service Connect 将代理配置为重试通过代理但失败的连接，第二次尝试将避免使用先前连接中的主机。这样可以确保通过 Service Connect 所进行的每次连接都不会因为一次性原因而失败。  
重试次数：2

**超时**  
Service Connect 将代理配置为客户端-服务器应用程序响应的最长等待时间。默认超时值为 15 秒，但该值可以更新。  
可选参数：  
**idleTimeout** ‐ 连接在空闲时保持活动状态的时间（以秒为单位）。值为 `0` 将禁用 `idleTimeout`。  
`HTTP`/`HTTP2`/`GRPC` 的 `idleTimeout` 默认值为 5 分钟。  
`TCP` 的 `idleTimeout` 默认值为 1 小时。  
**perRequestTimeout** – 等待上游对每个请求做出完整响应的时长。值为 `0` 将关闭 `perRequestTimeout`。仅当应用程序容器的 `appProtocol` 为 `HTTP`/`HTTP2`/`GRPC` 时才能设置此选项。默认值为 15 秒。  
如果将 `idleTimeout` 设置为小于 `perRequestTimeout` 的时间，则连接将在达到 `idleTimeout` 而不是 `perRequestTimeout` 时关闭。

## 注意事项
<a name="service-connect-considerations"></a>

在使用 Service Connect 时请注意以下事项：
+ 在 Fargate 中运行的任务必须使用 Fargate Linux 平台版本 `1.4.0` 或更高版本才能使用 Service Connect。
+ 容器实例上的 Amazon ECS 代理版本必须为 `1.67.2` 或更高版本。
+ 容器实例必须运行经 Amazon ECS 优化的 Amazon Linux 2023 AMI 版本 `20230428` 或更高版本或者经 Amazon ECS 优化的 Amazon Linux 2 AMI 版本 `2.0.20221115` 才能使用 Service Connect。除了 Amazon ECS 容器代理之外，这些版本还具有 Service Connect 代理。有关 Service Connect 代理的更多信息，请参阅 GitHub 上的 [Amazon ECS Service Connect 代理](https://github.com/aws/amazon-ecs-service-connect-agent)。
+ 容器实例必须具有对资源 `arn:aws:ecs:region:0123456789012:task-set/cluster/*` 的 `ecs:Poll` 权限。如果您使用的是 `ecsInstanceRole`，则无需添加其他权限。`AmazonEC2ContainerServiceforEC2Role` 托管策略具有必要权限。有关更多信息，请参阅 [Amazon ECS 容器实例 IAM 角色](instance_IAM_role.md)。
+ 使用 `bridge` 网络模式并使用 Service Connect 的任务不支持 `hostname` 容器定义参数。
+ 任务定义必须设置任务内存限制才能使用 Service Connect。有关更多信息，请参阅 [Service Connect 代理](#service-connect-concepts-proxy)。
+ 不支持设置容器内存限制的任务定义。

  您可以在容器上设置容器内存限制，但必须将任务内存限制设置为大于容器内存限制总和的数字。未在容器限制中分配的任务限制中的额外 CPU 和内存将由 Service Connect 代理容器和其他未设置容器限制的容器使用。有关更多信息，请参阅 [Service Connect 代理](#service-connect-concepts-proxy)。
+ 您可以将 Service Connect 配置为使用同一区域中的任何 AWS Cloud Map 命名空间，这些命名空间要么位于同一 AWS 账户中，要么使用 AWS Resource Access Manager 与您的 AWS 账户共享。有关如何使用共享命名空间的更多信息，请参阅 [使用共享 AWS Cloud Map 命名空间的 Amazon ECS Service Connect](service-connect-shared-namespaces.md)。
+ 每个服务所属的命名空间只能是唯一的。
+ 仅支持服务创建的任务。
+ 所有端点在命名空间内必须是唯一的。
+ 所有发现名称在命名空间内必须是唯一的。
+ 您必须重新部署现有服务，然后应用程序才能解析新的端点。在最新部署后添加到命名空间的新端点不会添加到任务配置中。有关更多信息，请参阅 [Amazon ECS Service Connect 组件](#service-connect-concepts-deploy)。
+ 删除集群时，Service Connect 不会删除命名空间。您必须删除 AWS Cloud Map 中的命名空间。
+ 应用程序负载均衡器流量默认为在 `awsvpc` 网络模式下通过 Service Connect 代理进行路由。如果您希望非服务流量绕过 Service Connect 代理，则请在 Service Connect 服务配置中使用 `[ingressPortOverride](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceConnectService.html)` 参数。
+ 采用 TLS 的 Service Connect 不支持 `bridge` 联网模式。仅支持 `awsvpc` 联网模式。
+ 在 `awsvpc` 模式下，Service Connect 代理将仅 IPv4 和双堆栈配置中服务的流量转发到 IPv4 本地主机 `127.0.0.1`。对于仅 IPv6 配置中的服务，代理将流量转发到 IPv6 本地主机 `::1`。我们建议将应用程序配置为侦听两个本地主机，以便在服务从仅 IPv4 或双堆栈配置更新为仅 IPv6 时获得无缝体验。有关更多信息，请参阅[EC2 的 Amazon ECS 任务联网选项](task-networking.md)和[Fargate 的 Amazon ECS 任务联网选项](fargate-task-networking.md)。

**Service Connect 不支持以下各项：**
+ Windows 容器
+ HTTP 1.0
+ 独立任务
+ 使用蓝绿部署（由 CodeDeploy 提供支持）和外部部署类型的服务
+ Service Connect 不支持 Amazon ECS Anywhere 的 `External` 容器实例。
+ PPv2
+ FIPS 模式

# Amazon ECS Service Connect 配置概述
<a name="service-connect-concepts"></a>

使用 Service Connect 时，需要在资源中配置一些参数。

下表介绍了 Amazon ECS 资源的配置参数。


| 参数位置 | 应用程序类型 | 说明 | 必填 | 
| --- | --- | --- | --- | 
| 任务定义 | 客户端 | 在客户端任务定义中，Service Connect 没有可用的更改。 | 不适用 | 
| 任务定义 | 客户端-服务器 | 服务器必须向容器的 portMappings 中的端口添加 name 字段。有关更多信息，请参阅 [portMappings](task_definition_parameters.md#ContainerDefinition-portMappings)。 | 是 | 
| 任务定义 | 客户端-服务器 | 服务器可以选择提供应用程序协议（例如，HTTP）来接收其服务器应用程序的协议特定的指标（例如，HTTP 5xx）。 | 否 | 
| 服务定义 | 客户端 | 客户端服务必须添加 serviceConnectConfiguration 才能配置要加入的命名空间。此命名空间必须包含该服务需要发现的所有服务器服务。有关更多信息，请参阅 [serviceConnectConfiguration](service_definition_parameters.md#Service-serviceConnectConfiguration)。 | 是 | 
| 服务定义 | 客户端-服务器 | 服务器服务必须添加 serviceConnectConfiguration 才能配置提供该服务的 DNS 名称、端口号和命名空间。有关更多信息，请参阅 [serviceConnectConfiguration](service_definition_parameters.md#Service-serviceConnectConfiguration)。 | 是 | 
| 集群 | 客户端 | 集群可以添加默认的 Service Connect 命名空间。在服务中配置 Service Connect 后，集群中的新服务会继承命名空间。 | 否 | 
| 集群 | 客户端-服务器 | 在适用于服务器服务的集群中，Service Connect 没有可用的更改。服务器任务定义和服务必须设置相应的配置。 | 不适用 | 

**配置 Service Connect 的步骤概述**  
以下步骤概述了如何配置 Service Connect。

**重要**  
 Service Connect 在您的账户中创建 AWS Cloud Map 服务。通过手动注册/取消注册实例、更改实例属性或删除服务来修改这些 AWS Cloud Map 资源可能会导致应用程序流量或后续部署出现意外行为。
 Service Connect 不支持任务定义中的链接。

1. 将端口名称添加到您的任务定义的端口映射中。此外，您可以识别应用程序的第 7 层协议，以获得更多指标。

1. 创建带有 AWS Cloud Map 命名空间的集群，使用共享命名空间，或者单独创建命名空间。对于简单的组织，使用您想要用于命名空间的名称创建一个集群并为命名空间指定相同的名称。在这种情况下，Amazon ECS 使用必要的配置创建了一个新的 HTTP 命名空间。Service Connect 不在 Amazon Route 53 中使用或创建 DNS 托管区。

1. 配置服务以在命名空间内创建 Service Connect 端点。

1. 部署服务以创建端点。Amazon ECS 向每个任务添加一个 Service Connect 代理容器，并在 AWS Cloud Map 中创建 Service Connect 端点。此容器未在任务定义中配置，任务定义无需修改即可重复使用，以便在同一个命名空间或多个命名空间中创建多个服务。

1. 将客户端应用程序部署为服务以连接到端点。Amazon ECS 通过每项任务中的 Service Connect 代理将它们连接到 Service Connect 端点。

   应用程序仅会使用代理连接到 Service Connect 端点。无需其他配置，即可使用代理。代理执行轮询负载均衡、异常值检测和重试。有关代理的更多信息，请参阅 [Service Connect 代理](service-connect-concepts-deploy.md#service-connect-concepts-proxy)。

1. 通过 Amazon CloudWatch 中的 Service Connect 代理监控流量。

## 集群配置
<a name="service-connect-concepts-cluster-defaults"></a>

您可以在创建或更新集群时设置 Service Connect 的默认命名空间。您指定为默认值的命名空间名称可以位于同一 AWS 区域和账户中，也可以位于同一 AWS 区域并使用 AWS Resource Access Manager 与其他 AWS 账户共享。

如果您创建集群并指定默认 Service Connect 命名空间，则在 Amazon ECS 创建命名空间期间，该集群将处于 `PROVISIONING` 状态等待。您可以在集群的状态中看到一个 `attachment`，它显示了命名空间的状态。默认情况下，附件不显示在 AWS CLI 中，您必须添加 `--include ATTACHMENTS` 才能查看。

如果您想要使用通过 AWS RAM 与您的 AWS 账户共享的命名空间，请在集群配置中指定命名空间的 Amazon 资源名称（ARN）。有关共享 AWS Cloud Map 命名空间的更多信息，请参阅 [使用共享 AWS Cloud Map 命名空间的 Amazon ECS Service Connect](service-connect-shared-namespaces.md)。

## 服务配置
<a name="service-connect-concepts-config"></a>

Service Connect 旨在要求最低配置。您需要为要在任务定义中与 Service Connect 结合使用的每个端口映射设置一个名称。在服务中，您需要开启 Service Connect，并在 AWS 账户中选择一个命名空间或共享命名空间来创建客户端服务。要创建客户端-服务器服务，您需要添加与其中一个端口映射的名称相匹配的单个 Service Connect 服务配置。Amazon ECS 重复使用任务定义中的端口号和端口名来定义 Service Connect 服务和端点。要覆盖这些值，您可以在控制台中使用其他参数 **Discovery**、**DNS** 和 **Port**，或者在 Amazon ECS API 中分别使用 `discoveryName` 和 `clientAliases`。

## 初始运行状况检查配置
<a name="service-connect-concepts-health-check"></a>

Service Connect 确保任务运行状况良好后才会将流量路由到这些任务。当任务启动时（在部署、扩展或替换期间），Service Connect 会监控任务的运行状况，确保任务已准备好接受流量。您必须在任务定义中为必备容器定义运行状况检查，才能启用此功能。

初始运行状况检查的行为考虑了任务准备好接受流量时到达状态时的潜在延迟：
+ 如果任务状态为 `HEALTHY`，则它将立即可用于流量。
+ 如果任务的运行状况为 `UNKNOWN`，则 Service Connect 会遵循任务必备容器的容器运行状况检查配置（请参阅[运行状况检查](task_definition_parameters.md#container_definition_healthcheck)）来计算超时时间（最长 `8 minutes`），然后再将其提供给流量，即使它仍然 `UNKNOWN`。
+ 如果任务状态为 `UNHEALTHY`，Amazon ECS 可能会启动替换任务。如果没有运行正常的任务可用，则可能会根据您的服务配置回滚部署。

对于所有持续流量，Service Connect 会使用基于异常值检测的被动运行状况检查来有效地路由流量。

# 使用共享 AWS Cloud Map 命名空间的 Amazon ECS Service Connect
<a name="service-connect-shared-namespaces"></a>

Amazon ECS Service Connect 支持在同一 AWS 区域内的多个 AWS 账户之间使用共享 AWS Cloud Map 命名空间。此功能使您能够创建分布式应用程序，其中运行在不同 AWS 账户中的服务可以通过 Service Connect 发现彼此并相互通信。共享命名空间使用 AWS Resource Access Manager（AWS RAM）进行管理，它允许安全的跨账户资源共享。有关共享命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)。

**重要**  
您必须使用 `AWSRAMPermissionCloudMapECSFullPermission` 托管权限来共享命名空间，Service Connect 才能与命名空间正常协作。

当您将共享 AWS Cloud Map 命名空间与 Service Connect 结合使用时，来自多个 AWS 账户的服务可以参与同一个服务命​​名空间。这对于拥有多个 AWS 账户、需要跨账户边界维护服务间通信同时确保安全性和隔离的组织来说特别有用。

**注意**  
要与不同 VPC 中的服务进行通信，您需要配置 VPC 间连接。这可以使用 VPC 对等连接来实现。有关更多信息，请参阅《Amazon Virtual Private Cloud VPC 对等连接指南》**中的[创建或删除 VPC 对等连接](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html)。

# 将共享的 AWS Cloud Map 命名空间与 Amazon ECS Service Connect 结合使用
<a name="service-connect-shared-namespaces-setup"></a>

为 Service Connect 设置共享的 AWS Cloud Map 命名空间涉及以下步骤：命名空间所有者创建命名空间，所有者通过 AWS Resource Access Manager（AWS RAM）共享命名空间，使用者接受资源共享，以及使用者配置 Service Connect 以使用共享命名空间。

## 步骤 1：创建 AWS Cloud Map 命名空间
<a name="service-connect-shared-namespaces-create"></a>

命名空间所有者创建一个将与其他账户共享的 AWS Cloud Map 命名空间。

**使用 AWS 管理控制台创建要共享的命名空间**

1. 打开 AWS Cloud Map 控制台，地址：[https://console.aws.amazon.com/cloudmap/](https://console.aws.amazon.com/cloudmap/)。

1. 选择**创建命名空间**。

1. 输入**命名空间名称**。所有参与账户的服务都将使用此名称。

1. 对于**命名空间类型**，请为您的使用案例选择合适的类型：
   + **API 调用** ‐ 用于服务发现的 HTTP 命名空间，没有 DNS 功能。
   + **VPC 中的 API 调用和 DNS 查询** ‐ 用于服务发现的私有 DNS 命名空间，具有 VPC 中的私有 DNS 查询。
   + **API 调用和公有 DNS 查询** ‐ 用于服务发现的公有 DNS 命名空间，具有公有 DNS 查询。

1.  选择**创建命名空间**。

## 步骤 2：使用 AWS RAM 共享命名空间
<a name="service-connect-shared-namespaces-share"></a>

命名空间所有者使用 AWS RAM 与其他 AWS 账户共享命名空间。

**使用 AWS RAM 控制台共享命名空间**

1. 打开 AWS RAM 控制台（[https://console.aws.amazon.com/ram/](https://console.aws.amazon.com/ram/)）。

1. 选择**创建资源共享**。

1. 对于**名称**，键入资源共享的描述性名称。

1. 在**资源**部分：

   1. 对于**资源类型**，选择 **Cloud Map 命名空间**。

   1. 选择您在上一步中创建的命名空间。

1. 在**托管权限**部分，指定 **AWSRAMPermissionCloudMapECSFullPermission**。
**重要**  
您必须使用 `AWSRAMPermissionCloudMapECSFullPermission` 托管权限来共享命名空间，Service Connect 才能与命名空间正常协作。

1. 在**主体**部分，指定要与其共享命名空间的 AWS 账户。您可以输入账户 ID 或组织单元 ID。

1. 选择**创建资源共享**。

## 步骤 3：接受资源共享
<a name="service-connect-shared-namespaces-accept"></a>

命名空间使用者账户必须接受资源共享邀请才能使用共享命名空间。

**使用 AWS RAM 控制台接受资源共享邀请**

1. 在使用者账户中，打开 AWS RAM 控制台，网址为 [https://console.aws.amazon.com/ram/](https://console.aws.amazon.com/ram/)。

1. 在导航窗格中，选择**与我共享**，然后选择**资源共享**。

1. 选择资源共享邀请，然后选择**接受资源共享**。

1. 接受后，请记下资源详细信息中的共享命名空间 ARN。配置 Service Connect 服务时，您将使用此 ARN。

## 步骤 4：为 Amazon ECS 服务配置共享命名空间
<a name="service-connect-shared-namespaces-configure"></a>

接受共享命名空间后，命名空间使用者可以将 Amazon ECS 服务配置为使用共享命名空间。该配置与使用常规命名空间类似，但您必须指定命名空间 ARN 而不是名称。有关详细的服务创建过程，请参阅 [创建 Amazon ECS 滚动更新部署](create-service-console-v2.md)。

**使用AWS 管理控制台创建具有共享命名空间的服务**

1. 在 [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2) 打开控制台。

1. 在**集群**页面上，选择要在其中创建服务的集群。

1. 在**服务**下，选择**创建**。

1. 根据工作负载填写其他详细信息后，请在 **Service Connect** 部分中选择**使用 Service Connect**。

1. 对于**命名空间**，输入共享命名空间的完整 ARN。

   ARN 格式为：`arn:aws:servicediscovery:region:account-id:namespace/namespace-id`。

1. 根据需要为服务类型（客户端或客户端-服务器）配置剩余 Service Connect 设置。

1. 完成服务创建过程。

您还可以使用 AWS CLI 或 AWS SDK，通过在 `serviceConnectConfiguration` 的 `namespace` 参数中指定共享命名空间 ARN 来配置服务。

```
aws ecs create-service \
    --cluster my-cluster \
    --service-name my-service \
    --task-definition my-task-def \
    --service-connect-configuration '{
        "enabled": true,
        "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-abcdef1234567890",
        "services": [{
            "portName": "web",
            "discoveryName": "my-service",
            "clientAliases": [{
                "port": 80,
                "dnsName": "my-service"
            }]
        }]
    }'
```

## 注意事项
<a name="service-connect-shared-namespaces-considerations"></a>

在将共享 AWS Cloud Map 命名空间与 Service Connect 结合使用时，请注意以下事项：
+ AWS RAM 必须在要使用共享命名空间的 AWS 区域可用。
+ 共享命名空间必须与您的 Amazon ECS 服务和集群位于同一 AWS 区域。
+ 在为 Service Connect 配置共享命名空间时，您必须使用命名空间 ARN，而不是 ID。
+ 所有命名空间类型均受支持：HTTP、私有 DNS 和公有 DNS 命名空间。
+ 如果撤消对共享命名空间的访问，则需要与该命名空间交互的 Amazon ECS 操作（例如 `CreateService`、`UpdateService` 和 `ListServicesByNamespace`）将失败。有关排查共享命名空间权限问题的更多信息，请参阅 [排查将 Amazon ECS Service Connect 与共享的 AWS Cloud Map 命名空间结合使用时出现的问题](service-connect-shared-namespaces-troubleshooting.md)。
+ 对于在共享私有 DNS 命名空间中使用 DNS 查询的服务发现：
  + 命名空间所有者需要使用与命名空间关联的私有托管区的 ID 以及使用者的 VPC 调用 `create-vpc-association-authorization`。

    ```
    aws route53 create-vpc-association-authorization --hosted-zone-id Z1234567890ABC --vpc VPCRegion=us-east-1,VPCId=vpc-12345678
    ```
  + 命名空间使用者需要使用私有托管区的 ID 调用 `associate-vpc-with-hosted-zone`。

    ```
    aws route53 associate-vpc-with-hosted-zone --hosted-zone-id Z1234567890ABC --vpc VPCRegion=us-east-1,VPCId=vpc-12345678
    ```
+ 仅命名空间所有者可以管理资源共享。
+ 命名空间使用者可以在共享命名空间内创建和管理服务，但不能修改命名空间本身。
+ 无论哪个账户创建服务，发现名称在共享命名空间内都必须是唯一的。
+ 共享命名空间中的服务可以发现并连接到有权访问该命名空间的其他 AWS 账户中的服务。
+ 在为 Service Connect 启用 TLS 并使用共享命名空间时，AWS 私有 CA 证书颁发机构（CA）的作用域限定为该命名空间。当对共享命名空间的访问被撤销时，对 CA 的访问也会停止。
+ 在使用共享命名空间时，命名空间所有者和使用者默认情况下无法访问跨账户 Amazon CloudWatch 指标。目标指标仅发布到拥有客户端服务的账户。拥有客户端服务的账户无法访问拥有客户端-服务器服务的账户接收到的指标，反之亦然。要允许跨账户访问指标，请设置 CloudWatch 跨账户可观测性。有关配置跨账户可观测性的更多信息，请参阅《Amazon CloudWatch 用户指南》**中的 [CloudWatch 跨账户可观测性](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html)。有关 Service Connect 的 CloudWatch 指标的更多信息，请参阅 [Amazon ECS CloudWatch 指标](available-metrics.md)。

# 排查将 Amazon ECS Service Connect 与共享的 AWS Cloud Map 命名空间结合使用时出现的问题
<a name="service-connect-shared-namespaces-troubleshooting"></a>

请使用以下信息排查共享 AWS Cloud Map 命名空间和 Service Connect 的问题。有关查找错误消息的更多信息，请参阅 [Amazon ECS 故障排除](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/troubleshooting.html)。

由于缺少权限或者如果命名空间的访问被撤销，会出现与权限问题相关的错误消息。

**重要**  
您必须使用 `AWSRAMPermissionCloudMapECSFullPermission` 托管权限来共享命名空间，Service Connect 才能与命名空间正常协作。

错误消息会以以下格式之一显示：

An error occurred (ClientException) when calling the <OperationName> operation: User: arn:aws:iam::<account-id>:user/<user-name> is not authorized to perform: <ActionName> on resource: <ResourceArn> because no resource-based policy allows the <ActionName> action（调用 <OperationName> 操作时发生错误 (ClientException)：用户 arn:aws:iam::<account-id>:user/<user-name> 无权对资源 <ResourceArn> 执行 <ActionName>，因为没有任何基于资源的策略允许执行 <ActionName> 操作）

以下情况可能会导致出现此格式的错误消息：

**集群创建或更新失败**  
当 Amazon ECS 操作（例如 `CreateCluster` 或 `UpdateCluster`）因缺少 AWS Cloud Map 权限而失败时，就会出现这些问题。这些操作需要以下 AWS Cloud Map 操作的权限：  
+ `servicediscovery:GetNamespace`
确保使用者账户已接受资源共享邀请，并且在 Service Connect 配置中使用正确的命名空间 ARN。

**服务创建或更新失败**  
当 Amazon ECS 操作（例如 `CreateService` 或 `UpdateService`）因缺少 AWS Cloud Map 权限而失败时，就会出现这些问题。这些操作需要以下 AWS Cloud Map 操作的权限：  
+ `servicediscovery:CreateService`
+ `servicediscovery:GetNamespace`
+ `servicediscovery:GetOperation`（用于创建新的 AWS Cloud Map 服务）
+ `servicediscovery:GetService`（当 AWS Cloud Map 服务已存在时）
确保使用者账户已接受资源共享邀请，并且在 Service Connect 配置中使用正确的命名空间 ARN。

**`ListServicesByNamespace` 操作失败**  
当 Amazon ECS `ListServicesByNamespace` 操作失败时，会出现此问题。此操作需要以下 AWS Cloud Map 操作的权限：  
+ `servicediscovery:GetNamespace`
要解决此问题，请执行以下操作：  
+ 验证使用者账户是否具有 `servicediscovery:GetNamespace` 权限。
+ 调用 API 时使用命名空间 ARN，而不是名称。
+ 确保资源共享处于活动状态并且已接受邀请。

User: <iam-user> is not authorized to perform: <ActionName> on resource: <ResourceArn> with an explicit deny in an identity-based policy.（用户 <iam-user> 无权对资源 <ResourceArn> 执行 <ActionName>，因为基于身份的策略中存在明确拒绝。）

以下情况可能会导致出现此格式的错误消息：

**服务删除失败并停滞在 `DRAINING` 状态**  
如果对命名空间的访问被撤销，则当 Amazon ECS `DeleteService` 操作因缺少 `servicediscovery:DeleteService` 权限而失败时，会出现此问题。该服务最初可能看似已成功删除，但会停滞在 `DRAINING` 状态。错误消息会显示为 Amazon ECS 服务事件。  
要解决此问题，命名空间所有者必须与使用者账户共享命名空间，以允许完成服务删除。

**服务中的任务运行失败**  
当任务因缺少权限而启动失败时，会出现此问题。错误消息显示为任务停止错误。有关更多信息，请参阅 [解决 Amazon ECS 已停止任务错误](resolve-stopped-errors.md)。  
运行任务需要以下 AWS Cloud Map 操作：  
+ `servicediscovery:GetOperation`
+ `servicediscovery:RegisterInstance`
确保使用者账户拥有所需的权限，并且可以访问共享命名空间。

**任务无法干净地停止或者停滞在 `DEACTIVATING` 或 `DEPROVISIONING` 状态**  
当任务在关闭期间因缺少权限而无法从 AWS Cloud Map 服务注销时，会出现此问题。错误作为 `statusReason` 显示在任务附加中，可以使用 `DescribeTasks` API 进行检索。有关更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [DescribeTasks](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DescribeTasks.html)。  
停止任务需要以下 AWS Cloud Map 操作：  
+ `servicediscovery:DeregisterInstance`
+ `servicediscovery:GetOperation`
如果对共享命名空间的访问被撤销，则任务可能会保持 `DEACTIVATING` 或 `DEPROVISIONING` 状态，直到命名空间访问恢复。请请求命名空间所有者恢复对命名空间的访问。

# Amazon ECS Service Connect 访问日志
<a name="service-connect-envoy-access-logs"></a>

Amazon ECS Service Connect 支持访问日志，以提供有关 Service Connect 代理处理的各个请求的详细遥测数据。访问日志通过捕获每个请求的流量元数据（例如，HTTP 方法、路径、响应代码、标志和计时信息）来补充现有应用程序日志。这样可以更深入地观察请求级别的流量模式和服务交互，从而有效地进行故障排除和监控。

要启用访问日志，请在 `serviceConnectConfiguration` 对象中同时指定 `logConfiguration` 和 `accessLogConfiguration` 对象。您可以在 `accessLogConfiguration` 中配置日志格式以及日志是否应包含查询参数。日志会通过 `logConfiguration` 中指定的日志驱动程序传输到目标日志组。

```
{
    "serviceConnectConfiguration": {
        "enabled": true,
        "namespace": "myapp.namespace",
        "services": [
            ...
        ],
        "logConfiguration": {
            "logDriver": "awslogs",
            "options": {
                "awslogs-group": "my-envoy-log-group",
                "awslogs-region": "us-west-2",
                "awslogs-stream-prefix": "myapp-envoy-logs"
            }
        },
         "accessLogConfiguration": {
            "format": "TEXT",
            "includeQueryParameters": "ENABLED" 
        }
    }
}
```

## 注意事项
<a name="service-connect-envoy-access-logs-considerations"></a>

在启用对访问日志的权限时，请考虑以下事项
+ 访问日志和应用程序日志都会写入 `/dev/stdout`。为了将访问日志与应用程序日志分开，我们建议使用带有自定义 Fluent Bit 或 Fluentd 配置的 `awsfirelens` 日志驱动程序。
+  我们建议使用 `awslogs` 日志驱动程序将应用程序和访问日志发送到同一个 CloudWatch 目标。
+ 使用平台版本 `1.4.0` 及更高版本的 Fargate 服务支持访问日志。
+ 默认情况下，访问日志中不包含请求 ID 和令牌等查询参数。要在访问日志中包含查询参数，请将 `includeQueryParameters` 设置为 `"ENABLED"`。

## 访问日志格式
<a name="service-connect-envoy-access-logs-formats"></a>

访问日志可以采用 JSON 格式字典或文本格式字符串格式，不同类型的访问日志支持的命令运算符不同。

### HTTP 访问日志
<a name="service-connect-envoy-access-logs-formats-http"></a>

HTTP 日志默认包含以下命令运算符：

------
#### [ Text ]

```
[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%"
%RESPONSE_CODE% %BYTES_RECEIVED% %BYTES_SENT% %DURATION%
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%"
"%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
```

------
#### [ JSON ]

```
{
  "start_time": "%START_TIME%",
  "method": "%REQ(:METHOD)%",
  "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
  "protocol": "%PROTOCOL%",
  "response_code": "%RESPONSE_CODE%",
  "bytes_received": "%BYTES_RECEIVED%",
  "bytes_sent": "%BYTES_SENT%",
  "duration_ms": "%DURATION%",
  "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
  "forwarded_for": "%REQ(X-FORWARDED-FOR)%",
  "user_agent": "%REQ(USER-AGENT)%",
  "request_id": "%REQ(X-REQUEST-ID)%",
  "authority": "%REQ(:AUTHORITY)%",
  "upstream_host": "%UPSTREAM_HOST%"
}
```

------

### HTTP2 访问日志
<a name="service-connect-envoy-access-logs-formats-http2"></a>

除了 HTTP 日志包含的命令运算符外，HTTP2 日志默认还包含 `%STREAM_ID%` 运算符。

------
#### [ Text ]

```
[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%"
%RESPONSE_CODE% %BYTES_RECEIVED% %BYTES_SENT% %DURATION%
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%"
"%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" "%STREAM_ID%"\n
```

------
#### [ JSON ]

```
{
  "start_time": "%START_TIME%",
  "method": "%REQ(:METHOD)%",
  "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
  "protocol": "%PROTOCOL%",
  "response_code": "%RESPONSE_CODE%",
  "bytes_received": "%BYTES_RECEIVED%",
  "bytes_sent": "%BYTES_SENT%",
  "duration": "%DURATION%",
  "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
  "forwarded_for": "%REQ(X-FORWARDED-FOR)%",
  "user_agent": "%REQ(USER-AGENT)%",
  "request_id": "%REQ(X-REQUEST-ID)%",
  "authority": "%REQ(:AUTHORITY)%",
  "upstream_host": "%UPSTREAM_HOST%",
  "stream_id": "%STREAM_ID%"
}
```

------

### gRPC 访问日志
<a name="service-connect-envoy-access-logs-formats-grpc"></a>

除了 HTTP 日志包含的命令运算符外，gRPC 访问日志默认还包含 `%STREAM_ID%` 和 `%GRPC_STATUS()%` 运算符。

------
#### [ Text ]

```
[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%"
%RESPONSE_CODE% %GRPC_STATUS()% %BYTES_RECEIVED% %BYTES_SENT% %DURATION%
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%"
"%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" "%STREAM_ID%"\n
```

------
#### [ JSON ]

```
{
  "start_time": "%START_TIME%",
  "method": "%REQ(:METHOD)%",
  "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
  "protocol": "%PROTOCOL%",
  "response_code": "%RESPONSE_CODE%",
  "grpc_status": "%GRPC_STATUS()%",
  "bytes_received": "%BYTES_RECEIVED%",
  "bytes_sent": "%BYTES_SENT%",
  "duration": "%DURATION%",
  "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
  "forwarded_for": "%REQ(X-FORWARDED-FOR)%",
  "user_agent": "%REQ(USER-AGENT)%",
  "request_id": "%REQ(X-REQUEST-ID)%",
  "authority": "%REQ(:AUTHORITY)%",
  "upstream_host": "%UPSTREAM_HOST%",
  "stream_id": "%STREAM_ID%"
}
```

------

### TCP 访问日志
<a name="service-connect-envoy-access-logs-formats-tcp"></a>

TCP 访问日志默认包含以下命令运算符：

------
#### [ Text ]

```
[%START_TIME%] %DOWNSTREAM_REMOTE_ADDRESS% %DOWNSTREAM_REMOTE_PORT% 
%BYTES_RECEIVED% %BYTES_SENT% %DURATION%  
%CONNECTION_TERMINATION_DETAILS% %CONNECTION_ID%\n
```

------
#### [ JSON ]

```
{
  "start_time": "%START_TIME%",
  "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
  "downstream_remote_port": "%DOWNSTREAM_REMOTE_PORT%",s
  "bytes_received": "%BYTES_RECEIVED%",
  "bytes_sent": "%BYTES_SENT%",
  "duration": "%DURATION%",
  "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%",
  "connection_id": %CONNECTION_ID%
}
```

------

有关这些命令运算符的更多信息，请参阅 Envoy 文档中的 [Command Operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators)。

# 为 Amazon ECS Service Connect 启用访问日志
<a name="service-connect-access-logs-configuration"></a>

默认情况下，使用 Service Connect 的 Amazon ECS 服务不启用访问日志。您可以通过以下方式启用访问日志。

## 使用 AWS CLI 启用访问日志
<a name="service-connect-access-logs-configure-cli"></a>

以下命令展示了如何使用 AWS CLI 通过在创建 Amazon ECS 服务时指定 `accessLogConfiguration` 来为这些服务启用访问日志：

```
aws ecs create-service \
    --cluster my-cluster \
    --service-name my-service \
    --task-definition my-task-def \
    --service-connect-configuration '{
        "enabled": true,
        "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-abcdef1234567890",
        "services": [{
            "portName": "web",
            "discoveryName": "my-service",
            "clientAliases": [{
                "port": 80,
                "dnsName": "my-service"
            }]
        }],
        "logConfiguration": {
            "logDriver": "awslogs",
            "options": {
                "awslogs-group": "my-envoy-log-group",
                "awslogs-region": "us-west-2",
                "awslogs-stream-prefix": "myapp-envoy-logs"
            }
        },
         "accessLogConfiguration": {
            "format": "TEXT",
            "includeQueryParameters": "ENABLED" 
        }
    }'
```

## 使用控制台启用访问日志
<a name="service-connect-access-logs-configure-console"></a>

有关详细的服务创建过程，请参阅 [创建 Amazon ECS 滚动更新部署](create-service-console-v2.md)。

**使用AWS 管理控制台创建具有共享命名空间的服务**

1. 在 [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2) 打开控制台。

1. 在**集群**页面上，选择要在其中创建服务的集群。

1. 在**服务**下，选择**创建**。

1. 根据工作负载填写其他详细信息后，请在 **Service Connect** 部分中选择**使用 Service Connect**。

1. 根据需要为服务类型（客户端或客户端-服务器）配置 Service Connect 设置。

1. 展开**访问日志配置**。对于**格式**，选择 **JSON** 或 `TEXT`。

1. 要在访问日志中包括查询参数，请选择**包括查询参数**。

1. 完成服务创建过程。

# 加密 Amazon ECS Service Connect 流量
<a name="service-connect-tls"></a>

Amazon ECS Service Connect 支持使用传输层安全性协议（TLS）证书对 Amazon ECS 服务进行自动流量加密。当您将 Amazon ECS 服务指向 [AWS 私有证书颁发机构（AWS 私有 CA）](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html)时，Amazon ECS 会自动预调配 TLS 证书，以加密您的 Amazon ECS Service Connect 服务之间的流量。Amazon ECS 生成、轮换和分发用于流量加密的 TLS 证书。

通过 Service Connect 进行自动流量加密将使用业界领先的加密功能来保护您的服务间通信，从而帮助您满足安全要求。它支持使用 `256-bit ECDSA` 和 `2048-bit RSA` 加密的 AWS 私有证书颁发机构 TLS 证书。您还可以完全控制私有证书和签名密钥，从而帮助您满足合规性要求。默认情况下，支持 TLS 1.3，但不支持 TLS 1.0：1.2。Service Connect 支持具有以下密码的 TLS 1.3：
+ `TLS_AES_128_GCM_SHA256`
+ `TLS_AES_256_GCM_SHA384`
+ `TLS_CHACHA20_POLY1305_SHA256`

**注意**  
要使用 TLS 1.3，您必须在目标上的侦听器上启用它。  
只有通过 Amazon ECS 代理的入站和出站流量才会被加密。

## Service Connect 和应用程序负载均衡器运行状况检查
<a name="service-connect-tls-alb-healthchecks"></a>

您可以将 Service Connect 与应用程序负载均衡器运行状况检查和 TLS 1.3 加密一起使用。

### 应用程序负载均衡器配置
<a name="service-connect-tls-alb-config"></a>

使用以下设置来配置应用程序负载均衡器：
+ 配置一个具有 TLS 1.3 安全策略（例如“ELBSecurityPolicy-TLS13-1-2-2021-06”）的 TLS 侦听器。有关更多信息，请参阅[应用程序负载均衡器的安全策略](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/describe-ssl-policies.html)。
+ 创建一个具有以下设置的目标组：
  + 将协议设置为 HTTPS
  + 将该目标组连接到该 TLS 侦听器
  + 配置运行状况检查端口，使其与 Service Connect 服务的容器端口匹配

### Service Connect 配置
<a name="service-connect-tls-sc-config"></a>

配置一个具有以下设置的服务：
+ 将该服务配置为使用 `awsvpc` 网络模式，因为不支持 `bridge` 网络模式。
+ 为该服务启用 Service Connect。
+ 使用以下设置设置负载均衡器配置：
  + 指定您为应用程序负载均衡器配置的目标组
  + 设置容器端口，使其与 Service Connect TLS 服务的容器端口匹配
+ 不要为该服务设置 `ingressPortOverride`。有关更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [ServiceConnectService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceConnectService.html)。

### 注意事项
<a name="service-connect-tls-alb-considerations"></a>

在使用应用程序负载均衡器、TLS 和 Service Connect 时请注意以下事项：
+ 将 Service Connect 与 TLS 加密结合使用时，应使用 `awsvpc` 网络模式进行 HTTPS 运行状况检查，而不是 `bridge` 网络模式。HTTP 运行状况检查将继续支持 `bridge` 模式。
+ 配置目标组的运行状况检查端口，使其与 Service Connect 服务的容器端口匹配，而不是使用默认的 HTTPS 端口（443）。

## AWS 私有证书颁发机构 证书和 Service Connect
<a name="service-connect-tls-certificates"></a>

您需要拥有基础设施 IAM 角色。有关此角色的更多信息，请参阅 [Amazon ECS 基础设施 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/infrastructure_IAM_role.html                     )。

**Service Connect 的 AWS 私有证书颁发机构 模式**

AWS 私有证书颁发机构 可以在两种模式下运行：通用模式和短暂模式。
+ 通用 – 可配置为任何到期日期的证书。
+ 短期 – 最长有效期为七天的证书。

虽然 Amazon ECS 对这两种模式都支持，但建议使用短期证书。默认情况下，证书每五天轮换一次，与通用型相比，在短期模式下运行可以节省大量成本。

Service Connect 不支持证书吊销，而是利用进行频繁的证书轮换的短期证书。您有权在 [Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 中使用[托管轮换](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotate-secrets_managed.html)修改轮换频率、禁用或删除密钥，但这样做可能会带来以下可能的后果。
+ 较短的轮换频率 – 较短的轮换频率会因 AWS 私有 CA、AWS KMS 和 Secrets Manager 以及轮换工作负载增加的自动扩缩而导致更高的成本。
+ 更长的轮换频率 – 如果轮换频率超过**七**天，应用程序的通信就会失败。
+ 删除密钥 – 删除密钥会导致轮换失败并影响客户应用程序通信。

如果您的密钥轮换失败，则会在 [AWS CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html) 中发布 `RotationFailed` 事件。您也可以为 `RotationFailed` 设置 [CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)。

**重要**  
不要将副本区域添加到密钥中。这样做可以防止 Amazon ECS 删除密钥，因为 Amazon ECS 无权从复制中移除区域。如果您已经添加了复制，请运行以下命令。  

```
aws secretsmanager remove-regions-from-replication \
 --secret-id SecretId \
 --remove-replica-regions region-name
```

**从属证书颁发机构**  
您可以将任何 AWS 私有 CA（根或从属）带到 Service Connect TLS，从而为服务颁发终端实体证书。所提供的颁发者在任何地方都被视为签名者和可信根。您可以从不同的从属 CA 为应用程序的不同部分颁发终端实体证书。使用 AWS CLI 时，请提供用于建立信任链的 CA 的 Amazon 资源名称（ARN）。

**本地证书颁发机构**  
要使用您的本地 CA，请在 AWS 私有证书颁发机构 中创建和配置从属 CA。这样可以确保为您的 Amazon ECS 工作负载颁发的所有 TLS 证书都与您在本地运行的工作负载共享信任链，并且能够安全连接。

**重要**  
请在您的 AWS 私有 CA 中添加**所需的**标签 `AmazonECSManaged : true`。

**基础设施即代码**  
将 Service Connect TLS 与基础设施即代码（IaC）工具配合使用时，请务必正确配置依赖项，以避免出现服务停滞在耗尽状态等问题。使用完您的 Amazon ECS 服务后应将您的 AWS KMS 密钥（如果提供）、IAM 角色和 AWS 私有 CA 依赖项删除。

如果用于 Service Connect 的命名空间是共享命名空间，则可以选择使用共享的 AWS 私有 CA 资源。有关更多信息，请参阅《AWS 私有证书颁发机构 用户指南》**中的[附加跨账户访问策略](https://docs.aws.amazon.com/privateca/latest/userguide/pca-ram.html)。

## Service Connect 和 Secrets Manager
<a name="service-connect-asm"></a>

**使用采用 TLS 加密的 Amazon ECS Service Connect 时，服务通过以下方式与 Secrets Manager 进行交互：**  
Service Connect 利用提供的基础设施角色在 Secrets Manager 中创建密钥。这些密钥用于存储 TLS 证书的关联私钥，用于加密 Service Connect 服务之间的流量。

**警告**  
Service Connect 会自动创建和管理这些密钥，简化了为您的服务实施 TLS 加密的过程。但是，请务必注意潜在的安全影响。对 Secrets Manager 具有读取权限的其他 IAM 角色可能能够访问这些自动创建的密钥。如果访问控制配置不当，这可能会将敏感的加密材料暴露给未经授权的各方。  
要降低这种风险，请遵循以下最佳实践：  
谨慎管理和限制对 Secrets Manager 的访问，尤其是对 Service Connect 创建的密钥的访问。
定期审计 IAM 角色及其权限，以确保最低权限原则得到遵循。

在授予对 Secrets Manager 的读取权限时，请考虑排除由 Service Connect 创建的 TLS 私钥。为此，您可以在 IAM 策略中使用一个条件来排除采用与模式匹配的 ARN 的密钥：

```
"arn:aws:secretsmanager:::secret:ecs-sc!"
```

拒绝对所有带有 `ecs-sc!` 前缀的密钥执行 `GetSecretValue` 操作的 IAM 策略示例：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:*:*:secret:ecs-sc!*"
        }
    ]
}
```

------

**注意**  
这是一个一般示例，可能需要根据您的特定使用案例和 AWS 账户配置进行调整。请始终彻底测试您的 IAM 策略，确保它们在保证安全的同时提供预期访问权限。

通过了解 Service Connect 与 Secrets Manager 的交互方式，您可以更好地管理 Amazon ECS 服务的安全，同时利用自动 TLS 加密的优势。

## Service Connect 和 AWS Key Management Service
<a name="service-connect-kms"></a>

您可以使用 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) 来加密和解密您的 Service Connect 资源。AWS KMS 是 AWS 管理的一项服务，可以通过该服务创建和管理用于保护数据的加密密钥。

将 AWS KMS 与 Service Connect 结合使用时，您可以选择使用 AWS 为您管理的 AWS 拥有的密钥，也可以选择现有的 AWS KMS 密钥。您也可以[创建新的 AWS KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html#create-symmetric-cmk)以供使用。

**提供您自己的加密密钥**  
您可以提供自己的密钥材料，也可以通过 AWS Key Management Service 使用外部密钥存储，将自己的密钥导入 AWS KMS，然后在 Amazon ECS Service Connect 中指定该密钥的 Amazon 资源名称（ARN）。

以下是示例 AWS KMS 策略。将所有 *user input* 值替换为您自己的值。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "id",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/role-name"
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:GenerateDataKey",
        "kms:GenerateDataKeyPair"
      ],
      "Resource": "*"
    }
  ]
}
```

------

有关密钥策略的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[创建密钥策略](https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-overview.html)。

**注意**  
Service Connect 仅支持对称加密 AWS KMS 密钥。您不能使用任何其他类型的 AWS KMS 密钥来加密您的 Service Connect 资源。有关确定 AWS KMS 密钥是否为对称加密密钥的帮助，请参阅 [Identify asymmetric KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/identify-key-types.html#identify-asymm-keys)。

有关 AWS Key Management Service 对称加密密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[对称加密 AWS KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#symmetric-cmks)。

# 为 Amazon ECS Service Connect 启用 TLS
<a name="enable-service-connect-tls"></a>

您可以在创建或更新 Service Connect 服务时启用流量加密。

**要使用 AWS 管理控制台 为现有命名空间中的服务启用流量加密**

1. 您需要拥有基础设施 IAM 角色。有关此角色的更多信息，请参阅 [Amazon ECS 基础设施 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/infrastructure_IAM_role.html                     )。

1. 在 [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2) 打开控制台。

1. 在导航窗格中，选择**命名空间**。

1. 选择包含您要为其启用流量加密的**服务**的**命名空间**。

1. 选择您要为其启用流量加密的**服务**。

1. 选择右上角的**更新服务**，然后向下滚动到 Service Connect 部分。

1. 在服务信息下选择**开启流量加密**以启用 TLS。

1. 对于 **Service Connect TLS 角色**，选择现有基础设施 IAM 角色或创建新角色。

1. 对于**签名者证书颁发机构**，请选择现有的证书颁发机构或创建一个新的证书颁发机构。

   有关详细信息，请参阅 [AWS 私有证书颁发机构 证书和 Service Connect](service-connect-tls.md#service-connect-tls-certificates)。

1. 对于**选择一个 AWS KMS key**，选择 AWS 拥有的密钥和托管密钥，或者可以选择其他密钥。您也可以选择创建一个新密钥。

有关使用 AWS CLI 为您的服务 [使用 AWS CLI 配置 Amazon ECS Service Connect](create-service-connect.md) 配置 TLS 的示例。

# 验证 Amazon ECS Service Connect 是否已启用 TLS
<a name="verify-tls-enabled"></a>

Service Connect 在 Service Connect 代理处启动 TLS，并在目标代理处将其终止。因此，应用程序代码永远看不到 TLS 交互。使用以下步骤验证 TLS 是否已启用。

1. 在您的应用程序映像中包含 `openssl` CLI。

1. 在您的服务上启用 [ECS Exec](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html) 以通过 SSM 连接到您的任务。或者，您可以在与服务相同的 Amazon VPC 中启动 Amazon EC2 实例。

1. 从要验证的服务中检索任务的 IP 和端口。您可以从 AWS Cloud Map 控制台检索 IP 地址。该信息位于命名空间的服务详细信息页面上。

1. 使用如下例所示的 `execute-command` 登录您的任何任务。或者，登录到**步骤 2** 中创建的 Amazon EC2 实例。

   ```
   $ aws ecs execute-command --cluster cluster-name \
       --task task-id  \
       --container container-name \
       --interactive \
       --command "/bin/sh"
   ```
**注意**  
直接调用 DNS 名称不会显示证书。

1. 在连接的 shell 中，使用 `openssl` CLI 验证和查看附加到任务的证书。

   示例：

   ```
   openssl s_client -connect 10.0.147.43:6379 < /dev/null 2> /dev/null \ 
   | openssl x509 -noout -text
   ```

   示例响应：

   ```
   Certificate:
       Data:
           Version: 3 (0x2)
           Serial Number:
               <serial-number>
           Signature Algorithm: ecdsa-with-SHA256
           Issuer: <issuer>
           Validity
               Not Before: Jan 23 21:38:12 2024 GMT
               Not After : Jan 30 22:38:12 2024 GMT
           Subject: <subject>
           Subject Public Key Info:
               Public Key Algorithm: id-ecPublicKey
                   Public-Key: (256 bit)
                   pub:
                       <pub>
                   ASN1 OID: prime256v1
                   NIST CURVE: P-256
           X509v3 extensions:
               X509v3 Subject Alternative Name:
                   DNS:redis.yelb-cftc
               X509v3 Basic Constraints:
                   CA:FALSE
               X509v3 Authority Key Identifier:
                   keyid:<key-id>
   
               X509v3 Subject Key Identifier:
                   1D:<id>
               X509v3 Key Usage: critical
                   Digital Signature, Key Encipherment
               X509v3 Extended Key Usage:
                   TLS Web Server Authentication, TLS Web Client Authentication
       Signature Algorithm: ecdsa-with-SHA256
           <hash>
   ```

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

您可以创建 Fargate 任务的 Amazon ECS 服务，该任务将 Service Connect 和 AWS CLI 结合使用。

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

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

以下是 Service Connect 的先决条件：
+ 验证安装并配置了最新版本的 AWS CLI。有关更多信息，请参阅[安装或更新到最新版本的 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、子网、路由表和安全组。有关更多信息，请参阅 [创建虚拟私有云](get-set-up-for-amazon-ecs.md#create-a-vpc)。
+ 您有一个名为 `ecsTaskExecutionRole` 的任务执行角色，并且 `AmazonECSTaskExecutionRolePolicy` 托管策略已附加到该角色。此角色允许 Fargate 将 NGINX 应用程序日志和 Service Connect 代理日志写入 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 区域 中不存在名称 `service-connect` 的 AWS Cloud Map 命名空间，因此命名空间由 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 Cloud Map 中创建的 AWS 管理控制台 或普通 AWS CLI 配置。

   例如，使用 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 代理插入一个额外的容器。代理侦听任务定义的容器端口映射中的端口。在 Amazon ECS 中运行的客户端应用程序中，客户端任务中的代理侦听与任务定义端口名、服务发现名称或服务客户端别名以及来自客户端别名的端口号的出站连接。

**使用 Service Connect 创建 Web 服务**

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

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

      此任务定义通过向端口映射添加 `name` 和 `appProtocol` 参数来配置 Service Connect。使用多个端口时，端口名称使该端口在服务配置中更易于识别。默认情况下，端口名也用作命名空间中其他应用程序使用的可发现名称。

      任务定义包含任务 IAM 角色，因为该服务已启用 ECS Exec。
**重要**  
此任务定义使用 `logConfiguration` 从 `stdout` 和 `stderr` 向 Amazon CloudWatch Logs 发送 nginx 输出。此任务执行角色不具有创建 CloudWatch Logs 日志组所需的额外权限。使用 AWS 管理控制台 或 AWS CLI 在 CloudWatch Logs 中创建日志组。如果您不想将 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` 的文件。此示例会使用在上一步中创建的任务定义。由于示例任务定义使用 `awsvpc` 网络模式，`awsvpcConfiguration` 是必需的。

      创建 ECS 服务时，请指定 Fargate 和支持 Service Connect 的 `LATEST` 平台版本。`securityGroups` 和 `subnets` 必须属于符合使用 Amazon ECS 要求的 VPC。您可以从 Amazon VPC 控制台获取安全组和子网 ID。

      此服务通过添加 `serviceConnectConfiguration` 参数来配置 Service Connect。不需要命名空间，因为集群配置了默认命名空间。在命名空间中的 ECS 中运行的客户端应用程序通过使用 `portName` 和 `clientAliases` 中的端口连接到此服务。例如，可使用 `http://nginx:80/` 访问此服务，因为 nginx 在根位置 `/` 提供了欢迎页面。不在 Amazon ECS 中运行或不在同一命名空间中的外部应用程序可以使用任务的 IP 地址和任务定义中的端口号，通过 Service Connect 代理访问此应用程序。对于您的 `tls` 配置，请为您的 IAM 角色的 `awsPcaAuthorityArn`、`kmsKey` 和 `roleArn` 添加证书 `arn`。

      此服务使用 `logConfiguration` 将 Service Connect 代理输出从 `stdout` 和 `stderr` 发送到 Amazon CloudWatch Logs。此任务执行角色不具有创建 CloudWatch Logs 日志组所需的额外权限。使用 AWS 管理控制台 或 AWS CLI 在 CloudWatch Logs 中创建日志组。我们建议您创建此日志组并将代理日志存储在 CloudWatch Logs 中。如果您不想将代理日志发送到 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 代理创建的其他指标。

**从外部应用程序连接到 Web 服务**
+ 使用任务 IP 地址连接到任务 IP 地址和容器端口

  使用 AWS CLI 并利用 `aws ecs list-tasks --cluster tutorial` 获取任务 ID。

  如果您的子网和安全组允许来自任务定义的端口上的公共互联网流量，则可以从计算机连接到公有 IP。但是“describe-tasks”无法获得公有 IP，因此这些步骤包括前往 Amazon EC2 AWS 管理控制台 或 AWS CLI 获取弹性网络接口的详细信息。

  在此示例中，同一 VPC 中的 Amazon EC2 实例使用任务的私有 IP。应用程序是 nginx，但 `server: envoy` 标头显示使用了 Service Connect 代理。Service Connect 代理正在从任务定义侦听容器端口。

  ```
  $ 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 代理在 CloudWatch 指标中创建应用程序（HTTP、HTTP2、gRPC 或 TCP 连接）指标。使用 CloudWatch 控制台时，请查看 Amazon ECS 命名空间下的 **DiscoveryName**、（**DiscoveryName、ServiceName、ClusterName**）、**TargetDiscoveryName** 和（**TargetDiscoveryName、ServiceName、ClusterName**）等其他指标维度。有关这些指标和维度的更多信息，请参阅《Amazon CloudWatch Logs 用户指南》中的[查看可用指标](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/viewing_metrics_with_cloudwatch.html)。

# 使用服务发现连接具有 DNS 名称的 Amazon ECS 服务
<a name="service-discovery"></a>

您的 Amazon ECS 服务可以选择配置为使用 Amazon ECS 服务发现。服务发现使用 AWS Cloud Map API 操作，用于托管 Amazon ECS 服务的 HTTP 和 DNS 命名空间。有关更多信息，请参阅 [AWS Cloud Map 开发人员指南](https://docs.aws.amazon.com/cloud-map/latest/dg/Welcome.html) 中的*什么是 AWS Cloud Map*。

服务发现在以下 AWS 区域可用：


| 区域名称 | 区域 | 
| --- | --- | 
|  美国东部（弗吉尼亚州北部）  |  us-east-1  | 
|  美国东部（俄亥俄州）  |  us-east-2  | 
|  美国西部（北加利福尼亚）  |  us-west-1  | 
|  美国西部（俄勒冈州）  |  us-west-2  | 
|  非洲（开普敦）  |  af-south-1  | 
|  亚太地区（香港）  |  ap-east-1  | 
|  亚太地区（台北）  |  ap-east-2  | 
|  亚太地区（孟买）  |  ap-south-1  | 
|  亚太地区（海得拉巴）  |  ap-south-2  | 
|  亚太地区（东京）  |  ap-northeast-1  | 
|  亚太地区（首尔）  |  ap-northeast-2  | 
|  亚太地区（大阪）  |  ap-northeast-3  | 
|  亚太地区（新加坡）  |  ap-southeast-1  | 
|  亚太地区（悉尼）  |  ap-southeast-2  | 
|  亚太地区（雅加达）  |  ap-southeast-3  | 
|  亚太地区（墨尔本）  |  ap-southeast-4  | 
|  亚太地区（马来西亚）  |  ap-southeast-5  | 
|  亚太地区（新西兰）  |  ap-southeast-6  | 
|  亚太地区（泰国）  |  ap-southeast-7  | 
|  加拿大（中部）  |  ca-central-1  | 
|  加拿大西部（卡尔加里）  |  ca-west-1  | 
|  中国（北京）  |  cn-north-1  | 
|  中国（宁夏）  |  cn-northwest-1  | 
|  欧洲地区（法兰克福）  |  eu-central-1  | 
|  欧洲（苏黎世）  |  eu-central-2  | 
|  欧洲地区（爱尔兰）  |  eu-west-1  | 
|  欧洲地区（伦敦）  |  eu-west-2  | 
|  欧洲地区（巴黎）  |  eu-west-3  | 
|  欧洲地区（米兰）  |  eu-south-1  | 
|  欧洲地区（斯德哥尔摩）  |  eu-north-1  | 
|  以色列（特拉维夫）  |  il-central-1  | 
|  欧洲（西班牙）  |  eu-south-2  | 
|  中东（阿联酋）  |  me-central-1  | 
|  墨西哥（中部）  |  mx-central-1  | 
|  中东（巴林）  |  me-south-1  | 
|  南美洲（圣保罗）  |  sa-east-1  | 
|  AWS GovCloud（美国东部）  |  us-gov-east-1  | 
|  AWS GovCloud（美国西部）  |  us-gov-west-1  | 

## 服务发现概念
<a name="service-discovery-concepts"></a>

服务发现包括以下组件：
+ **服务发现命名空间**：共享相同域名的服务发现服务的逻辑组，例如 `example.com`，这是您想要路由流量的位置。您可以通过调用 `aws servicediscovery create-private-dns-namespace` 命令或在 Amazon ECS 控制台中创建命名空间。您可以使用 `aws servicediscovery list-namespaces` 命令来查看有关当前账户创建的命名空间的摘要信息。有关服务发现命令的更多信息，请参阅 *`[create-private-dns-namespace](https://docs.aws.amazon.com/cli/latest/reference/servicediscovery/create-private-dns-namespace.html)`（服务发现）`[list-namespaces](https://docs.aws.amazon.com/cli/latest/reference/servicediscovery/list-namespaces.html)` 参考指南*中的 AWS Cloud Map 和 AWS CLI。
+ **服务发现服务**：存在于服务发现命名空间中，由命名空间的服务名称和 DNS 配置组成。它提供了以下核心组件：
  + **服务注册**：让您可通过 DNS 或 AWS Cloud Map API 操作查找服务，并获取一个或多个可用于连接到该服务的可用端点。
+ **服务发现实例**：存在于服务发现中并包含与服务目录中的每个 Amazon ECS 服务相关联的属性。
  + **实例属性**：将以下元数据添加为配置为使用服务发现的每个 Amazon ECS 服务的自定义属性：
    + **`AWS_INSTANCE_IPV4`** -对于 `A` 记录，为 Route 53 响应 DNS 查询而返回和 AWS Cloud Map 在发现实例详细信息时返回的 IPv4 地址，例如 `192.0.2.44`。
    + **`AWS_INSTANCE_IPV6`**：对于 `AAAA` 记录，为 Route 53 响应 DNS 查询而返回和 AWS Cloud Map 在发现实例详细信息时返回的 IPv6 地址，例如 ` 2001:0db8:85a3:0000:0000:abcd:0001:2345`。为 Amazon ECS 双堆栈服务添加了 `AWS_INSTANCE_IPv4` 和 `AWS_INSTANCE_IPv6`。对 Amazon ECS 仅 IPv6 服务仅添加了 `AWS_INSTANCE_IPv6`。
    + **`AWS_INSTANCE_PORT`** – 与服务发现服务关联的端口值。
    + **`AVAILABILITY_ZONE`** – 任务启动到的可用区。对于使用 EC2 的任务，这是容器实例存在于的可用区。对于使用 Fargate 的任务，这是弹性网络接口存在于的可用区。
    + **`REGION`** – 任务存在于的区域。
    + **`ECS_SERVICE_NAME`** – 任务属于的 Amazon ECS 服务的名称。
    + **`ECS_CLUSTER_NAME`** – 任务属于的 Amazon ECS 集群的名称。
    + **`EC2_INSTANCE_ID`**：在其上放置任务的容器实例的 ID。如果任务使用 Fargate，则不会添加此自定义属性。
    + **`ECS_TASK_DEFINITION_FAMILY`**：任务使用的任务定义系列。
    + **`ECS_TASK_SET_EXTERNAL_ID`**：如果为外部部署创建任务集并将任务集与服务发现注册表关联，`ECS_TASK_SET_EXTERNAL_ID` 属性将包含任务集的外部 ID。
+ **Amazon ECS 运行状况检查**：Amazon ECS 执行定期容器级别的运行状况检查。如果端点不传递运行状况检查，则会将其从 DNS 路由中删除并标记为不正常。

## 服务发现注意事项
<a name="service-discovery-considerations"></a>

使用服务发现时应注意以下事项：
+ Fargate 上使用平台版本1.1.0或更高版本的任务支持服务发现。有关更多信息，请参阅 [适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。
+ 配置为使用服务发现的服务每个服务限制为 1,000 个任务。这是由于 Route 53 服务配额造成的。
+ Amazon ECS 控制台中的创建服务工作流程仅支持向私有 DNS 命名空间注册服务。在创建 AWS Cloud Map 私有 DNS 命名空间时，将自动创建 Route 53 私有托管区域。
+ 必须配置 VPC DNS 属性才能成功解析 DNS。有关如何配置属性的信息，请参阅 *Amazon VPC 用户指南*中 [VPC 中的 DNS 支持](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-support)。
+ Amazon ECS 不支持将服务注册到共享的 AWS Cloud Map 命名空间。
+ 为服务发现服务创建的 DNS 记录将始终注册任务的私有 IP 地址，而不是公有 IP 地址，即使使用公共命名空间也是如此。
+ 服务发现要求任务指定 `awsvpc`、`bridge` 或 `host` 网络模式（不支持 `none`）。
+ 如果服务任务定义使用 `awsvpc` 网络模式，您可以为每个服务任务创建 `A` 或 `SRV` 记录的任意组合。如果您使用 `SRV` 记录，则需要端口。如果服务使用双堆栈子网，则还可以创建 `AAAA` 记录。如果服务使用仅 IPv6 子网，则无法创建 `A` 记录。
+ 如果服务任务定义使用 `bridge` 或 `host` 网络模式，则 SRV 记录是唯一受支持的 DNS 记录类型。为每个服务任务创建 SRV 记录。SRV 记录必须从任务定义中指定容器名称和容器端口组合。
+ 服务发现服务的 DNS 记录可以在 VPC 中查询。它们采用以下格式：`<service-discovery-service-name>.<service-discovery-namespace>`。
+ 在服务名称上执行 DNS 查询时，`A` 和 `AAAA` 记录会返回一组与任务对应的 IP 地址。`SRV` 记录会返回每个任务的一组 IP 地址和端口。
+ 如果您有不超过 8 条正常的记录，Route 53 会向所有 DNS 查询提供所有正常记录。
+ 如果所有记录都不正常，Route 53 会向 DNS 查询提供最多 8 条不正常的记录。
+ 您可以为负载均衡器后面的服务配置服务发现，但服务发现流量会始终路由至此任务而不会路由至负载均衡器。
+ 服务发现不支持使用 Classic Load Balancers。
+ 我们建议对服务发现服务使用由 Amazon ECS 管理的容器级别的运行状况检查。
  + **HealthCheckCustomConfig** – Amazon ECS 代表您管理运行状况检查。Amazon ECS 使用来自容器和运行状况检查的信息以及您的任务状态，通过 AWS Cloud Map 更新运行状况。在创建服务发现服务时，使用 `--health-check-custom-config` 参数来指定。有关更多信息，请参阅 *AWS Cloud Map API 参考*中的 [HealthCheckCustomConfig](https://docs.aws.amazon.com/cloud-map/latest/api/API_HealthCheckCustomConfig.html)。
+ 使用服务发现时创建的 AWS Cloud Map 资源必须手动清理。
+ 在容器运行状况检查返回值之前，任务和实例将注册为 `UNHEALTHY`。如果运行状况检查通过，则状态更新为 `HEALTHY`。如果容器运行状况检查失败，则服务发现实例将被注销。

## 服务发现定价
<a name="service-discovery-pricing"></a>

使用 Amazon ECS 服务发现的客户需要为 Route 53 资源和 AWS Cloud Map 发现 API 操作付费。这涉及到创建 Route 53 托管区域和查询服务注册表的成本。更多信息，请参阅 *AWS Cloud Map 开发人员指南*中的 [AWS Cloud Map 定价](https://docs.aws.amazon.com/cloud-map/latest/dg/cloud-map-pricing.html)。

Amazon ECS 执行容器级别的运行状况检查并将其公开到 AWS Cloud Map 自定义运行状况检查 API 操作。目前将此提供给客户没有任何额外成本。如果您为公开任务配置其他网络运行状况检查，则需要为这些运行状况检查付费。

# 创建使用服务发现的 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
   ```

# 使用 Amazon VPC Lattice 连接、观察和保护 Amazon ECS 服务
<a name="ecs-vpc-lattice"></a>

Amazon VPC Lattice 是一项完全托管的应用程序联网服务，Amazon ECS 客户无需修改其代码即可观察、保护和监控在不同 AWS 计算服务、VPC 和账户之间构建的应用程序。

VPC Lattice 使用目标组，即计算资源的集合。这些目标可以运行您的应用程序或服务，可以是 Amazon EC2 实例、IP 地址、Lambda 函数和应用程序负载均衡器。通过将其使用的 Amazon ECS 服务与 VPC Lattice 目标组相关联，客户现在可以在 VPC Lattice 中启用 Amazon ECS 任务作为 IP 目标。启动注册服务的任务时，Amazon ECS 会自动向 VPC Lattice 目标组注册任务。

**注意**  
使用五种 VPC Lattice 配置时，部署时间可能会比使用较少配置时稍长一些。

当满足条件时，侦听器规则将用于将流量转发到指定的目标组。侦听器使用您在端口配置的协议检查连接请求。服务根据您在配置侦听器时定义的规则将请求路由到其已注册目标。

根据 VPC Lattice 运行状况检查，如果任务运行状况不佳，Amazon ECS 还会自动替换该任务。与 VPC Lattice 关联后，Amazon ECS 客户还可以利用 VPC Lattice 中的许多其他跨计算连接、安全和可观测性功能，例如使用 AWS Resource Access Manager 跨集群、VPC 和账户连接到服务、用于授权和身份验证的 IAM 集成以及高级流量管理功能。

Amazon ECS 客户可以通过以下方式享受 VPC Lattice 的优势。
+ 提高开发人员的工作效率：VPC Lattice 允许您专注于构建功能，从而提高开发人员的工作效率，而 VPC Lattice 则以统一的方式处理所有计算平台上的联网、安全和可观测性问题。
+ 更好的安全状况：VPC Lattice 使您的开发人员能够轻松验证和保护跨应用程序和计算平台的通信，在传输过程中强制加密，并使用 VPC Lattice 身份验证策略应用精细的访问控制。这使您能够实现更好的安全状况，以满足行业领先的监管和合规性要求。
+ 提高应用程序的可扩展性和韧性：VPC Lattice 允许您创建一个由已部署的应用程序组成的网络，并实现路径、标头和基于方法的路由、身份验证、授权和监控等功能。这些优势是在不增加工作负载资源开销的情况下提供的，并且可以支持每秒生成数百万个请求的多集群部署，而不会增加明显的延迟。
+ 通过异构基础设施实现灵活部署：VPC Lattice 可为所有计算服务（例如Amazon ECS、Fargate、Amazon EC2、Amazon EKS 和 Lambda）提供一致的功能，并允许您的组织灵活地为每个应用程序选择合适的基础设施。

## 了解 VPC Lattice 如何与其他 Amazon ECS 服务配合使用
<a name="ecs-lattice-compatibility"></a>

将 VPC Lattice 与 Amazon ECS 配合使用可能会改变您使用其他 Amazon ECS 服务的方式，而其他方面保持不变。

**应用程序负载均衡器**  
您不再需要创建特定的应用程序负载均衡器来与 VPC Lattice 中的应用程序负载均衡器目标组类型一起使用，以便该负载均衡器链接到 Amazon ECS 服务。您只需要使用 VPC Lattice 目标组配置 Amazon ECS 服务即可。您也可以选择同时将应用程序负载均衡器与 Amazon ECS 配合使用。

**Amazon ECS 滚动部署**  
只有 Amazon ECS 滚动部署可以与 VPC Lattice 配合使用，而 Amazon ECS 在部署期间可以安全地将任务带入服务并从服务中移除。不支持代码部署和蓝绿部署。

要了解有关 VPC Lattice 的更多信息，请参阅 [Amazon VPC Lattice 用户指南](https://docs.aws.amazon.com/vpc-lattice/latest/ug/what-is-vpc-lattice.html)。

# 创建支持 VPC Lattice 的服务
<a name="ecs-vpc-lattice-create-service"></a>

您可以使用 AWS 管理控制台 或 AWS CLI 创建支持 VPC Lattice 的服务。

## 先决条件
<a name="create-ecs-vpc-lattice-prereqs"></a>

在开始本教程之前，请确保满足以下先决条件：
+ 安装并配置了最新版本的 AWS CLI。有关更多信息，请参阅[安装 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)。
**注意**  
您可以使用双堆栈服务端点通过 IPv4 和 IPv6 从 AWS CLI、SDK 和 Amazon ECS API 与 Amazon ECS 进行交互。有关更多信息，请参阅 [使用 Amazon ECS 双堆栈端点](dual-stack-endpoint.md)。
+ 完成 [设置以使用 Amazon ECS](get-set-up-for-amazon-ecs.md) 中所述的步骤。
+ 您的 IAM 用户具有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 策略示例中指定的必需权限。

## 使用 AWS 管理控制台 创建支持 VPC Lattice 的服务
<a name="ecs-lattice-create-console"></a>

按照以下步骤使用 AWS 管理控制台 创建支持 VPC Lattice 的服务。

1. 在 [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2) 打开控制台。

1. 在导航页面中，选择**集群**。

1. 在**集群**页面上，选择要在其中创建服务的集群。

1. 在 **Services**（服务）选项卡上，选择 **Create**（创建）。

   如果您以前从未创建过服务，请按照[使用控制台创建 Amazon ECS 服务](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-service-console-v2.html)中的步骤进行操作，然后在进入 VPC Lattice 部分后继续执行这些步骤。

1. 勾选按钮，选择**开启 VPC Lattice**。

1. 要使用现有的角色，则对于 **Amazon ECS 的 ECS 基础设施角色**，请选择您已经创建的角色，以便在创建 VPC Lattice 目标组时使用。要创建新角色，请**创建 ECS 基础设施角色**。

1. 选择 **VPC**。

   **VPC** 取决于您在注册任务定义时选择的联网模式。如果将 `host` 或 `network` 模式与 EC2 结合使用，请选择您的 VPC。

   对于 `awsvpc` 模式，系统会根据您在**联网**下选择的 VPC 自动选择 VPC，并且无法更改。

1. 在**目标组**下，选择一个或多个目标组。您需要选择至少 1 个目标组，最多可选择 5 个目标组。要添加更多目标组，请选择**添加目标组**。为您选择的每个目标组选择**端口名称**、**协议**和**端口**。要删除目标组，请选择**移除**。
**注意**  
如果要添加现有目标组，则需要使用 AWS CLI。有关如何使用 AWS CLI 添加目标组的说明，请参阅《AWS Command Line Interface 参考》中的 [register-targets](https://docs.aws.amazon.com/cli/latest/reference/vpc-lattice/register-targets.html)**。
虽然 VPC Lattice 服务可以有多个目标组，但每个目标组只能添加到一个服务中。
要在仅 IPv6 配置中创建服务，请选择 IP 地址类型为 `IPv6` 的目标组。

1. 然后，您可以导航到 VPC Lattice 控制台继续进行设置。进入控制台后，您可以在侦听器默认操作或现有 VPC Lattice 服务的规则中加入新的目标组。

   有关更多信息，请参阅 [Listener rules for your VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/listener-rules.html)。

**重要**  
您需要允许安全组使用入站规则 `vpc-lattice` 前缀，否则任务和运行状况检查可能会失败。

## 使用 AWS CLI 创建支持 VPC Lattice 的服务
<a name="ecs-lattice-create-cli"></a>

使用 AWS CLI 创建支持 VPC Lattice 的服务。将每个*用户输入占位符*替换为您自己的信息。

1. 创建目标组配置文件。以下示例名为 `tg-config.json`

   ```
   {
       "ipAddressType": "IPV4",
       "port": 443,
       "protocol": "HTTPS",
       "protocolVersion": "HTTP1",
       "vpcIdentifier": "vpc-f1663d9868EXAMPLE"
   }
   ```

1. 使用以下命令创建 VPC Lattice 目标组。

   ```
   aws vpc-lattice create-target-group \
       --name my-lattice-target-group-ip \
       --type IP \
       --config file://tg-config.json
   ```
**注意**  
要在仅 IPv6 配置中创建服务，请创建 IP 地址类型为 `IPv6` 的目标组。有关更多信息，请参阅《AWS CLI 命令参考》**中的 [create-target-group](https://docs.aws.amazon.com/cli/latest/reference/vpc-lattice/create-target-group.html)。

   输出示例：

   ```
   {
       "arn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-0eaa4b9ab4EXAMPLE",
       "config": {
           "healthCheck": {
               "enabled": true,
               "healthCheckIntervalSeconds": 30,
               "healthCheckTimeoutSeconds": 5,
               "healthyThresholdCount": 5,
               "matcher": {
                   "httpCode": "200"
               },
               "path": "/",
               "protocol": "HTTPS",
               "protocolVersion": "HTTP1",
               "unhealthyThresholdCount": 2
           },
           "ipAddressType": "IPV4",
           "port": 443,
           "protocol": "HTTPS",
           "protocolVersion": "HTTP1",
           "vpcIdentifier": "vpc-f1663d9868EXAMPLE"
       },
       "id": "tg-0eaa4b9ab4EXAMPLE",
       "name": "my-lattice-target-group-ip",
       "status": "CREATE_IN_PROGRESS",
       "type": "IP"
   }
   ```

1. 以下名为 *ecs-service-vpc-lattice.json* 的 JSON 文件是用于将 Amazon ECS 服务附加到 VPC Lattice 目标组的示例。以下示例中的 `portName` 与您在任务定义 `portMappings` 属性 `name` 字段中定义的相同。

   ```
   {
       "serviceName": "ecs-service-vpc-lattice",
       "taskDefinition": "ecs-task-def",
           "vpcLatticeConfigurations": [
           {
               "targetGroupArn": "arn:aws:vpc-lattice:us-west-2:123456789012:targetgroup/tg-0eaa4b9ab4EXAMPLE",
               "portName": "testvpclattice",
               "roleArn": "arn:aws:iam::123456789012:role/ecsInfrastructureRoleVpcLattice"
           }
       ],
       "desiredCount": 5,
       "role": "ecsServiceRole"
   }
   ```

   使用以下命令创建 Amazon ECS 服务，并使用上面的 json 示例将其附加到 VPC Lattice 目标组。

   ```
   aws ecs create-service \
       --cluster clusterName \
       --serviceName ecs-service-vpc-lattice \
       --cli-input-json file://ecs-service-vpc-lattice.json
   ```

**注意**  
Amazon ECS Anywhere 不支持 VPC Lattice。