

# 设计适用于 Amazon ECS 的应用程序架构
<a name="application_architecture"></a>

您可以通过为应用程序创建任务定义来构建应用程序。任务定义包含用于定义有关应用程序的信息的参数，包括：
+ 要使用的容量，这决定了托管您的任务的基础设施。

  使用 EC2 容量提供程序时，您还可以选择实例类型。使用 Amazon ECS 托管实例容量提供程序时，您可以提供 Amazon ECS 管理计算容量的实例要求。对于某些实例类型（例如 GPU），您需要设置特定参数。有关更多信息，请参阅 [Amazon ECS 任务定义应用场景](use-cases.md)。
+ 容器映像，包含您的应用程序代码和运行应用程序代码所需的所有依赖项。
+ 在您的任务中用于容器的联网模式。

  联网模式决定了任务通过网络进行通信的方式。

  对于在 EC2 实例和 Amazon ECS 托管实例上运行的任务，有多种选择，但我们建议您使用 `awsvpc` 网络模式。您可以更好地控制您的应用程序相互之间以及与 VPC 内其他服务之间的通信方式，因此 `awsvpc` 网络模式可简化容器联网。

  对于在 Fargate 上运行的任务，您必须使用 `awsvpc` 网络模式。
+ 要用于您的任务的日志记录配置。
+ 在任务中用于容器的任何数据卷。

要获得任务定义参数的完整列表，请参阅 [Fargate 的 Amazon ECS 任务定义参数](task_definition_parameters.md)。

创建任务定义时，请遵循以下准则：
+ 将每个任务定义系列仅用于一个业务目的。

  如果您在同一个任务定义中将多种类型的应用程序容器分组在一起，则无法独立扩缩这些容器。例如，网站和 API 通常需要不同的扩缩模式。随着流量的增加，所需的 Web 容器数量可能会与 API 容器数量不同。如果这两个容器部署在同一个任务定义中，则每个任务会运行相同数量的 Web 容器和 API 容器。
+ 将每个应用程序版本与任务定义系列中的任务定义修订版进行匹配。

  在任务定义系列中，每个任务定义修订版代表特定容器映像设置的时间点快照。这类似于容器是一个快照，其中包含运行特定版本应用程序代码所需的所有组件。

  创建应用程序代码版本、容器映像标签和任务定义修订版之间的一对一映射。典型的发布过程涉及一个 git commit，它会变成一个标有 git commit SHA 的容器映像。然后，该容器映像标签将获得自己的 Amazon ECS 任务定义修订版。最后，对 Amazon ECS 服务进行了更新，以部署新的任务定义修订版。
+ 为每个任务定义系列使用不同的 IAM 角色。

  使用自己的 IAM 角色定义每个任务定义。实施这种做法，同时为每个业务组件提供自己的任务定义系列。通过实施这两种最佳实践，您可以限制每项服务对您 AWS 账户中资源的访问权限。例如，您可以授予身份验证服务访问权限，以连接到您的密码数据库。同时，您可以确保只有您的订单服务才能访问信用卡付款信息。

# Amazon ECS 任务大小的最佳实践
<a name="capacity-tasksize"></a>

 容器和任务大小对于扩展和容量计划都至关重要。在 Amazon ECS 中，CPU 和内存这两个资源指标用于测量容量。CPU 以整个 vCPU 的 1/1024 为单位测量（其中 1024 个单位等于一整个 vCPU）。内存以兆字节为单位衡量。在任务定义中，您可以配置资源预留和限制。

配置预留时，就是在设置任务所需的最低资源量。您的任务至少会收到所请求的资源量。您的应用程序可能能够使用比您声明的预留更多的 CPU 或内存。但是，这受制于您所声明的任何限制。使用超过预留量被称为突增。在 Amazon ECS 中，保证预留。例如，如果您使用 Amazon EC2 实例来提供容量，则 Amazon ECS 不会将任务放置在无法完成预留的实例上。

限制是指您的容器或任务可以使用的最大 CPU 单位量或内存量。任何使用超过此限制的 CPU 数量的尝试都会导致节流。任何使用更多内存的尝试都会导致您的容器停止。

选择这些值可能会具有挑战性。这是因为最适合您的应用程序的值在很大程度上取决于应用程序的资源需求。对应用程序进行负载测试是成功计划资源需求和更好地了解应用程序需求的关键。

## 无状态应用程序
<a name="capacity-tasksize-stateless"></a>

对于水平扩展的无状态应用程序，例如负载均衡器后面的应用程序，建议您首先确定应用程序在提供请求时消耗的内存量。为执行此操作，您可以使用传统工具（例如 `ps` 或 `top`）或监控解决方案（例如 CloudWatch Container Insights）。

在确定 CPU 预留时，请考虑如何扩展应用程序以满足您的业务需求。您可以使用较小的 CPU 预留（例如 256 个 CPU 单元（或 1/4 vCPU），以细粒度的方式进行横向扩展，从而最大限度地降低成本。但是，它们的扩展速度可能不够快，无法满足需求的显著激增。您可以使用更大的 CPU 预留来更快地横向缩减和扩展，从而更快地满足需求激增。但是，预留的 CPU 越大，成本就越高。

## 其他客户端应用程序
<a name="capacity-tasksize-other"></a>

对于无法横向扩展的应用程序（例如单例工作线程或数据库服务器），可用容量和成本是您最重要的考虑因素。您应该根据负载测试表明需要提供的流量来选择内存和 CPU 的数量，以满足您的服务级别目标。Amazon ECS 可确保将应用程序放置在具有足够容量的主机上。

# Amazon ECS 托管实例的 Amazon ECS 任务联网
<a name="managed-instance-networking"></a>

在 Amazon ECS 托管实例上运行的 Amazon ECS 任务的网络行为由任务定义中指定的*网络模式*决定。您必须在任务定义中指定网络模式。您将无法使用未指定网络模式的任务定义在 Amazon ECS 托管实例上运行任务。Amazon ECS 托管实例支持以下联网模式，可确保在 Amazon EC2 上从 Fargate 或 Amazon ECS 迁移工作负载时实现向后兼容：


| 网络模式 | 说明 | 
| --- | --- | 
|  `awsvpc`  |  每个任务都会接收自己的弹性网络接口（ENI）和私有 IPv4 地址。这提供了与 Amazon EC2 实例相同的联网属性，并且与传统的 Fargate 任务兼容。使用 ENI 中继实现高任务密度。  | 
|  `host`  |  任务直接共享主机的网络命名空间。容器联网与底层主机实例相关联。  | 

## 在仅 IPv6 模式下使用 VPC
<a name="managed-instances-networking-ipv6-only"></a>

