

# 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 '.'
```