在仅 IPv6 配置中，Amazon ECS 任务仅通过 IPv6 进行通信。要为仅 IPv6 配置设置 VPC 和子网，您必须向 VPC 添加 IPv6 CIDR 数据块，并创建仅包含 IPv6 CIDR 数据块的子网。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[为 VPC 添加 IPv6 支持](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html)和[创建子网](https://docs.aws.amazon.com/vpc/latest/userguide/create-subnets.html)。您还必须使用 IPv6 目标更新路由表，并为安全组配置 IPv6 规则。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[配置路由表](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html)和[配置安全组规则](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-security-group-rules.html)。

请注意以下事项：
+ 您可以通过直接更新服务以使用仅 IPv6 子网，或者创建仅 IPv6 并行服务并使用 Amazon ECS 蓝绿部署将流量转移到新服务，来将仅 IPv4 或双堆栈 Amazon ECS 服务更新为仅 IPv6 配置。有关 Amazon ECS 蓝绿部署的更多信息，请参阅[Amazon ECS 蓝/绿部署](deployment-type-blue-green.md)。
+ 仅 IPv6 Amazon ECS 服务必须使用带有 IPv6 目标组的双堆栈负载均衡器。如果您要迁移位于应用程序负载均衡器或网络负载均衡器后面的现有 Amazon ECS 服务，则可以创建新的双堆栈负载均衡器并转移来自旧负载均衡器的流量，或者更新现有负载均衡器的 IP 地址类型。

   有关网络负载均衡器的更多信息，请参阅《网络负载均衡器用户指南》**中的[创建网络负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/create-network-load-balancer.html)和[更新网络负载均衡器的 IP 地址类型](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-ip-address-type.html)。有关应用程序负载均衡器的更多信息，请参阅《应用程序负载均衡器用户指南》**中的[创建应用程序负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-application-load-balancer.html)和[更新应用程序负载均衡器的 IP 地址类型](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-ip-address-type.html)。
+ 对于仅 IPv6 配置中的 Amazon ECS 任务，如果要与仅 IPv4 端点通信，您可以设置 DNS64 和 NAT64，以将网络地址从 IPv6 转换为 IPv4。有关更多信息，请参阅 *Amazon VPC 用户指南*中的 [DNS64 和 NAT64](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-nat64-dns64.html)。
+ 在仅 IPv6 配置中，Amazon ECS 工作负载在从 Amazon ECR 拉取映像时必须使用 Amazon ECR 双堆栈映像 URI 端点。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[通过 IPv6 发出请求入门](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-requests.html#ipv6-access-getting-started)。
**注意**  
Amazon ECR 不支持仅 IPv6 配置中的任务可使用的双堆栈接口 VPC 端点。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[通过 IPv6 发出请求入门](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-requests.html#ipv6-access-getting-started)。
+ 仅 IPv6 配置不支持 Amazon ECS Exec。

# 为 Amazon ECS 托管实例上的任务分配网络接口。
<a name="managed-instances-awsvpc-mode"></a>

 在 Amazon ECS 托管实例中使用 `awsvpc` 网络模式可简化容器联网，因为您可以更好地控制您的应用程序相互之间以及与 VPC 内的其他服务之间的通信方式。`awsvpc` 网络模式还为您的容器提供了更高的安全性，使您能够在任务中更精细地使用安全组和网络监视工具。

默认情况下，当实例类型支持中继时，每个 Amazon ECS 托管实例在启动期间都会附加一个中继弹性网络接口（ENI）作为主 ENI。有关支持 ENI 中继的实例类型的更多信息，请参阅[增加的 Amazon ECS 容器网络接口支持的实例](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/eni-trunking-supported-instance-types.html)。

**注意**  
如果所选实例类型不支持中继型ENI，则实例将使用常规 ENI 启动。

实例上运行的每个任务都会接收自己的附加到中继 ENI 的 ENI 以及主私有 IP 地址。如果您的 VPC 配置了双堆栈模式，并且您使用具有 IPv6 CIDR 数据块的子网，则 ENI 也会接收 IPv6 地址。使用公有子网时，您可以选择通过为子网启用 IPv4 公有寻址来向 Amazon ECS 托管实例主 ENI 分配公有 IP 地址。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[修改子网的 IP 寻址属性](https://docs.aws.amazon.com//vpc/latest/userguide/subnet-public-ip.html)。一个任务在给定的时间只能有一个与之关联的 ENI。

 属于同一任务的容器可以通过 `localhost` 接口进行通信。有关 VPC 和子网的更多信息，请参阅《Amazon VPC 用户指南》**中的 [Amazon VPC 的工作原理](https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html)

以下操作使用附加到实例的主 ENI：
+ **映像下载**：可通过主 ENI 从 Amazon ECR 下载容器映像。
+ **密钥检索**：可通过主 ENI 检索 Secrets Manager 密钥和其他凭证。
+ **日志上传**：日志通过主 ENI 上传到 CloudWatch。
+ **环境文件下载**：可通过主 ENI 下载环境文件。

应用程序流量流经任务 ENI。

由于每个任务都有自己的 ENI，因此您可以使用联网功能（例如 VPC 流日志），以便可以监控您任务的流量。有关更多信息，请参阅《Amazon VPC 用户指南》**中的 [VPC 流日志](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html)。

您还可以利用 AWS PrivateLink。您可以配置 VPC 接口端点，以便可以通过私有 IP 地址访问 Amazon ECS API。AWS PrivateLink 将 VPC 和 Amazon ECS 之间的所有网络流量限制在 Amazon 网络以内。您无需互联网网关、NAT 设备或虚拟私有网关。有关更多信息，请参阅 [Amazon ECS 接口 VPC 端点（AWS PrivateLink）](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/vpc-endpoints.html)。

`awsvpc` 网络模式还允许您在使用未附加中继 ENI 的实例类型时，利用 Amazon VPC Traffic Mirroring 来保护和监控网络流量。有关更多信息，请参阅《Amazon VPC Traffic Mirroring 指南》**中的 [What is Traffic Mirroring?](https://docs.aws.amazon.com/vpc/latest/mirroring/what-is-traffic-mirroring.html)。

## `awsvpc` 模式的注意事项
<a name="managed-instances-awsvpc-considerations"></a>
+ 任务需要使用 Amazon ECS 服务相关角色来管理 ENI。当您创建集群或服务时，系统会自动创建此角色。
+ 任务 ENI 由 Amazon ECS 管理，无法手动分离或修改。
+ 在运行独立任务（`RunTask`）或创建/更新服务（`CreateService`/`UpdateService`）时，不支持使用 `assignPublicIp` 为任务 ENI 分配公有 IP 地址。
+ 在任务级别配置 `awsvpc` 联网时，您必须使用与 Amazon ECS 托管实例容量提供程序的启动模板中指定的 VPC 相同的 VPC。您可以使用与启动模板中指定的子网和安全组不同的子网和安全组。
+ 对于 `awsvpc` 网络模式任务，在配置负载均衡器目标组时请使用 `ip` 目标类型。Amazon ECS 会自动管理支持的联网模式的目标组注册。

## 在双堆栈模式下使用 VPC
<a name="managed-instance-networking-vpc-dual-stack"></a>

在双堆栈模式下使用 VPC 时，您的任务可通过 IPv4 或 IPv6 或两者进行通信。IPv4 和 IPv6 地址彼此独立。因此，您必须在 VPC 中分别针对 IPv4 和 IPv6 配置路由和安全设置。有关如何将 VPC 配置为双堆栈模式的更多信息，请参阅《Amazon VPC 用户指南》**中的[迁移到 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)。

如果您使用互联网网关或仅出站互联网网关配置 VPC，则可以在双堆栈模式下使用 VPC。通过这样做，分配了 IPv6 地址的任务可以通过互联网网关或仅限出口的互联网网关访问互联网。NAT 网关是可选项。有关更多信息，请参阅 *Amazon VPC 用户用户指南*中的[互联网网关](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)和 [Egress-only 互联网网关](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html)。

如果满足以下条件，则向 Amazon ECS 任务分配 IPv6 地址：
+ 托管任务的 Amazon ECS 托管实例正在使用 `1.45.0` 或更高版本的容器代理。有关如何检查您的实例正在使用的代理版本以及根据需要进行更新的信息，请参阅[更新 Amazon ECS 容器代理](ecs-agent-update.md)。
+ `dualStackIPv6` 账户设置为已启用。有关更多信息，请参阅 [通过账户设置访问 Amazon ECS 功能](ecs-account-settings.md)。
+ 您的任务是使用 `awsvpc` 网络模式。
+ 您的 VPC 和子网已为 IPv6 配置。配置包括在指定子网中创建的网络接口。有关如何将 VPC 配置为双堆栈模式的更多信息，请参阅《Amazon VPC 用户指南》**中的[迁移到 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html) 和[修改子网的 IPv6 寻址属性](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-ipv6)。

# 主机网络模式
<a name="managed-instances-host-modes"></a>

在 `host` 模式下，任务直接共享主机的网络命名空间。容器的联网配置与您在创建 Amazon ECS 托管实例容量提供程序时使用 `networkConfiguration` 参数指定的底层 Amazon ECS 托管实例主机实例相关联。``

使用这种网络模式有明显的缺点。在每台主机上只能运行一个任务的单个实例化。这是因为只有第一个任务可以绑定到 Amazon EC2 实例上所需的端口。使用 `host` 网络模式时，也无法重新映射容器端口。例如，如果应用程序需要侦听特定的端口号，则您无法直接重新映射该端口号。相反，您必须通过更改应用程序配置来管理所有端口冲突。

使用 `host` 网络模式还存在安全影响。此模式允许容器模拟主机，并允许容器连接到主机上的私有环回网络服务。

仅当您需要直接访问主机联网或迁移需要主机级网络访问的应用程序时，才使用主机模式。

# EC2 的 Amazon ECS 任务联网选项
<a name="task-networking"></a>

Amazon EC2 实例上托管的 Amazon ECS 任务的联网行为取决于任务定义中所定义的*网络模式*。我们建议您使用 `awsvpc` 网络模式，除非您特别需要使用其他网络模式。

以下是可用的网络模式。


| 网络模式 | EC2 上的 Linux 容器 | EC2 上的 Windows 容器 | Description | 
| --- | --- | --- | --- | 
|  `awsvpc`  |  支持  |  是  |  向任务分配其自己的弹性网络接口（ENI）和主要私有 IPv4 或 IPv6 地址。这将为任务提供与 Amazon EC2 实例相同的网络属性。  | 
|  `bridge`  |  是  |  否  |  任务使用 Linux 上的 Docker 内置虚拟网络，该网络在托管任务的每个 Amazon EC2 实例内运行。Linux 上的内置虚拟网络使用 `bridge` Docker 网络驱动程序。如果未在任务定义中指定网络模式，则这是 Linux 上的默认网络模式。  | 
|  `host`  |  是  |  否  |  任务通过直接映射容器端口到托管任务的 Amazon EC2 实例的 ENI，使用会绕过 Docker 内置虚拟网络的主机网络。动态端口映射不可在此网络模式中使用。使用此模式的任务定义中的容器必须指定具体的 `hostPort` 号。主机上的端口号不可被用于多个任务。因此，您不可以在单个 Amazon EC2 实例上运行相同任务定义的多个任务。  | 
|  `none`  |  是  |  否  |  任务没有外部网络连接。  | 
|  `default`  |  否  |  是  |  任务使用 Windows 上的 Docker 内置虚拟网络，该网络在托管任务的每个 Amazon EC2 实例内运行。Windows 上的内置虚拟网络使用 `nat` Docker 网络驱动程序。如果未在任务定义中指定网络模式，则这是 Windows 上的默认网络模式。  | 

有关 Linux 上的 Docker 联网的更多信息，请参阅 *Docker 文档*中的[联网概述](https://docs.docker.com/engine/network/)。

有关 Windows 上的 Docker 联网的更多信息，请参阅 Microsoft *Windows 上的容器文档*中的 [Windows 容器联网](https://learn.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture)。

## 在仅 IPv6 模式下使用 VPC
<a name="networking-ipv6-only"></a>

在仅 IPv6 配置中，Amazon ECS 任务仅通过 IPv6 进行通信。要为仅 IPv6 配置设置 VPC 和子网，您必须向 VPC 添加 IPv6 CIDR 数据块，并创建仅包含 IPv6 CIDR 数据块的新子网。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[为 VPC 添加 IPv6 支持](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html)和[创建子网](https://docs.aws.amazon.com/vpc/latest/userguide/create-subnets.html)。

您还必须使用 IPv6 目标更新路由表，并为安全组配置 IPv6 规则。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[配置路由表](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html)和[配置安全组规则](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-security-group-rules.html)。

请注意以下事项：
+ 您可以通过直接更新服务以使用仅 IPv6 子网，或者创建仅 IPv6 并行服务并使用 Amazon ECS 蓝绿部署将流量转移到新服务，来将仅 IPv4 或双堆栈 Amazon ECS 服务更新为仅 IPv6 配置。有关 Amazon ECS 蓝绿部署的更多信息，请参阅[Amazon ECS 蓝/绿部署](deployment-type-blue-green.md)。
+ 仅 IPv6 Amazon ECS 服务必须使用带有 IPv6 目标组的双堆栈负载均衡器。如果您要迁移位于应用程序负载均衡器或网络负载均衡器后面的现有 Amazon ECS 服务，则可以创建新的双堆栈负载均衡器并转移来自旧负载均衡器的流量，或者更新现有负载均衡器的 IP 地址类型。

  有关网络负载均衡器的更多信息，请参阅《网络负载均衡器用户指南》**中的[创建网络负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/create-network-load-balancer.html)和[更新网络负载均衡器的 IP 地址类型](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-ip-address-type.html)。有关应用程序负载均衡器的更多信息，请参阅《应用程序负载均衡器用户指南》**中的[创建应用程序负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-application-load-balancer.html)和[更新应用程序负载均衡器的 IP 地址类型](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-ip-address-type.html)。
+ Windows 不支持仅 IPv6 配置。您必须使用经 Amazon ECS 优化的 Linux AMI 才能在仅 IPv6 配置中运行任务。有关经 Amazon ECS 优化的 Linux AMI 的更多信息，请参阅[经 Amazon ECS 优化的 Linux AMI](ecs-optimized_AMI.md)。
+ 当您启动一个容器实例来在仅 IPv6 配置中运行任务时，必须使用 `--enable-primary-ipv6` EC2 参数为该实例设置主 IPv6 地址。
**注意**  
如果没有主 IPv6 地址，则以主机或桥接网络模式在容器实例上运行的任务将无法向负载均衡器或 AWS Cloud Map 注册。

  有关运行 Amazon EC2 实例的 `--enable-primary-ipv6` 的更多信息，请参阅《AWS CLI 命令参考》**中的 [run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html)。

  有关使用AWS 管理控制台启动容器实例的更多信息，请参阅 [启动 Amazon ECS Linux 容器实例](launch_container_instance.md)。
+ 默认情况下，Amazon ECS 容器代理会通过查看实例的默认 IPv4 和 IPv6 路由来尝试检测容器实例是否与仅 IPv6 配置兼容。要覆盖此行为，您可以在实例的 `/etc/ecs/ecs.config` 文件中将 ` ECS_INSTANCE_IP_COMPATIBILITY` 参数设置为 `ipv4` 或 `ipv6`。
+ 任务必须使用 `1.99.1` 或更高版本的容器代理。有关如何检查您的实例正在使用的代理版本以及根据需要进行更新的信息，请参阅[更新 Amazon ECS 容器代理](ecs-agent-update.md)。
+ 对于仅 IPv6 配置中的 Amazon ECS 任务，如果要与仅 IPv4 端点通信，您可以设置 DNS64 和 NAT64，以将网络地址从 IPv6 转换为 IPv4。有关更多信息，请参阅 *Amazon VPC 用户指南*中的 [DNS64 和 NAT64](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-nat64-dns64.html)。
+ 在仅 IPv6 配置中，Amazon ECS 工作负载在从 Amazon ECR 拉取映像时必须使用 Amazon ECR 双堆栈映像 URI 端点。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[通过 IPv6 发出请求入门](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-requests.html#ipv6-access-getting-started)。
**注意**  
Amazon ECR 不支持仅 IPv6 配置中的任务可使用的双堆栈接口 VPC 端点。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[通过 IPv6 发出请求入门](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-requests.html#ipv6-access-getting-started)。
+ 仅 IPv6 配置不支持 Amazon ECS Exec。

### 支持 Amazon ECS 仅 IPv6 模式的 AWS 区域
<a name="networking-ipv6-only-regions"></a>

在 Amazon ECS 可用的以下 AWS 区域，您可以在仅 IPv6 配置中运行任务：
+ 美国东部（俄亥俄州）
+ 美国东部（弗吉尼亚州北部）
+ 美国西部（北加利福尼亚）
+ 美国西部（俄勒冈州）
+ 非洲（开普敦）
+ 亚太地区（香港）
+ 亚太地区（海得拉巴）
+ 亚太地区（雅加达）
+ 亚太地区（墨尔本）
+ 亚太地区（孟买）
+ 亚太地区（大阪）
+ 亚太地区（首尔）
+ 亚太地区（新加坡）
+ 亚太地区（悉尼）
+ 亚太地区（东京）
+ 加拿大（中部）
+ 加拿大西部（卡尔加里）
+ 中国（北京）
+ 中国（宁夏）
+ 欧洲地区（法兰克福）
+ 欧洲地区（伦敦）
+ 欧洲地区（米兰）
+ 欧洲地区（巴黎）
+ 欧洲（西班牙）
+ 以色列（特拉维夫）
+ 中东（巴林）
+ 中东（阿联酋）：
+ 南美洲（圣保罗）
+ AWS GovCloud（美国东部）
+ AWS GovCloud（美国西部）

# 为 Amazon ECS 任务分配网络接口
<a name="task-networking-awsvpc"></a>

`awsvpc` 网络模式提供的任务联网功能使 Amazon ECS 任务具有与 Amazon EC2 实例相同的联网属性。使用 `awsvpc` 网络模式可简化容器联网，因为您可以更好地控制您的应用程序相互之间以及与 VPC 内其他服务之间的通信方式。`awsvpc` 网络模式还为您的容器提供了更高的安全性，使您能够在任务中更精细地使用安全组和网络监视工具。您也可以利用其他 Amazon EC2 联网功能（例如 VPC 流日志），以便监控来往于您的任务的流量。此外，属于同一任务的容器可以通过 `localhost` 接口进行通信。

任务弹性网络接口（ENI）是 Amazon ECS 的完全托管功能。Amazon ECS 创建 ENI 并将它附加到具有指定安全组的 Amazon EC2 实例。任务在 ENI 上发送和接收网络流量的方式与 Amazon EC2 实例使用其主要网络接口的方式相同。预设情况下，每个任务 ENI 都会分配一个专用 IPv4 地址。如果您的 VPC 启用了双堆栈模式，并且您使用带有 IPv6 CIDR 数据块的子网，则任务 ENI 也将收到 IPv6 地址。每个任务只能有一个 ENI。

这些 ENI 在您账户的 Amazon EC2 控制台中可见。您的账户无法分离或修改 ENI。这是为了防止意外删除与正在运行的任务关联的 ENI。您可以在 Amazon ECS 控制台中或使用 [DescribeTasks](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DescribeTasks.html) API 操作查看任务的 ENI 连接信息。当任务停止或服务缩减时，将分离并删除任务 ENI。

当您需要提高的 ENI 密度时，请使用 `awsvpcTrunking` 账户设置。Amazon ECS 还会为您的容器实例创建和附加“中继”网络接口。中继网络接口完全由 Amazon ECS 托管。在您从 Amazon ECS 集群中终止或注销容器实例时，将删除中继 ENI。有 `awsvpcTrunking` 账户设置的更多信息，请参阅 [先决条件](container-instance-eni.md#eni-trunking-launching)。

您可以在任务定义的 `networkMode` 参数中指定 `awsvpc`。有关更多信息，请参阅 [网络模式](task_definition_parameters.md#network_mode)。

然后在运行任务或创建服务时使用 `networkConfiguration` 参数，其中包含用于放置任务的一个或多个子网，以及用于附加到 ENI 的一个或多个安全组。有关更多信息，请参阅 [网络配置](service_definition_parameters.md#sd-networkconfiguration)。这些任务放置在与这些子网相同的可用性区域中的兼容 Amazon EC2 实例上，并且指定的安全组与为该任务预置的 ENI 相关联。

## Linux 注意事项
<a name="linux"></a>

 在使用 Linux 操作系统时考虑以下事项。
+ 如果您在 `awsvpc` 模式下使用 a p5.48xlarge 实例，则在该实例上运行的任务不能超过 1 个。
+ 使用 `awsvpc` 网络模式的任务和服务需要与 Amazon ECS 服务相关的角色，从而向 Amazon ECS 提供代表您调用其他 AWS 服务的权限。此角色是在创建集群时（或者在 AWS 管理控制台 中创建或更新服务时）自动为您创建的。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。您也可以使用以下 AWS CLI 命令创建服务相关的角色：

  ```
  aws iam [create-service-linked-role](https://docs.aws.amazon.com/cli/latest/reference/iam/create-service-linked-role.html) --aws-service-name ecs.amazonaws.com
  ```
+ 您的 Amazon EC2 Linux 实例需要版本 `1.15.0` 或更高版本的容器代理运行使用 `awsvpc` 网络模式。如果您正在使用经 Amazon ECS 优化的 AMI，您的实例将需要不低于 `1.15.0-4` 版本的 `ecs-init` 程序包。
+ 在 VPC 上启用 `enableDnsHostnames` 和 `enableDnsSupport` 选项时， Amazon ECS使用任务联网和 Amazon 提供的（内部）DNS 主机名来填充任务的主机名。如果未启用这些选项，则任务的 DNS 主机名将被设置为随机主机名。有关 VPC 的 DNS 设置的更多信息，请参阅《Amazon VPC 用户指南》**中的[在您的 VPC 中使用 DNS](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html)。
+ 每个使用 `awsvpc` 网络模式的 Amazon ECS 任务都会接收到自己的弹性网络接口（ENI），该网络接口附加到托管它的 Amazon EC2 实例。可以附加到 Amazon EC2 Linux 实例的网络接口数量有默认配额。主网络接口算作该配额中的一个。例如，默认情况下，最多只能将三个 ENI 附加到一个 `c5.large` 实例。实例的主网络接口计为一个。您可以向该实例再附加 2 个 ENI。由于每个使用 `awsvpc` 网络模式的任务均需一个 ENI，因此，您通常只能在该实例类型上运行 2 个此类任务。要详细了解每种实例类型的默认 ENI 限制，请参阅《Amazon EC2 用户指南》中的[每种实例类型的每个网络接口的 IP 地址数](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI)**。
+ Amazon ECS 支持使用支持的实例类型启动 Amazon EC2 Linux 实例，并增加 ENI 密度。当您选择加入 `awsvpcTrunking` 账户设置并将使用这些实例类型的 Amazon EC2 Linux 实例注册到集群时，这些实例具有更高的 ENI 配额。将这些实例与此更高配额结合使用意味着您可以在每个 Amazon EC2 Linux 实例上放置更多的任务。为了将增加的 ENI 密度与中继功能结合使用，您的 Amazon EC2 实例必须使用版本 `1.28.1` 或更高版本的容器代理。如果您正在使用经 Amazon ECS 优化的 AMI，您的实例将还需要不低于版本 `1.28.1-2` 的 `ecs-init` 软件包。有关选择使用 `awsvpcTrunking` 账户设置的更多信息，请参阅 [通过账户设置访问 Amazon ECS 功能](ecs-account-settings.md)。有关 ENI 中继的更多信息，请参阅[增加 Amazon ECS Linux 容器实例网络接口](container-instance-eni.md)。
+ 当在 Amazon EC2 Linux 实例上托管使用 `awsvpc` 网络模式的任务时，不会为您的任务 ENI 提供公有 IP 地址。要访问互联网，必须在配置为使用 NAT 网关的私有子网中启动任务。有关更多信息，请参阅*《Amazon VPC 用户指南》*中的 [NAT 网关](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)。入站网络访问必须从使用私有 IP 地址的 VPC 内进行，或者通过 VPC 内的负载均衡器进行路由。在公有子网中启动的任务无法访问互联网。
+ Amazon ECS 仅为您识别连接到 Amazon EC2 Linux 实例的 ENI。如果您手动将 ENI 附加到您的实例，Amazon ECS 可能会尝试向没有足够网络适配器的实例添加任务。这可能会导致任务超时并转为取消预置状态，然后变为已停止状态。我们建议您不要手动将 ENI 附加到实例。
+ Amazon EC2 Linux 实例必须注册到可以考虑在 `awsvpc` 网络模式下放置任务的 `ecs.capability.task-eni` 功能。运行版本 `1.15.0-4` 或更高版本的 `ecs-init` 的实例注册自动有此属性。
+ 创建并连接到 Amazon EC2 Linux 实例的 ENI 不能手动分离或由您的账户修改。这是为了防止意外删除与正在运行的任务关联的 ENI。要释放任务的 ENI，请停止该任务。
+ 在运行任务或创建使用 `awsvpc` 网络模式的服务时，限制为可在 `awsVpcConfiguration` 中指定 16 个子网和 5 个安全组。有关更多信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [AwsVpcConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_AwsVpcConfiguration.html)。
+ 在用 `awsvpc` 网络模式启动任务时，Amazon ECS 容器代理会为每个任务创建一个附加的 `pause` 容器，然后在任务定义中启动该容器。然后，它通过运行 [amazon-ecs-cni-plugins](https://github.com/aws/amazon-ecs-cni-plugins) CNI 插件来配置 `pause` 容器的网络命名空间。然后，该代理会启动任务中的其余容器，以使其共享 `pause` 容器的网络堆栈。这意味着，一个任务中的所有容器均可通过 ENI 的 IP 地址来寻址，并且这些容器可以通过 `localhost` 接口相互通信。
+ 任务使用 `awsvpc` 网络模式的服务只支持应用程序负载均衡器和网络负载均衡器。当您为这些服务创建任何目标组时，必须选择 `ip` 作为目标类型。切勿使用 `instance`。这是因为使用 `awsvpc` 网络模式的任务与 ENI 而不是 Amazon EC2 Linux 实例关联。有关更多信息，请参阅 [使用负载均衡分配 Amazon ECS 服务流量](service-load-balancing.md)。
+ 如果您的 VPC 进行了更新以更改其使用的 DHCP 选项集，则无法将这些更改应用于现有任务。在应用这些更改的情况下启动新任务，验证它们是否正常工作，然后停止现有任务以安全地更改这些网络配置。

## Windows 注意事项
<a name="windows"></a>

 以下是使用 Windows 操作系统时的注意事项：
+ 使用经 Amazon ECS 优化的 Windows Server 2016 AMI 的容器实例无法托管使用 `awsvpc` 网络模式的任务。如果您的集群包含经 Amazon ECS 优化的 Windows Server 2016 AMI 和支持 `awsvpc` 网络模式的 Windows AMI，则使用 `awsvpc` 网络模式的任务不会在 Windows 2016 Server 实例上启动。而是会在支持 `awsvpc` 网络模式的实例上启动。
+ 您的 Amazon EC2 Windows 实例需要版本 `1.57.1` 或更高版本的容器代理为使用 `awsvpc` 网络模式的 Windows 容器使用 CloudWatch 指标。
+ 使用 `awsvpc` 网络模式的任务和服务需要与 Amazon ECS 服务相关的角色，从而向 Amazon ECS 提供代表您调用其他 AWS 服务的权限。此角色是在创建集群时（或者在 AWS 管理控制台 中创建或更新服务时）自动为您创建的。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。您也可以使用以下 AWS CLI 命令创建服务相关角色。

  ```
  aws iam [create-service-linked-role](https://docs.aws.amazon.com/cli/latest/reference/iam/create-service-linked-role.html) --aws-service-name ecs.amazonaws.com
  ```
+ 您的 Amazon EC2 Windows 实例需要版本 `1.54.0` 或更高版本的容器代理运行使用 `awsvpc` 网络模式。在引导实例时，必须配置 `awsvpc` 网络模式所需的选项。有关更多信息，请参阅 [引导启动 Amazon ECS Windows 容器实例以传递数据](bootstrap_windows_container_instance.md)。
+ 在 VPC 上同时启用 `enableDnsHostnames` 和 `enableDnsSupport` 选项时，Amazon ECS 会使用 Amazon 提供的（内部）DNS 主机名来填充任何主机名。如果未启用这些选项，则任务的 DNS 主机名为随机主机名。有关 VPC 的 DNS 设置的更多信息，请参阅《Amazon VPC 用户指南》**中的[在您的 VPC 中使用 DNS](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html)。
+ 每个使用 `awsvpc` 网络模式的 Amazon ECS 任务都会接收到自己的弹性网络接口（ENI），该网络接口附加到托管它的 Amazon EC2 Windows 实例。可以附加到 Amazon EC2 Windows 实例的网络接口数量有默认配额。主网络接口算作该配额中的一个。例如，默认情况下，最多只可将三个 ENI 附加到一个 `c5.large` 实例。实例的主网络接口计为其中一个。您可以向该实例再附加 2 个 ENI。由于每个使用 `awsvpc` 网络模式的任务均需一个 ENI，因此，您通常只能在该实例类型上运行 2 个此类任务。要详细了解每种实例类型的默认 ENI 限制，请参阅《Amazon EC2 用户指南》中的[每种实例类型的每个网络接口的 IP 地址数](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/using-eni.html#AvailableIpPerENI)**。
+ 当在 Amazon EC2 Windows 上托管使用 `awsvpc` 网络模式时，不会为您的任务 ENI 提供公有 IP 地址。要访问互联网，请在配置为使用 NAT 网关的私有子网中启动任务。有关更多信息，请参阅*《Amazon VPC 用户指南》*中的 [NAT 网关](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)。入站网络访问必须使用私有 IP 地址从 VPC 内进行，或者通过 VPC 内的负载均衡器进行路由。在公有子网中启动的任务无法访问互联网。
+ Amazon ECS 仅为您识别已附加到 Amazon EC2 Windows 实例的 ENI。如果您手动将 ENI 附加到您的实例，Amazon ECS 可能会尝试向没有足够网络适配器的实例添加任务。这可能会导致任务超时并转为取消预置状态，然后变为已停止状态。我们建议您不要手动将 ENI 附加到实例。
+ Amazon EC2 Windows 实例必须注册到可以考虑在 `awsvpc` 网络模式下放置任务的 `ecs.capability.task-eni` 功能。
+  您不能手动修改或分离创建并连接到 Amazon EC2 Windows 实例的 ENI。这是为了防止您意外删除与正在运行的任务关联的 ENI。要释放任务的 ENI，请停止该任务。
+  当运行任务或创建使用 `awsvpc` 网络模式的服务时，您最多只能在 `awsVpcConfiguration` 中指定 16 个子网和 5 个安全组。有关更多信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [AwsVpcConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_AwsVpcConfiguration.html)。
+ 在用 `awsvpc` 网络模式启动任务时，Amazon ECS 容器代理会为每个任务创建一个附加的 `pause` 容器，然后在任务定义中启动该容器。然后，它通过运行 [amazon-ecs-cni-plugins](https://github.com/aws/amazon-ecs-cni-plugins) CNI 插件来配置 `pause` 容器的网络命名空间。然后，该代理会启动任务中的其余容器，以使其共享 `pause` 容器的网络堆栈。这意味着，一个任务中的所有容器均可通过 ENI 的 IP 地址来寻址，并且这些容器可以通过 `localhost` 接口相互通信。
+ 任务使用 `awsvpc` 网络模式的服务只支持应用程序负载均衡器和网络负载均衡器。当您为这些服务创建任何目标组时，必须选择 `ip` 而不是 `instance` 作为目标类型。这是因为使用 `awsvpc` 网络模式的任务与 ENI 而不是 Amazon EC2 Windows 实例关联。有关更多信息，请参阅 [使用负载均衡分配 Amazon ECS 服务流量](service-load-balancing.md)。
+ 如果您的 VPC 进行了更新以更改其使用的 DHCP 选项集，则无法将这些更改应用于现有任务。在应用这些更改的情况下启动新任务，验证它们是否正常工作，然后停止现有任务以安全地更改这些网络配置。
+ 在 EC2 Windows 配置中使用 `awsvpc` 网络模式时，不支持以下内容：
  + 双堆栈配置
  + IPv6
  + ENI 中继

## 在双堆栈模式下使用 VPC
<a name="task-networking-vpc-dual-stack"></a>

在双堆栈模式下使用 VPC 时，您的任务可通过 IPv4 或 IPv6 或两者进行通信。IPv4 和 IPv6 地址彼此独立。因此，您必须在 VPC 中分别针对 IPv4 和 IPv6 配置路由和安全设置。有关如何将 VPC 配置为双堆栈模式的更多信息，请参阅《Amazon VPC 用户指南》**中的[迁移到 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)。

如果您使用互联网网关或仅出站互联网网关配置 VPC，则可以在双堆栈模式下使用 VPC。通过这样做，分配了 IPv6 地址的任务可以通过互联网网关或仅限出口的互联网网关访问互联网。NAT 网关是可选项。有关更多信息，请参阅 *Amazon VPC 用户用户指南*中的[互联网网关](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)和 [Egress-only 互联网网关](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html)。

如果满足以下条件，则向 Amazon ECS 任务分配 IPv6 地址：
+ 托管该任务的 Amazon EC2 Linux 实例正在使用版本 `1.45.0` 或更高版本的容器代理。有关如何检查您的实例正在使用的代理版本以及根据需要进行更新的信息，请参阅[更新 Amazon ECS 容器代理](ecs-agent-update.md)。
+ `dualStackIPv6` 账户设置为已启用。有关更多信息，请参阅 [通过账户设置访问 Amazon ECS 功能](ecs-account-settings.md)。
+ 您的任务是使用 `awsvpc` 网络模式。
+ 您的 VPC 和子网已为 IPv6 配置。配置包括在指定子网中创建的网络接口。有关如何将 VPC 配置为双堆栈模式的更多信息，请参阅《Amazon VPC 用户指南》**中的[迁移到 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html) 和[修改子网的 IPv6 寻址属性](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-ipv6)。

# 将 Amazon ECS 容器端口映射到 EC2 实例网络接口
<a name="networking-networkmode-host"></a>

`host` 网络模式仅支持 Amazon EC2 实例上托管的 Amazon ECS 任务。在 Fargate 上使用 Amazon ECS 时不支持该功能。

`host` 网络模式是 Amazon ECS 支持的最基本的网络模式。使用主机模式时，容器的网络连接直接绑定到运行容器的底层主机。

![\[该图显示了使用主机网络模式的容器的网络架构。\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/networkmode-host.png)


假设您正在运行一个 Node.js 容器，其中包含一个 Express 应用程序，该应用程序监听类似于上图所示端口的端口 `3000`。使用 `host` 网络模式时，容器使用底层主机 Amazon EC2 实例的 IP 地址在端口 3000 上接收流量。不建议使用此模式。

使用这种网络模式有明显的缺点。在每台主机上只能运行一个任务的单个实例化。这是因为只有第一个任务可以绑定到 Amazon EC2 实例上所需的端口。使用 `host` 网络模式时，也无法重新映射容器端口。例如，如果应用程序需要侦听特定的端口号，则您无法直接重新映射该端口号。相反，您必须通过更改应用程序配置来管理所有端口冲突。

使用 `host` 网络模式还存在安全影响。此模式允许容器模拟主机，并允许容器连接到主机上的私有环回网络服务。

# 将 Docker 的虚拟网络用于 Amazon ECS Linux 任务
<a name="networking-networkmode-bridge"></a>

`bridge` 网络模式仅支持 Amazon EC2 实例上托管的 Amazon ECS 任务。

在 `bridge` 模式下，您使用虚拟网桥在主机和容器的网络之间创建一个层。这样，您就可以创建将主机端口重新映射到容器端口的端口映射。映射可以是静态，也可以是动态。

![\[该图显示了使用桥接网络模式和静态端口映射的网络架构。\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/networkmode-bridge.png)


使用静态端口映射，您可以明确定义要映射到容器端口的主机端口。使用上面的示例，主机上的端口 `80` 被映射到容器上的端口 `3000`。要与容器化应用程序通信，您需要将流量发送到 Amazon EC2 实例的 IP 地址的端口 `80`。从容器化应用程序的角度来看，它可以看到端口 `3000` 上的入站流量。

如果您只想更改流量端口，则静态端口映射是合适的。但是，这仍然具有与使用 `host` 网络模式相同的缺点。在每台主机上只能运行一个任务的单个实例化。这是因为静态端口映射仅允许将单个容器映射到端口 80。

要解决此问题，请考虑使用带有动态端口映射的 `bridge` 网络模式，如下图所示。

![\[该图显示了使用桥接网络模式和动态端口映射的网络架构。\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/networkmode-bridge-dynamic.png)


通过不在端口映射中指定主机端口，您可以让 Docker 从临时端口范围中选择未使用的随机端口，并将其分配为容器的公共主机端口。例如，监听容器上端口 `3000` 的 Node.js 应用程序可能会被分配一个随机的大数值端口，例如 Amazon EC2 主机上的 `47760`。这样做意味着您可以在主机上运行该容器的多个副本。此外，还可以在主机上为每个容器分配自己的端口。容器的每个副本都会在端口 `3000` 上接收流量。但是，向这些容器发送流量的客户端使用随机分配的主机端口。

Amazon ECS 可帮助您跟踪为每项任务随机分配的端口。它通过自动更新负载均衡器目标组和 AWS Cloud Map 服务发现以包含任务 IP 地址和端口列表来实现此目的。这样可以更轻松地使用通过动态端口使用 `bridge` 模式运行的服务。

但是，使用 `bridge` 网络模式的一项缺点是，很难将服务锁定为服务通信。由于服务可能会分配给任何随机的、未使用的端口，因此有必要在主机之间开放广泛的端口范围。但是，要创建特定的规则，使某项特定服务只能与另一项特定服务进行通信并不容易。这些服务没有用于安全组网络规则的特定端口。

## 为仅 IPv6 工作负载配置桥式联网模式
<a name="networking-networkmode-bridge-ipv6-only"></a>

要配置 `bridge` 模式以通过 IPv6 进行通信，您必须更新 Docker 进程守护程序设置。请使用以下内容更新 `/etc/docker/daemon.json`：

```
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64",
  "ip6tables": true,
  "experimental": true
}
```

更新 Docker 进程守护程序设置后，您需要重启进程守护程序。

**注意**  
当您更新并重启进程守护程序后，Docker 会在实例上启用 IPv6 转发，这可能会导致使用 Amazon Linux 2 AMI 的实例丢失默认路由。为避免这种情况，请使用下面的命令通过子网的 IPv6 网关添加默认路由。  

```
ip route add default via FE80:EC2::1 dev eth0 metric 100
```

# Fargate 的 Amazon ECS 任务联网选项
<a name="fargate-task-networking"></a>

预设情况下，Fargate 上的每个 Amazon ECS 任务都会提供弹性网络接口（ENI）和主要私有 IP 地址。使用公有子网时，您可以选择向任务的 ENI 分配公有 IP 地址。如果您的 VPC 配置了双堆栈模式，并且您使用具有 IPv6 CIDR 数据块的子网，则您的任务 ENI 也将接收 IPv6 地址。一个任务在给定的时间只能有一个与之关联的 ENI。属于同一任务的容器可以通过 `localhost` 接口进行通信。有关 VPC 和子网的更多信息，请参阅《Amazon VPC 用户指南》**中的 [Amazon VPC 的工作原理](https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html)。

要使 Fargate 上的任务拉取容器映像，任务必须具有通往互联网的路由。下面说明如何验证您的任务具有通往互联网的路由。
+ 使用公有子网时，您可以向任务 ENI 分配公有 IP 地址。
+ 使用私有子网时，子网可以连接一个 NAT 网关。
+ 使用 Amazon ECR 中托管的容器映像时，您可以将 Amazon ECR 配置为使用接口 VPC 端点，将通过任务的私有 IPv4 地址进行映像提取 。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[Amazon ECR 接口 VPC 端点（AWS PrivateLink）](https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html)。

由于每个任务都有自己的 ENI，因此您可以使用联网功能（例如 VPC 流日志），以便可以监控您任务的流量。有关更多信息，请参阅《Amazon VPC 用户指南》**中的 [VPC 流日志](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html)。

您还可以利用 AWS PrivateLink。您可以配置 VPC 接口端点，以便可以通过私有 IP 地址访问 Amazon ECS API。AWS PrivateLink 将 VPC 和 Amazon ECS 之间的所有网络流量限制在 Amazon 网络以内。您无需互联网网关、NAT 设备或虚拟私有网关。有关更多信息，请参阅 [Amazon ECS 接口 VPC 端点（AWS PrivateLink）](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/vpc-endpoints.html)。

有关如何将 `NetworkConfiguration` 资源与 CloudFormation 一起使用的示例，请参阅 [Amazon ECS 的 CloudFormation 示例模板](working-with-templates.md)。

创建的 ENI 由 AWS Fargate 完全托管。此外，还有一个关联的 IAM 策略用于向 Fargate 授予权限。对于使用 Fargate 平台版本 `1.4.0` 或更高版本的任务，任务会接收单个 ENI（称为任务 ENI），所有网络流量都将流经 VPC 内的这个 ENI。此流量记录在您的 VPC 流日志中。对于使用 Fargate 平台版本 `1.3.0` 及更早版本的任务，除了任务 ENI 外，任务还会收到单独的 Fargate 拥有的 ENI，该 ENI 用于某些在 VPC 流日志中不可见的网络流量。下表介绍网络流量行为以及每个平台版本所需的 IAM 策略。


|  Action  |  Linux 平台版本 `1.3.0` 及更早版本的流量  |  Linux 平台版本 `1.4.0` 的流量  |  Windows 平台版本 `1.0.0` 的流量  |  IAM 权限  | 
| --- | --- | --- | --- | --- | 
|  检索 Amazon ECR 登录凭证  |  Fargate 拥有的 ENI  |  任务 ENI  |  任务 ENI  |  任务执行 IAM 角色  | 
|  映像提取  |  任务 ENI  |  任务 ENI  |  任务 ENI  |  任务执行 IAM 角色  | 
|  通过日志驱动程序发送日志  |  任务 ENI  |  任务 ENI  |  任务 ENI  |  任务执行 IAM 角色  | 
|  通过适用于 Amazon ECS 的 FireLens 发送日志  |  任务 ENI  |  任务 ENI  |  任务 ENI  |  任务 IAM 角色  | 
|  从 Secrets Manager 或 Systems Manager 中检索密码  |  Fargate 拥有的 ENI  |  任务 ENI  |  任务 ENI  |  任务执行 IAM 角色  | 
|  Amazon EFS 文件系统流量  |  不可用  |  任务 ENI  |  任务 ENI  |  任务 IAM 角色  | 
|  应用程序流量  |  任务 ENI  |  任务 ENI  |  任务 ENI  |  任务 IAM 角色  | 

## 注意事项
<a name="fargate-task-networking-considerations"></a>

在使用任务联网时考虑以下事项。
+ Amazon ECS 服务链接角色需要为 Amazon ECS 提供代表您呼叫其他 AWS 服务的权限。此角色是在创建集群时或者在 AWS 管理控制台 中创建或更新服务时为您创建的。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。您也可以使用以下 AWS CLI 命令创建服务相关角色。

  ```
  aws iam [create-service-linked-role](https://docs.aws.amazon.com/cli/latest/reference/iam/create-service-linked-role.html) --aws-service-name ecs.amazonaws.com
  ```
+ 在 VPC 上启用 `enableDnsHostnames` 和 `enableDnsSupport` 选项时，Amazon ECS 使用 Amazon 提供的 DNS 主机名来填充任务的主机名。如果未启用这些选项，则任务的 DNS 主机名将被设置为随机主机名。有关 VPC 的 DNS 设置的更多信息，请参阅《Amazon VPC 用户指南》**中的[在您的 VPC 中使用 DNS](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html)。
+ 您最多只能为 `awsVpcConfiguration` 指定 16 个子网和 5 个安全组。有关更多信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [AwsVpcConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_AwsVpcConfiguration.html)。
+ 您不能手动分离或修改 Fargate 创建并附加的 ENI。这是为了防止意外删除与正在运行的任务关联的 ENI。要释放任务的 ENI，请停止该任务。
+ 如果 VPC 子网进行了更新以更改其使用的 DHCP 选项集，则无法将这些更改应用于使用 VPC 的现有任务。启动新任务，以在测试新更改的同时获得平稳迁移的新设置，然后在不需要回滚的情况下停止旧的任务。
+ 以下内容适用于在 Fargate 平台版本 `1.4.0` 或更高版本（适用于 Linux）或 `1.0.0`（适用于 Windows）上运行的任务。在双堆栈子网中启动的任务会接收一个 IPv4 地址和一个 IPv6 地址。在仅 IPv6 子网中启动的任务仅接收 IPv6 地址。
+ 对于使用平台版本 `1.4.0` 或更高版本（对于 Linux）或 `1.0.0`（对于 Windows）的任务，任务 ENI 支持巨型帧。网络接口配置了最大传输单元（MTU），这是单个帧内将放入的最大有效载荷的大小。MTU 越大，单个帧内可以放入的应用程序有效载荷就越多，这可以减少每帧开销并提高效率。当您的任务和目标之间的网络路径支持巨型帧时，支持巨型帧将减少开销。
+ 任务使用 Fargate 的服务仅支持应用程序负载均衡器和网络负载均衡器。不支持经典负载均衡器。当您创建任何目标组时，必须选择 `ip` 而不是 `instance` 作为目标类型。有关更多信息，请参阅 [使用负载均衡分配 Amazon ECS 服务流量](service-load-balancing.md)。

## 在双堆栈模式下使用 VPC
<a name="fargate-task-networking-vpc-dual-stack"></a>

在双堆栈模式下使用 VPC 时，您的任务可通过 IPv4 /或 IPv6 或两者进行通信。IPv4 和 IPv6 地址是彼此独立的；您必须在 VPC 中分别针对 IPv4 和 IPv6 配置路由和安全设置。有关将 VPC 配置为双堆栈模式的更多信息，请参阅 *Amazon VPC用户指南* 中的[迁移到 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)。

如果满足以下条件，将向 Fargate 上的 Amazon ECS 任务分配 IPv6 地址：
+ 您的 Amazon ECS `dualStackIPv6` 账户设置为 IAM 主体在您启动任务所在的区域启动您的任务时打开（`enabled`）。此设置仅可使用 API 或 AWS CLI 修改。您可以选择为账户中的特定 IAM 主体开启此设置，也可以通过设置账户默认设置为整个账户开启此设置。有关更多信息，请参阅 [通过账户设置访问 Amazon ECS 功能](ecs-account-settings.md)。
+ 您的 VPC 和子网已为 IPv6 启用。有关如何将 VPC 配置为双堆栈模式的更多信息，请参阅《Amazon VPC 用户指南》**中的[迁移到 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)。
+ 您的子网已启用自动分配 IPv6 地址。有关如何配置子网的更多信息，请参阅《Amazon VPC 用户指南》**中的[修改子网的 IPv6 寻址属性](https://docs.aws.amazon.com/vpc/latest/userguide/modify-subnets.html)。
+ 任务或服务使用 Fargate 平台版本 `1.4.0` 或更高版本（用于 Linux）。

对于双堆栈模式下在 VPC 中运行的 Fargate 上的 Amazon ECS 任务，要与任务启动过程中使用的依赖服务（例如，ECR、SSM 和 SecretManager）通信，公有子网的路由表需要通往互联网网关的 IPv4（0.0.0.0/0）路由，私有子网的路由表需要通往 NAT 网关的 IPv4（0.0.0.0/0）路由。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[互联网网关](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)和 [NAT 网关](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)。

有关如何配置双堆栈 VPC 的示例，请参阅 [双堆栈 VPC 配置示例](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-example.html)。

## 在仅 IPv6 模式下使用 VPC
<a name="fargate-task-networking-vpc-ipv6-only"></a>

在仅 IPv6 配置中，Amazon ECS 任务仅通过 IPv6 进行通信。要为仅 IPv6 配置设置 VPC 和子网，您必须向 VPC 添加 IPv6 CIDR 数据块，并创建仅包含 IPv6 CIDR 数据块的子网。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[为 VPC 添加 IPv6 支持](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html)和[创建子网](https://docs.aws.amazon.com/vpc/latest/userguide/create-subnets.html)。您还必须使用 IPv6 目标更新路由表，并为安全组配置 IPv6 规则。有关更多信息，请参阅《Amazon VPC 用户指南》**中的[配置路由表](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html)和[配置安全组规则](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-security-group-rules.html)。

请注意以下事项：
+ 您可以通过直接更新服务以使用仅 IPv6 子网，或者创建仅 IPv6 并行服务并使用 Amazon ECS 蓝绿部署将流量转移到新服务，来将仅 IPv4 或双堆栈 Amazon ECS 服务更新为仅 IPv6 配置。有关 Amazon ECS 蓝绿部署的更多信息，请参阅[Amazon ECS 蓝/绿部署](deployment-type-blue-green.md)。
+ 仅 IPv6 Amazon ECS 服务必须使用带有 IPv6 目标组的双堆栈负载均衡器。如果您要迁移位于应用程序负载均衡器或网络负载均衡器后面的现有 Amazon ECS 服务，则可以创建新的双堆栈负载均衡器并转移来自旧负载均衡器的流量，或者更新现有负载均衡器的 IP 地址类型。

   有关网络负载均衡器的更多信息，请参阅《网络负载均衡器用户指南》**中的[创建网络负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/create-network-load-balancer.html)和[更新网络负载均衡器的 IP 地址类型](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-ip-address-type.html)。有关应用程序负载均衡器的更多信息，请参阅《应用程序负载均衡器用户指南》**中的[创建应用程序负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-application-load-balancer.html)和[更新应用程序负载均衡器的 IP 地址类型](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-ip-address-type.html)。
+ Windows 不支持仅 IPv6 配置。
+ 对于仅 IPv6 配置中的 Amazon ECS 任务，如果要与仅 IPv4 端点通信，您可以设置 DNS64 和 NAT64，以将网络地址从 IPv6 转换为 IPv4。有关更多信息，请参阅 *Amazon VPC 用户指南*中的 [DNS64 和 NAT64](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-nat64-dns64.html)。
+ Fargate 平台版本 `1.4.0` 或更高版本支持仅 IPv6 配置。
+ 在仅 IPv6 配置中，Amazon ECS 工作负载在从 Amazon ECR 拉取映像时必须使用 Amazon ECR 双堆栈映像 URI 端点。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[通过 IPv6 发出请求入门](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-requests.html#ipv6-access-getting-started)。
**注意**  
Amazon ECR 不支持仅 IPv6 配置中的任务可使用的双堆栈接口 VPC 端点。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[通过 IPv6 发出请求入门](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-requests.html#ipv6-access-getting-started)。
+ 仅 IPv6 配置不支持 Amazon ECS Exec。
+ Amazon CloudWatch 不支持可用于监控仅 IPv6 配置中使用 FIPS-140 合规性的 Amazon ECS 任务的双堆栈 FIPS 端点。有关 FIPS-140 的更多信息，请参阅 [AWS Fargate 美国联邦信息处理标准（FIPS-140）](ecs-fips-compliance.md)。

### 支持 Amazon ECS 仅 IPv6 模式的 AWS 区域
<a name="fargate-task-networking-ipv6-only-regions"></a>

在 Amazon ECS 可用的以下 AWS 区域，您可以在仅 IPv6 配置中运行任务：
+ 美国东部（俄亥俄州）
+ 美国东部（弗吉尼亚州北部）
+ 美国西部（北加利福尼亚）
+ 美国西部（俄勒冈州）
+ 非洲（开普敦）
+ 亚太地区（香港）
+ 亚太地区（海得拉巴）
+ 亚太地区（雅加达）
+ 亚太地区（墨尔本）
+ 亚太地区（孟买）
+ 亚太地区（大阪）
+ 亚太地区（首尔）
+ 亚太地区（新加坡）
+ 亚太地区（悉尼）
+ 亚太地区（东京）
+ 加拿大（中部）
+ 加拿大西部（卡尔加里）
+ 中国（北京）
+ 中国（宁夏）
+ 欧洲地区（法兰克福）
+ 欧洲地区（伦敦）
+ 欧洲地区（米兰）
+ 欧洲地区（巴黎）
+ 欧洲（西班牙）
+ 以色列（特拉维夫）
+ 中东（巴林）
+ 中东（阿联酋）：
+ 南美洲（圣保罗）
+ AWS GovCloud（美国东部）
+ AWS GovCloud（美国西部）

# Amazon ECS 任务的存储选项
<a name="using_data_volumes"></a>

Amazon ECS 为您提供了灵活、经济高效且易于使用的数据存储选项，具体取决于您的需求。Amazon ECS 支持以下容器的数据卷选项：


| 数据量 | 支持的容量 | 支持的操作系统 | 存储持久性 | 使用案例 | 
| --- | --- | --- | --- | --- | 
| Amazon Elastic Block Store (Amazon EBS) | Fargate、Amazon EC2、Amazon ECS 托管实例 | Linux、Windows（仅在 Amazon EC2 上） | 附加到独立任务时可以持久保存。附加到服务维护的任务时是短暂的。 | Amazon EBS 卷为数据密集型容器化工作负载提供经济高效、持久、高性能的块存储。常见使用情况包括事务性工作负载（例如数据库、虚拟桌面和根卷）以及吞吐量密集型工作负载（例如日志处理和 ETL 工作负载）。有关更多信息，请参阅 [将 Amazon EBS 卷与 Amazon ECS 结合使用](ebs-volumes.md)。 | 
| Amazon Elastic File System (Amazon EFS) | Fargate、Amazon EC2、Amazon ECS 托管实例 | Linux | 持续的 | Amazon EFS 卷提供简单、可扩展和持久的共享文件存储用于 Amazon ECS 任务，它会随着您添加和删除文件而自动增长和缩小。Amazon EFS 卷支持并发性，对于水平扩展且需要低延迟、高吞吐量和先写后读一致性等存储功能的容器化应用程序，非常有用。常见使用案例包括数据分析、媒体处理、内容管理和 Web 服务等工作负载。有关更多信息，请参阅 [将 Amazon EFS 卷与 Amazon ECS 结合使用](efs-volumes.md)。 | 
| 适用于 Windows File Server 的 Amazon FSx | Amazon EC2 | Windows | 持续的 | 适用于 Windows File Server 的 FSx 卷提供完全托管的 Windows 文件服务器，您可以使用这些服务器来预调配需要持久、分布式、共享和静态文件存储的 Windows 任务。常见使用案例包括 .NET 应用程序，这些应用程序可能需要本地文件夹作为持久存储来保存应用程序输出。适用于 Windows File Server 的 Amazon FSx 在容器中提供了本地文件夹，使多个容器能够在由 SMB 共享支持的同一个文件系统上进行读写操作。有关更多信息，请参阅 [将适用于 Windows File Server 的 FSx 卷与 Amazon ECS 结合使用](wfsx-volumes.md)。 | 
| 适用于 NetApp ONTAP 的 Amazon FSx | Amazon EC2 | Linux | 持续的 | 适用于 NetApp ONTAP 的 Amazon FSx 卷提供完全托管式 NetApp ONTAP 文件系统，您可以使用这些系统来预置需要持久、高性能和功能丰富的共享文件存储的 Linux 任务。适用于 NetApp ONTAP 的 Amazon FSx 支持 NFS 和 SMB 协议，并提供快照、克隆和重复数据删除等企业级功能。常见使用案例包括高性能计算工作负载、内容存储库和需要兼容 POSIX 的共享存储的应用程序。有关更多信息，请参阅[从 Amazon ECS 容器中挂载适用于 NetApp ONTAP 的 Amazon FSx 文件系统](https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/mount-ontap-ecs-containers.html)。 | 
| Docker 卷 | Amazon EC2 | Windows、Linux | 持续的 | Docker 卷是 Docker 容器运行时的一项功能，它允许容器通过从主机的文件系统挂载目录来持久保存数据。Docker 卷驱动程序（也称为插件）用于将容器卷与外部存储系统集成。Docker 卷可以由第三方驱动程序或内置的 local 驱动程序管理。Docker 卷的常见使用案例包括提供持久数据卷或在同一容器实例的不同容器上的不同位置共享卷。有关更多信息，请参阅 [将 Docker 卷与 Amazon ECS 结合使用](docker-volumes.md)。 | 
| 绑定挂载 | Fargate、Amazon EC2、Amazon ECS 托管实例 | Windows、Linux | 临时的 | 绑定挂载由挂载到容器中的主机上的文件或目录组成，例如 Amazon EC2 实例或 AWS Fargate。绑定挂载的常见使用案例包括与同一任务中的其他容器共享源容器中的卷，或者在一个或多个容器中挂载主机卷或空卷。有关更多信息，请参阅 [将绑定挂载与 Amazon ECS 结合使用](bind-mounts.md)。 | 

# 将 Amazon EBS 卷与 Amazon ECS 结合使用
<a name="ebs-volumes"></a>

Amazon Elastic Block Store（Amazon EBS）卷为数据密集型工作负载提供高度可用、经济高效、持久、高性能的块存储。Amazon EBS 卷可以与 Amazon ECS 任务一起用于高吞吐量和事务密集型应用程序。有关 Amazon EBS 卷的更多信息，请参阅《Amazon EBS 用户指南》[https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volumes.html](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volumes.html)中的 *Amazon EBS 卷*。

附加到 Amazon ECS 任务的 Amazon EBS 卷由 Amazon ECS 代表您管理。在独立任务启动期间，您可以提供用于将一个 EBS 卷附加到任务的配置。在创建或更新服务期间，您可以提供针对 Amazon ECS 服务管理的每个任务，用于为每个任务挂载一个 EBS 卷的配置。您可以配置新的空卷以进行附加，也可以使用快照从现有卷加载数据。

**注意**  
使用快照配置卷时，您可以指定一个 `volumeInitializationRate`（以 MiB/s 为单位），以该速度从快照中提取数据，从而创建在可预测的时间内完全初始化的卷。有关卷初始化的更多信息，请参阅《*Amazon EBS 用户指南*》中的 [Initialize Amazon EBS volumes](https://docs.aws.amazon.com/ebs/latest/userguide/initalize-volume.html)。有关配置 Amazon EBS 卷的更多信息，请参阅[在 Amazon ECS 任务定义中将卷配置推迟到启动时间](specify-ebs-config.md)和[指定 Amazon ECS 部署时的 Amazon EBS 卷配置](configure-ebs-volume.md)。

使用任务定义中的 `configuredAtLaunch` 参数将卷配置推迟到启动时间。通过在启动时提供卷配置而不是在任务定义中提供，您可以创建不受特定数据卷类型或特定 EBS 卷设置限制的任务定义。然后，您可以在不同的运行时环境中重复使用任务定义。例如在部署期间，您可以为生产工作负载提供比预生产环境更多的吞吐量。

 附加到任务的 Amazon EBS 卷可以使用 AWS Key Management Service（AWS KMS）密钥进行加密，以保护您的数据。有关更多信息，请参阅[加密附加到 Amazon ECS 任务的 Amazon EBS 卷中存储的数据](ebs-kms-encryption.md)。

要监控卷的性能，您还可以使用 Amazon CloudWatch 指标。有关 Amazon EBS 卷的 Amazon ECS 指标的更多信息，请参阅 [Amazon ECS CloudWatch 指标](available-metrics.md) 和 [Amazon ECS Container Insights 指标](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-ECS.html)。

所有支持 Amazon ECS 的商业和中国 [AWS 区域](https://docs.aws.amazon.com/glossary/latest/reference/glos-chap.html?icmpid=docs_homepage_addtlrcs#region) 都支持将 Amazon EBS 卷附加到任务。

## 支持的操作系统和容量
<a name="ebs-volumes-configuration"></a>

下表提供了支持的操作系统和容量配置。


| 容量 | Linux  | Windows | 
| --- | --- | --- | 
| Fargate |  平台版本 1.4.0 或更高版本（Linux）支持 Amazon EBS 卷。有关更多信息，请参阅 [适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。 | 不支持 | 
| EC2 | 托管在基于 Nitro 的实例上并具有经 Amazon ECS 优化的亚马逊机器映像（AMI）的任务支持 Amazon EBS 卷。有关实例类型的信息，请参阅《Amazon EC2 用户指南》中的[实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html)。ECS 优化型 AMI `20231219` 或更高版本支持 Amazon EBS 卷。有关更多信息，请参阅[检索经 Amazon ECS 优化的 AMI 元数据](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/retrieve-ecs-optimized_AMI.html)。 | 在使用 Amazon ECS 优化型亚马逊机器映像（AMI）的基于 Nitro 的实例上托管的任务。有关实例类型的信息，请参阅《Amazon EC2 用户指南》中的[实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html)。ECS 优化型 AMI `20241017` 或更高版本支持 Amazon EBS 卷。有关更多信息，请参阅[检索 Amazon ECS 优化型 Windows AMI 元数据](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/retrieve-ecs-optimized_windows_AMI.html)。 | 
| Amazon ECS 托管实例 | Linux 上的 Amazon ECS 托管实例上托管的任务支持 Amazon EBS 卷。 | 不支持 | 

## 注意事项
<a name="ebs-volume-considerations"></a>

 使用 Amazon EBS 卷时应考虑以下事项：
+ 您无法将 Amazon EBS 卷配置为附加到 `use1-az3` 可用区中的 Fargate Amazon ECS 任务。
+ 托管在 Fargate 上的任务不支持磁性（`standard`）Amazon EBS 卷类型。有关 Amazon EBS 卷类型的更多信息，请参阅《Amazon EC2 用户指南》[https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html)中的 *Amazon EBS 卷*。
+ 创建服务或在部署时配置卷的独立任务时，需要 Amazon ECS 基础设施的 IAM 角色。您可以将 AWS 托管的 `AmazonECSInfrastructureRolePolicyForVolumes` IAM 策略附加到角色，也可以使用托管策略作为指南，以创建并附加您自己的具有满足您特定需求的权限的策略。有关更多信息，请参阅 [Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。
+ 您最多可以将一个 Amazon EBS 卷附加到每个 Amazon ECS 任务，并且该卷必须是新卷。您不能将现有的 Amazon EBS 卷挂载到任务中。但是，您可以在部署时使用现有卷的快照来配置新的 Amazon EBS 卷。
+ 要将 Amazon EBS 卷与 Amazon ECS 服务结合使用，部署控制器必须是 `ECS`。使用此部署控制器时，支持滚动和蓝/绿部署策略。
+ 要使任务中的容器写入已装载的 Amazon EBS 卷，该容器必须具有适当的文件系统权限。当您在容器定义中指定非根用户时，Amazon ECS 会自动为卷配置基于组的权限，以允许指定的用户读取和写入该卷。如果未指定用户，则容器以根用户身份运行，并拥有对卷的完全访问权限。
+ Amazon ECS 会自动将保留的标签 `AmazonECSCreated` 和 `AmazonECSManaged` 添加到附加的卷中。如果您从卷中移除这些标签，则 Amazon ECS 将无法代表您管理该卷。有关标记 Amazon EBS 卷的更多信息，请参阅[标记 Amazon EBS 卷](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specify-ebs-config.html#ebs-volume-tagging)。有关标记 Amazon ECS 源的更多信息，请参阅[标记 Amazon ECS 资源](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-using-tags.html)。
+ 不支持通过包含分区的 Amazon EBS 卷的快照预调配卷。
+ 附加到由服务管理的任务的卷不会被保留，并且总是会在任务终止时被删除。
+ 您无法将 Amazon EBS 卷配置为附加到正在 AWS Outposts 上运行的 Amazon ECS 任务。

# 非根用户行为
<a name="ebs-non-root-behavior"></a>

当您在容器定义中指定非根用户时，Amazon ECS 会自动为 Amazon EBS 卷配置基于组的权限，以允许指定的用户读取和写入该卷。卷装载时具有以下特性：
+ 卷由根用户和根组拥有。
+ 组权限设置为允许读写访问。
+ 将非根用户添加到合适的组以访问卷。

将 Amazon EBS 卷用于非根容器时，请遵循下面的最佳实践：
+ 在容器映像中使用一致的用户 ID（UID）和组 ID（GID），以确保权限一致。
+ 在容器映像中预先创建挂载点目录，并设置合适的所有权和权限。
+ 在开发环境中使用 Amazon EBS 卷测试您的容器，以确认文件系统权限是否按预期工作。
+ 如果同一任务中的多个容器共享一个卷，请确保它们使用兼容的 UID/GID，或者以一致的访问期望挂载卷。

# 在 Amazon ECS 任务定义中将卷配置推迟到启动时间
<a name="specify-ebs-config"></a>

要将 Amazon EBS 卷配置为附加到您的任务，您必须在任务定义中指定卷和挂载点配置和给卷命名。您还必须将 `configuredAtLaunch` 设置为 `true`，因为无法在任务定义中为附加配置 Amazon EBS 卷。反之，在部署期间可配置 Amazon EBS 卷进行附加。

要使用 AWS Command Line Interface（AWS CLI）注册任务定义，请将模板另存为 JSON 文件，然后将该文件作为 `[register-task-definition](https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html)` 命令的输入传递。

要使用 AWS 管理控制台 创建和注册任务定义，请参阅[使用控制台创建 Amazon ECS 任务定义](create-task-definition.md)。

以下任务定义在任务定义中显示 `mountPoints` 和 `volumes` 对象的语法。有关任务定义参数的更多信息，请参阅[Fargate 的 Amazon ECS 任务定义参数](task_definition_parameters.md)。要使用此示例，请将 `user input placeholders` 替换为您自己的信息。

## Linux
<a name="linux-example"></a>

```
{
    "family": "mytaskdef",
    "containerDefinitions": [
        {
            "name": "nginx",
            "image": "public.ecr.aws/nginx/nginx:latest",
            "networkMode": "awsvpc",
           "portMappings": [
                {
                    "name": "nginx-80-tcp",
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "mountPoints": [
                {
                    "sourceVolume": "myEBSVolume",
                    "containerPath": "/mount/ebs",
                    "readOnly": true
                }
            ]
        }
    ],
    "volumes": [
        {
            "name": "myEBSVolume",
            "configuredAtLaunch": true
        }
    ],
    "requiresCompatibilities": [
        "FARGATE", "EC2"
    ],
    "cpu": "1024",
    "memory": "3072",
    "networkMode": "awsvpc"
}
```

## Windows
<a name="windows-example"></a>

```
{
    "family": "mytaskdef",
     "memory": "4096",
     "cpu": "2048",
    "family": "windows-simple-iis-2019-core",
    "executionRoleArn": "arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
    "runtimePlatform": {"operatingSystemFamily": "WINDOWS_SERVER_2019_CORE"},
    "requiresCompatibilities": ["EC2"]
    "containerDefinitions": [
        {
             "command": ["New-Item -Path C:\\inetpub\\wwwroot\\index.html -Type file -Value '<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>'; C:\\ServiceMonitor.exe w3svc"],
            "entryPoint": [
                "powershell",
                "-Command"
            ],
            "essential": true,
            "cpu": 2048,
            "memory": 4096,
            "image": "mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019",
            "name": "sample_windows_app",
            "portMappings": [
                {
                    "hostPort": 443,
                    "containerPort": 80,
                    "protocol": "tcp"
                }
            ],
            "mountPoints": [
                {
                    "sourceVolume": "myEBSVolume",
                    "containerPath": "drive:\ebs",
                    "readOnly": true
                }
            ]
        }
    ],
    "volumes": [
        {
            "name": "myEBSVolume",
            "configuredAtLaunch": true
        }
    ],
    "requiresCompatibilities": [
        "FARGATE", "EC2"
    ],
    "cpu": "1024",
    "memory": "3072",
    "networkMode": "awsvpc"
}
```

`mountPoints`  
类型：对象数组  
必需：否  
容器中数据卷的挂载点。此参数对应于 create-container Docker API 中的 `Volumes` 和 docker run 命令的 `--volume` 选项。  
Windows 容器可在 `$env:ProgramData` 所在的驱动器上挂载整个目录。Windows 容器无法在其他驱动器上挂载目录，并且挂载点不能跨驱动器使用。您必须指定挂载点才能将 Amazon EBS 卷直接附加到 Amazon ECS 任务。    
`sourceVolume`  
类型：字符串  
必需：是，当使用 `mountPoints` 时  
要挂载的卷的名称。  
`containerPath`  
类型：字符串  
必需：是，当使用 `mountPoints` 时  
挂载卷的容器中的路径。  
`readOnly`  
类型：布尔值  
必需：否  
如果此值为`true`，则容器具有对卷的只读访问权。如果此值为`false`，则容器可对卷进行写入。默认值为 `false`。  
对于在运行 Windows 操作系统的 EC2 实例上运行的任务，请保留默认值 `false`。

`name`  
类型：字符串  
必需：否  
卷的名称。最多允许 255 个字母（大写和小写字母）、数字、连字符（`-`）和下划线（`_`）。此名称已在容器定义 `mountPoints` 对象的 `sourceVolume` 参数中引用。

`configuredAtLaunch`  
类型：布尔值  
必需：是，当您要使用将 EBS 卷直接附加到任务时。  
指定卷在启动时是否可配置。如果设置为 `true`，您可以在运行独立任务或者创建或更新服务时配置卷。如果设置为 `false`，则无法在任务定义中提供其他卷配置。必须提供此参数并将其设置为 `true` 才能将 Amazon EBS 卷配置为附加到一个任务中。

# 加密附加到 Amazon ECS 任务的 Amazon EBS 卷中存储的数据
<a name="ebs-kms-encryption"></a>

您可以使用 AWS Key Management Service（AWS KMS）来创建和管理用于保护您的数据的加密密钥。Amazon EBS 卷通过使用 AWS KMS keys 进行静态加密。将加密以下类型的数据：
+ 在卷上静态存储的数据
+ 磁盘 I/O
+ 从卷中创建的快照
+ 从加密的快照创建的新卷

附加到任务的 Amazon EBS 卷可以通过使用别名为 `alias/aws/ebs` 的默认 AWS 托管式密钥 或卷配置中指定的对称客户自主管理型密钥进行加密。默认的 AWS 托管式密钥 对每个 AWS 区域 的每个 AWS 账户 都是唯一的，并且将自动创建。要创建对称的客户托管密钥，请按照《AWS KMS 开发人员指南》**的[创建对称加密 KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html#create-symmetric-cmk)中的步骤进行操作。

您可以默认配置 Amazon EBS 加密，以便使用您为账户指定的 KMS 密钥，对创建并附加到特定 AWS 区域中的任务的所有新卷进行加密。有关 Amazon EBS 加密和默认加密的更多信息，请参阅《*Amazon EBS 用户指南*》中的 [Amazon EBS encryption](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-encryption.html)。

## Amazon ECS 托管实例行为
<a name="managed-instances"></a>

您可以通过启用加密来加密 Amazon EBS 卷：使用默认加密，或者在创建要加密的卷时启用加密。有关如何默认启用加密（在账户级别）的信息，请参阅《Amazon EBS 用户指南》**中的[默认加密](https://docs.aws.amazon.com/ebs/latest/userguide/encryption-by-default.html)。

您可以配置这些密钥的任意组合。KMS 密钥的优先顺序如下：

1. 卷配置中指定的 KMS 密钥。在卷配置中指定 KMS 密钥时，它会覆盖 Amazon EBS 默认值以及在账户级别指定的任何 KMS 密钥。

1. 在账户级别指定的 KMS 密钥。为 Amazon ECS 托管存储的集群级加密指定 KMS 密钥时，它会覆盖 Amazon EBS 默认加密，但不会覆盖卷配置中指定的任何 KMS 密钥。

1. Amazon EBS 默认加密。当您未指定账户级 KMS 密钥或卷配置中的密钥时，将应用默认加密。如果默认启用 Amazon EBS 加密，则默认值是您默认指定用于加密的 KMS 密钥。否则，默认值是别名为 `alias/aws/ebs` 的 AWS 托管式密钥。
**注意**  
如果在卷配置中将 `encrypted` 设置为 `false`，不指定账户级 KMS 密钥，并且默认启用 Amazon EBS 加密，则默认情况下，仍将使用为 Amazon EBS 加密指定的密钥对卷进行加密。

## 非 Amazon ECS 托管实例行为
<a name="non-managed-instances"></a>

您还可以在创建或更新集群时为 Amazon ECS 托管存储设置 Amazon ECS 集群级加密。集群级加密在任务级别生效，可用于使用指定的 KMS 密钥加密附加到特定集群中运行的每个任务的 Amazon EBS 卷。有关如何为每个任务在集群级别配置加密的更多信息，请参阅《Amazon ECS API 参考》**中的 [ManagedStorageConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedStorageConfiguration.html)。

您可以配置这些密钥的任意组合。KMS 密钥的优先顺序如下：

1. 卷配置中指定的 KMS 密钥。在卷配置中指定 KMS 密钥时，它会覆盖 Amazon EBS 默认值以及在集群级别指定的任何 KMS 密钥。

1. 在集群级别指定的 KMS 密钥。为 Amazon ECS 托管存储的集群级加密指定 KMS 密钥时，它会覆盖 Amazon EBS 默认加密，但不会覆盖卷配置中指定的任何 KMS 密钥。

1. Amazon EBS 默认加密。当您未指定集群级 KMS 密钥或卷配置中的密钥时，将应用默认加密。如果默认启用 Amazon EBS 加密，则默认值是您默认指定用于加密的 KMS 密钥。否则，默认值是别名为 `alias/aws/ebs` 的 AWS 托管式密钥。
**注意**  
如果在卷配置中将 `encrypted` 设置为 `false`，不指定集群级 KMS 密钥，并且默认启用 Amazon EBS 加密，则默认情况下，仍将使用为 Amazon EBS 加密指定的密钥对卷进行加密。

## 客户托管的 KMS 密钥策略
<a name="ebs-kms-encryption-policy"></a>

要使用客户自主管理型密钥对附加到任务的 EBS 卷进行加密，您必须配置 KMS 密钥策略，以确保用于卷配置的 IAM 角色拥有使用该密钥的必要权限。密钥策略必须包含 `kms:CreateGrant` 和 `kms:GenerateDataKey*` 权限。`kms:ReEncryptTo` 和 `kms:ReEncryptFrom` 权限是加密使用快照创建的卷所必需的。如果您只想为附加配置和加密新的空卷，您可以排除 `kms:ReEncryptTo` 和 `kms:ReEncryptFrom` 权限。

以下 JSON 代码段显示您可以附加到 KMS 密钥策略的密钥策略语句。使用这些语句将为 Amazon ECS 提供使用该密钥来加密 EBS 卷的权限。要使用策略语句示例，请将 `user input placeholders` 替换为您自己的信息。与往常一样，只配置您需要的权限。

```
{
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:role/ecsInfrastructureRole" },
      "Action": "kms:DescribeKey",
      "Resource":"*"
    },
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:role/ecsInfrastructureRole" },
      "Action": [
      "kms:GenerateDataKey*",
      "kms:ReEncryptTo",
      "kms:ReEncryptFrom"
      ],
      "Resource":"*",
      "Condition": {
        "StringEquals": {
          "kms:CallerAccount": "aws_account_id",
          "kms:ViaService": "ec2.region.amazonaws.com"
        },
        "ForAnyValue:StringEquals": {
          "kms:EncryptionContextKeys": "aws:ebs:id"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:role/ecsInfrastructureRole" },
      "Action": "kms:CreateGrant",
      "Resource":"*",
      "Condition": {
        "StringEquals": {
          "kms:CallerAccount": "aws_account_id",
          "kms:ViaService": "ec2.region.amazonaws.com"
        },
        "ForAnyValue:StringEquals": {
          "kms:EncryptionContextKeys": "aws:ebs:id"
        },
        "Bool": {
          "kms:GrantIsForAWSResource": true
        }
      }
    }
```

有关密钥策略和权限的更多信息，请参阅《AWS KMS 开发人员指南》**中的 [AWS KMS 中的密钥策略](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)和 [AWS KMS 权限](https://docs.aws.amazon.com/kms/latest/developerguide/kms-api-permissions-reference.html)。要排查与密钥权限相关的 EBS 卷附加问题，请参阅[排查 Amazon ECS 任务挂载 Amazon EBS 卷的问题](troubleshoot-ebs-volumes.md)。

# 指定 Amazon ECS 部署时的 Amazon EBS 卷配置
<a name="configure-ebs-volume"></a>

将 `configuredAtLaunch` 参数设置为 `true` 注册任务定义后，您可以在运行独立任务或创建或更新服务时在部署时配置 Amazon EBS 卷。有关使用 `configuredAtLaunch` 参数将卷配置推迟到启动时间的更多信息，请参阅[在 Amazon ECS 任务定义中将卷配置推迟到启动时间](specify-ebs-config.md)。

要配置卷，您可以使用 Amazon ECS API，也可以将 JSON 文件作为以下 AWS CLI 命令的输入传递：
+ 运行独立 ECS 任务的 `[run-task](https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)`。
+ 在特定的容器实例中运行独立 ECS 任务的 `[start-task](https://docs.aws.amazon.com/cli/latest/reference/ecs/start-task.html)`。此命令不适用于 Fargate 任务。
+ 创建新的 ECS 服务的 `[create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html)`。
+ 更新现有服务的 `[update-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html)`。

**注意**  
要使任务中的容器写入已装载的 Amazon EBS 卷，该容器必须具有适当的文件系统权限。当您在容器定义中指定非根用户时，Amazon ECS 会自动为卷配置基于组的权限，以允许指定的用户读取和写入该卷。如果未指定用户，则容器以根用户身份运行，并拥有对卷的完全访问权限。

 您也可以使用 AWS 管理控制台 来配置 Amazon EBS 卷。有关更多信息，请参阅 [将应用程序作为 Amazon ECS 任务运行](standalone-task-create.md)、[创建 Amazon ECS 滚动更新部署](create-service-console-v2.md) 和 [更新 Amazon ECS 服务](update-service-console-v2.md)。

以下 JSON 代码段显示可在部署时配置的 Amazon EBS 卷的所有参数。要使用这些参数进行卷配置，请将 `user input placeholders` 替换为您自己的信息。有关这些参数的更多信息，请参阅[卷配置](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html#sd-volumeConfigurations)。

```
"volumeConfigurations": [
        {
            "name": "ebs-volume", 
            "managedEBSVolume": {
                "encrypted": true, 
                "kmsKeyId": "arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", 
                "volumeType": "gp3", 
                "sizeInGiB": 10, 
                "snapshotId": "snap-12345", 
                "volumeInitializationRate":100,
                "iops": 3000, 
                "throughput": 125, 
                "tagSpecifications": [
                    {
                        "resourceType": "volume", 
                        "tags": [
                            {
                                "key": "key1", 
                                "value": "value1"
                            }
                        ], 
                        "propagateTags": "NONE"
                    }
                ], 
                "roleArn": "arn:aws:iam::1111222333:role/ecsInfrastructureRole", 
                 "terminationPolicy": {
                    "deleteOnTermination": true//can't be configured for service-managed tasks, always true 
                },
                "filesystemType": "ext4"
            }
        }
    ]
```

**重要**  
确保您在配置中指定的 `volumeName` 与您在任务定义中指定的 `volumeName` 相同。

有关检查卷附加状态的信息，请参阅[排查 Amazon ECS 任务挂载 Amazon EBS 卷的问题](troubleshoot-ebs-volumes.md)。有关 EBS 卷附加所需的 Amazon ECS 基础设施 AWS Identity and Access Management（IAM）角色的信息，请参阅[Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。

以下是显示 Amazon EBS 卷配置的 JSON 代码段示例。这些示例可以通过将代码段保存在 JSON 文件中并将文件作为 AWS CLI 命令的参数（使用 `--cli-input-json file://filename` 参数）传递来使用。将 `user input placeholders` 替换为您自己的信息。

## 为独立任务配置卷
<a name="ebs-run-task"></a>

以下代码段显示配置 Amazon EBS 卷以附加到独立任务的语法。以下 JSON 代码段显示配置 `volumeType`、`sizeInGiB`、`encrypted` 和 `kmsKeyId` 设置的语法。JSON 文件中指定的配置用于创建 EBS 卷并将其附加到独立任务。

```
{
   "cluster": "mycluster",
   "taskDefinition": "mytaskdef",
   "volumeConfigurations": [
        {
            "name": "datadir",
            "managedEBSVolume": {
                "volumeType": "gp3",
                "sizeInGiB": 100,
                "roleArn":"arn:aws:iam::1111222333:role/ecsInfrastructureRole",
                "encrypted": true,
                "kmsKeyId": "arn:aws:kms:region:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
            }
        }
   ]
}
```

## 在创建服务时配置卷
<a name="ebs-create-service"></a>

以下代码段显示配置 Amazon EBS 卷以附加到服务管理的任务的语法。卷来自使用 `snapshotId` 参数指定的快照，速率为 200 MiB/s。JSON 文件中指定的配置用于创建 EBS 卷并将其附加到服务管理的每个任务。

```
{
   "cluster": "mycluster",
   "taskDefinition": "mytaskdef",
   "serviceName": "mysvc",
   "desiredCount": 2,
   "volumeConfigurations": [
        {
            "name": "myEbsVolume",
            "managedEBSVolume": {
              "roleArn":"arn:aws:iam::1111222333:role/ecsInfrastructureRole",
              "snapshotId": "snap-12345",
              "volumeInitializationRate": 200
            }
        }
   ]
}
```

## 在更新服务时配置卷
<a name="ebs-update-service"></a>

以下 JSON 代码段显示更新以前未将 Amazon EBS 卷配置为附加到任务的服务的语法。您必须提供任务定义修订的 ARN，其 `configuredAtLaunch` 被设置为 `true`。以下 JSON 代码段显示配置 `volumeType`、`sizeInGiB`、`throughput` 和 `iops` 以及 `filesystemType` 设置的语法。此配置用于创建 EBS 卷并将其附加到服务管理的每个任务。

```
{
   "cluster": "mycluster",
   "taskDefinition": "mytaskdef",
   "service": "mysvc",
   "desiredCount": 2,
   "volumeConfigurations": [
        {
            "name": "myEbsVolume",
            "managedEBSVolume": {
              "roleArn":"arn:aws:iam::1111222333:role/ecsInfrastructureRole",
               "volumeType": "gp3",
                "sizeInGiB": 100,
                 "iops": 3000, 
                "throughput": 125, 
                "filesystemType": "ext4"
            }
        }
   ]
}
```

### 将服务配置为不再利用 Amazon EBS 卷
<a name="ebs-service-disable-ebs"></a>

以下 JSON 代码段显示更新服务以不再利用 Amazon EBS 卷的语法。您必须提供 `configuredAtLaunch` 被设置为 `false` 的任务定义的 ARN，或者不带 `configuredAtLaunch` 参数的任务定义。您还必须提供一个空的 `volumeConfigurations` 对象。

```
{
   "cluster": "mycluster",
   "taskDefinition": "mytaskdef",
   "service": "mysvc",
   "desiredCount": 2,
   "volumeConfigurations": []
}
```

## Amazon EBS 卷的终止策略
<a name="ebs-volume-termination-policy"></a>

当 Amazon ECS 任务终止时，Amazon ECS 使用 `deleteOnTermination` 值来确定是否应删除与已终止的任务关联的 Amazon EBS 卷。默认情况下，任务终止时，将会删除附加到任务的 EBS 卷。对于独立任务，您可以更改此设置，改为在任务终止时保留卷。

**注意**  
附加到由服务管理的任务的卷不会被保留，并且总是会在任务终止时被删除。

## 标记 Amazon EBS 卷
<a name="ebs-volume-tagging"></a>

您可以使用 `tagSpecifications` 对象标记 Amazon EBS 卷。使用该对象，您可以提供自己的标签，并从任务定义或服务中设置标签的传播，具体取决于卷是附加到一项独立任务还是附加到服务中的某项任务。可以附加到一个卷上的最大标签数为 50。

**重要**  
Amazon ECS 会自动将保留的 `AmazonECSCreated` 和 `AmazonECSManaged` 标签附加到 Amazon EBS 卷中。这意味着您可以控制最多将 48 个其他标签附加到卷的情况。这些附加标签可以是用户定义的、ECS 管理的或传播的标签。

如果您想向卷中添加 Amazon ECS 托管的标签，则必须在 `UpdateService`、`CreateService`、`RunTask` 或 `StartTask` 调用中将 `enableECSManagedTags` 设置为 `true`。如果您启用 Amazon ECS 管理的标签，Amazon ECS 将使用集群和服务信息（`aws:ecs:clusterName` 和 `aws:ecs:serviceName`）自动标记卷。有关标记 Amazon ECS 源的更多信息，请参阅[标记 Amazon ECS 资源](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-using-tags.html)。

以下 JSON 代码段显示使用用户定义的标签标记附加到服务中每个任务的每个 Amazon EBS 卷的语法。要使用此示例创建服务，请将 `user input placeholders` 替换为您自己的信息。

```
{
   "cluster": "mycluster",
   "taskDefinition": "mytaskdef",
   "serviceName": "mysvc",
   "desiredCount": 2,
   "enableECSManagedTags": true,
   "volumeConfigurations": [
        {
            "name": "datadir",
            "managedEBSVolume": {
                "volumeType": "gp3",
                "sizeInGiB": 100,
                 "tagSpecifications": [
                    {
                        "resourceType": "volume", 
                        "tags": [
                            {
                                "key": "key1", 
                                "value": "value1"
                            }
                        ], 
                        "propagateTags": "NONE"
                    }
                ],
                "roleArn":"arn:aws:iam:1111222333:role/ecsInfrastructureRole",
                "encrypted": true,
                "kmsKeyId": "arn:aws:kms:region:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
            }
        }
   ]
}
```

**重要**  
您必须指定 `volume` 资源类型来标记 Amazon EBS 卷。

# Fargate 按需任务的 Amazon EBS 卷的性能
<a name="ebs-fargate-performance-limits"></a>

可用于 Fargate 按需任务的基准 Amazon EBS 卷 IOPS 和吞吐量取决于您为任务请求的总 CPU 单位数。如果您为 Fargate 任务请求 0.25、0.5 或 1 个虚拟 CPU 单位（vCPU），建议您配置通用型 SSD 卷（`gp2` 或 `gp3`）或硬盘驱动器（HDD）卷（`st1` 或 `sc1`）。如果您为 Fargate 任务请求 1 个以上 vCPU，则以下基准性能限制适用于附加到该任务的 Amazon EBS 卷。您可能会暂时获得比以下限制更高的 EBS 性能。但是，建议您根据这些限制来计划工作负载。


| 请求的 CPU 单位数（以 vCPU 为单位） | 基准 Amazon EBS IOPS（16 KiB I/O） | 基准 Amazon EBS 吞吐量（以 MiBps 为单位，128 KiB I/O） | 基准带宽（以 Mbps 为单位） | 
| --- | --- | --- | --- | 
| 2 | 3000 | 75 | 360 | 
| 4 | 5000 | 120 | 1,150 | 
| 8 | 10000 | 250 | 2,300 | 
| 16 | 15000 | 500 | 4,500 | 

**注意**  
 当您配置 Amazon EBS 卷以附加到 Fargate 任务时，Fargate 任务的 Amazon EBS 性能限制将在任务的临时存储和附加的卷之间共享。

# EC2 任务的 Amazon EBS 卷的性能
<a name="ebs-fargate-performance-limits-ec2"></a>

Amazon EBS 提供卷类型，各种类型性能特点和价格不同，因此您可根据应用程序要求定制您所需的存储性能和相应成本。有关性能的信息，包括每个卷的 IOPS 和每个卷的吞吐量，请参阅《Amazon Elastic Block Store 用户指南》中的 [Amazon EBS volume types](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html)**。

# Amazon ECS 托管实例任务的 Amazon EBS 卷的性能
<a name="ebs-managed-instances-performance"></a>

Amazon EBS 提供卷类型，各种类型性能特点和价格不同，因此您可根据应用程序要求定制您所需的存储性能和相应成本。有关性能的信息，包括每个卷的 IOPS 和每个卷的吞吐量，请参阅《Amazon Elastic Block Store 用户指南》中的 [Amazon EBS volume types](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html)**。

# 排查 Amazon ECS 任务挂载 Amazon EBS 卷的问题
<a name="troubleshoot-ebs-volumes"></a>

您可能需要对 Amazon EBS 卷与 Amazon ECS 任务的连接进行问题排查或验证。

## 检查卷附加状态
<a name="troubleshoot-ebs-volumes-location"></a>

您可以使用 AWS 管理控制台 来查看 Amazon EBS 卷附加到 Amazon ECS 任务的状态。如果任务开始但附加失败，则您还会看到一个状态原因，可以用它来进行故障排除。创建的卷将被删除，且任务将停止。有关状态原因的更多信息，请参阅 [Amazon EBS 卷附加到 Amazon ECS 任务的状态原因](troubleshoot-ebs-volumes-scenarios.md)。

**要使用控制台查看卷的附加状态和状态原因**

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

1. 在**集群**页面上，选择您的任务在其中运行的集群。此时会显示集群的详细信息页面。

1. 在集群的详细信息页面上，选择**任务**选项卡。

1. 选择要查看其卷挂载状态的任务。如果要检查的任务已停止，则可能需要使用**筛选所需状态**并选择**已停止**。

1. 在任务的详细信息页面上，选择**卷**选项卡。您将能够在**附加状态**下看到 Amazon EBS 卷的附加状态。如果卷无法附加到任务，则可以在**附加状态**下选择状态以显示失败原因。

您还可以使用 [DescribeTasks](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DescribeTasks.html) API 查看任务的卷附加状态和关联的状态原因。

## 服务和任务失败
<a name="service-task-failures"></a>

您可能会遇到非特定于 Amazon EBS 卷的服务或任务故障，这些故障可能会影响卷附加。有关更多信息，请参阅 
+ [服务事件消息](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-event-messages.html)
+ [已停止的任务错误代码](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/stopped-task-error-codes.html)
+ [API 失败原因](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/api_failures_messages.html)

# 容器无法写入 Amazon EBS 卷
<a name="troubleshoot-non-root-container"></a>

没有适当权限的非根用户  
当您在容器定义中指定非根用户时，Amazon ECS 会自动为卷配置基于组的权限，以允许写入访问。但是，如果您仍然遇到权限问题：  
+ 使用格式 `uid:gid`（例如 `1001:1001`）验证容器定义中是否正确指定了 `user` 参数。
+ 确保在挂载卷后，您的容器映像不会覆盖用户权限。
+ 通过检查容器日志或使用 Amazon ECS Exec 检查正在运行的容器，检查您的应用程序是否以预期用户 ID 运行。

有权限问题的根用户  
如果在容器定义中没有指定用户，则容器将以根用户身份运行，并且应拥有对卷的完全访问权限。如果遇到问题：  
+ 通过检查容器内的挂载点，验证卷是否已正确挂载。
+ 确保未在挂载点配置中将该卷配置为只读。

具有不同用户的多容器任务  
在多个容器以不同用户身份运行的任务中，Amazon ECS 会自动管理组权限，以允许所有指定用户写入卷。如果容器无法写入：  
+ 验证所有需要写入权限的容器是否都正确配置了 `user` 参数。
+ 检查所有需要访问该卷的容器是否都已正确挂载该卷。

有关在容器定义中配置用户的更多信息，请参阅 [Fargate 的 Amazon ECS 任务定义参数](https://docs.aws.amazon.com/./task_definition_parameters.html)。

# Amazon EBS 卷附加到 Amazon ECS 任务的状态原因
<a name="troubleshoot-ebs-volumes-scenarios"></a>

使用以下参考来修复您在配置 Amazon EBS 卷以附加到 Amazon ECS 任务时，在 AWS 管理控制台 中可能遇到的以状态原因形式出现的问题。有关在控制台中查找这些状态原因的更多信息，请参阅[检查卷附加状态](troubleshoot-ebs-volumes.md#troubleshoot-ebs-volumes-location)。

ECS 无法担任配置的 ECS 基础设施角色“arn:aws:iam::*111122223333*:role/*ecsInfrastructureRole*”。请确认传递的角色与 Amazon ECS 之间存在适当的信任关系  
此状态原因显示在以下场景中。  
+  您提供没有附加必要的信任策略的 IAM 角色。如果 Amazon ECS 基础设施 IAM 角色没有必要的信任策略，则 Amazon ECS 无法访问该角色。任务可能会卡在 `DEPROVISIONING` 状态。有关必要信任策略的更多信息，请参阅[Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。
+ 您的 IAM 用户无权将 Amazon ECS 基础设施角色传递给 Amazon ECS。任务可能会卡在 `DEPROVISIONING` 状态。为避免出现此问题，您可以将 `PassRole` 权限附加到您的用户。有关更多信息，请参阅 [Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。
+ 您的 IAM 角色没有附加 Amazon EBS 卷的必要权限。任务可能会卡在 `DEPROVISIONING` 状态。有关将 Amazon EBS 卷附加到任务所需的特定权限的更多信息，请参阅[Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。
您也可能会因角色传播延迟看到此错误消息。如果在等待几分钟后重试使用该角色仍无法解决问题，则可能错误地配置了角色的信任策略。

ECS 未能设置 EBS 卷。遇到 IdempotentParameterMismatch”；“您提供的客户端令牌与已删除的资源相关联。请使用其他客户端令牌。”  
以下 AWS KMS 密钥场景可能会导致出现 `IdempotentParameterMismatch` 消息：  
+ 您指定的 KMS 密钥 ARN、ID 或别名无效。在这种情况下，任务可能看起来成功启动，但由于 AWS 对 KMS 密钥进行了异步身份验证，因此任务最终会失败。有关更多信息，请参阅《Amazon EC2 用户指南》**中的 [Amazon EBS 加密](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-encryption.html)。
+ 您提供的客户托管密钥缺少允许 Amazon ECS 基础设施 IAM 角色使用该密钥进行加密的权限。为避免出现密钥策略权限问题，请参阅 [Amazon EBS 卷的数据加密](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ebs-volumes.html#ebs-kms-encryption)中的 AWS KMS 密钥策略示例。
您可以将 Amazon EventBridge 设置为向目标（例如 Amazon CloudWatch 组）发送 Amazon EBS 卷事件和 Amazon ECS 任务状态更改事件。然后，您可以使用这些事件来识别影响卷附加的特定客户托管密钥相关问题。有关更多信息，请参阅   
+  AWS re:Post 上的[如何创建 CloudWatch 日志组以用作 EventBridge 规则的目标？](https://repost.aws/knowledge-center/cloudwatch-log-group-eventbridge)。
+ [任务状态更改事件](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_cwe_events.html#ecs_task_events)。
+ 《Amazon EBS 用户指南》中的 [Amazon EventBridge events for Amazon EBS](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-cloud-watch-events.html)**。

在配置 EBS 卷到任务的附加时，ECS 超时。  
以下文件系统格式场景将产生此消息。  
+ 您在配置期间指定的文件系统格式与[任务的操作系统](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RuntimePlatform.html)不兼容。
+ 您将 Amazon EBS 卷配置为从快照中创建，但快照的文件系统格式与任务的操作系统不兼容。对于从快照创建的卷，必须指定创建快照时卷使用的相同文件系统类型。
您可以利用 Amazon ECS 容器代理日志对 EC2 任务的此消息进行问题排查。有关更多信息，请参阅 [Amazon ECS 日志文件位置](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/logs.html)和 [Amazon ECS 日志收集器](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-logs-collector.html)。

# 将 Amazon EFS 卷与 Amazon ECS 结合使用
<a name="efs-volumes"></a>

Amazon Elastic File System（Amazon EFS）提供简单的可扩展文件存储以供您的 Amazon ECS 任务使用。使用 Amazon EFS 时，存储容量是弹性的。它会随着您添加和删除文件而自动增加和缩减。您的应用程序可在需要时获得所需存储。

您可以将 Amazon EFS 文件系统与 Amazon ECS 配合使用，以便导出跨容器实例的实例集的文件系统数据。这样，无论您的任务登录的是哪个实例，都可以访问相同的持久性存储。您的任务定义必须引用容器实例上的卷挂载才能使用该文件系统。

有关教程，请参阅 [使用控制台为 Amazon ECS 配置 Amazon EFS 文件系统](tutorial-efs-volumes.md)。

## 注意事项
<a name="efs-volume-considerations"></a>

 使用 Amazon EFS 卷时应考虑以下事项：
+ 对于在 EC2 上运行的任务，已将 Amazon EFS 文件系统支持作为一个公共预览版添加，其中包括经 Amazon ECS 优化的 AMI 版本 `20191212` 以及容器代理版本 1.35.0。但是，Amazon EFS 文件系统支持通过经 Amazon ECS 优化的 AMI 版本 `20200319` 和容器代理版本1.38.0 正式推出，该版本包含 Amazon EFS 接入点和 IAM 授权功能。我们建议您使用经 Amazon ECS 优化的 AMI 版本 `20200319` 或更高版本以利用这些功能。有关更多信息，请参阅 [经 Amazon ECS 优化的 Linux AMI](ecs-optimized_AMI.md)。
**注意**  
如果您创建自己的 AMI，则必须使用容器代理 1.38.0 或更高版本、`ecs-init` 1.38.0-1 或更高版本，并在 Amazon EC2 实例上运行以下命令以启用 Amazon ECS 卷插件。命令取决于您将 Amazon Linux 2 还是 Amazon Linux 用作基本映像。  
Amazon Linux 2  

  ```
  yum install amazon-efs-utils
  systemctl enable --now amazon-ecs-volume-plugin
  ```
Amazon Linux  

  ```
  yum install amazon-efs-utils
  sudo shutdown -r now
  ```
+ 对于 Fargate 托管的任务，平台版本 1.4.0 或更高版本（Linux）支持 Amazon EFS 文件系统。有关更多信息，请参阅 [适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。
+ 在 Fargate 上托管的任务中使用 Amazon EFS 卷时，Fargate 将创建负责管理 Amazon EFS 卷的主管容器。主管容器使用少量的任务内存和 CPU。主管容器在查询任务元数据版本 4 端点时可见。此外，它作为容器名称 `aws-fargate-supervisor` 在 CloudWatch Container Insights 中可见。有关使用 EC2 的更多信息，请参阅[Amazon ECS 任务元数据端点版本 4](task-metadata-endpoint-v4.md)。有关使用 Fargate 的更多信息，请参阅[Fargate 上任务的 Amazon ECS 任务元数据端点版本 4](task-metadata-endpoint-v4-fargate.md)。
+ 不支持在外部实例上使用 Amazon EFS 卷或指定 `EFSVolumeConfiguration`。
+ 在 Amazon ECS 托管实例上运行的任务支持使用 Amazon EFS 卷。
+ 建议您将代理配置文件中的 `ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION` 参数值设置为小于默认值（约 1 小时）。此更改有助于防止 EFS 挂载凭证过期，并允许清理未使用的挂载。有关更多信息，请参阅 [Amazon ECS 容器代理配置](ecs-agent-config.md)。

## 使用 Amazon EFS 接入点
<a name="efs-volume-accesspoints"></a>

Amazon EFS 接入点是 EFS 文件系统中特定于应用程序的入口点，用于管理应用程序对共享数据集的访问。有关 Amazon EFS 接入点以及如何控制访问的更多信息，请参阅《Amazon Elastic File System 用户指南》**中的[使用 Amazon EFS 接入点工作](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html)。

接入点可以为通过接入点发出的所有文件系统请求强制执行用户身份（包括用户的 POSIX 组）。接入点还可以为文件系统强制执行不同的根目录。这样，客户端只能访问指定目录或其子目录中的数据。

**注意**  
创建 EFS 接入点时，请在文件系统上指定用作根目录的路径。在 Amazon ECS 任务定义中引用具有接入点 ID 的 EFS 文件系统时，必须忽略根目录或将根目录设置为 `/`，以便在 EFS 接入点上强制执行设置的路径。

您可以使用 Amazon ECS 任务 IAM 角色强制特定应用程序使用特定的接入点。通过将 IAM 策略与接入点相结合，您可以为您的应用程序提供对特定数据集的安全访问。有关如何使用任务 IAM 角色的更多信息，请参阅[Amazon ECS 任务 IAM 角色](task-iam-roles.md)。

# 将 Amazon EFS 卷与 Amazon ECS 结合使用的最佳实践
<a name="efs-best-practices"></a>

将 Amazon EFS 与 Amazon ECS 结合使用时，请记下以下最佳实践建议。

## Amazon EFS 卷的安全性和访问控制
<a name="storage-efs-security"></a>

Amazon EFS 提供访问控制功能，您可以使用这些功能来确保存储在 Amazon EFS 文件系统中的数据是安全的，并且只能从需要它的应用程序中访问。您可以通过启用静态加密和动态加密来保护数据。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的 [Amazon EFS 中的数据加密](https://docs.aws.amazon.com/efs/latest/ug/encryption.html)。

除了数据加密之外，您还可以使用 Amazon EFS 来限制对文件系统的访问。可以通过三种方法在 EFS 中实现访问控制。
+ **安全组** – 使用 Amazon EFS 挂载目标，您可以配置用于允许和拒绝网络流量的安全组。您可以将附加到 Amazon EFS 的安全组配置为允许来自附加到您的 Amazon ECS 实例的安全组的 NFS 流量（端口 2049），或者在使用 `awsvpc` 网络模式时，允许来自 Amazon ECS 任务的该流量。
+ **IAM** – 您可以使用 IAM 限制对 Amazon EFS 文件系统的访问。配置后，Amazon ECS 任务需要一个 IAM 角色来访问文件系统，以挂载 EFS 文件系统。有关详细信息，请参阅 *Amazon Elastic 文件系统用户指南* 中的[使用 IAM 控制文件系统数据访问](https://docs.aws.amazon.com/efs/latest/ug/iam-access-control-nfs-efs.html)。

  IAM 策略还可以强制执行预定义的条件，例如要求客户端使用 TLS 连接到 Amazon EFS 文件系统。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的[客户端的 Amazon EFS 条件键](https://docs.aws.amazon.com/efs/latest/ug/iam-access-control-nfs-efs.html#efs-condition-keys-for-nfs)。
+ **Amazon EFS 接入点** – Amazon EFS 接入点是 Amazon EFS 文件系统中特定于应用程序的入口点。您可以使用接入点为通过接入点发出的所有文件系统请求强制执行用户身份（包括用户的 POSIX 组）。接入点还可以为文件系统强制执行不同的根目录。这样，客户端只能访问指定目录或其子目录中的数据。

### IAM 策略
<a name="storage-efs-security-iam"></a>

您可以使用 IAM 策略来控制对 Amazon EFS 文件系统的访问权限。

您可以为使用文件系统策略访问文件系统的客户端指定以下操作。


| Action | 说明 | 
| --- | --- | 
|  `elasticfilesystem:ClientMount`  |  提供对文件系统的只读访问权限。  | 
|  `elasticfilesystem:ClientWrite`  |  提供对文件系统的写入权限。  | 
|  `elasticfilesystem:ClientRootAccess`  |  提供在访问文件系统时使用根用户的权限。  | 

您需要在策略中指定每个操作。这些策略可通过以下方式定义：
+ 基于客户端 – 将策略附加到任务角色

  在创建任务定义时设置 **IAM 授权**选项。
+ 基于资源 – 将策略附加到 Amazon EFS 文件系统

  如果不存在基于资源的策略，则默认情况下，在创建文件系统时，会向所有主体（\$1）授予访问权限。

在您设置 **IAM 授权**选项时，我们会将与任务角色关联的策略与 Amazon EFS 基于资源的策略进行合并。**IAM 授权**选项将任务身份（任务角色）和策略传递给 Amazon EFS。设置后，Amazon EFS 基于资源的策略就能为策略中指定的 IAM 用户或角色提供上下文。如果您未设置该选项，Amazon EFS 资源级策略会将 IAM 用户标识为“匿名”。

考虑在 Amazon EFS 文件系统上实施全部三种访问控制，以最大限度地提高安全性。例如，您可以将附加到 Amazon EFS 挂载点的安全组配置为仅允许来自与您的容器实例或 Amazon ECS 任务关联的安全组的入口 NFS 流量。此外，您可以将 Amazon EFS 配置为要求 IAM 角色访问文件系统，即使连接来自允许的安全组。最后，您可以使用 Amazon EFS 接入点，强制执行 POSIX 用户权限并为应用程序指定根目录。

以下任务定义代码段显示如何使用接入点挂载 Amazon EFS 文件系统。

```
"volumes": [
    {
      "efsVolumeConfiguration": {
        "fileSystemId": "fs-1234",
        "authorizationConfig": {
          "accessPointId": "fsap-1234",
          "iam": "ENABLED"
        },
        "transitEncryption": "ENABLED",
        "rootDirectory": ""
      },
      "name": "my-filesystem"
    }
]
```

## Amazon EFS 卷性能
<a name="storage-efs-performance"></a>

Amazon EFS 提供两种性能模式：通用型模式和最大 I/O 模式。通用型模式适用于对延迟敏感的应用程序，例如内容管理系统和 CI/CD 工具。相比之下，最大 I/O 文件系统适用于数据分析、媒体处理和机器学习等工作负载。这些工作负载需要从数百甚至数千个容器中执行并行操作，并且需要尽可能高的总吞吐量和 IOPS。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的 [Amazon EFS 性能模式](https://docs.aws.amazon.com/efs/latest/ug/performance.html#performancemodes)。

某些对延迟敏感的工作负载同时需要由最大 I/O 性能模式提供更高的 I/O 级别以及由通用性能模式提供的更低延迟。对于此类工作负载，我们建议创建多个通用性能模式文件系统。用此方式，您可以将应用程序工作负载分散到所有这些文件系统间，只要工作负载和应用程序可以支持它即可。

## Amazon EFS 卷吞吐量
<a name="storage-efs-performance-throughput"></a>

所有 Amazon EFS 文件系统都有相关的计量吞吐量，该吞吐量由使用*预调配吞吐量*的文件系统的预调配吞吐量或使用*突增吞吐量*的文件系统以 EFS 标准或单区存储类别存储的数据量决定。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的[了解计量吞吐量](https://docs.aws.amazon.com/efs/latest/ug/performance.html#read-write-throughput)。

Amazon EFS 文件系统的默认吞吐量模式为突增模式。在突增模式下，可用于文件系统的吞吐量会随着文件系统的增长而横向缩减或扩展。因为基于文件的工作负载通常会激增，在一段时间内需要高水平的吞吐量，其余时间则需要低水平的吞吐量，因此，Amazon EFS 被设计为可在一段时间内突增到允许高吞吐量。此外，由于许多工作负载的读取量大，因此读取操作与其他 NFS 操作（例如写入）的计量比例为 1:3。

所有 Amazon EFS 文件系统均为每 TB 的 Amazon EFS 标准存储或 Amazon EFS 单区存储提供 50 MB/s 的一致基准性能。所有文件系统，不管其大小如何，都能突增到 100 MB/s。拥有超过 1TB 的 EFS 标准存储或 EFS 单区存储的文件系统每 TB 可以突增至 100 MB/s。由于读取操作以 1:3 的比例计量，对于每 TiB 的读取吞吐量，您最多可以驱动到 300 MiB/s。当您将数据添加到文件系统时，文件系统可用的最大吞吐量会随着您在 Amazon EFS 标准存储类别中的存储量而自动线性扩展。如果您需要的吞吐量超过存储的数据量所能达到的吞吐量，则可以将预配置吞吐量配置为工作负载需要的特定量。

文件系统吞吐量在连接到文件系统的所有 Amazon EC2 实例间共享。例如，一个吞吐量可突增至 100 MB/s 的 1TB 文件系统可以从单个 Amazon EC2 实例中驱动 100 MB/s，每个实例可以驱动 10 MB/s。有关更多信息，请参阅*《Amazon Elastic 文件系统用户指南》*中的 [Amazon EFS 性能](https://docs.aws.amazon.com/efs/latest/ug/performance.html)。

## 优化 Amazon EFS 卷的成本
<a name="storage-efs-costopt"></a>

Amazon EFS 为您简化扩展存储的过程。随着您添加更多数据，Amazon EFS 文件系统会自动增长。尤其是在 Amazon EFS *突增吞吐量*模式下，Amazon EFS 上的吞吐量将随着标准存储类别中文件系统大小的增大而扩展。要在不为 EFS 文件系统的预调配吞吐量支付额外费用的情况下提高吞吐量，您可以与多个应用程序共享一个 Amazon EFS 文件系统。使用 Amazon EFS 接入点，您可以在共享的 Amazon EFS 文件系统中实施存储隔离。这样，即使应用程序仍共享同一个文件系统，但除非您授权，否则它们无法访问数据。

随着数据的增长，Amazon EFS 可帮助您将不经常访问的文件自动移动到较低的存储类别。Amazon EFS 标准-不频繁访问（IA）存储类别可降低并非每天访问的文件的存储成本。这样做并不会损害 Amazon EFS 提供的高可用性、高持久性、弹性和 POSIX 文件系统访问。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的 [EFS 存储类](https://docs.aws.amazon.com/efs/latest/ug/features.html)。

考虑使用 Amazon EFS 生命周期策略，通过将不经常访问的文件移至 Amazon EFS IA 存储来自动节省成本。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的 [Amazon EFS 生命周期管理](https://docs.aws.amazon.com/efs/latest/ug/lifecycle-management-efs.html)。

创建 Amazon EFS 文件系统时，您可以在 Amazon EFS 跨多个可用区（标准）复制您的数据或将您的数据冗余存储在单个可用区中之间进行选择。与 Amazon EFS 标准存储类别相比，Amazon EFS 单区存储类别可以大幅降低存储成本。对于不需要多可用区弹性的工作负载，考虑使用 Amazon EFS 单区存储类别。您可以通过将不经常访问的文件移至 Amazon EFS 单区-不频繁访问来进一步降低 Amazon EFS 单区存储的成本。有关更多信息，请参阅 [Amazon EFS 不频繁访问](https://aws.amazon.com/efs/features/infrequent-access/)。

## Amazon EFS 卷数据保护
<a name="storage-efs-dataprotection"></a>

对于使用标准存储类别的文件系统，Amazon EFS 跨多个可用区冗余存储您的数据。如果您选择 Amazon EFS 单区存储类别，则您的数据将冗余存储在单个可用区内。此外，Amazon EFS 被设计为在指定年度内提供 99.999999999%（11 个 9）的持久性。

与任何环境一样，最佳做法是进行备份并构建防范意外删除的保护措施。对于 Amazon EFS 数据，最佳实践包括使用 AWS Backup 进行正常运行且定期测试的备份。使用 Amazon EFS 单区存储类别的文件系统默认配置为在创建文件系统时自动备份文件，除非您选择禁用此功能。有关更多信息，请参阅《Amazon Elastic File System 用户指南》中的 [Backing up EFS file systems](https://docs.aws.amazon.com/efs/latest/ug/awsbackup.html)**。

# 在 Amazon ECS 任务定义中指定 Amazon EFS 文件系统
<a name="specify-efs-config"></a>

要为容器使用 Amazon EFS 文件系统卷，您必须在任务定义中指定卷和挂载点配置。以下任务定义 JSON 代码段显示容器的 `volumes` 和 `mountPoints` 对象的语法。

```
{
    "containerDefinitions": [
        {
            "name": "container-using-efs",
            "image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
            "entryPoint": [
                "sh",
                "-c"
            ],
            "command": [
                "ls -la /mount/efs"
            ],
            "mountPoints": [
                {
                    "sourceVolume": "myEfsVolume",
                    "containerPath": "/mount/efs",
                    "readOnly": true
                }
            ]
        }
    ],
    "volumes": [
        {
            "name": "myEfsVolume",
            "efsVolumeConfiguration": {
                "fileSystemId": "fs-1234",
                "rootDirectory": "/path/to/my/data",
                "transitEncryption": "ENABLED",
                "transitEncryptionPort": integer,
                "authorizationConfig": {
                    "accessPointId": "fsap-1234",
                    "iam": "ENABLED"
                }
            }
        }
    ]
}
```

`efsVolumeConfiguration`  
类型：对象  
必需：否  
使用 Amazon EFS 卷时将指定此参数。    
`fileSystemId`  
类型：字符串  
是否必需：是  
要使用的 Amazon EFS 文件系统 ID。  
`rootDirectory`  
类型：字符串  
必需：否  
Amazon EFS 文件系统中要作为主机内的根目录挂载的目录。如果忽略此参数，将使用 Amazon EFS 卷的根目录。指定`/`与忽略此参数效果相同。  
如果在 `authorizationConfig` 中指定了 EFS 接入点，则必须省略根目录值，或者将其设置为 `/`，以便在 EFS 接入点上强制执行设置的路径。  
`transitEncryption`  
类型：字符串  
有效值：`ENABLED` \$1 `DISABLED`  
必需：否  
指定是否对 Amazon ECS 主机和 Amazon EFS 服务器之间的 Amazon EFS 传输中数据启用加密。如果使用 Amazon EFS IAM 授权，则必须启用传输加密。如果忽略此参数，将使用默认值`DISABLED`。有关更多信息，请参阅*《Amazon Elastic File System 用户指南》*中的[加密传输中数据](https://docs.aws.amazon.com/efs/latest/ug/encryption-in-transit.html)。  
`transitEncryptionPort`  
类型：整数  
必需：否  
在 Amazon ECS 主机和 Amazon EFS 服务器之间发送加密数据时要使用的端口。如果未指定传输加密端口，将使用 Amazon EFS 挂载帮助程序使用的端口选择策略。有关更多信息，请参阅*《Amazon Elastic File System 用户指南》*中的 [EFS 挂载帮助程序](https://docs.aws.amazon.com/efs/latest/ug/efs-mount-helper.html)。  
`authorizationConfig`  
类型：对象  
必需：否  
Amazon EFS 文件系统的授权配置详细信息。    
`accessPointId`  
类型：字符串  
必需：否  
要使用的接入点 ID。如果指定了接入点，则必须省略在 `efsVolumeConfiguration` 中指定的根目录值，或者将其设置为 `/`，以便在 EFS 接入点上强制执行设置的路径。如果使用接入点，则必须在`EFSVolumeConfiguration`中启用传输加密。有关更多信息，请参阅《Amazon Elastic File System 用户指南》**中的[使用 Amazon EFS 接入点工作](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html)。  
`iam`  
类型：字符串  
有效值：`ENABLED` \$1 `DISABLED`  
必需：否  
 指定挂载 Amazon EFS 文件系统时是否使用在任务定义中定义的 Amazon ECS 任务 IAM 角色。如果启用，则必须在`EFSVolumeConfiguration`中启用传输加密。如果忽略此参数，将使用默认值`DISABLED`。有关更多信息，请参阅[适用于任务的 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)。

# 使用控制台为 Amazon ECS 配置 Amazon EFS 文件系统
<a name="tutorial-efs-volumes"></a>

了解如何将 Amazon Elastic File System（Amazon EFS）文件系统与 Amazon ECS 结合使用。

## 步骤 1：创建 Amazon ECS 集群
<a name="efs-create-cluster"></a>

请按照以下步骤创建 Amazon ECS 集群。

**要创建新集群（Amazon ECS 控制台）**

在开始之前，分配相应的 IAM 权限。有关更多信息，请参阅 [Amazon ECS 集群示例](security_iam_id-based-policy-examples.md#IAM_cluster_policies)。

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

1. 从导航栏中，选择要使用的区域。

1. 在导航窗格中，选择**集群**。

1. 在 **Clusters**（集群）页面上，选择 **Create cluster**（创建集群）。

1. 在**集群配置**下方的**集群名称**中，输入 `EFS-tutorial` 作为集群名称。

1. （可选）要更改任务和服务启动所在的 VPC 和子网，在 **Networking**（联网）下，执行以下任一操作：
   + 要删除子网，请在 **Subnets**（子网）下，为您要删除的每个子网选择 **X**。
   + 要更改为**默认** VPC 以外的 VPC，请在 **VPC** 下选择现有 **VPC**，然后在**子网**下选择每个子网。

1.  要向集群添加 Amazon EC2 实例，请展开**基础设施**，然后选择 **Amazon EC2 实例**。接下来，配置充当容量提供程序的 自动扩缩组：

   1. 要创建 自动扩缩组，请从 **自动扩缩组（ASG）**（自动扩缩组（ASG））中，选择 **Create new group**（创建新组），然后提供有关组的以下详细信息：
     + 对于**操作系统/架构**，选择 Amazon Linux 2。
     + 对于 **EC2 实例类型**，选择 `t2.micro`。

        对于 **SSH key pair**（SSH 密钥对），连接到实例时，选择可证明您身份的密钥对。
     + 对于**容量**，输入 `1`。

1. 选择**创建**。

## 步骤 2：为 Amazon EC2 实例和 Amazon EFS 文件系统创建安全组
<a name="efs-security-group"></a>

在此步骤中，您需要为 Amazon EC2 实例创建一个安全组，以允许端口 80 上的入站网络流量，并为 Amazon EFS 文件系统创建一个安全组，以允许您的容器实例进行入站访问。

使用以下选项为您的 Amazon EC2 实例创建安全组：
+ **安全组名称**：安全组的唯一名称。
+ **VPC**：您之前为集群确定的 VPC。
+ **入站规则**
  + **类型**：**HTTP**
  + **来源**：**0.0.0.0/0**。

使用以下选项为您的 Amazon EFS 文件系统创建安全组：
+ **安全组名称**：安全组的唯一名称。例如 `EFS-access-for-sg-dc025fa2`。
+ **VPC**：您之前为集群确定的 VPC。
+ **入站规则**
  + **类型**：**NFS**
  + **来源**：使用您为实例创建的安全组的 ID **自定义**。

有关如何创建安全组的信息，请参阅《适用于 Linux 实例的 Amazon EC2 用户指南》**中的[为 Amazon EC2 实例创建安全组](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-security-group.html)。

## 步骤 3：创建 Amazon EFS 文件系统
<a name="efs-create-filesystem"></a>

在该步骤中，您将创建一个 Amazon EFS 文件系统。

**为 Amazon ECS 任务创建 Amazon EFS 文件系统。**

1. 访问 [https://console.aws.amazon.com/efs/](https://console.aws.amazon.com/efs/)，打开 Amazon Elastic File System 控制台。

1. 选择 **Create file system**。

1. 输入文件系统的名称，然后选择托管容器实例的 VPC。默认情况下，指定 VPC 中的每个子网都会收到使用该 VPC 默认安全组的挂载目标。然后，选择**自定义**。
**注意**  
此教程假设您的 Amazon EFS 文件系统、Amazon ECS 集群、容器实例和任务位于同一 VPC 中。有关从其他 VPC 挂载文件系统的更多信息，请参阅《Amazon EFS 用户指南》**中的[演练：从其他 VPC 挂载文件系统](https://docs.aws.amazon.com/efs/latest/ug/efs-different-vpc.html)。

1. 在**文件系统设置**页面上，配置可选设置，然后在**性能设置**下，为您的文件系统选择**突增**吞吐量模式。配置完设置后，选择**下一步**。

   1. （可选）为文件系统添加标签。例如，通过在 **Name** 键旁边的 **Value** 列中输入名称可以为文件系统指定唯一的名称。

   1. （可选）启用生命周期管理可节省不经常访问的存储的成本。有关更多信息，请参阅 *Amazon Elastic File System 用户指南*中的 [EFS 生命周期管理](https://docs.aws.amazon.com/efs/latest/ug/lifecycle-management-efs.html)。

   1. （可选）启用加密。选中该复选框可对 Amazon EFS 文件系统启用静态加密。

1. 在**网络访问**页面的**挂载目标**下，将每个可用区的现有安全组配置替换为您在 [步骤 2：为 Amazon EC2 实例和 Amazon EFS 文件系统创建安全组](#efs-security-group) 中为文件系统创建的安全组，然后选择**下一步**。

1.  您无需为本教程配置**文件系统策略**，因此您可以通过选择**下一步**来跳过本部分。

1. 查看文件系统选项，然后选择**创建**以完成此过程。

1. 从**文件系统**屏幕中，记录**文件系统 ID**。在下一步中，您将在 Amazon ECS 任务定义中引用此值。

## 步骤 4：向 Amazon EFS 文件系统添加内容
<a name="efs-add-content"></a>

在此步骤中，您将 Amazon EFS 文件系统挂载到 Amazon EC2 实例并向其添加内容。这在本教程中用于测试，目的是说明数据的持久性质。使用此功能时，您通常会使用您的应用程序或其他方法将数据写入 Amazon EFS 文件系统。

**创建 Amazon EC2 实例并挂载 Amazon EFS 文件系统**

1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 选择 **Launch Instance（启动实例）**。

1. 在**应用程序和操作系统映像（亚马逊机器映像）**下，选择 **Amazon Linux 2 AMI（HVM）**。

1. 在**实例类型**下，保留默认实例类型 `t2.micro`。

1.  在**密钥对（登录）**下，选择用于 SSH 访问实例的密钥对。

1. 在**网络设置**下，选择您为 Amazon EFS 文件系统和 Amazon ECS 集群指定的 VPC。选择子网和在 [步骤 2：为 Amazon EC2 实例和 Amazon EFS 文件系统创建安全组](#efs-security-group) 中创建的实例安全组。配置实例的安全组。确保已启用**自动分配公有 IP**。

1. 在**配置存储**下，选择文件系统的**编辑**按钮，然后选择 **EFS**。选择您在 [步骤 3：创建 Amazon EFS 文件系统](#efs-create-filesystem) 中创建的文件系统。您可以选择更改挂载点或保留默认值。
**重要**  
您必须先选择子网，然后才能将文件系统添加到实例中。

1. 清除**自动创建和附加安全组**。将另一个复选框保持选中状态。请选择 **Add shared file system**（添加共享文件系统）。

1. 在**高级详细信息**下，确保通过 Amazon EFS 文件系统挂载步骤自动填充用户数据脚本。

1.  在**摘要**下，确保**实例数**为 **1**。选择**启动实例**。

1. 在**启动状态**页面上，选择**查看所有实例**以查看实例的状态。最初，**实例状态**为 `PENDING`。在状态变为 `RUNNING` 且实例通过所有状态检查后，实例就可以使用了。

现在，您可以连接到 Amazon EC2 实例并向 Amazon EFS 文件系统添加内容。

**连接到 Amazon EC2 实例并向 Amazon EFS 文件系统添加内容**

1. SSH 到您创建的 Amazon EC2 实例。有关更多信息，请参阅《Amazon EC2 用户指南》中的[使用 SSH 连接到 Linux 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-to-linux-instance.html)**。

1. 从终端窗口，运行 **df -T** 命令以验证 Amazon EFS 文件系统是否已挂载。在下面的输出中，我们突出了 Amazon EFS 文件系统挂载。

   ```
   $ df -T
   Filesystem     Type            1K-blocks    Used        Available Use% Mounted on
   devtmpfs       devtmpfs           485468       0           485468   0% /dev
   tmpfs          tmpfs              503480       0           503480   0% /dev/shm
   tmpfs          tmpfs              503480     424           503056   1% /run
   tmpfs          tmpfs              503480       0           503480   0% /sys/fs/cgroup
   /dev/xvda1     xfs               8376300 1310952          7065348  16% /
   127.0.0.1:/    nfs4     9007199254739968       0 9007199254739968   0% /mnt/efs/fs1
   tmpfs          tmpfs              100700       0           100700   0% /run/user/1000
   ```

1. 导航到挂载 Amazon EFS 文件系统的目录。在上述示例中，即为 `/mnt/efs/fs1`。

1. 使用以下内容创建名为 `index.html` 的文件：

   ```
   <html>
       <body>
           <h1>It Works!</h1>
           <p>You are using an Amazon EFS file system for persistent container storage.</p>
       </body>
   </html>
   ```

## 步骤 5：创建任务定义
<a name="efs-task-def"></a>

以下任务定义创建名为 `efs-html` 的数据卷。`nginx` 容器将该主机数据卷挂载在 NGINX 根目录（`/usr/share/nginx/html`）下。

**要使用 Amazon ECS 控制台创建新的任务定义**

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

1. 在导航窗格中，选择 **Task definitions**（任务定义）。

1. 选择 **Create new task definition**（创建新的任务定义）、**Create new task definition with JSON**（使用 JSON 创建新的任务定义）。

1. 在 JSON 编辑器框中，复制并粘贴以下 JSON 文本，将 `fileSystemId` 替换为 Amazon EFS 文件系统的 ID。

   ```
   {
       "containerDefinitions": [
           {
               "memory": 128,
               "portMappings": [
                   {
                       "hostPort": 80,
                       "containerPort": 80,
                       "protocol": "tcp"
                   }
               ],
               "essential": true,
               "mountPoints": [
                   {
                       "containerPath": "/usr/share/nginx/html",
                       "sourceVolume": "efs-html"
                   }
               ],
               "name": "nginx",
               "image": "public.ecr.aws/docker/library/nginx:latest"
           }
       ],
       "volumes": [
           {
               "name": "efs-html",
               "efsVolumeConfiguration": {
                   "fileSystemId": "fs-1324abcd",
                   "transitEncryption": "ENABLED"
               }
           }
       ],
       "family": "efs-tutorial",
       "executionRoleArn":"arn:aws:iam::111122223333:role/ecsTaskExecutionRole"
   }
   ```
**注意**  
Amazon ECS 任务执行 IAM 角色不需要任何特定的 Amazon EFS 相关权限，即可挂载 Amazon EFS 文件系统。如果不存在基于 Amazon EFS 资源的策略，则默认情况下，在创建文件系统时，会向所有主体（\$1）授予访问权限。  
只有在 Amazon ECS 任务定义中启用了“EFS IAM 授权”时，才需要使用 Amazon ECS 任务角色。启用后，必须允许任务角色身份访问基于 Amazon EFS 资源的策略中的 Amazon EFS 文件系统，并且应禁用匿名访问权限。

1. 选择**创建**。

## 步骤 6：运行任务并查看结果
<a name="efs-run-task"></a>

现在，您的 Amazon EFS 文件系统已经创建，并且已经有 NGINX 容器要提供的 Web 内容，您可以使用您创建的任务定义运行任务了。NGINX Web 服务器提供简单的 HTML 页面。如果更新 Amazon EFS 文件系统中的内容，更改会传播到挂载了该文件系统的所有容器。

该任务在您为集群定义的子网中运行。

**使用控制台运行任务并查看结果**

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

1. 在 **Clusters**（集群）页面上，选择包含要运行独立任务的集群。

   确定要从其中启动服务的资源。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tutorial-efs-volumes.html)

1. （可选）选择计划任务在集群基础设施中的分发方式。展开 **Compute configuration**（计算配置），然后执行以下操作：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tutorial-efs-volumes.html)

1. 对于**应用程序类型**，选择**任务**。

1. 对于**任务定义**，选择您之前创建的 `efs-tutorial` 任务定义。

1. 对于**所需任务**，输入 `1`。

1. 选择**创建**。

1. 在**集群**页面上，选择**基础设施**。

1. 在**容器实例**下，选择要连接的容器实例。

1. 在**容器实例**页面的**联网**下，记录您的实例的**公有 IP**。

1. 打开浏览器并输入公有 IP 地址。您将看到以下消息：

   ```
   It works!
   You are using an Amazon EFS file system for persistent container storage.
   ```
**注意**  
如果没有看到该消息，请确保容器实例的安全组允许端口 80 上的入站网络流量，且文件系统的安全组允许从容器实例进行入站访问。

# 将适用于 Windows File Server 的 FSx 卷与 Amazon ECS 结合使用
<a name="wfsx-volumes"></a>

适用于 Windows File Server 的 FSx 提供完全托管的 Windows 文件服务器，由 Windows 文件系统提供支持。使用适用于 Windows File Server 的 FSx 和 ECS 时，您可以使用永久、分布式、共享的静态文件存储来配置 Windows 任务。有关更多信息，请参阅[适用于 Windows File Server 的 FSx 定义](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/what-is.html)。

**注意**  
使用经 Amazon ECS 优化的 Windows Server 2016 的完整 AMI 的 EC2 实例不支持适用于 Windows File Server 的 FSx ECS 任务卷。  
在 Fargate 配置中，您不能在 Windows 容器中使用适用于 Windows File Server 的 FSx 卷。相反，您可以[修改容器以在启动时挂载它们](https://aws.amazon.com/blogs/containers/use-smb-storage-with-windows-containers-on-aws-fargate/)。

您可以使用适用于 Windows File Server 的 FSx 来部署需要访问共享外部存储、高可用区域存储或高吞吐量存储的 Windows 工作负载。您可以将一个或多个适用于 Windows File Server 的 FSx 文件系统卷挂载到 Amazon ECS Windows 实例上运行的 Amazon ECS 容器中。在单个 Amazon ECS 任务中，您可以在多个 Amazon ECS 容器之间共享适用于 Windows File Server 的 FSx 文件系统卷的 FSX。

要使用适用于 Windows File Server 的 FSx 和 ECS，在任务定义中包含 F适用于 Windows File Server 的 FSx 文件系统 ID 和相关信息。它们在以下示例任务定义 JSON 代码段中。在创建和运行任务定义之前，您需要执行以下操作。
+ 已加入到有效域的 ECS Windows EC2 实例。它可以由 [AWS Directory Service for Microsoft Active Directory](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/directory_microsoft_ad.html)、本地 Active Directory 或 Amazon EC2 上的自行托管的 Active Directory 托管。
+ AWS Secrets Manager 密钥或 Systems Manager 参数，其中包含用于加入 Active Directory 域和附加适用于 Windows File Server 的 FSx 文件系统的凭证。凭证值是您在创建 Active Directory 时输入的名称和密码凭证。

有关相关教程，请参阅 [了解为 Amazon ECS 配置适用于 Windows File Server 的 FSx 文件系统](tutorial-wfsx-volumes.md)。

## 注意事项
<a name="wfsx-volume-considerations"></a>

使用适用于 Windows File Server 的 FSx 卷时，请考虑以下事项：
+ FSx for Windows File Server 卷在 Windows Amazon EC2 实例上由 Amazon ECS 原生支持——Amazon ECS 通过任务定义配置自动管理挂载操作。

  在 Linux Amazon EC2 实例上，Amazon ECS 无法通过任务定义自动挂载 FSx for Windows File Server 卷。不过，您可以在主机层面手动将 FSx for Windows File Server 文件共享挂载到 Linux EC2 实例上，然后将该路径绑定挂载到您的 Amazon ECS 容器中。有关更多信息，请参阅[从 Linux 挂载 Amazon FSx 文件共享](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/map-shares-linux.html)。
**重要**  
此为自行管理配置。有关在 Linux 上挂载和维护 FSx for Windows File Server 文件共享的指导，请参阅 [FSx for Windows File Server 文档。](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/)
**重要**  
在 Linux EC2 实例上手动挂载 FSx for Windows File Server 共享时，Amazon ECS 与 FSx for Windows File Server 独立运行——Amazon ECS 不监控 Amazon FSx 挂载点，FSx for Windows File Server 也不追踪 Amazon ECS 任务放置或生命周期事件。您需自行负责确保 Amazon ECS 容器实例与 Amazon FSx 文件系统之间的网络可达性、实施挂载运行状况检查，并处理重连逻辑以应对失效转移事件。
+ 使用 Amazon ECS 的适用于 Windows File Server 的 FSx 不支持 AWS Fargate。
+ Amazon ECS 托管实例不支持将适用于 Windows File Server 的 FSx 与 Amazon ECS 结合使用。
+ 使用 Amazon ECS 的适用于 Windows File Server 的 FSx 使用 `awsvpc` 网络模式需要版本 `1.54.0` 或更高版本的容器代理。
+ 可用于 Amazon ECS 任务的最大驱动器号数为 23。每个具有适用于 Windows File Server 的 FSx 卷都将获得分配给它的驱动器号。
+ 默认情况下，任务资源清理时间为任务结束后的三个小时。即使没有任务使用它，由任务创建的文件映射仍将持续 3 小时。可以通过使用 Amazon ECS 环境变量来配置`ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION` 原定设置清理时间。有关更多信息，请参阅 [Amazon ECS 容器代理配置](ecs-agent-config.md)。
+ 任务通常仅在适用于 Windows File Server 的 FSx 文件系统相同的 VPC 中运行。但是，如果 Amazon ECS 集群 VPC 与适用于 Windows File Server 的 FSx 文件系统之间通过 VPC 对等连接建立了网络连接，则可以实现跨 VPC 的支持。
+ 通过配置 VPC 安全组，可以在网络级别控制对适用于 Windows File Server 的 FSx 文件系统的访问。只有通过正确配置的 Active Directory 安全组加入 Active Directory 域的 EC2 实例上托管的任务才能访问适用于 Windows File Server 的 FSx 文件共享。如果安全组配置错误，Amazon ECS 将导致任务启动失败，并显示以下错误消息：`unable to mount file system fs-id`。” 
+ 适用于 Windows File Server 的 FSx 集成 AWS Identity and Access Management（IAM）来控制您的 IAM 用户和组可以对适用于 Windows File Server 的 FSx 资源执行的操作。通过客户端授权，客户可以定义 IAM 角色，这些角色允许或拒绝对适用于 Windows File Server 的 FSx 文件系统的访问，可以选择要求只读访问，也可以选择允许或不允许客户端对文件系统的根访问。有关更多信息，请参阅 Amazon FSx Windows 用户指南中的[安全性](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/security.html)。

# 将适用于 Windows File Server 的 FSx 与 Amazon ECS 结合使用的最佳实践
<a name="wfsx-best-practices"></a>

将适用于 Windows File Server 的 FSx 与 Amazon ECS 结合使用时，请记下以下最佳实践建议。

## 适用于 Windows File Server 的 FSx 的安全和访问控制
<a name="wfsx-security-access-controls"></a>

适用于 Windows File Server 的 FSx 提供以下访问控制功能，您可以使用这些功能来确保存储在适用于 Windows File Server 的 FSx 文件系统中的数据是安全的，并且只能从需要它的应用程序中访问。

### 适用于 Windows File Server 的 FSx 卷的数据加密
<a name="storage-fsx-security-encryption"></a>

适用于 Windows File Server 的 FSx 支持两种形式的文件系统加密。它们是传输中数据的加密和静态加密。在支持 SMB 协议 3.0 或更高版本的容器实例上映射的文件共享支持传输中数据加密。创建 Amazon FSx 文件系统时，系统会自动启用静态数据加密。Amazon FSx 会在您访问文件系统时使用 SMB 加密自动加密传输中数据，而无需修改应用程序。有关更多信息，请参阅《适用于 Windows File Server 的 Amazon FSx 用户指南》**中的 [Amazon FSx 中的数据加密](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/encryption.html)。

### 使用 Windows ACL 进行文件夹级别的访问控制
<a name="storage-fsx-security-access"></a>

Windows Amazon EC2 实例使用 Active Directory 凭证访问 Amazon FSx 文件共享。它使用标准的 Windows 访问控制列表（ACL）进行精细的文件和文件夹级别的访问控制。您可以创建多个凭证，每个凭证用于共享中映射到特定任务的特定文件夹。

在以下示例中，任务可以使用保存在 Secrets Manager 中的凭证访问文件夹 `App01`。它的 Amazon 资源名称（ARN）为 `1234`。

```
"rootDirectory": "\\path\\to\\my\\data\App01",
"credentialsParameter": "arn-1234",
"domain": "corp.fullyqualified.com",
```

在另一个示例中，任务可以使用保存在 Secrets Manager 中的凭证访问文件夹 `App02`。其 ARN 为 `6789`。

```
"rootDirectory": "\\path\\to\\my\\data\App02",
"credentialsParameter": "arn-6789",
"domain": "corp.fullyqualified.com",
```

# 在 Amazon ECS 任务定义中指定适用于 Windows File Server 的 FSx 文件系统
<a name="specify-wfsx-config"></a>

要为容器使用适用于 Windows File Server 的 FSx 文件系统卷，请在任务定义中指定卷和挂载点配置。以下任务定义 JSON 代码段显示容器的 `volumes` 和 `mountPoints` 对象的语法。

```
{
    "containerDefinitions": [
        {
            "entryPoint": [
                "powershell",
                "-Command"
            ],
            "portMappings": [],
            "command": ["New-Item -Path C:\\fsx-windows-dir\\index.html -ItemType file -Value '<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>It Works!</h2> <p>You are using Amazon FSx for Windows File Server file system for persistent container storage.</p>' -Force"],
            "cpu": 512,
            "memory": 256,
            "image": "mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019",
            "essential": false,
            "name": "container1",
            "mountPoints": [
                {
                    "sourceVolume": "fsx-windows-dir",
                    "containerPath": "C:\\fsx-windows-dir",
                    "readOnly": false
                }
            ]
        },
        {
            "entryPoint": [
                "powershell",
                "-Command"
            ],
            "portMappings": [
                {
                    "hostPort": 443,
                    "protocol": "tcp",
                    "containerPort": 80
                }
            ],
            "command": ["Remove-Item -Recurse C:\\inetpub\\wwwroot\\* -Force; Start-Sleep -Seconds 120; Move-Item -Path C:\\fsx-windows-dir\\index.html -Destination C:\\inetpub\\wwwroot\\index.html -Force; C:\\ServiceMonitor.exe w3svc"],
            "mountPoints": [
                {
                    "sourceVolume": "fsx-windows-dir",
                    "containerPath": "C:\\fsx-windows-dir",
                    "readOnly": false
                }
            ],
            "cpu": 512,
            "memory": 256,
            "image": "mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019",
            "essential": true,
            "name": "container2"
        }
    ],
    "family": "fsx-windows",
    "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
    "volumes": [
        {
            "name": "fsx-windows-dir",
            "fsxWindowsFileServerVolumeConfiguration": {
                "fileSystemId": "fs-0eeb5730b2EXAMPLE",
                "authorizationConfig": {
                    "domain": "example.com",
                    "credentialsParameter": "arn:arn-1234"
                },
                "rootDirectory": "share"
            }
        }
    ]
}
```

`FSxWindowsFileServerVolumeConfiguration`  
类型：对象  
必需：否  
当您使用适用于 Windows File Server 的 FSx [https://docs.aws.amazon.com/fsx/latest/WindowsGuide/what-is.html](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/what-is.html)文件系统进行任务存储时，指定此参数。    
`fileSystemId`  
类型：字符串  
是否必需：是  
要使用的适用于 Windows File Server 的 FSx 文件系统 ID。  
`rootDirectory`  
类型：字符串  
是否必需：是  
适用于 Windows File Server 的 FSx 文件系统中要作为主机内的根目录挂载的目录。  
`authorizationConfig`    
`credentialsParameter`  
类型：字符串  
是否必需：是  
授权凭证选项：  
+ [Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 密钥的 Amazon 资源名称（ARN）。
+ [Secrets Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/integration-ps-secretsmanager.html) 参数的 Amazon 资源名称（ARN）。  
`domain`  
类型：字符串  
是否必需：是  
由 [AWS Directory Service for Microsoft Active Directory](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/directory_microsoft_ad.html)（AWS Managed Microsoft AD）目录托管的完全限定域名或自托管 EC2 Active Directory。

## 存储适用于 Windows File Server 的 FSx 卷凭证的方法
<a name="creds"></a>

存储凭证的凭证有两种不同的方法，以便与凭证参数一起使用。
+ **AWS Secrets Manager 密钥**

  此凭证可以在 AWS Secrets Manager 控制台中使用*其他密钥类型*类别。您可以为每个键/值对、用户名/管理员和密码/*password* 添加一行。
+ **Systems Manager 参数**

  通过以下示例代码片段中的形式输入文本，可以在 Systems Manager 参数控制台中创建此凭证。

  ```
  {
    "username": "admin",
    "password": "password"
  }
  ```

任务定义 `FSxWindowsFileServerVolumeConfiguration` 参数中的 `credentialsParameter` 将保存密钥 ARN 或 Systems Manager 参数 ARN。有关更多信息，请参阅 *Secrets Manager用户指南*中的[什么是 AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)以及 *Systems Manager 用户指南*中的 [Systems Manager 参数存储](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。

# 了解为 Amazon ECS 配置适用于 Windows File Server 的 FSx 文件系统
<a name="tutorial-wfsx-volumes"></a>

了解如何启动经 Amazon ECS 优化的 Windows 实例，该实例托管适用于 Windows File Server 的 FSx 文件系统和可访问该文件系统的容器。要执行此操作，您首先创建一个Directory Service AWS托管 Microsoft Active Directory。然后，您可以创建适用于 Windows File Server 的 FSx 文件系统和带有 Amazon EC2 实例和任务定义的集群。您可以配置容器的任务定义使用适用于 Windows File Server 的 FSx 文件系统。最后，您测试文件系统。

每次启动或删除 Active Directory 或适用于 Windows File Server 的 FSx 文件系统时都需要 20 到 45 分钟。准备至少保留 90 分钟以完成本教程或通过几个课程完成本教程。

## 教程的先决条件
<a name="wfsx-prerequisites"></a>
+ 管理用户。请参阅[设置以使用 Amazon ECS](get-set-up-for-amazon-ecs.md)。
+ （可选）一个 `PEM` 密钥对，用于通过 RDP 访问连接到您的 EC2 Windows 实例。有关如何创建密钥对的信息，请参阅《Amazon EC2 用户指南》中的 [Amazon EC2 密钥对和 Amazon EC2 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)**。
+ 至少有一个公有子网和一个私有子网以及一个安全组的 VPC。您可以使用您的原定设置 VPC。您不需要 NAT 网关或设备。Directory Service 不支持 Active Directory 的网络地址转换（NATI）。为了实现这一点，您的 VPC 中必须有 Active Directory、适用于 Windows File Server 的 FSx 文件系统、ECS 集群和 EC2 实例。有关 VPC 和 Active Directory 的更多信息，请参阅[创建 VPC](https://docs.aws.amazon.com/vpc/latest/userguide/create-vpc.html) 和 [Prerequisites for creating an AWS Managed Microsoft AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html#ms_ad_getting_started_prereqs)。
+ IAM ecsInstanceRole 和 ecsTaskExecutionRole 权限与您的账户关联。这些服务链接角色允许服务代表您进行 API 调用并访问容器、密钥、目录和文件服务器。

## 步骤 1：创建 IAM 访问角色
<a name="iam-roles"></a>

**使用 AWS 管理控制台 创建集群**

1. 请参阅 [Amazon ECS 容器实例 IAM 角色](instance_IAM_role.md) 来检查你是否有ecsInstanceRole，如果没有，查看你如何创建。

1. 我们建议为实际生产环境中的最低权限自定义角色策略。为了完成本教程，请验证以下 AWS 托管策略附加到您的 ecsInstanceRole 上。如果尚未附加策略，则附加策略。
   + AmazonEC2ContainerServiceforEC2Role
   + AmazonSSMManagedInstanceCore
   + AmazonSSMDirectoryServiceAccess

   要附加 AWS 托管策略

   1. 打开 [IAM 控制台](https://console.aws.amazon.com//iam/)。

   1. 在导航窗格中，选择**角色**。

   1. 选择 **AWS 托管角色**。

   1. 依次选择**权限、附加策略**。

   1. 要缩小要附加的可用策略范围，请使用**筛选条件**。

   1. 选择适当的策略，然后选择**附加策略**。

1. 请参阅 [Amazon ECS 任务执行 IAM 角色](task_execution_IAM_role.md) 来检查你是否有ecsTaskExecutionRole，如果没有，查看你如何创建。

   我们建议为实际生产环境中的最低权限自定义角色策略。为了完成本教程，请验证以下 AWS 托管策略附加到您的 ecsTaskExecutionRole上。如果尚未附加策略，则附加策略。使用上一节中给出的过程附加 AWS 托管策略。
   + SecretsManagerReadWrite
   + AmazonFSxReadOnlyAccess
   + AmazonSSMReadOnlyAccess
   + AmazonECSTaskExecutionRolePolicy

## 步骤 2：创建 Windows Active Directory（AD）
<a name="wfsx-create-ads"></a>

1. 按照《AWS Directory Service 管理指南》**中 [Creating your AWS Managed Microsoft AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html#ms_ad_getting_started_create_directory) 部分描述的步骤进行操作。使用您为本教程指定的 VPC。在 *Creating your AWS Managed Microsoft AD* 的第 3 步中，保存用户名和管理员密码，以便在后续步骤中使用。另外，记下完全限定域名，以备后续步骤使用。在创建 Active Directory 时，您可以完成以下步骤。

1. 创建要在以下步骤中使用的 AWS Secrets Manager 密码。有关更多信息，请参阅《AWS Secrets Manager 用户指南》中的 [Get started with Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html#get-started)**。

   1. 打开 [Secrets Manager 控制台](https://console.aws.amazon.com//secretsmanager/)。

   1. 单击**存储新密钥**。

   1. 选择**其他密钥类型**。

   1. 对于**私有密钥/值**，在第一行创建值为 **admin** 的密钥 **username**。点击**\$1 添加行**。

   1. 在新行中，创建密钥 **password**。对于值，键入在*创建 AWS 托管 AD 目录*的步骤 3 中输入的密码。

   1. 点击**下一步**按钮。

   1. 提供密钥名称和说明。单击**下一步**。

   1. 单击**下一步**。单击**存储**。

   1. 在**密钥**列表页面上，单击您刚刚创建的密钥。

   1. 保存新密钥的 ARN，以便在以下步骤中使用。

   1. 您的 Active Directory 正在创建时，您可以继续执行下一步。

## 步骤 3：确认并更新安全组规则
<a name="wfsx-sg"></a>

在此步骤中，您将验证并更新您正在使用的安全组的规则。对此，您可以使用为 VPC 创建的原定设置安全组。

**验证并更新安全组。**

您需要创建或编辑安全组以从端口发送数据和向端口发送数据，在适用于 Windows File Server 的 FSx *用户指南*中的 [Amazon VPC 安全组](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/limit-access-security-groups.html#fsx-vpc-security-groups)中描述这些端口。您可以通过创建下表入站规则的第一行中显示的安全组入站规则来执行此操作。规则允许来自分配给相同安全组的网络接口（及其关联实例）的入站流量。您创建的所有云资源都位于同一 VPC 中，并连接到同一安全组。因此，此规则允许根据需要向适用于 Windows File Server 的 FSx 系统、Active Directory 和 ECS 实例发送流量。其他入站规则允许流量为网站提供服务，并允许 RDP 访问连接到 ECS 实例。

下表显示了本教程需要哪些安全组入站规则。


| Type | 协议 | 端口范围 | 来源 | 
| --- | --- | --- | --- | 
|  所有流量  |  All  |  全部  |  *sg-securitygroup*  | 
|  HTTPS  |  TCP  |  443  |  0.0.0.0/0  | 
|  RDP  |  TCP  |  3389  |  您的笔记本电脑 IP 地址  | 

下表显示了本教程所需的安全组出站规则。


| Type | 协议 | 端口范围 | 目标 | 
| --- | --- | --- | --- | 
|  所有流量  |  All  |  全部  |  0.0.0.0/0  | 

1. 打开[EC2 控制台](https://console.aws.amazon.com//ec2/)并从左侧菜单中选择**安全组**。

1. 从现在显示的安全组列表中，选中用于本教程的安全组左侧的复选框。

   显示您的安全组详细信息。

1. 通过选择**入站规则**或**出站规则**选项卡并选择**编辑入站规则**或**编辑出站规则**按钮来编辑入站和出站规则。编辑规则以匹配前表中显示的规则。在本教程的稍后阶段创建 EC2 实例后，按照《Amazon EC2 用户指南》中的[使用 RDP 连接到 Windows 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connecting_to_windows_instance.html)**部分所述，使用 EC2 实例的公有 IP 地址编辑入站规则 RDP 源。

## 步骤 4：创建适用于 Windows File Server 的 FSx 文件系统
<a name="wfsx-create-fsx"></a>

验证并更新安全组，创建 Active Directory 并处于活动状态后，在与 Active Directory 相同的 VPC 中创建适用于 Windows File Server 的 FSx 文件系统。使用以下步骤创建适用于 Windows File Server 的 FSx 文件系统供 Windows 任务使用。

**创建您的第一个文件系统。**

1. 打开 [Amazon FSx 控制台](https://console.aws.amazon.com//fsx/)。

1. 在控制面板上，选择**创建文件系统**以启动文件系统创建向导。

1. 在**选择文件系统类型**页面上，选择**适用于 Windows File Server 的 FSx**，然后选择**下一步**。显示**创建文件系统**页面。

1. 在**文件系统详细信息**部分中，为您的文件系统提供一个名称。命名您的文件系统可以更轻松地查找和管理它们。最多可以使用 256 个 Unicode 字符。允许的字符包括字母、数字、空格和特殊字符加号（\$1）。减号（-）、等号（=）、句点（.）、下划线（\$1）、冒号（:）和正斜杠（/）。

1. 对于**部署类型**，选择**单可用区**部署部署在单个可用区中的文件系统。*单可用区 2*是最新一代的单可用区文件系统，支持 SSD 和 HDD 存储。

1. 对于**存储类型**，选择 **HDD**。

1. 对于**存储容量**，输入最小存储容量。

1. 保持**吞吐能力**设置为默认设置。

1. 在**网络和安全**部分，选择您为 Directory Service 目录选择的同一个 Amazon VPC。

1. 对于**VPC 安全组**，选择选择在*步骤3：验证和更新安全组中验证的安全组*。

1. 对于**Windows 身份验证**，选择 **AWS托管 Microsoft Active Directory**，然后选择您的 Directory Service 目录。

1. 对于**加密**，请保留 **aws/fsx（默认）**的默认**加密密钥**设置。

1. 保留**维护首选项**的原定设置。

1. 点击**下一步**按钮。

1. 检查**创建文件系统**页面上显示的文件系统配置。请注意创建文件系统后可以修改的文件系统设置（供您参考）。选择**创建文件系统**。

1. 请记下文件系统 ID 值。您将在后面的步骤中用到它。

   在创建适用于 Windows File Server 的 FSx 文件系统时，您可以继续执行后续步骤以创建集群和 EC2 实例。

## 步骤 5：创建 Amazon ECS 集群
<a name="wfsx-create-cluster"></a>

**使用 Amazon ECS 控制台创建集群**

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

1. 从导航栏中，选择要使用的区域。

1. 在导航窗格中，选择**集群**。

1. 在 **Clusters**（集群）页面上，选择 **Create cluster**（创建集群）。

1. 在**集群配置**下方的**集群名称**中，输入 **windows-fsx-cluster**。

1. 展开**基础设施**，清除 AWS Fargate（无服务器），然后选择 **Amazon EC2 实例**。

   1. 要创建 自动扩缩组，请从 **自动扩缩组（ASG）**（自动扩缩组（ASG））中，选择 **Create new group**（创建新组），然后提供有关组的以下详细信息：
     + 对于**操作系统/架构**，请选择 **Windows Server 2019 Core**。
     + 对于 **EC2 实例类型**，选择 t2.medium 或 t2.micro。

1. 选择**创建**。

## 步骤 6：创建经 Amazon ECS 优化的 Amazon EC2 实例
<a name="wfsx-create-instance"></a>

创建 Amazon ECS Windows 容器实例。

**创建 Amazon ECS 实例**

1. 使用 `aws ssm get-parameters` 命令检索托管您 VPC 的区域的 AMI 名称。有关更多信息，请参阅[检索经 Amazon ECS 优化的 AMI 元数据](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/retrieve-ecs-optimized_windows_AMI.html)。

1. 用来创建启动实例的 Amazon EC2 控制台。

   1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

   1. 从导航栏中，选择要使用的区域。

   1. 从 **EC2 控制面板**中，选择 **Launch Instance**（启动实例）。

   1. 对于**名称**，输入唯一的名称。

   1. 对于**应用程序和操作系统映像（亚马逊机器映像）**，在**搜索**字段中，输入您检索的 AMI 名称。

   1. 对于**实例类型**，选择 t2.medium 或 t2.micro。

   1. 对于**密钥对（登录）**，选择一个密钥对。如果您未指定密钥对，则您 

   1. 在**网络设置**下，对于 **VPC** 和**子网**，选择您的 VPC 和公有子网。

   1. 在 **Network settings**（网络设置）下，对于 **Security group**（安全组），可以选择现有安全组或创建新安全组。确保您选择的安全组在 [教程的先决条件](#wfsx-prerequisites) 中定义了入站和出站规则

   1. 在 **Network settings**（网络设置）下，对于 **Auto-assign Public IP**（自动分配公有 IP），选择 **Enable**（启用）。

   1. 展开**高级详细信息**，然后对于**域加入目录**，选择您创建的 Active Directory 的 ID。此选项域在 EC2 实例启动时加入您的 AD。

   1. 在 **Advanced details**（高级详细信息）下，对于 **IAM instance profile**（IAM 实例配置文件），选择 **ecsInstanceRole**。

   1. 使用以下用户数据配置您的 Amazon ECS 容器实例。在 **Advanced Details**（高级详细信息）下，将以下脚本粘贴到 **User data**（用户数据）字段中，将 *cluster\$1name* 替换为您的集群的名称。

      ```
      <powershell>
      Initialize-ECSAgent -Cluster windows-fsx-cluster -EnableTaskIAMRole
      </powershell>
      ```

   1. 准备好后，选中确认字段，然后选择 **Launch Instances**。

   1. 确认页面会让您知道自己的实例已启动。选择 **View Instances** 以关闭确认页面并返回控制台。

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

1. 在导航窗格中，选择**集群**，然后选择 **windows-fsx-cluster**。

1. 选择**基础设施**选项卡，验证您的实例是否已在 **windows-fsx-cluster** 集群中注册。

## 步骤 7：注册 Windows 任务定义
<a name="register_windows_task_def"></a>

您必须先注册任务定义，然后才能在 Amazon ECS 集群中运行 Windows 容器。以下任务定义示例显示一个简单网页。此任务将启动两个具有 FSX 文件系统访问权限的容器。第一个容器将 HTML 文件写入文件系统。第二个容器从文件系统下载 HTML 文件并提供网页。

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

1. 在导航窗格中，选择 **Task definitions**（任务定义）。

1. 选择 **Create new task definition**（创建新的任务定义）、**Create new task definition with JSON**（使用 JSON 创建新的任务定义）。

1. 在 JSON 编辑器框中，替换任务执行角色的值以及有关 FSx 文件系统的详细信息，然后选择**保存**。

   ```
   {
       "containerDefinitions": [
           {
               "entryPoint": [
                   "powershell",
                   "-Command"
               ],
               "portMappings": [],
               "command": ["New-Item -Path C:\\fsx-windows-dir\\index.html -ItemType file -Value '<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>It Works!</h2> <p>You are using Amazon FSx for Windows File Server file system for persistent container storage.</p>' -Force"],
               "cpu": 512,
               "memory": 256,
               "image": "mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019",
               "essential": false,
               "name": "container1",
               "mountPoints": [
                   {
                       "sourceVolume": "fsx-windows-dir",
                       "containerPath": "C:\\fsx-windows-dir",
                       "readOnly": false
                   }
               ]
           },
           {
               "entryPoint": [
                   "powershell",
                   "-Command"
               ],
               "portMappings": [
                   {
                       "hostPort": 443,
                       "protocol": "tcp",
                       "containerPort": 80
                   }
               ],
               "command": ["Remove-Item -Recurse C:\\inetpub\\wwwroot\\* -Force; Start-Sleep -Seconds 120; Move-Item -Path C:\\fsx-windows-dir\\index.html -Destination C:\\inetpub\\wwwroot\\index.html -Force; C:\\ServiceMonitor.exe w3svc"],
               "mountPoints": [
                   {
                       "sourceVolume": "fsx-windows-dir",
                       "containerPath": "C:\\fsx-windows-dir",
                       "readOnly": false
                   }
               ],
               "cpu": 512,
               "memory": 256,
               "image": "mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019",
               "essential": true,
               "name": "container2"
           }
       ],
       "family": "fsx-windows",
       "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
       "volumes": [
           {
               "name": "fsx-windows-dir",
               "fsxWindowsFileServerVolumeConfiguration": {
                   "fileSystemId": "fs-0eeb5730b2EXAMPLE",
                   "authorizationConfig": {
                       "domain": "example.com",
                       "credentialsParameter": "arn:arn-1234"
                   },
                   "rootDirectory": "share"
               }
           }
       ]
   }
   ```

## 步骤 8：运行任务并查看结果
<a name="wfsx-run-task"></a>

在运行任务之前，请验证适用于 Windows File Server 的 FSx 文件系统的状态是**Available**。可用后，您可以使用创建的任务定义运行任务。任务首先是创建容器，使用文件系统在它们之间随机打开 HTML 文件。随机打开后，Web 服务器提供简单的 HTML 页面。

**注意**  
您可能无法从 VPN 内连接到网站。

**使用 Amazon ECS 控制台运行任务并查看结果。**

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

1. 在导航窗格中，选择**集群**，然后选择 **windows-fsx-cluster**。

1. 选择**任务**选项卡，然后选择**运行新任务**。

1. 对于**启动类型**，选择 **EC2**。

1. 在部署配置下的**任务定义**中，选择 **fsx-windows**，然后选择**创建**。

1. 当您的任务状态为 **RUNNING** 时，选择任务 ID。

1. 在**容器**下，当 container1 状态为 **STOPPED** 时，选择 container2 以查看容器的详细信息。

1.  在 **container2 的容器详细信息**下，选择**网络绑定**，然后单击与容器关联的外部 IP 地址。您的浏览器将打开并显示以下消息。

   ```
   Amazon ECS Sample App
   It Works! 
   You are using Amazon FSx for Windows File Server file system for persistent container storage.
   ```
**注意**  
显示消息可能需要几分钟时间。如果您在几分钟后未看到此消息，请检查是否未在 VPN 中运行，并确保容器实例的安全组允许端口 443 上的入站网络 HTTP 通信。

## 步骤 9：清除
<a name="wfsx-cleanup"></a>

**注意**  
要花费 20 到45 分钟删除适用于 Windows File Server 的 FSx 文件系统或 AD。您必须等待，直到适用于 Windows File Server 的 FSx 文件系统删除操作完成，然后再开始 AD 删除操作。

**删除适用于 Windows File Server 的 FSx 文件系统。**

1. 打开 [Amazon FSx 控制台](https://console.aws.amazon.com//fsx/)。

1. 选择刚刚创建的适用于 Windows File Server 的 FSx 文件系统左侧的单选按钮。

1. 选择**操作**。

1. 选择**删除文件系统**。

**删除 AD。**

1. 打开 [Directory Service 控制台](https://console.aws.amazon.com//directoryservicev2/)。

1. 选择刚刚创建的 AD 左侧的单选按钮。

1. 选择**操作**。

1. 选择**删除目录**。

**请删除集群。**

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

1. 在导航窗格中，选择**集群**，然后选择 **windows-fsx-cluster**。

1. 选择**删除集群**。

1. 输入短语，然后选择**删除**。

**终止 EC2 实例。**

1. 打开 [Amazon EC2 控制台](https://console.aws.amazon.com//ec2/)。

1. 从左侧菜单中，选择**实例**。

1. 选中您创建的 EC2 实例左侧的框。

1. 单击**实例状态**、**终止实例**。

**删除密钥。**

1. 打开 [Secrets Manager 控制台](https://console.aws.amazon.com//secretsmanager/)。

1. 选择您为本演练创建的密钥。

1. 点击**操作**。

1. 选择**删除密钥**。

# 将 Docker 卷与 Amazon ECS 结合使用
<a name="docker-volumes"></a>

当使用 Docker 卷时，可以使用内置的 `local` 驱动程序或第三方卷驱动程序。Docker 卷由 Docker 管理，而目录在包含卷数据的容器实例上的 `/var/lib/docker/volumes` 中创建。

要使用 Docker 卷，请在任务定义中指定 `dockerVolumeConfiguration`。有关更多信息，请参阅 Docker 文档中的 [Volumes](https://docs.docker.com/engine/storage/volumes/)。

Docker 卷的一些常见使用案例如下：
+ 提供持久性数据卷以用于容器
+ 在同一个容器实例上不同容器中的不同位置共享一个定义的数据卷
+ 定义空的非持久性数据卷，并将其挂载到同一任务内的多个容器上
+ 向由第三方驱动程序管理的任务提供数据卷

## 使用 Docker 卷的注意事项
<a name="docker-volume-considerations"></a>

使用 Docker 卷时考虑以下事项：
+ 只有在使用 EC2 启动类型或外部实例时，才支持 Docker 卷。
+ Windows 容器仅支持使用 `local` 驱动程序。
+ 如果使用第三方驱动程序，确保在容器代理启动之前在容器实例上安装并激活该驱动程序。如果在代理启动之前第三方驱动程序未处于活动状态，则可以使用下列命令之一重新启动容器代理：
  + 对于经 Amazon ECS 优化的 Amazon Linux 2 AMI：

    ```
    sudo systemctl restart ecs
    ```
  + 对于经 Amazon ECS 优化的 Amazon Linux AMI：

    ```
    sudo stop ecs && sudo start ecs
    ```

有关如何在任务定义中指定 Docker 卷的信息，请参阅[在 Amazon ECS 任务定义中指定 Docker 卷](specify-volume-config.md)。

# 在 Amazon ECS 任务定义中指定 Docker 卷
<a name="specify-volume-config"></a>

在您的容器可以使用数据卷之前，您必须在任务定义中指定卷和挂载点配置。此部分描述容器的卷配置。对于使用 Docker 卷的任务，请指定 `dockerVolumeConfiguration`。对于使用绑定挂载主机卷的任务，请指定 `host` 和可选的 `sourcePath`。

以下任务定义 JSON 显示容器的 `volumes` 和 `mountPoints` 对象的语法。

```
{
    "containerDefinitions": [
        {
            "mountPoints": [
                {
                    "sourceVolume": "string",
                    "containerPath": "/path/to/mount_volume",
                    "readOnly": boolean
                }
            ]
        }
    ],
    "volumes": [
        {
            "name": "string",
            "dockerVolumeConfiguration": {
                "scope": "string",
                "autoprovision": boolean,
                "driver": "string",
                "driverOpts": {
                    "key": "value"
                },
                "labels": {
                    "key": "value"
                }
            }
        }
    ]
}
```

`name`  
类型：字符串  
必需：否  
卷的名称。最多允许 255 个字母（大写和小写字母）、数字、连字符（`-`）和下划线（`_`）。此名称已在容器定义 `mountPoints` 对象的 `sourceVolume` 参数中引用。

`dockerVolumeConfiguration`  
类型：[DockerVolumeConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DockerVolumeConfiguration.html) 对象  
必需：否  
使用 Docker 卷时将指定此参数。只有在 EC2 实例上运行任务时，才支持 Docker 卷。Windows 容器仅支持使用 `local` 驱动程序。要使用绑定挂载，请改为指定 `host`。    
`scope`  
类型：字符串  
有效值：`task` \$1 `shared`  
必需：否  
Docker 卷的范围，可确定其生命周期。当任务开始时，将自动预配置范围限定为 `task` 的 Docker 卷；而当任务停止时销毁此卷。任务停止后，范围限定为 `shared` 的 Docker 卷将持续存在。  
`autoprovision`  
类型：布尔值  
默认值：`false`  
必需：否  
如果此值为 `true`，则将创建 Docker 卷（如果此卷不存在）。仅在 `scope` 为 `shared` 时使用此字段。如果 `scope` 为 `task`，则必须省略此参数。  
`driver`  
类型：字符串  
必需：否  
要使用的 Docker 卷驱动程序。由于驱动程序值用于任务放置，因此，该名称必须与 Docker 提供的驱动程序名称匹配。如果已使用 Docker 插件 CLI 创建驱动程序，则使用 `docker plugin ls` 可从容器实例中检索驱动程序名称。如果已使用其他方法安装驱动程序，则使用 Docker 插件发现功能可检索驱动程序名称。  
`driverOpts`  
类型：字符串  
必需：否  
要传递的 Docker 驱动程序特定的选项的映射。此参数将映射到 Docker 中“创建卷”部分中的 `DriverOpts`。  
`labels`  
类型：字符串  
必需：否  
要添加到 Docker 卷的自定义元数据。

`mountPoints`  
类型：对象数组  
必需：否  
容器中数据卷的挂载点。此参数对应于 create-container Docker API 中的 `Volumes` 和 docker run 命令的 `--volume` 选项。  
Windows 容器可在 `$env:ProgramData` 所在的驱动器上挂载整个目录。Windows 容器无法在其他驱动器上挂载目录，并且挂载点不能跨驱动器使用。您必须指定挂载点才能将 Amazon EBS 卷直接附加到 Amazon ECS 任务。    
`sourceVolume`  
类型：字符串  
必需：是，当使用 `mountPoints` 时  
要挂载的卷的名称。  
`containerPath`  
类型：字符串  
必需：是，当使用 `mountPoints` 时  
挂载卷的容器中的路径。  
`readOnly`  
类型：布尔值  
必需：否  
如果此值为`true`，则容器具有对卷的只读访问权。如果此值为`false`，则容器可对卷进行写入。默认值为 `false`。  
对于在运行 Windows 操作系统的 EC2 实例上运行的任务，请保留默认值 `false`。

# 适用于 Amazon ECS 的 Docker 卷示例
<a name="docker-volume-examples"></a>

以下示例说明如何为容器提供临时存储、如何为多个容器提供共享卷，以及如何为容器提供 NFS 持久性存储。

**要使用 Docker 卷为容器提供临时存储**

在此示例中，容器使用在任务完成后处置的空数据卷。一个示例使用案例为，您可能具有一个需要在任务期间访问某个临时文件存储位置的容器。可以使用 Docker 卷实现此任务。

1. 在任务定义 `volumes` 部分中，使用 `name` 和 `DockerVolumeConfiguration` 值定义数据卷。在此示例中，我们将范围指定为 `task`，以便在任务停止后删除此卷并使用内置的 `local` 驱动程序。

   ```
   "volumes": [
       {
           "name": "scratch",
           "dockerVolumeConfiguration" : {
               "scope": "task",
               "driver": "local",
               "labels": {
                   "scratch": "space"
               }
           }
       }
   ]
   ```

1. 在 `containerDefinitions` 部分中，使用引用已定义卷的名称的 `mountPoints` 值和将卷挂载到容器上所在的 `containerPath` 值定义容器。

   ```
   "containerDefinitions": [
       {
           "name": "container-1",
           "mountPoints": [
               {
                 "sourceVolume": "scratch",
                 "containerPath": "/var/scratch"
               }
           ]
       }
   ]
   ```

**使用 Docker 卷为多个容器提供持久性存储**

在本示例中，您希望多个容器使用一个共享卷，并希望在使用此卷的任何单个任务停止后该卷持续存在。正在使用的是内置的 `local` 驱动程序。以便该卷仍绑定到容器实例的生命周期。

1. 在任务定义 `volumes` 部分中，使用 `name` 和 `DockerVolumeConfiguration` 值定义数据卷。在此示例中，指定 `shared` 范围以便卷持续存在，将自动预置设置为 `true`。这样就可以创建卷以供使用。然后，还可使用内置的 `local` 驱动程序。

   ```
   "volumes": [
       {
           "name": "database",
           "dockerVolumeConfiguration" : {
               "scope": "shared",
               "autoprovision": true,
               "driver": "local",
               "labels": {
                   "database": "database_name"
               }
           }
       }
   ]
   ```

1. 在 `containerDefinitions` 部分中，使用引用已定义卷的名称的 `mountPoints` 值和将卷挂载到容器上所在的 `containerPath` 值定义容器。

   ```
   "containerDefinitions": [
       {
           "name": "container-1",
           "mountPoints": [
           {
             "sourceVolume": "database",
             "containerPath": "/var/database"
           }
         ]
       },
       {
         "name": "container-2",
         "mountPoints": [
           {
             "sourceVolume": "database",
             "containerPath": "/var/database"
           }
         ]
       }
     ]
   ```

**使用 Docker 卷为容器提供 NFS 持久性存储**

 在此示例中，容器使用 NFS 数据卷，该数据卷在任务启动时自动挂载，在任务停止时自动卸载。这使用了 Docker 内置 `local` 驱动程序。一个示例使用案例为，您可能具有本地 NFS 存储，并且需要从 ECS Anywhere 任务访问该存储。可以通过带有 NFS 驱动程序选项的 Docker 卷实现此目标。

1. 在任务定义 `volumes` 部分中，使用 `name` 和 `DockerVolumeConfiguration` 值定义数据卷。在此示例中，指定 `task` 范围以便在任务停止后卸载卷。使用 `local` 驱动程序并使用 `type`、`device` 和 `o` 选项相应地配置 `driverOpts`。`NFS_SERVER` 替换为 NFS 服务器端点。

   ```
   "volumes": [
          {
              "name": "NFS",
              "dockerVolumeConfiguration" : {
                  "scope": "task",
                  "driver": "local",
                  "driverOpts": {
                      "type": "nfs",
                      "device": "$NFS_SERVER:/mnt/nfs",
                      "o": "addr=$NFS_SERVER"
                  }
              }
          }
      ]
   ```

1. 在 `containerDefinitions` 部分中，使用引用已定义卷的名称的 `mountPoints` 值和将卷挂载到容器上所在的 `containerPath` 值定义容器。

   ```
   "containerDefinitions": [
          {
              "name": "container-1",
              "mountPoints": [
                  {
                    "sourceVolume": "NFS",
                    "containerPath": "/var/nfsmount"
                  }
              ]
          }
      ]
   ```

# 将绑定挂载与 Amazon ECS 结合使用
<a name="bind-mounts"></a>

使用绑定挂载，主机上的文件或目录（如 Amazon EC2 实例）被挂载到容器中。Fargate 和 Amazon EC2 实例上托管的任务都支持绑定挂载。绑定挂载与使用它们的容器的生命周期相关。停止使用绑定挂载的所有容器后（例如，停止任务时），数据将被删除。对于托管在 Amazon EC2 实例上的任务，可以通过在任务定义中指定 `host` 和可选值 `sourcePath`，将数据绑定到主机 Amazon EC2 实例的生命周期。有关更多信息，请参阅 Docker 文档中的 [Bind mounts](https://docs.docker.com/engine/storage/bind-mounts/)。

以下是绑定挂载的常见使用案例。
+ 提供空数据卷以挂载在一个或多个容器中。
+ 在一个或多个容器中挂载主机数据卷。
+ 与相同任务中的其他容器共享来自源容器的数据卷。
+ 将 Dockerfile 路径及其内容公开到一个或多个容器。

## 使用绑定挂载时的注意事项
<a name="bind-mount-considerations"></a>

使用绑定挂载时应考虑以下事项。
+ 默认情况下，使用平台版本 `1.4.0` 或更高版本（Linux）或者 `1.0.0` 或更高版本（Windows）在 AWS Fargate 上托管的任务会收到至少 20GiB 的临时存储以用于绑定挂载。您可以增加临时存储总量，最多可达 200GiB，方法是在您的任务定义中指定 `ephemeralStorage` 参数。
+ 要在任务运行时将 Dockerfile 中的文件公开到数据卷，Amazon ECS 数据面板将查找 `VOLUME` 指令。如果 `VOLUME` 指令中指定的绝对路径与任务定义中指定的 `containerPath` 绝对路径相同，则指令路径 `VOLUME` 中的数据将复制到数据卷。在下面的 Dockerfile 示例中，`/var/log/exported` 目录中名为 `examplefile` 的文件将写入主机，然后挂载到容器中。

  ```
  FROM public.ecr.aws/amazonlinux/amazonlinux:latest
  RUN mkdir -p /var/log/exported
  RUN touch /var/log/exported/examplefile
  VOLUME ["/var/log/exported"]
  ```

  预设情况下，卷权限设置为 `0755` 和所有者设置为 `root`。您可以在 Dockerfile 中自定义这些权限。以下示例将目录的所有者定义为 `node`。

  ```
  FROM public.ecr.aws/amazonlinux/amazonlinux:latest
  RUN yum install -y shadow-utils && yum clean all
  RUN useradd node
  RUN mkdir -p /var/log/exported && chown node:node /var/log/exported
  RUN touch /var/log/exported/examplefile
  USER node
  VOLUME ["/var/log/exported"]
  ```
+ 对于 Amazon EC2 实例上托管的任务，如果未指定 `host` 和 `sourcePath` 值，则 Docker 进程守护程序将为您管理绑定挂载。如果没有容器引用此绑定挂载，则 Amazon ECS 容器代理任务清理服务最终会将其删除。默认情况下，这发生在容器退出三个小时后。但是，您可以使用 `ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION` 代理变量配置此持续时间。有关更多信息，请参阅 [Amazon ECS 容器代理配置](ecs-agent-config.md)。如果需要在容器的生命周期内保持此数据，请为绑定挂载指定一个 `sourcePath` 值。
+ 对于托管在 Amazon ECS 托管实例上的任务，其根文件系统部分为只读。读/写绑定挂载必须使用可写目录，例如 `/var` 用于存储永久数据或 `/tmp` 用于存储临时数据。尝试在其他目录创建读/写绑定挂载将导致任务启动失败，并返回类似如下错误：

  ```
  error creating empty volume: error while creating volume path '/path': mkdir /path: read-only file system
  ```

  只读绑定挂载（在 `mountPoints` 参数中配置 `"readOnly": true`）可以指向主机上任何可访问的目录。

  要查看完整的可写路径列表，您可以在 Amazon ECS 托管实例上运行一个任务，并使用相关命令检查实例的挂载表。创建一个任务定义，并进行如下设置以访问主机文件系统：

  ```
  {
      "pidMode": "host",
      "containerDefinitions": [{
          "privileged": true,
          ...
      }]
  }
  ```

  然后在容器内执行以下命令：

  ```
  # List writable mounts
  cat /proc/1/root/proc/1/mounts | awk '$4 ~ /^rw,/ || $4 == "rw" {print $2}' | sort
  
  # List read-only mounts
  cat /proc/1/root/proc/1/mounts | awk '$4 ~ /^ro,/ || $4 == "ro" {print $2}' | sort
  ```
**重要**  
`privileged` 设置在主机上授予容器扩展功能，相当于 root 权限。在本例中，此项设置用于检查主机的挂载表以进行诊断。有关更多信息，请参阅 [避免以特权身份运行容器（Amazon EC2）](security-tasks-containers.md#security-tasks-containers-recommendations-avoid-privileged-containers)。

  有关在容器中运行交互式命令的更多信息，请参阅 [使用 ECS Exec 监控 Amazon ECS 容器](ecs-exec.md)。

# 在 Amazon ECS 任务定义中指定绑定挂载
<a name="specify-bind-mount-config"></a>

对于在 Fargate 或 Amazon EC2 实例上托管的 Amazon ECS 任务，以下任务定义 JSON 代码段显示任务定义的 `volumes`、`mountPoints` 和 `ephemeralStorage` 对象的语法。

```
{
   "family": "",
   ...
   "containerDefinitions" : [
      {
         "mountPoints" : [
            {
               "containerPath" : "/path/to/mount_volume",
               "sourceVolume" : "string"
            }
          ],
          "name" : "string"
       }
    ],
    ...
    "volumes" : [
       {
          "name" : "string"
       }
    ],
    "ephemeralStorage": {
	   "sizeInGiB": integer
    }
}
```

对于 Amazon EC2 实例上托管的 Amazon ECS 任务，您可以在指定任务卷详细信息时使用可选的 `host` 参数和 `sourcePath`。指定后，它将绑定挂载与任务的生命周期而不是容器关联起来。

```
"volumes" : [
    {
        "host" : {
            "sourcePath" : "string"
        },
        "name" : "string"
    }
]
```

下面将更详细地描述每个任务定义参数。

`name`  
类型：字符串  
必需：否  
卷的名称。最多允许 255 个字母（大写和小写字母）、数字、连字符（`-`）和下划线（`_`）。此名称已在容器定义 `mountPoints` 对象的 `sourceVolume` 参数中引用。

`host`  
必需：否  
`host` 参数用于将绑定挂载的生命周期绑定到主机 Amazon EC2 实例（而不是任务）及其存储位置。如果 `host` 参数为空，则 Docker 进程守护程序将为您的数据卷分配一个主机路径，但不保证数据在与其关联的容器停止运行后将保留。  
Windows 容器可在 `$env:ProgramData` 所在的驱动器上挂载整个目录。  
只有在使用 Amazon EC2 实例或 Amazon ECS 托管实例上托管的任务时，才支持 `sourcePath` 参数。  
`sourcePath`  
类型：字符串  
必需：否  
在使用 `host` 参数时，指定 `sourcePath` 可声明提供给容器的主机 Amazon EC2 容器实例上的路径。如果此参数为空，则 Docker 进程守护程序将为您分配一个主机路径。如果 `host` 参数包含 `sourcePath` 文件位置，则数据卷将在主机 Amazon EC2 容器实例上的指定位置保留，除非您手动将其删除。如果主机 Amazon EC2 容器实例上不存在 `sourcePath` 值，则 Docker 进程守护程序将创建该值。如果该位置不存在，则将导出源路径文件夹的内容。

`mountPoints`  
类型：对象数组  
必需：否  
容器中数据卷的挂载点。此参数对应于 create-container Docker API 中的 `Volumes` 和 docker run 命令的 `--volume` 选项。  
Windows 容器可在 `$env:ProgramData` 所在的驱动器上挂载整个目录。Windows 容器无法在其他驱动器上挂载目录，并且挂载点不能跨驱动器使用。您必须指定挂载点才能将 Amazon EBS 卷直接附加到 Amazon ECS 任务。    
`sourceVolume`  
类型：字符串  
必需：是，当使用 `mountPoints` 时  
要挂载的卷的名称。  
`containerPath`  
类型：字符串  
必需：是，当使用 `mountPoints` 时  
挂载卷的容器中的路径。  
`readOnly`  
类型：布尔值  
必需：否  
如果此值为`true`，则容器具有对卷的只读访问权。如果此值为`false`，则容器可对卷进行写入。默认值为 `false`。  
对于在运行 Windows 操作系统的 EC2 实例上运行的任务，请保留默认值 `false`。

`ephemeralStorage`  
类型：对象  
必需：否  
要为任务分配的临时存储容量。对于使用平台版本 `1.4.0` 或更高版本（Linux）或者 `1.0.0` 或更高版本（Windows）的 AWS Fargate 上托管的任务，此参数用于将短暂可用存储的总量扩展到默认数量之外。  
您可以使用 Copilot CLI、CloudFormation、AWS SDK 或 CLI 为绑定挂载指定临时存储容量。

# Amazon ECS 绑定挂载示例
<a name="bind-mount-examples"></a>

以下示例介绍了为容器使用绑定挂载的常见使用案例。

**为 Fargate 任务分配更多的临时存储空间**

对于在使用平台版本 `1.4.0` 或更高版本（Linux）或 `1.0.0`（Windows）的 Fargate 上托管的 Amazon ECS 任务，您可以为任务中要使用的容器分配超过原定设置数量的短暂存储。此示例可以合并到其他示例中，以便为 Fargate 任务分配更多的临时存储空间。
+ 在任务定义中，定义 `ephemeralStorage` 对象。`sizeInGiB` 必须是介于 `21` 和 `200` 之间的整数，单位是 GiB。

  ```
  "ephemeralStorage": {
      "sizeInGiB": integer
  }
  ```

**为一个或多个容器提供空数据卷**

在某些使用案例中，您希望为任务中的容器提供一些临时空间。例如，您可能在任务期间具有需要访问同一临时文件存储位置的两个数据库容器。可以通过绑定挂载实现此目标。

1. 在任务定义 `volumes` 部分中，使用名称 `database_scratch` 定义绑定挂载。

   ```
     "volumes": [
       {
         "name": "database_scratch"
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，创建数据库容器定义。以便它们挂载卷。

   ```
   "containerDefinitions": [
       {
         "name": "database1",
         "image": "my-repo/database",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "database_scratch",
             "containerPath": "/var/scratch"
           }
         ]
       },
       {
         "name": "database2",
         "image": "my-repo/database",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "database_scratch",
             "containerPath": "/var/scratch"
           }
         ]
       }
     ]
   ```

**将 Dockerfile 中的路径及其内容公开给容器**

在本例中，您有一个 Dockerfile，用于写入要挂载到容器中的数据。此示例适用于 Fargate 或 Amazon EC2 实例上托管的任务。

1. 创建 Dockerfile。下面的示例使用公共 Amazon Linux2 容器映像，并在我们希望挂载容器的 `/var/log/exported` 目录中创建一个名为 `examplefile` 的文件。`VOLUME` 指令应该指定绝对路径。

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   RUN mkdir -p /var/log/exported
   RUN touch /var/log/exported/examplefile
   VOLUME ["/var/log/exported"]
   ```

   预设情况下，卷权限设置为 `0755` 和所有者设置为 `root`。可以在 Dockerfile 中变更这些权限。在下面的示例中，`/var/log/exported` 目录的所有者设置为 `node`。

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   RUN yum install -y shadow-utils && yum clean all
   RUN useradd node
   RUN mkdir -p /var/log/exported && chown node:node /var/log/exported					    
   USER node
   RUN touch /var/log/exported/examplefile
   VOLUME ["/var/log/exported"]
   ```

1. 在任务定义 `volumes` 部分中，使用名称 `application_logs` 定义卷。

   ```
     "volumes": [
       {
         "name": "application_logs"
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，创建应用程序容器定义。以便它们挂载存储。`containerPath` 值必须与 Dockerfile 的 `VOLUME` 指令中指定的绝对路径匹配。

   ```
     "containerDefinitions": [
       {
         "name": "application1",
         "image": "my-repo/application",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "application_logs",
             "containerPath": "/var/log/exported"
           }
         ]
       },
       {
         "name": "application2",
         "image": "my-repo/application",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "application_logs",
             "containerPath": "/var/log/exported"
           }
         ]
       }
     ]
   ```

**为与主机 Amazon EC2 实例生命周期相关的容器提供空数据卷**

对于在 Amazon EC2 实例上托管的任务，可以使用绑定挂载，并将数据绑定到主机 Amazon EC2 实例的生命周期。您可以通过使用 `host` 参数并指定 `sourcePath` 值进行此操作。存在于 `sourcePath` 的任何文件将提交至值为 `containerPath` 的容器。写入 `containerPath` 值的任何文件将会写入主机 Amazon EC2 实例上的 `sourcePath` 值。
**重要**  
Amazon ECS 不会跨 Amazon EC2 实例同步您的存储。使用持久性存储的任务可置于您的集群中具有可用容量的任何 Amazon EC2 实例上。如果任务在停止和重新启动后需要持久存储，应始终在任务启动时使用 AWS CLI [start-task](https://docs.aws.amazon.com/cli/latest/reference/ecs/start-task.html) 命令指定相同的 Amazon EC2 实例。您也可以将 Amazon EFS 卷用于持久性存储。有关更多信息，请参阅 [将 Amazon EFS 卷与 Amazon ECS 结合使用](efs-volumes.md)。

1. 在任务定义 `volumes` 部分中，使用 `name` 和 `sourcePath` 值定义绑定挂载。在下面的示例中，主机 Amazon EC2 实例包含 `/ecs/webdata` 您希望挂载容器中的数据。

   ```
     "volumes": [
       {
         "name": "webdata",
         "host": {
           "sourcePath": "/ecs/webdata"
         }
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，使用引用绑定挂载的名称的 `mountPoints` 值和要在容器上挂载绑定挂载的 `containerPath` 值定义容器。

   ```
     "containerDefinitions": [
       {
         "name": "web",
         "image": "public.ecr.aws/docker/library/nginx:latest",
         "cpu": 99,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webdata",
             "containerPath": "/usr/share/nginx/html"
           }
         ]
       }
     ]
   ```

**在不同位置多个容器上挂载定义的卷**

您可以在任务定义中定义数据卷并在其他容器上的不同位置挂载该卷。例如，您的主机容器在 `/data/webroot` 有一个网站数据文件夹。您可能想在具有不同文档根目录的两个不同 Web 服务器上以只读方式挂载该数据卷。

1. 在任务定义 `volumes` 部分中，使用名称 `webroot` 和源路径 `/data/webroot` 定义数据卷。

   ```
     "volumes": [
       {
         "name": "webroot",
         "host": {
           "sourcePath": "/data/webroot"
         }
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，使用将 `mountPoints` 卷与指向容器的文档根目录的 `webroot` 值关联的 `containerPath` 值为每个 Web 服务器定义容器。

   ```
     "containerDefinitions": [
       {
         "name": "web-server-1",
         "image": "my-repo/ubuntu-apache",
         "cpu": 100,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webroot",
             "containerPath": "/var/www/html",
             "readOnly": true
           }
         ]
       },
       {
         "name": "web-server-2",
         "image": "my-repo/sles11-apache",
         "cpu": 100,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 8080,
             "hostPort": 8080
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webroot",
             "containerPath": "/srv/www/htdocs",
             "readOnly": true
           }
         ]
       }
     ]
   ```

**使用 `volumesFrom` 从其他容器挂载卷**

对于托管在 Amazon EC2 实例上的任务，您可以在一个容器上定义一个或多个卷，然后在相同任务内的不同容器定义中使用 `volumesFrom` 参数从其初始定义的挂载点的 `sourceContainer` 中挂载所有卷。`volumesFrom` 参数适用于任务定义中定义的卷以及使用 Dockerfile 内置到映像中的卷。

1. （可选）要共享映像中内置的卷，请使用 Dockerfile 中的 `VOLUME` 指令。以下示例 Dockerfile 使用了 `httpd` 映像，然后添加卷并在 Apache 文档根目录中的 `dockerfile_volume` 处挂载卷。这是 `httpd` Web 服务器使用的文件夹。

   ```
   FROM httpd
   VOLUME ["/usr/local/apache2/htdocs/dockerfile_volume"]
   ```

   您可以使用此 Dockerfile 生成映像并将其推送至存储库（如 Docker Hub），然后在任务定义中使用它。以下步骤中使用的示例 `my-repo/httpd_dockerfile_volume` 映像是通过上述 Dockerfile 构建的。

1. 创建一个为您的容器定义其他卷和挂载点的任务定义。在此示例 `volumes` 部分中，您将创建一个名为 `empty` 的空卷，此卷由 Docker 进程守护程序管理。还有一个定义的主机卷，被称为 `host_etc`。它在主机容器实例上导出 `/etc` 文件夹。

   ```
   {
     "family": "test-volumes-from",
     "volumes": [
       {
         "name": "empty",
         "host": {}
       },
       {
         "name": "host_etc",
         "host": {
           "sourcePath": "/etc"
         }
       }
     ],
   ```

   在容器定义部分中，创建一个挂载之前定义的卷的容器。在此示例中，`web` 容器会挂载 `empty` 和 `host_etc` 卷。该容器使用通过 Dockerfile 中的卷构建的映像。

   ```
   "containerDefinitions": [
       {
         "name": "web",
         "image": "my-repo/httpd_dockerfile_volume",
         "cpu": 100,
         "memory": 500,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "mountPoints": [
           {
             "sourceVolume": "empty",
             "containerPath": "/usr/local/apache2/htdocs/empty_volume"
           },
           {
             "sourceVolume": "host_etc",
             "containerPath": "/usr/local/apache2/htdocs/host_etc"
           }
         ],
         "essential": true
       },
   ```

   创建另一个容器，该容器使用 `volumesFrom` 挂载与 `web` 容器关联的所有卷。`web` 容器上的所有卷以同样方式挂载在 `busybox` 容器上。这包括在 Dockerfile 中指定的用于构建 `my-repo/httpd_dockerfile_volume` 映像的卷。

   ```
       {
         "name": "busybox",
         "image": "busybox",
         "volumesFrom": [
           {
             "sourceContainer": "web"
           }
         ],
         "cpu": 100,
         "memory": 500,
         "entryPoint": [
           "sh",
           "-c"
         ],
         "command": [
           "echo $(date) > /usr/local/apache2/htdocs/empty_volume/date && echo $(date) > /usr/local/apache2/htdocs/host_etc/date && echo $(date) > /usr/local/apache2/htdocs/dockerfile_volume/date"
         ],
         "essential": false
       }
     ]
   }
   ```

   当此任务运行时，这两个容器将挂载卷，并且 `busybox` 容器中的 `command` 会将日期和时间写入文件。此文件在每个卷文件夹中被称为 `date`。这些文件夹随后将显示在由 `web` 容器显示的网站上。
**注意**  
由于 `busybox` 容器运行快速命令然后退出，它必须在容器定义中设置为 `"essential": false`。否则，它在退出时会停止整个任务。

# 管理 Amazon ECS 上的容器交换内存空间
<a name="container-swap"></a>

使用 Amazon ECS，您可以在容器级别控制基于 Linux 的 Amazon EC2 实例上的交换内存空间使用量。使用每个容器的交换配置，任务定义中的每个容器都可以启用或禁用交换。对于启用此功能的用户，可以对所用的最大交换空间量进行限制。例如，延迟关键型容器可以禁用交换。相比之下，具有高暂时内存需求的容器可以打开交换，以减少容器负载时出现内存不足错误的机率。

容器的交换配置由以下容器定义参数管理。

`maxSwap`  
容器可以使用的交换内存总量（以 MiB 为单位）。此参数会转换为 docker run 命令的 `--memory-swap` 选项，值为容器内存与 `maxSwap` 值之和。  
如果指定`maxSwap`值为`0`，则该容器不使用交换。接受的值为`0`或任何正整数。如果省略 `maxSwap` 参数，该容器将为其运行所在的容器实例使用交换配置。必须为要使用的`swappiness`参数设置`maxSwap`值。

`swappiness`  
您可以使用此功能调整容器的内存 swappiness 行为。`swappiness` 值为 `0` 不会导致交换，除非有需要。`swappiness` 值为 `100` 将导致页面被积极地交换。接受的值为`0`到`100`之间的整数。如果未指定`swappiness`参数，则使用默认值`60`。如果未指定 `maxSwap` 的值，则此参数将被忽略。此参数对应于 docker run 命令的 `--memory-swappiness` 选项。

在以下示例中，提供了 JSON 语法。

```
"containerDefinitions": [{
        ...
        "linuxParameters": {
            "maxSwap": integer,
            "swappiness": integer
        },
        ...
}]
```

## 注意事项
<a name="container-swap-considerations"></a>

在使用每个容器交换配置时，请考虑以下事项。
+ 必须在托管任务的 Amazon EC2 实例上启用和分配交换空间，以供容器使用。预设情况下，经 Amazon ECS 优化的 AMI 没有启用交换功能。必须在实例上启用交换才能使用此功能。有关更多信息，请参阅《Amazon EC2 用户指南》的中的[实例存储交换卷](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-store-swap-volumes.html)**或[如何分配内存以便在 Amazon EC2 实例中用作交换空间？](https://repost.aws/knowledge-center/ec2-memory-swap-file)。
+ 仅指定 EC2 的任务定义支持交换空间容器定义参数。仅供 Fargate 上的 Amazon ECS 使用的任务定义不支持这些参数。
+ 仅 Linux 容器支持此功能。目前不支持 Windows 容器。
+ 如果任务定义中忽略了 `maxSwap` 和 `swappiness` 任务定义参数，每个容器都有默认的 `swappiness` 值 `60`。此外，总交换使用量限制为容器内存的两倍。
+ 如果您在 Amazon Linux 2023 上使用任务，则不支持 `swappiness` 参数。

# Amazon ECS 托管实例的 Amazon ECS 任务定义差异
<a name="managed-instances-tasks-services"></a>

要使用 Amazon ECS 托管实例，您必须将任务定义配置为使用 Amazon ECS 托管实例启动类型。使用 Amazon ECS 托管实例还需注意其他事项。

## 任务定义参数
<a name="managed-instances-task-parameters"></a>

使用 Amazon ECS 托管实例的任务支持大多数可用的 Amazon ECS 任务定义参数。然而，在与 Amazon ECS 托管实例任务一起使用时，某些参数具有特定行为或限制。

以下任务定义参数在 Amazon ECS 托管实例任务中无效：
+ `disableNetworking`
+ `dnsSearchDomains`
+ `dnsServers`
+ `dockerLabels`
+ `dockerSecurityOptions`
+ `dockerVolumeConfiguration`
+ `ephemeralStorage`
+ `extraHosts`
+ `fsxWindowsFileServerVolumeConfiguration`
+ `hostname`
+ `inferenceAccelerator`
+ `ipcMode`
+ `links`
+ `maxSwap`
+ `proxyConfiguration`
+ `sharedMemorySize`
+ `sourcepath` 卷
+ `swappiness`
+ `tmpfs`

以下任务定义参数在 Amazon ECS 托管实例任务中有效，但应注意以下限制：
+ `networkConfiguration`：Amazon ECS 托管实例任务使用 `awsvpc` 或 `host` 网络模式。
+ `placementConstraints`：支持以下约束属性。
  + `ecs.subnet-id`
  + `ecs.availability-zone`
  + `ecs.instance-type`
  + `ecs.cpu-architecture`
+ `requiresCompatibilities`：必须包含 `MANAGED_INSTANCES`，以确保任务定义与 Amazon ECS 托管实例兼容。
+ `resourceRequirement`：不支持 `InferenceAccelerator`。
+ `operatingSystemFamily`：Amazon ECS 托管实例使用 `LINUX`。
+ `volumes`-当将绑定挂载与 `sourcePath` 搭配使用时，其路径必须指向主机上的可写目录。Amazon ECS 托管实例文件系统的部分内容为只读。可写目录包括 `/var` 和 `/tmp`。有关更多信息，请参阅 [将绑定挂载与 Amazon ECS 结合使用](bind-mounts.md)。

为确保您的任务定义验证能否用于 Amazon ECS 托管实例，可在注册任务定义时指定以下内容：
+ 在 AWS 管理控制台中，为**需要兼容性**字段指定 `MANAGED_INSTANCES`。
+ 在 AWS CLI 中指定 `--requires-compatibilities` 选项。
+ 在 Amazon ECS API 中指定 `requiresCompatibilities` 标记。

# Fargate 的 Amazon ECS 任务定义差异
<a name="fargate-tasks-services"></a>

要使用 Fargate，您必须将任务定义配置为使用 Fargate 启动类型。使用 Fargate 时还有其他注意事项。

## 任务定义参数
<a name="fargate-task-parameters"></a>

使用 Fargate 的任务并非支持所有可用的 Amazon ECS 任务定义参数。某些参数完全不受支持，而其他参数对于 Fargate 任务的行为则不同。

以下任务定义参数在 Fargate 任务中无效：
+ `disableNetworking`
+ `dnsSearchDomains`
+ `dnsServers`
+ `dockerSecurityOptions`
+ `extraHosts`
+ `gpu`
+ `ipcMode`
+ `links`
+ `placementConstraints`
+ `privileged`
+ `maxSwap`
+ `swappiness`

以下任务定义参数在 Fargate 任务中有效，但应注意以下限制：
+ `linuxParameters` – 当指定适用于容器的 Linux 特定选项时，对于 `capabilities`，您可以添加的唯一功能是 `CAP_SYS_PTRACE`。`devices`、`sharedMemorySize` 和 `tmpfs` 参数不受支持。有关更多信息，请参阅 [Linux 参数](task_definition_parameters.md#container_definition_linuxparameters)。
+ `volumes` – Fargate 任务仅支持绑定挂载主机卷，因此， `dockerVolumeConfiguration` 参数不受支持。有关更多信息，请参阅 [卷](task_definition_parameters.md#volumes)。
+ `cpu`：对于 AWS Fargate 上的 Windows 容器，该值不能小于 1 vCPU。
+ `networkConfiguration`：Fargate 任务始终使用 `awsvpc` 网络模式。

为确保您的任务定义可验证用于 Fargate，可在注册任务定义时指定以下内容：
+ 在 AWS 管理控制台中，为**需要兼容性**字段指定 `FARGATE`。
+ 在 AWS CLI 中指定 `--requires-compatibilities` 选项。
+ 在 Amazon ECS API 中指定 `requiresCompatibilities` 标记。

## 操作系统和架构
<a name="fargate-task-os"></a>

为 AWS Fargate 配置任务和容器定义时，您必须指定容器运行的操作系统。AWS Fargate 支持以下操作系统：
+ Amazon Linux 2
**注意**  
Linux 容器仅使用主机操作系统中的内核和内核配置。例如，内核配置包括 `sysctl` 系统控件。Linux 容器映像可以由包含任何 Linux 发行版中的文件和程序的基本映像创建。如果 CPU 架构匹配，则可以在任何操作系统上通过任何 Linux 容器映像运行容器。
+ Windows Server 2019 Full
+ Windows Server 2019 Core
+ Windows Server 2022 Full
+ Windows Server 2022 Core

当您在 AWS Fargate 上运行 Windows 容器时，您必须具有 X86\$164 CPU 架构。

当您在 AWS Fargate 上运行 Linux 容器时，您可以使用 X86\$164 CPU 架构，也可以使用 ARM64 架构用于基于 ARM 的应用程序。有关更多信息，请参阅 [适用于 64 位 ARM 工作负载的 Amazon ECS 任务定义](ecs-arm64.md)。

## 任务 CPU 和内存
<a name="fargate-tasks-size"></a>

AWS Fargate 的 Amazon ECS 任务定义需要您在任务级别指定 CPU 和内存。只需在任务级别指定这些资源便可满足大多数使用案例。下表显示了任务级 CPU 和内存的有效组合。您可以通过以 MiB 或 GB 字符串方式在任务定义中指定内存值。例如，您可以使用 `3072`（以 MiB 为单位）或 `3 GB`（以 GB 为单位）指定内存值。您可以通过 CPU 单位数或虚拟 CPU（vCPU）数字符串的方式在 JSON 文件中将 CPU 值。例如，您可以使用 `1024`（CPU 单位数）或 `1 vCPU`（vCPU 数）来指定 CPU 值。


|  CPU 值  |  内存值  |  AWS Fargate 支持的操作系统  | 
| --- | --- | --- | 
|  256 (.25 vCPU)  |  512MiB、1GB、2GB  |  Linux  | 
|  512 (.5 vCPU)  |  1GB、2GB、3GB、4GB  |  Linux  | 
|  1024 (1 vCPU)  |  2GB、3GB、4GB、5GB、6GB、7GB、8GB  |  Linux、Windows  | 
|  2048 (2 vCPU)  |  4 GB 到 16 GB 之间（以 1 GB 为增量）  |  Linux、Windows  | 
|  4096 (4 vCPU)  |  8 GB 到 30 GB 之间（以 1 GB 为增量）  |  Linux、Windows  | 
|  8192 (8 vCPU)  此选项需要 Linux 平台 `1.4.0` 或更高版本。   |  16 GB 到 60 GB 之间（以 4 GB 为增量）  |  Linux  | 
|  16384 (16vCPU)  此选项需要 Linux 平台 `1.4.0` 或更高版本。   |  32 GB 到 120 GB 之间（以 8 GB 为增量）  |  Linux  | 

## 任务联网
<a name="fargate-tasks-services-networking"></a>

AWS Fargate 的 Amazon ECS 任务要求使用 `awsvpc` 网络模式，该模式可为每个任务提供一个弹性网络接口。在使用此网络模式运行任务或创建服务时，必须指定一个或多个要附加网络接口的子网以及一个或多个要应用于该网络接口的安全组。

如果您使用的是公有子网，请决定是否为网络接口提供公有 IP 地址。对于公有子网中拉取容器映像的 Fargate 任务，需要向该任务的弹性网络接口分配一个公有 IP 地址，还需要一个到互联网的路由，或一个可以将请求路由到互联网的 NAT 网关。对于私有子网中拉取容器映像的 Fargate 任务，您需要私有子网中的 NAT 网关以将请求路由到互联网。在 Amazon ECR 中托管容器映像时，您可以将 Amazon ECR 配置为使用接口 VPC 端点。在这种情况下，任务的专用 IPv4 地址将用于图像提取。有关 Amazon ECR 接口端点的更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的 [Amazon ECR 接口 VPC 端点（AWS PrivateLink）](https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html)。

以下是 Fargate 服务的 `networkConfiguration` 部分的示例：

```
"networkConfiguration": { 
   "awsvpcConfiguration": { 
      "assignPublicIp": "ENABLED",
      "securityGroups": [ "sg-12345678" ],
      "subnets": [ "subnet-12345678" ]
   }
}
```

## 任务资源限制
<a name="fargate-resource-limits"></a>

AWS Fargate 上的 Linux 容器的 Amazon ECS 任务定义支持使用 `ulimits` 参数来定义要为容器设置的资源限制。

AWS Fargate 上的 Windows 的 Amazon ECS 任务定义支持使用 `ulimits` 参数来定义要为容器设置的资源限制。

Fargate 上托管的 Amazon ECS 任务使用操作系统设置的默认资源限制值，`nofile` 资源限制参数除外。`nofile` 资源限制对容器可以使用的打开文件数量设置限制。在 Fargate 上，默认的 `nofile` 软限制为 ` 65535`，硬限制为 `65535`。您可以将两个限制的值最高设置为 `1048576`。

下面是一个示例任务定义代码段，介绍如何定义 `nofile` 限制已经增加了一倍：

```
"ulimits": [
    {
       "name": "nofile",
       "softLimit": 2048,
       "hardLimit": 8192
    }
]
```

有关可以调整的其他资源限制的更多信息，请参阅[资源限制](task_definition_parameters.md#container_definition_limits)。

## 日志记录
<a name="fargate-tasks-logging"></a>

### 事件日志记录
<a name="fargate-event-logging"></a>

Amazon ECS 将其采取的操作记录到 EventBridge 中。您可以使用 EventBridge 的 Amazon ECS 事件来接收有关 Amazon ECS 集群、服务和任务当前状态的近实时通知。此外，您还可以自动执行操作以响应这些事件。有关更多信息，请参阅 [使用 EventBridge 自动响应 Amazon ECS 错误](cloudwatch_event_stream.md)。

### 任务生命周期日志记录
<a name="fargate-task-status"></a>

在 Fargate 上运行的任务会发布时间戳，以便在任务生命周期的各个状态中跟踪任务。通过描述 AWS CLI 和开发工具包中的任务，可以在 AWS 管理控制台 中的任务详细信息中查看时间戳。例如，您可以使用时间戳来评估任务下载容器映像所花费的时间，并决定是应优化容器映像大小，还是使用 Seekable OCI 索引。有关容器映像实践的更多信息，请参阅 [Amazon ECS 容器映像的最佳实践](container-considerations.md)。

### 应用程序日志记录
<a name="fargate-app-logging"></a>

AWS Fargate 的 Amazon ECS 任务定义支持用于日志配置的 `awslogs`、`splunk` 和 `awsfirelens` 日志驱动程序。

`awslogs` 日志驱动程序会将您的 Fargate 任务配置为向 Amazon CloudWatch Logs 信息。下面显示了任务定义中配置 `awslogs` 日志驱动程序的代码段：

```
"logConfiguration": { 
   "logDriver": "awslogs",
   "options": { 
      "awslogs-group" : "/ecs/fargate-task-definition",
      "awslogs-region": "us-east-1",
      "awslogs-stream-prefix": "ecs"
   }
}
```

有关在任务定义中使用 `awslogs` 日志驱动程序以将容器日志发送到 CloudWatch Logs 的更多信息，请参阅 [将 Amazon ECS 日志发送到 CloudWatch](using_awslogs.md)。

有关任务定义中的 `awsfirelens` 日志驱动程序的更多信息，请参阅[将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner](using_firelens.md)。

有关在任务定义中使用 `splunk` 日志驱动程序的更多信息，请参阅[`splunk` 日志驱动程序](example_task_definitions.md#example_task_definition-splunk)。

## 任务存储
<a name="fargate-tasks-storage"></a>

对于 Fargate 上托管的 Amazon ECS 任务，支持以下存储类型：
+ Amazon EBS 卷为数据密集型容器化工作负载提供经济高效、持久、高性能的块存储。有关更多信息，请参阅 [将 Amazon EBS 卷与 Amazon ECS 结合使用](ebs-volumes.md)。
+ Amazon EFS 卷（用于持久性存储）。有关更多信息，请参阅 [将 Amazon EFS 卷与 Amazon ECS 结合使用](efs-volumes.md)。
+ 绑定挂载以实现临时存储。有关更多信息，请参阅 [将绑定挂载与 Amazon ECS 结合使用](bind-mounts.md)。

## 使用 Seekable OCI（SOCI）延迟加载容器映像
<a name="fargate-tasks-soci-images"></a>

Fargate 上使用 Linux 平台版本 `1.4.0` 的 Amazon ECS 任务可以使用 Seekable OCI（SOCI）来帮助更快地启动任务。借助 SOCI，容器只需花几秒钟的时间进行映像拉取即可启动，从而在后台下载映像时为环境设置和应用程序实例化提供了时间。这称为*延迟加载*。当 Fargate 启动 Amazon ECS 任务时，Fargate 会自动检测任务中是否存在映像的 SOCI 索引，并在不等待下载整个映像的情况下启动容器。

对于在没有 SOCI 索引的情况下运行的容器，容器映像将在容器启动之前完全下载。此行为在 Fargate 的所有其他平台版本上以及 Amazon EC2 实例上经 Amazon ECS 优化的 AMI 上均相同。

Seekable OCI（SOCI）是 AWS 开发的一种开源技术，它可以通过延迟加载容器映像来更快地启动容器。SOCI 的工作原理是为现有容器映像中的文件创建索引（SOCI 索引）。此索引有助于更快地启动容器，从而提供在下载整个映像之前从容器映像中提取单个文件的功能。SOCI 索引必须作为构件存储在与容器注册表中的映像相同的存储库中。您只能使用来自可信来源的 SOCI 索引，因为该索引是映像内容的权威来源。有关更多信息，请参阅[介绍用于延迟加载容器映像的 Seekable OCI](https://aws.amazon.com/about-aws/whats-new/2022/09/introducing-seekable-oci-lazy-loading-container-images/)。

需要使用 SOCI 的客户将只能使用 SOCI 索引清单 v2。之前已在 Fargate 上使用 SOCI 的现有客户可以继续使用 SOCI 索引清单 v1，但是我们强烈建议这些客户迁移到 SOCI 索引清单 v2。SOCI 索引清单 v2 会在容器映像与其 SOCI 索引之间建立显式关系，从而确保部署的一致性。
<a name="fargate-soci-considerations"></a>
**注意事项**  
如果您希望 Fargate 使用 SOCI 索引在任务中延迟加载容器映像，请考虑以下几点：
+ 只有在 Linux 平台版本 `1.4.0` 上运行的任务才能使用 SOCI 索引。不支持在 Fargate 上运行 Windows 容器的任务。
+ 支持在 X86\$164 或 ARM64 CPU 架构上运行的任务。
+ 任务定义中的容器映像必须存储在兼容的映像注册表中。以下列出了兼容的注册表：
  + Amazon ECR 私有注册表。
+ 仅支持使用 gzip 压缩或未压缩的容器映像。不支持使用 zstd 压缩的容器映像。
+ 对于 SOCI 索引清单 v2，生成 SOCI 索引清单会修改容器映像清单，因为我们为 SOCI 索引添加了注释。这将导致新的容器映像摘要。容器映像文件系统层的内容并无变化。
+ 对于 SOCI 索引清单 v2，如果容器映像已经存储在容器映像存储库中，则在生成 SOCI 索引后，您需要重新推送容器映像。重新推送容器映像不会因重复的文件系统层而增加存储成本，因为仅会上传新的清单文件。
+ 建议您尝试使用大于 250 MiB 压缩后的容器映像进行延迟加载。您不太可能看到加载较小映像的时间缩短。
+ 由于延迟加载可能会改变任务启动所需的时间，因此您可能需要对各种超时时间进行更改，例如 Elastic Load Balancing 的运行状况检查宽限期。
+ 要防止容器映像延迟加载，您需要在不附加 SOCI 索引的情况下重新推送容器映像。
<a name="create-soci"></a>
**创建 Seekable OCI 索引**  
对于要延迟加载的容器映像，需要创建 SOCI 索引（元数据文件），并将其与容器映像一起存储在容器映像存储库中。要创建和推送 SOCI 索引，您可以使用 GitHub 上的开源 [soci-snapshotter CLI 工具](https://github.com/awslabs/soci-snapshotter)。或者，您可以部署 CloudFormation AWS SOCI 索引构建器。这是一种无服务器解决方案，可以在将容器映像推送到 Amazon ECR 时自动创建和推送 SOCI 索引。有关解决方案和安装步骤的更多信息，请参阅 GitHub 上的 [CloudFormation AWS SOCI 索引构建器](https://awslabs.github.io/cfn-ecr-aws-soci-index-builder/)。CloudFormation AWS SOCI 索引构建器是自动开始使用 SOCI 的一种方法，而开源 SOCI 工具在索引生成方面具有更大的灵活性，并且能够将索引生成集成到持续集成和持续交付（CI/CD）管道中。

**注意**  
要为映像创建 SOCI 索引，该映像必须存在于正在运行 `soci-snapshotter` 的计算机上的 containerd 映像存储中。如果映像在 Docker 映像存储中，则无法找到该映像。
<a name="verify-soci"></a>
**验证任务是否使用延迟加载**  
要验证任务是否使用 SOCI 延迟加载，请从任务内部检查任务元数据端点。在您查询任务元数据端点版本 4 时，在您要查询的容器的默认路径中有一个 `Snapshotter` 字段。此外，`/task` 路径中每个容器都有 `Snapshotter` 字段。此字段的默认值为 `overlayfs`，如果使用 SOCI，则此字段设置为 `soci`。要验证容器映像是否附加了 SOCI 索引清单 v2，您可以使用 AWS CLI 从 Amazon ECR 检索映像索引。

```
IMAGE_REPOSITORY=r
IMAGE_TAG=latest

aws ecr batch-get-image \
    --repository-name=$IMAGE_REPOSITORY \
    --image-ids imageTag=$IMAGE_TAG \
    --query 'images[0].imageManifest' --output text | jq -r '.manifests[] | select(.artifactType=="application/vnd.amazon.soci.index.v2+json")'
```

要验证容器映像是否附加了 SOCI 索引清单 v1，您可以使用 OCI Referrers API。

```
ACCOUNT_ID=111222333444
AWS_REGION=us-east-1
IMAGE_REPOSITORY=nginx-demo
IMAGE_TAG=latest
IMAGE_DIGEST=$(aws ecr describe-images --repository-name $IMAGE_REPOSITORY --image-ids imageTag=$IMAGE_TAG --query 'imageDetails[0].imageDigest' --output text)
ECR_PASSWORD=$(aws ecr get-login-password)

curl \
    --silent \
    --user AWS:$ECR_PASSWORD \
    https://$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/v2/$IMAGE_REPOSITORY/referrers/$IMAGE_DIGEST?artifactType=application%2Fvnd.amazon.soci.index.v1%2Bjson | jq -r '.'
```

# 运行 Windows 的 EC2 实例的 Amazon ECS 任务定义差异
<a name="windows_task_definitions"></a>

在 EC2 Windows 实例上运行的任务并不支持所有可用的 Amazon ECS 任务定义参数。某些参数完全不受支持，而其他参数的行为则不同。

Amazon EC2 Windows 任务定义不支持以下任务定义参数：
+ `containerDefinitions`
  + `disableNetworking`
  + `dnsServers`
  + `dnsSearchDomains`
  + `extraHosts`
  + `links`
  + `linuxParameters`
  + `privileged`
  + `readonlyRootFilesystem`
  + `user`
  + `ulimits`
+ `volumes`
  + `dockerVolumeConfiguration`
+ `cpu`

  我们建议为 Windows 容器指定容器级 CPU。
+ `memory`

  我们建议为 Windows 容器指定容器级内存。
+ `proxyConfiguration`
+ `ipcMode`
+ `pidMode`
+ `taskRoleArn`

  EC2 Windows 实例上的任务的 IAM 角色需要额外配置，但此配置很大程度上类似于在 Linux 容器实例上配置任务的 IAM 角色。有关更多信息，请参阅 [Amazon EC2 Windows 实例附加配置](task-iam-roles.md#windows_task_IAM_roles)。