

# 在 Amazon ECS 上计划您的容器
<a name="scheduling_tasks"></a>

Amazon Elastic Container Service（Amazon ECS）是一个共享状态的乐观并发系统，可为您的容器化工作负载提供灵活的计划功能。Amazon ECS 调度器利用由 Amazon ECS API 提供的相同集群状态信息来制定适当的放置决策。

Amazon ECS 提供用于长期运行的任务和应用程序的服务调度器。它还允许运行独立任务或计划任务（用于批处理作业或单个运行任务）。您可以为运行最能满足您需求的任务指定任务放置策略和约束。例如，您可以指定任务是跨多个可用区运行，还是在单个可用区内运行。您还可以选择将任务集成到自己的自定义或第三方调度器。


| Option | 何时使用 | 更多信息 | 
| --- | --- | --- | 
| 服务 | 服务计划程序适用于长时间运行的无状态服务和应用程序。此外，服务调度器可以选择性地确保针对 Elastic Load Balancing 负载均衡器注册任务。您可以更新由服务调度器维护的服务。这可能包括部署新的任务定义或更改正在运行的所需任务的数量。预设情况下，服务调度器可在多个可用区之间分布任务，但您可以使用任务放置策略和约束自定义任务放置决策。 | [Amazon ECS 服务](ecs_services.md) | 
| 独立任务 | 独立任务适用于诸如执行工作然后停止的批处理作业这样的流程。例如，您可以拥有在工作进入队列时调用 RunTask 的流程。任务从队列中拉取工作、执行工作，然后退出。使用 RunTask，您可以允许原定设置任务放置策略在集群中随机分配任务。这可以最大程度地减小单一实例获得不成比例数量任务的机会。 | [Amazon ECS 独立任务](standalone-tasks.md) | 
| 计划任务 | 当您需要在集群中以设定的时间间隔运行任务时，计划任务是适合的，您可以使用 EventBridge Scheduler 创建计划。您可以为备份操作或日志扫描运行任务。您创建的 EventBridge Scheduler 计划可以在指定时间在集群中运行一个或多个任务。您的调度事件可以设置为特定的时间间隔（每 N 分钟、小时或天运行一次）。否则，对于更复杂的调度，您可以使用 cron 表达式。 | [使用 Amazon EventBridge 调度器计划 Amazon ECS 任务](tasks-scheduled-eventbridge-scheduler.md) | 

## 计算选项
<a name="compute-option"></a>

通过 Amazon ECS，您可以指定运行任务或服务的基础设施。您可以使用容量提供程序策略或启动类型。

对于 Fargate，容量提供程序是 Fargate 和 Fargate Spot。对于 EC2，容量提供程序是具有已注册容器实例的自动扩缩组。

容量提供程序策略将您的任务分配给与您的集群关联的容量提供程序。

只有已与集群关联且状态为 `ACTIVE` 或 `UPDATING` 的容量提供程序才能在容量提供程序策略中使用。在创建集群时，您可以将容量提供程序与集群相关联。

在容量提供程序策略中，可选*基准值*指明在指定的容量提供程序上至少运行多少个任务。在一个容量提供程序策略中，只能有一个容量提供程序策略定义了基准。

*权重值*指明使用指定容量提供程序的已启动任务总数的相对百分比。考虑以下示例。您的策略包含两个容量提供程序，并且两者的权重均为 `1`。当满足基准百分比时，任务会在两个容量提供程序之间均匀分配。按照相同的逻辑，假定您指定 *capacityProviderA* 的权重为 `1`，并指定 *capacityProviderB* 的权重为 `4`，那么，对于使用 *capacityProviderA* 运行的每个任务，都会有四个任务使用 *capacityProviderB*。

计算选项会直接在 Fargate 或您手动注册到集群的 Amazon EC2 实例上启动您的任务。

# Amazon ECS 任务生命周期
<a name="task-lifecycle-explanation"></a>

如果手动启动任务或将任务作为服务的一部分启动，则任务在自行完成或被手动停止之前可能经历多种状态。一些任务旨在作为批处理作业运行，将自然地依次经历 `PENDING`、`RUNNING` 和 `STOPPED` 状态。可为服务的一部分的其他任务旨在无限期持续运行，或根据需要向上扩展和向上扩展。

当请求任务状态更改（如停止任务或更新所需服务计数以将其扩展或缩减）时，Amazon ECS 容器代理会根据任务的上一个已知状态（`lastStatus`）和任务的所需状态（`desiredStatus`）跟踪这些更改。任务的上一个已知状态和所需状态均可在控制台中或通过使用 API 或 AWS CLI 描述任务进行查看。

以下流程图显示任务生命周期流程。

![\[任务生命周期状态图。状态为 PROVISIONING、PENDING、ACTIVATING、RUNNING、DEACTIVATING、STOPPING。\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/task-lifecycle.png)


## 生命周期状态
<a name="lifecycle-states"></a>

以下是每个任务生命周期状态的描述。

正在预置  
Amazon ECS 必须先执行其他步骤，然后再启动任务。例如，对于使用 `awsvpc` 网络模式的任务，需要预置弹性网络接口。

PENDING  
这是一个过渡状态，其中 Amazon ECS 正在等待容器代理采取进一步操作。任务一直处于待处理状态，直到有可用资源可用于该任务。

正在激活  
这种一种过渡状态，在此状态下，Amazon ECS 必须在启动任务后但在任务可以过渡到 `RUNNING` 状态之前执行其他步骤。这是 Amazon ECS 提取容器映像、创建容器、配置任务联网、注册负载均衡器目标组和配置服务发现的状态。

正在运行  
任务正在成功运行。

正在停用  
这种一种过渡状态，在此状态下，Amazon ECS 必须在任务停止前执行其他步骤。例如，对于配置为使用弹性负载均衡目标组的服务所包含的任务，将在此状态下取消注册目标组。

正在停止  
这是一个过渡状态，其中 Amazon ECS 正在等待容器代理采取进一步操作。  
对于 Linux 容器，容器代理将使用 `STOPSIGNAL` 指令发送容器映像中定义的停止信号，以通知应用程序需要完成并关闭。默认情况下，这是 `SIGTERM`。然后，在等待任务定义中设置的 `StopTimeout` 时长后，它将发送 `SIGKILL`。

正在取消预置  
Amazon ECS 必须在已停止任务后但在任务过渡到 `STOPPED` 状态之前执行其他步骤。例如，对于使用 `awsvpc` 网络模式的任务，需要分离并删除弹性网络接口。

已停止  
任务已成功停止。  
如果您的任务因某个错误而停止，请参阅 [查看 Amazon ECS 已停止任务错误](stopped-task-errors.md)。

DELETED  
这是任务停止时的过渡状态。此状态不会显示在控制台中，而是显示在 `describe-tasks` 中。

# Amazon ECS 如何将任务放置在容器实例上
<a name="task-placement"></a>

您可以使用任务放置来配置 Amazon ECS，以将您的任务放在满足特定标准（例如可用区或实例类型）的容器实例上。

以下是任务放置组件：
+ 任务放置策略是：用于选择放置任务的容器实例或要终止的任务的算法。例如，Amazon ECS 可以随机选择容器实例；还可以选择一组容器实例，将任务平均分配到其中。
+ 任务组：一组相关的任务，例如数据库任务。
+ 任务放置约束：必须满足这些规则才能在容器实例上放置任务。如果不满足该约束条件，则任务不会被放置并且会保持 `PENDING` 状态。例如，您可以使用约束条件将任务仅放置在特定的实例类型上。

Amazon ECS 针对不同的容量选项提供了不同的算法。

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

对于在 Amazon ECS 托管实例上运行的任务，Amazon ECS 必须确定任务的放置位置以及在缩减任务数量时终止哪些任务。Amazon ECS 会根据容量提供程序启动模板中指定的实例要求、任务定义中指定的 CPU 和内存等要求以及任务放置约束来做出此决定。

**注意**  
Amazon ECS 托管实例不支持任务放置策略。Amazon ECS 将尽最大努力将任务分散到各个可访问的可用区。

Amazon ECS 放置任务时，使用以下流程选择容器实例：

1. 识别满足任务定义中对 CPU、GPU、内存和端口要求的容器实例。

1. 识别满足任务放置约束的容器实例。

1. 识别符合容量提供程序启动模板中指定的实例要求的容器实例。

1. 选择放置任务的容器实例。

## EC2
<a name="ec2-launch-type"></a>

对于使用 EC2 启动类型的任务，Amazon ECS 必须根据任务定义中指定的要求（例如 CPU 和内存）确定将任务放置在何处。同样，如果您缩减任务计数，Amazon ECS 必须确定终止哪些任务。您可以应用任务放置策略和约束，自定义 Amazon ECS 如何放置和终止任务。

原定设置任务放置策略取决于您是手动运行任务（独立任务）还是在服务中运行任务。对于作为 Amazon ECS 服务的一部分运行的任务，任务放置策略是使用 `attribute:ecs.availability-zone` 的 `spread`。对于不在服务中的任务，没有默认的任务放置约束。有关更多信息，请参阅 [在 Amazon ECS 上计划您的容器](scheduling_tasks.md)。

**注意**  
任务放置策略是尽力而为。Amazon ECS 仍会尝试放置任务，即使在大多数最优放置选项不可用时也是如此。但是，任务放置约束是绑定的，它们可能阻止任务放置。

您可以将任务放置策略与约束配合使用。例如，您可以使用任务放置策略和任务放置约束在多个可用区中分配任务，并根据每个可用区中的内存装填任务，但只针对 G2 实例。

Amazon ECS 放置任务时，使用以下流程选择容器实例：

1. 识别满足任务定义中对 CPU、GPU、内存和端口要求的容器实例。

1. 识别满足任务放置约束的容器实例。

1. 识别满足任务放置策略的容器实例。

1. 选择放置任务的容器实例。

## Fargate
<a name="fargate-launch-type"></a>

使用 Fargate 的任务不支持任务放置策略和约束。Fargate 将尽最大努力将任务分散到各个可访问的可用区。如果容量提供程序同时包含 Fargate 和 Fargate Spot，则每个容量提供程序的分散行为是独立的。

# Amazon ECS 托管实例自动扩缩和任务放置
<a name="managed-instance-auto-scaling"></a>

Amazon ECS 托管实例使用智能算法自动扩缩集群容量，并将任务高效地放置到您的基础设施中。了解这些算法的工作原理有助于您优化服务配置并排查放置行为相关问题。

## 任务放置算法
<a name="managed-instance-task-placement-algorithm"></a>

Amazon ECS 托管实例使用复杂的放置算法来在安排任务时平衡可用性、资源利用率和网络需求。

### 可用区分布
<a name="managed-instance-az-spread-behavior"></a>

默认情况下，Amazon ECS 托管实例通过将任务分散到多个可用区来优先考虑可用性：
+ 对于包含多个任务的服务，Amazon ECS 托管实例会尽可能确保分布在不同可用区的至少三个实例上
+ 这种行为提供了容错能力，但可能会导致每个实例的资源利用率降低
+ 可用区分布优先于装箱优化

### 装箱行为
<a name="managed-instance-bin-packing"></a>

虽然 Amazon ECS 托管实例可以执行装箱来最大限度地提高资源利用率，但是这种行为会受到您的网络配置的影响：
+ 为了实现装箱，请将您的服务配置为使用单个子网
+ 多子网配置优先考虑可用区分布而非资源密度
+ 在初始服务启动期间比在扩展事件期间更有可能进行装箱

### ENI 密度注意事项
<a name="managed-instance-eni-density"></a>

对于使用 `awsvpc` 网络模式的服务，Amazon ECS 托管实例在做出放置决策时会考虑弹性网络接口（ENI）密度：
+ `awsvpc` 模式下的每个任务都需要专用 ENI
+ 实例类型具有影响任务密度的不同 ENI 限制
+ 在选择目标实例时，Amazon ECS 托管实例会考虑 ENI 可用性

**注意**  
我们正在不断改进 ENI 密度计算来优化放置决策。

## 容量提供程序决策逻辑
<a name="managed-instance-capacity-provider-decisions"></a>

Amazon ECS 托管实例容量提供程序会根据多种因素做出扩展和放置决策：

资源要求  
待处理任务的 CPU、内存和网络要求

实例可用性  
现有实例的当前容量和利用率

网络约束  
子网配置和 ENI 可用性

可用区分配  
在多个可用区之间保持容错能力

## 配置选项
<a name="managed-instance-configuration-options"></a>

### 子网选择策略
<a name="managed-instance-subnet-strategy"></a>

您的子网配置会显著影响任务放置行为：

多个子网（默认）  
优先考虑可用区分布以实现高可用性  
可能导致每个实例的资源利用率较低  
推荐用于需要容错能力的生产工作负载

单个子网  
启用装箱以提高资源利用率  
将任务集中在一个可用区，降低容错能力  
适用于开发或成本优化的工作负载

### 网络模式注意事项
<a name="managed-instance-network-mode-considerations"></a>

您选择的网络模式会影响放置决策：
+ `awsvpc` 模式 – 每个任务都需要专用 ENI，限制每个实例的任务密度
+ `host` 模式 – 任务直接使用主机的网络，放置主要由资源可用性决定

### CPU 架构注意事项
<a name="managed-instance-cpu-architecture-considerations"></a>

您在任务定义中指定的 `cpuArchitecture` 用于将任务放置到特定架构上。如果不指定 `cpuArchitecture`，Amazon ECS 将根据容量提供程序配置尝试将任务放置在任何可用的 CPU 架构上。您可指定 `X86_64` 或 `ARM64`。

## 排查任务放置问题
<a name="managed-instance-troubleshooting-placement"></a>

### 常见放置模式
<a name="managed-instance-common-placement-patterns"></a>

了解预期放置模式有助于区分正常行为和潜在问题：

分散分布  
任务分布在多个实例上，部分利用率  
使用多个子网时的正常行为  
表示可用性优先于资源效率

集中放置  
将多个任务放置在较少实例上，利用率更高  
使用单个子网配置时需要  
初始服务启动期间可能会发生

不均分布  
一些实例利用率很高，而另一些实例未得到充分利用  
可能表示 ENI 限制或资源约束  
考虑检查实例类型和网络配置

### 优化放置行为
<a name="managed-instance-placement-optimization"></a>

要根据您的特定要求优化任务放置：

1. 评估可用性要求与成本优化需求

1. 根据优先级选择合适的子网配置

1. 为网络模式选择具有足够 ENI 容量的实例类型

1. 监控放置模式并根据需要调整配置

## 最佳实践
<a name="managed-instance-best-practices"></a>
+ **对于生产工作负载** – 使用跨不同可用区的多个子网来确保高可用性，接受资源利用率方面的权衡。
+ **对于开发或测试** – 考虑单个子网配置，以最大限度地提高资源利用率并降低成本
+ **对于 `awsvpc` 模式** – 选择具有足够 ENI 容量的实例类型以避免放置约束
+ **对于成本优化** – 监控利用率模式并调整服务配置，以平衡可用性和效率
+ **对于故障排除** – 在调查意外放置模式时，请查看子网配置和网络模式

# 使用策略来定义 Amazon ECS 任务放置
<a name="task-placement-strategies"></a>

对于使用 EC2 启动类型的任务，Amazon ECS 必须根据任务定义中指定的要求（例如 CPU 和内存）确定将任务放置在何处。同样，如果您缩减任务计数，Amazon ECS 必须确定终止哪些任务。您可以应用任务放置策略和约束，自定义 Amazon ECS 如何放置和终止任务。

原定设置任务放置策略取决于您是手动运行任务（独立任务）还是在服务中运行任务。对于作为 Amazon ECS 服务的一部分运行的任务，任务放置策略是使用 `attribute:ecs.availability-zone` 的 `spread`。对于不在服务中的任务，没有默认的任务放置约束。有关更多信息，请参阅 [在 Amazon ECS 上计划您的容器](scheduling_tasks.md)。

**注意**  
任务放置策略是尽力而为。Amazon ECS 仍会尝试放置任务，即使在大多数最优放置选项不可用时也是如此。但是，任务放置约束是绑定的，它们可能阻止任务放置。

您可以将任务放置策略与约束配合使用。例如，您可以使用任务放置策略和任务放置约束在多个可用区中分配任务，并根据每个可用区中的内存装填任务，但只针对 G2 实例。

Amazon ECS 放置任务时，使用以下流程选择容器实例：

1. 识别满足任务定义中对 CPU、GPU、内存和端口要求的容器实例。

1. 识别满足任务放置约束的容器实例。

1. 识别满足任务放置策略的容器实例。

1. 选择放置任务的容器实例。

使用 `placementStrategy` 参数在服务定义或任务定义中指定任务放置策略。

```
"placementStrategy": [
    {
        "field": "The field to apply the placement strategy against",
        "type": "The placement strategy to use"
    }
]
```

您可以在运行任务（[RunTask](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html)）、创建新服务（[CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html)）或更新现有服务（[UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)）时指定策略。

下表介绍了可用的类型和字段。


| 类型 | 有效的字段值 | 
| --- | --- | 
| binpack 将任务放置在容器实例上，以保留最少的未使用 CPU 或内存。此策略最大限度地减少了正在使用的容器实例的数量。 当使用此策略并执行横向缩减操作时，Amazon ECS 将终止任务。它根据任务终止后留在容器实例上的资源量执行此操作。任务终止后剩下可用资源最多的容器实例将终止该任务。 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/task-placement-strategies.html)  | 
| random 任务随机放置。 | 未使用 | 
| spread根据指定的值均匀放置任务。 服务任务根据该服务的任务分布。独立任务根据同一任务组中的任务分布。有关任务组的更多信息，请参阅 [与组相关的 Amazon ECS 任务](task-groups.md)。当使用 `spread` 策略并采取横向缩减行动时，Amazon ECS 将选择要终止的任务，以保持可用性区域之间的平衡。在可用区域内，将随机选择任务。 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/task-placement-strategies.html)  | 

也可以针对现有服务更新任务放置策略。有关更多信息，请参阅 [Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。

您可以按照您希望的执行顺序创建策略阵列，从而创建使用多种策略的任务置放策略。例如，如果您想将任务分散到多个可用区，然后根据每个可用区内的内存装填任务，请指定可用区策略，然后指定内存策略。有关策略示例，请参阅 [Amazon ECS 任务放置策略示例](strategy-examples.md)。

# Amazon ECS 任务放置策略示例
<a name="strategy-examples"></a>

您可以使用以下操作指定任务放置策略：[CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html)、[UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html) 和 [RunTask](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html)。

**Topics**
+ [跨可用区平均分配任务](#even-az)
+ [在所有实例上平均分配任务](#even-instance)
+ [基于内存的垃圾箱任务](#binpack)
+ [随机置放任务](#random)
+ [以下策略跨可在多个可用区中平均分配任务，然后在每个可用区内的实例中平均分配任务](#az-instance)
+ [在多个可用区中平均分配任务，然后根据每个可用区内的内存装填任务](#az-memory)
+ [在实例之间平均分配任务，然后根据内存装填任务](#instance-memory)

## 跨可用区平均分配任务
<a name="even-az"></a>

以下策略可在各可用区之间平均分配任务。

```
"placementStrategy": [
    {
        "field": "attribute:ecs.availability-zone",
        "type": "spread"
    }
]
```

## 在所有实例上平均分配任务
<a name="even-instance"></a>

以下策略可在所有实例中平均分配任务。

```
"placementStrategy": [
    {
        "field": "instanceId",
        "type": "spread"
    }
]
```

## 基于内存的垃圾箱任务
<a name="binpack"></a>

以下策略根据内存装填任务。

```
"placementStrategy": [
    {
        "field": "memory",
        "type": "binpack"
    }
]
```

## 随机置放任务
<a name="random"></a>

以下策略随机放置任务。

```
"placementStrategy": [
    {
        "type": "random"
    }
]
```

## 以下策略跨可在多个可用区中平均分配任务，然后在每个可用区内的实例中平均分配任务
<a name="az-instance"></a>

以下策略跨可在多个可用区中平均分配任务，然后在每个可用区内的实例中平均分配任务。

```
"placementStrategy": [
    {
        "field": "attribute:ecs.availability-zone",
        "type": "spread"
    },
    {
        "field": "instanceId",
        "type": "spread"
    }
]
```

## 在多个可用区中平均分配任务，然后根据每个可用区内的内存装填任务
<a name="az-memory"></a>

以下策略可在多个可用区中平均分配任务，然后根据每个可用区内的内存装填任务。

```
"placementStrategy": [
    {
        "field": "attribute:ecs.availability-zone",
        "type": "spread"
    },
    {
        "field": "memory",
        "type": "binpack"
    }
]
```

## 在实例之间平均分配任务，然后根据内存装填任务
<a name="instance-memory"></a>

以下策略将任务平均分配给所有实例，然后根据每个实例中的内存装填任务。

```
"placementStrategy": [
    {
        "field": "instanceId",
        "type": "spread"
    },
    {
        "field": "memory",
        "type": "binpack"
    }
]
```

# 与组相关的 Amazon ECS 任务
<a name="task-groups"></a>

您可以识别一组相关任务并将其放置在任务组中。使用 `spread` 任务放置策略时，将具有相同任务组名称的所有任务视为一个集合。例如，假设一个集群中运行着不同应用程序，如数据库和 Web 服务器。要确保数据库在可用性区域之间保持平衡，请将它们添加到名为 `databases` 的任务组中，然后使用 `spread` 任务放置策略。有关更多信息，请参阅 [使用策略来定义 Amazon ECS 任务放置](task-placement-strategies.md)。

任务组也可以用作任务放置约束。在 `memberOf` 约束中指定任务组时，任务仅发送到在指定任务组中运行任务的容器实例。有关示例，请参阅[Amazon ECS 任务放置约束示例](constraint-examples.md)。

预设情况下，独立任务使用任务定义系列名称（例如 `family:my-task-definition`）作为任务组名称（如果未指定自定义任务组名称）。作为服务的一部分启动的任务使用服务名称作为任务组名称，不能更改。

以下任务组要求适用。
+ 任务组名称必须为 255 个字符或更少。
+ 每项任务只能处于一个组中。
+ 任务启动后，您将无法修改其任务组。

# 定义 Amazon ECS 将哪些容器实例用于任务
<a name="task-placement-constraints"></a>

任务放置约束是关于容器实例的规则，Amazon ECS 使用该规则来确定是否允许在实例上运行任务。必须至少有一个容器实例匹配约束条件。如果没有与约束条件匹配的实例，则任务将保持 `PENDING` 状态。创建新服务或更新现有服务时，您可以为服务的任务指定任务放置限制。

您可以使用 `placementConstraint` 参数在服务定义、任务定义或任务中指定任务放置约束。

```
"placementConstraints": [
    {
        "expression": "The expression that defines the task placement constraints",
        "type": "The placement constraint type to use"
    }
]
```

下表介绍如何使用这些参数。


| Constraint type | 可以在何时指定 | 
| --- | --- | 
| distinctInstance将每个活动任务放入不同的容器实例。Amazon ECS 会检查所需的任务状态以放置任务。例如，假设现有任务所需的状态为 `STOPPED`（但最近的状态不是该状态），则可以将新传入的任务放入同一个实例，尽管存在 `distinctInstance` 放置约束。因此，您可能会看到同一个实例上有 2 个任务最近的状态都为 `RUNNING`。 建议为其任务寻求强隔离的客户使用 Fargate。Fargate 在硬件虚拟化环境中运行每个任务。这将确保这些容器化工作负载不会与其他任务共享网络接口、Fargate 临时存储、CPU 或内存。有关更多信息，请参阅 [AWS Fargate 的安全概述](https://d1.awsstatic.com/whitepapers/AWS_Fargate_Security_Overview_Whitepaper.pdf)。 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/task-placement-constraints.html)  | 
| memberOf将任务放置在满足表达式的容器实例中。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/task-placement-constraints.html) | 

使用 `memberOf` 约束类型时，您可以使用集群查询语言创建表达式，该语言定义了 Amazon ECS 在其中放置任务的容器实例。表达式是供您按属性对容器实例进行分组的一种方式。表达式位于 `placementConstraint` 的 `expression ` 参数中。

## Amazon ECS 容器实例属性
<a name="attributes"></a>

您可以将自定义元数据添加到容器实例中，称为*属性*。每个属性都有一个名称和一个可选字符串值。您可以使用 Amazon ECS 提供的内置属性，或自定义属性。

以下部分包含示例内置、可选属性和自定义属性。

### 内置属性
<a name="ecs-automatic-attributes"></a>

Amazon ECS 会自动将以下属性应用于您的容器实例。

`ecs.ami-id`  
用于启动实例的 AMI 的 ID。本属性的示例值为 `ami-1234abcd`。

`ecs.availability-zone`  
实例所在的可用区。本属性的示例值为 `us-east-1a`。

`ecs.instance-type`  
实例的实例类型。本属性的示例值为 `g2.2xlarge`。

`ecs.os-type`  
实例的操作系统。此属性的可能值为 `linux` 和 `windows`。

`ecs.os-family`  
实例的操作系统版本。  
对于 Linux 实例，有效值为 `LINUX`。对于 Windows 实例，ECS 以 `WINDOWS_SERVER_<OS_Release>_<FULL or CORE>` 格式设置值。有效值为 `WINDOWS_SERVER_2022_FULL`、`WINDOWS_SERVER_2022_CORE`、`WINDOWS_SERVER_20H2_CORE`、`WINDOWS_SERVER_2019_FULL`、`WINDOWS_SERVER_2019_CORE` 和 `WINDOWS_SERVER_2016_FULL`。  
这对于 Windows 容器和 Windows containers on AWS Fargate 很重要，因为每个 Windows 容器的操作系统版本都必须与主机的操作系统版本相匹配。如果容器映像的 Windows 版本与主机不同，则容器无法启动。有关更多信息，请参阅 Microsoft 文档网站上的 [Windows 容器版本兼容性](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-2022%2Cwindows-11)。  
如果您的集群运行多个 Windows 版本，则可以使用置放约束来确保将任务放在运行相同版本的 EC2 实例上：`memberOf(attribute:ecs.os-family == WINDOWS_SERVER_<OS_Release>_<FULL or CORE>)`。有关更多信息，请参阅 [检索经 Amazon ECS 优化的 Windows AMI 元数据](retrieve-ecs-optimized_windows_AMI.md)。

`ecs.cpu-architecture`  
实例的 CPU 架构。本属性的示例值为 `x86_64` 和 `arm64`。

`ecs.vpc-id`  
启动实例的 VPC。本属性的示例值为 `vpc-1234abcd`。

`ecs.subnet-id`  
实例正在使用的子网。本属性的示例值为 `subnet-1234abcd`。

**注意**  
Amazon ECS 托管实例支持以下属性子集：  
`ecs.subnet-id`
`ecs.availability-zone`
`ecs.instance-type`
`ecs.cpu-architecture`

### 可选属性
<a name="ecs-optional-attributes"></a>

Amazon ECS 可能会将以下属性添加到您的容器实例。

`ecs.awsvpc-trunk-id`  
如果此属性存在，则实例具有中继网络接口。有关更多信息，请参阅 [增加 Amazon ECS Linux 容器实例网络接口](container-instance-eni.md)。

`ecs.outpost-arn`  
如果此属性存在，则包含 Outpost 的 Amazon 资源名称（ARN）。有关更多信息，请参阅 [AWS Outposts 上的 Amazon Elastic Container Service](using-outposts.md)。

`ecs.capability.external`  
如果此属性存在，则实例将标识为外部实例。有关更多信息，请参阅 [外部实例的 Amazon ECS 集群](ecs-anywhere.md)。

### 自定义属性
<a name="ecs-custom-attributes"></a>

您可以将自定义属性应用于您的容器实例。例如，您可以定义名为 "stack"、值为 "prod" 的属性。

指定自定义属性时，必须考虑以下内容。
+ `name` 必须包含 1 到 128 个字符，名称可以包含字母（大写和小写形式）、数字、连字符、下划线、正斜杠、反斜杠或句点。
+ `value` 必须包含 1 到 128 个字符，可以包含字母（大写和小写形式）、数字、连字符、下划线、句点、符号（@）、正斜杠、反斜杠、冒号或空格。该值不能包含任何前导空格或尾随空格。

# 创建表达式，以为 Amazon ECS 任务定义容器实例
<a name="cluster-query-language"></a>

集群查询是允许您将对象分组的表达式。例如，您可以按属性（例如可用区、实例类型或自定义元数据）将容器实例分组。有关更多信息，请参阅 [Amazon ECS 容器实例属性](task-placement-constraints.md#attributes)。

在您定义了一组容器实例后，可以自定义 Amazon ECS，根据组在容器实例上放置任务。有关更多信息，请参阅[将应用程序作为 Amazon ECS 任务运行](standalone-task-create.md)和[创建 Amazon ECS 滚动更新部署](create-service-console-v2.md)。您还可以在列出容器实例时应用组筛选条件。

## 表达式语法
<a name="expression-syntax"></a>

表达式有如下语法：

```
subject operator [argument]
```

**主题**  
要评估的属性或字段。

`agentConnected`  
按 Amazon ECS 容器代理连接状态选择容器实例。您可以使用此过滤器来搜索具有已断开连接的容器代理的实例。  
有效运算符：equals (==)、not\$1equals (\$1=)、in、not\$1in (\$1in)、matches (=\$1)、not\$1matches (\$1\$1)

`agentVersion`  
按 Amazon ECS 容器代理版本选择容器实例。您可以使用此过滤器查找运行过期版本的 Amazon ECS 容器代理的实例。  
有效运算符：equals (==)、not\$1equals (\$1=)、greater\$1than (>)、greater\$1than\$1equal (>=)、less\$1than (<)、less\$1than\$1equal (<=)

`attribute:attribute-name`  
按属性选择容器实例。有关更多信息，请参阅 [Amazon ECS 容器实例属性](task-placement-constraints.md#attributes)。

`ec2InstanceId`  
按 Amazon EC2 实例 ID 选择容器实例。  
有效运算符：equals (==)、not\$1equals (\$1=)、in、not\$1in (\$1in)、matches (=\$1)、not\$1matches (\$1\$1)

`registeredAt`  
按容器实例注册日期选择容器实例。您可以使用此过滤器查找新注册的实例或已注册很久的实例。  
有效运算符：equals (==)、not\$1equals (\$1=)、greater\$1than (>)、greater\$1than\$1equal (>=)、less\$1than (<)、less\$1than\$1equal (<=)  
有效日期格式：2018-06-18T22:28:28\$100:00、2018-06-18T22:28:28Z、2018-06-18T22:28:28、2018-06-18

`runningTasksCount`  
按运行任务数选择容器实例。您可以使用此过滤器查找空或接近空的实例（在其上运行的任务很少）。  
有效运算符：equals (==)、not\$1equals (\$1=)、greater\$1than (>)、greater\$1than\$1equal (>=)、less\$1than (<)、less\$1than\$1equal (<=)

`task:group`  
按任务组选择容器实例。有关更多信息，请参阅 [与组相关的 Amazon ECS 任务](task-groups.md)。

**运算符**  
比较运算符。支持以下运算符。


|  运算符  |  说明  | 
| --- | --- | 
|  ==, equals  |  字符串相等  | 
|  \$1=, not\$1equals  |  字符串不相等  | 
|  >, greater\$1than  |  Greater than  | 
|  >=, greater\$1than\$1equal  |  大于或等于  | 
|  <, less\$1than  |  Less than  | 
|  <=, less\$1than\$1equal  |  小于或等于  | 
|  exists  |  主题存在  | 
|  \$1exists, not\$1exists  |  主题不存在  | 
|  in  |  值在参数列表中  | 
|  \$1in, not\$1in  |  值不在参数列表中  | 
|  =\$1, matches  |  模式匹配  | 
|  \$1\$1, not\$1matches  |  模式不匹配  | 

**注意**  
单个表达式不能包含圆括号。但是，可以使用圆括号来指定复合表达式中的优先顺序。

**参数**  
很多运算符的参数是一个文本值。

`in` 和 `not_in` 运算符要求参数是一个参数列表。按如下所示指定参数列表：

```
[argument1, argument2, ..., argumentN]
```

matches 和 not\$1matches 运算符要求参数符合 Java 正则表达式的语法。有关更多信息，请参阅 [java.util.regex.Pattern](http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html)。

**复合表达式**

您可以使用以下布尔值运算符组合表达式：
+ &&, 和
+ \$1\$1 或者
+ \$1, 非

您可以使用圆括号指定优先顺序：

```
(expression1 or expression2) and expression3
```

## 表达式示例
<a name="expression-examples"></a>

以下为表达式示例。

**示例：字符串相等**  
以下表达式选择具有指定实例类型的实例。

```
attribute:ecs.instance-type == t2.small
```

**示例：参数列表**  
以下表达式选择在 us-east-1a 或 us-east-1b 可用区中的实例。

```
attribute:ecs.availability-zone in [us-east-1a, us-east-1b]
```

**示例：复合表达式**  
以下表达式选择不在 us-east-1d 可用区内的 G2 实例。

```
attribute:ecs.instance-type =~ g2.* and attribute:ecs.availability-zone != us-east-1d
```

**示例：任务关联**  
以下表达式选择在 `service:production` 组中托管任务的实例。

```
task:group == service:production
```

**示例：任务反关联**  
以下表达式选择未在数据库组中托管任务的实例。

```
not(task:group == database)
```

**示例：运行任务数**  
以下表达式选择仅运行一个任务的实例。

```
runningTasksCount == 1
```

**示例：Amazon ECS 容器代理版本**  
以下表达式选择运行版本低于 1.14.5 的容器代理的实例。

```
agentVersion < 1.14.5
```

**示例：实例注册时间**  
以下表达式选择在 2018 年 2 月 13 日前注册的实例。

```
registeredAt < 2018-02-13
```

**示例：Amazon EC2 实例 ID**  
以下表达式选择具有以下 Amazon EC2 实例 ID 的实例。

```
ec2InstanceId in ['i-abcd1234', 'i-wxyx7890']
```

# Amazon ECS 任务放置约束示例
<a name="constraint-examples"></a>

下面是一些任务放置约束示例。

此示例使用 `memberOf` 约束在 t2 实例上放置任务。可以使用以下操作指定此约束：[CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html)、[UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)、[RegisterTaskDefinition](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RegisterTaskDefinition.html) 和 [RunTask](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html)。

```
"placementConstraints": [
    {
        "expression": "attribute:ecs.instance-type =~ t2.*",
        "type": "memberOf"
    }
]
```

该示例使用 `memberOf` 约束将任务放置在进程守护程序服务 `daemon-service` 任务组中具有任务的实例上，同时考虑到同时指定的任何任务放置策略。此约束可确保进程守护程序服务任务在副本服务任务之前放置在 EC2 实例上。

将 `daemon-service` 替换为进程守护程序服务的名称。

```
"placementConstraints": [
    {
        "expression": "task:group == service:daemon-service",
        "type": "memberOf"
    }
]
```

该示例使用 `memberOf` 约束将任务放置在 `databases` 任务组中具有其他任务的实例上，同时考虑到也指定的任何任务放置策略。有关任务组的更多信息，请参阅 [与组相关的 Amazon ECS 任务](task-groups.md)。可以使用以下操作指定此约束：[CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html)、[UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)、[RegisterTaskDefinition](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RegisterTaskDefinition.html) 和 [RunTask](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html)。

```
"placementConstraints": [
    {
        "expression": "task:group == databases",
        "type": "memberOf"
    }
]
```

`distinctInstance` 约束将组中的每项任务放置于不同实例上。可以使用以下操作指定此约束：[CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html)、[UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html) 和 [RunTask](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html)。

Amazon ECS 会检查所需的任务状态以放置任务。例如，假设现有任务所需的状态为 `STOPPED`（但最近的状态不是该状态），则可以将新传入的任务放入同一个实例，尽管存在 `distinctInstance` 放置约束。因此，您可能会看到同一个实例上有 2 个任务最近的状态都为 `RUNNING`。

```
"placementConstraints": [
    {
        "type": "distinctInstance"
    }
]
```

# Amazon ECS 独立任务
<a name="standalone-tasks"></a>

如果您具有执行某些工作然后再停止（例如批处理进程）的应用程序，则您可以将应用程序作为任务运行。如果您想运行一次任务，则可以使用控制台、AWS CLI、API 或 SDK。

如果您需要按基于费率、基于 cron 的计划或一次性计划运行应用程序，则可以使用 EventBridge 计划程序创建计划。

## 任务工作流程
<a name="task-workflow"></a>

当您启动 Amazon ECS 任务（独立任务或 Amazon ECS 服务执行的任务）时，会创建一项任务且最初会将其移至 `PROVISIONING` 状态。当任务处于 `PROVISIONING` 状态时，任务和容器都不存在，因为 Amazon ECS 需要找到用于放置任务的计算容量。

Amazon ECS 会根据您的启动类型或容量提供程序配置为您的任务选择合适的计算容量。您可以在 Fargate 和 EC2 中使用容量提供程序和容量提供程序策略。使用 Fargate，您不必考虑集群容量的预调配、配置和扩展。Fargate 负责您的任务的所有基础设施管理。对于 EC2，您可以通过将 Amazon EC2 实例注册到集群来管理集群容量，也可以使用集群自动扩缩来简化计算容量管理。集群自动扩缩负责动态扩展集群容量，以便您可以专注于正在运行的任务。Amazon ECS 根据您在任务定义中指定的要求（例如 CPU 和内存）以及您的放置约束和策略确定将任务放置在何处。有关更多信息，请参阅[Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。

如果您使用启用了托管式扩缩的容量提供程序，则由于缺乏计算容量而无法启动的任务将移至 `PROVISIONING` 状态，而不是立即失败。找到放置任务的容量后，Amazon ECS 会预调配必要的附件（例如，`awsvpc` 模式下任务的弹性网络接口（ENI））。它使用 Amazon ECS 容器代理提取您的容器映像，然后再启动您的容器。预调配完成且相关容器启动后，Amazon ECS 会将任务移至 `RUNNING` 状态。有关任务状态的信息，请参阅 [Amazon ECS 任务生命周期](task-lifecycle-explanation.md)。

# 将应用程序作为 Amazon ECS 任务运行
<a name="standalone-task-create"></a>

您可以使用 AWS 管理控制台 为一次性过程创建任务。

**要创建独立任务（AWS 管理控制台）**

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

1. Amazon ECS 控制台允许您通过集群详细信息页面或任务定义修订列表创建独立任务。根据您选择的资源页面，使用以下步骤来创建您的独立任务。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/standalone-task-create.html)

1. 对于**现有集群**，选择该集群。

   选择**创建集群**，以在新集群上运行该任务

1. 选择任务在集群基础设施中的分发方式。在**计算配置**下，选择您的选项。要使用容量提供程序策略，您必须在集群级别配置容量提供程序。

   如果您尚未将集群配置为使用容量提供程序，则请改用启动类型。

   如果要在 Amazon ECS 托管实例上运行工作负载，则必须使用容量提供程序策略选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/standalone-task-create.html)

1. 在**部署配置**下，执行以下操作：

   1. 对于**任务定义**，输入该任务定义。
**重要**  
控制台验证选择内容，确保所选任务定义系列和修订版与定义的计算配置兼容。

   1. 对于 **Desired tasks**（预期任务），请输入要启动的任务数量。

   1. 对于**任务组**，键入任务组名称。

1. 如果您的任务定义使用 `awsvpc` 网络模式，请展开 **Networking**（联网）。使用以下步骤指定自定义配置。

   1. 对于 **VPC**，选择要使用的 VPC。

   1. 对于 **Subnets**（子网），选择 VPC 中的一个或多个子网，任务计划程序在放置任务时会考虑这些子网。

   1. 对于**安全组**，您可以选择现有安全组或创建新安全组。要使用现有安全组，请选择该安全组并移至下一步。要创建新安全组，请选择**创建新安全组**。您必须指定安全组名称、说明，然后为该安全组添加一个或多个入站规则。

   1. 对于**公有 IP**，选择是否向任务的弹性网络接口（ENI）自动分配公有 IP 地址。

      在公有子网中运行时，可以为 AWS Fargate 任务分配一个公有 IP 地址，以便它们具有通往互联网的路由。无法使用此字段为 EC2 任务分配公有 IP。有关更多信息，请参阅 [Fargate 的 Amazon ECS 任务联网选项](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-networking.html)和[为 Amazon ECS 任务分配网络接口](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking-awsvpc.html)。

1. 如果您的任务使用的数据卷与部署时的配置兼容，则可以通过扩展**卷**来配置该卷。

   卷名称和卷类型在创建任务定义修订时配置，在运行独立任务时无法更改。要更新卷名称和类型，您必须创建新的任务定义修订并使用新修订运行任务。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/standalone-task-create.html)

1. （可选）要使用默认策略之外的其他任务放置策略，请展开 **Task Placement**（任务放置），然后从以下选项中进行选择。

    有关更多信息，请参阅 [Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。
   + **AZ 均衡分散** – 在各个可用区以及每个可用区中的各个容器实例中分配任务。
   + **AZ 均衡装填** – 在各个可用区以及具有最低可用内存的容器实例中分配任务。
   + **装填** – 根据 CPU 或内存的最低可用量来分配任务。
   + **每个主机一项任务** – 在每个容器实例中最多可放置服务的一个任务。
   + **自定义** – 定义您自己的任务放置策略。

   如果您选择了 **Custom**（自定义），请定义放置任务的算法和任务放置过程中要考虑的规则。
   + 在 **Strategy**（策略）下，对于 **Type**（类型）和 **Field**（字段），选择算法和用于该算法的实体。

     您最多可输入 5 个策略。
   + 在**约束**下，对于**类型**和**表达式**，选择要用于该约束的规则和属性。

     例如，要设置在 T2 实例上放置任务的约束，对于 **Expression**（表达式），输入 **attribute:ecs.instance-type =\$1 t2.\$1**。

     您最多可输入 10 个约束。

1. （可选）要覆盖任务定义中定义的任务 IAM 角色或任务执行角色，请展开 **Task overrides**（任务覆盖），然后完成以下步骤：

   1. 对于**任务角色**，请选择此任务的 IAM 角色。有关更多信息，请参阅 [Amazon ECS 任务 IAM 角色](task-iam-roles.md)。

      此处只显示具有 `ecs-tasks.amazonaws.com` 信任关系的角色。有关如何为任务创建 IAM 角色的说明，请参阅 [创建任务 IAM 角色](task-iam-roles.md#create_task_iam_policy_and_role)。

   1. 对于**任务执行角色**，请选择任务执行角色。有关更多信息，请参阅 [Amazon ECS 任务执行 IAM 角色](task_execution_IAM_role.md)。

1. （可选）要覆盖容器命令和环境变量，请展开 **Container Overrides**（容器覆盖），然后展开容器。
   +  要向容器发送任务定义命令以外的命令，请在**命令覆盖**中输入 Docker 命令。
   + 要添加环境变量，请选择 **Add Environment Variable**（添加环境变量）。对于 **Key**，键入您的环境变量名称。对于**值**，输入环境值的字符串值，不使用双引号（`" "`）。

     AWS 用双引号（" "）括起字符串，并按以下格式将字符串传递给容器：

     ```
     MY_ENV_VAR="This variable contains a string."
     ```

1. （可选）为了帮助识别您的任务，请展开**标签**部分，然后配置您的标签。

   要让 Amazon ECS 使用集群名称和任务定义标签自动标记全部新启动的任务，选择 **Turn on Amazon ECS managed tags**（启用 Amazon ECS 托管标签），然后选择 **Task definitions**（任务定义）。

   添加或删除标签。
   + [添加标签] 选择 **Add tag**（添加标签），然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

1. 选择**创建**。

# 使用 Amazon EventBridge 调度器计划 Amazon ECS 任务
<a name="tasks-scheduled-eventbridge-scheduler"></a>

EventBridge 调度器是一个无服务器调度器，使您能够从一个中央托管服务创建、运行和管理任务。它提供独立于事件总线和规则的一次性和重复性计划功能。EventBridge Scheduler 具有高度可定制性，与 EventBridge 计划规则相比，可扩展性更高，目标 API 操作和 AWS 服务范围更广。EventBridge Scheduler 提供以下计划，您可以在 EventBridge Scheduler 控制台中为您的任务配置这些计划：
+ 基于速率 
+ 基于 Cron

  您可以在任何时区配置基于 cron 的计划。
+ 一次性计划

  您可以在任何时区配置一次性的计划。

您可以使用 Amazon EventBridge 调度器计划 Amazon ECS。

尽管您可以在 Amazon ECS 控制台中创建计划任务，但目前 EventBridge 调度器控制台提供了更多功能。

在计划任务之前，完成以下步骤：

1. 使用 VPC 控制台，获取任务运行所在的子网 ID 和子网的安全组 ID。有关更多信息，请参阅《Amazon VPC 用户指南》**中的 [VPC 的子网](https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html)和[使用安全组控制指向 AWS 资源的流量](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html)。

1. 配置 EventBridge Scheduler 执行角色。有关更多信息，请参阅《Amazon EventBridge 调度器用户指南》**中的[设置执行角色](https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html#setting-up-execution-role)。

1. 如果要使用容量提供程序策略来运行任务，则必须拥有与集群关联的容量提供程序。

**要使用控制台创建新计划**

1. 打开 Amazon EventBridge 调度器控制台，网址为：[https://console.aws.amazon.com/scheduler/home](https://console.aws.amazon.com/scheduler/home/)。

1.  在**计划**页面，选择**创建计划**。

1.  在**指定计划详细信息**页面，在**计划名称和描述**部分中，执行以下操作：

   1. 对于**计划名称**，输入计划的名称。例如 **MyTestSchedule**。

   1. （可选）对于**描述**，输入对计划的描述。例如 **TestSchedule**。

   1. 对于**计划组**，请选择一个计划组。如果您没有计划组，选择**默认**。要创建计划组，选择**创建自己的计划**。

      您可以使用计划组将标签添加到计划组。

1. 选择计划选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tasks-scheduled-eventbridge-scheduler.html)

1. （可选）如果您在上一步中选择**定期计划**，在**时间范围**部分，请执行以下操作：

   1. 对于**时区**，请选择时区。

   1. 对于**开始日期和时间**，请输入 `YYYY/MM/DD` 格式的有效日期，然后指定 24 小时 `hh:mm` 格式的时间戳。

   1. 对于**结束日期和时间**，请输入 `YYYY/MM/DD` 格式的有效日期，然后指定 24 小时 `hh:mm` 格式的时间戳。

1. 选择**下一步**。

1. 在**选择目标**页面上，执行以下操作：

   1. 选择**所有 API**，然后在搜索框中输入 **ECS**。

   1. 选择 **Amazon ECS**。

   1. 在搜索框中输入 **RunTask**，然后选择 **RunTask**。

   1. 对于 **Cluster**，选择集群。

   1. 对于 **ECS 任务**，请选择要用于任务的任务定义。

   1. 选择任务在集群基础设施中的分发方式。展开**计算选项**，然后选择以下选项之一    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tasks-scheduled-eventbridge-scheduler.html)

   1. 对于**子网**，请输入要在其中运行任务的子网 ID。

   1. 对于**安全组**，请输入子网的安全组 ID。

   1. （可选）要使用默认策略之外的其他任务放置策略，请展开**置放约束**，然后输入约束。

       有关更多信息，请参阅 [Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。

   1. （可选）为了帮助识别您的任务，请在**标签**下配置您的标签。

      要让 Amazon ECS 使用任务定义标签自动标记全部新启动的任务，选择**启用 Amazon ECS 托管标签**。

1. 选择**下一步**。

1. 在**设置**页面上，执行以下操作：

   1. 要打开计划，在**计划状态**下，切换**启用计划**。

   1. 要为计划配置重试策略，在**重试策略和死信队列（DLQ）**下，请执行以下操作：
      + 切换**重试**。
      + 对于**事件的最长保留时间**，输入 EventBridge Scheduler 器必须保留未处理事件的最长**小时**和**分钟**数。
      + 最长时间为 24 小时。
      + 对于**最大重试次数**，输入在目标返回错误的情况下，EventBridge  调度器重试计划的最大次数。

         最大值为 185 次重试。

      配置重试策略后，如果计划未能调用其目标，EventBridge 调度器将重新运行该计划。如果已配置，则必须为计划设置最长保留时间和最大重试次数。

   1. 选择 EventBridge 调度器存储未送达事件的位置。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tasks-scheduled-eventbridge-scheduler.html)

   1. 要使用客户托管密钥加密目标输入，在**加密**下，选择**自定义加密设置（高级）**。

      如果选择此选项，请输入现有的 KMS 密钥 ARN 或选择**创建一个 AWS KMS key** 以导航到 AWS KMS 控制台。有关 EventBridge 调度器如何加密静态数据的更多信息，请参阅 *Amazon EventBridge 调度器用户指南* 中的 [静态加密](https://docs.aws.amazon.com/scheduler/latest/UserGuide/encryption-rest.html)。

   1. 对于**权限**，选择**使用现有角色**，然后选择角色。

      要让 EventBridge 调度器为您创建新的执行角色，请选择**为此计划创建新角色**。然后，在**角色名称**中输入名称。如果您选择此选项，EventBridge 调度器会将模板化目标所需的必要权限附加到该角色。

1. 选择**下一步**。

1.  在**查看并创建计划**页面上，查看计划的详细信息。在每个部分中，选择**编辑**返回到该步骤并编辑其详细信息。

1. 选择**创建计划**。

   您可以在**计划**页面上查看新的和现有的计划列表。在**状态**列下，验证新计划是否**已启用**。

## 后续步骤
<a name="eventbridge-scheduler-next-steps"></a>

您可以使用 EventBridge Scheduler 控制台或 AWS CLI 来管理计划。有关更多信息，请参阅《Amazon EventBridge 调度器用户指南》**中的[管理计划](https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule.html)。

# 停止 Amazon ECS 任务
<a name="standalone-task-stop"></a>

如果您不再需要保持独立任务的运行状态，则可以停止该任务。Amazon ECS 控制台可以轻松停止一项或多项任务。

无法重启已停止的独立实例。

如果您想停止服务，请参阅[使用控制台删除 Amazon ECS 服务](delete-service-v2.md)。

**要停止独立任务（AWS 管理控制台）**

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

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

1. 在**集群**页面上，选择要导航到集群详细信息页面的集群。

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

1. 您可以使用**筛选启动类型**列表按启动类型筛选任务。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/standalone-task-stop.html)

# Amazon ECS 服务
<a name="ecs_services"></a>

您可以使用 Amazon ECS 服务在 Amazon ECS 集群中同时运行和维护指定数量的任务定义实例。如果其中一个任务失败或停止，Amazon ECS 服务调度器会启动另一个任务定义实例来替换它。这有助于保持服务中的预期任务数。

您也可选择在负载均衡器后面运行服务。负载均衡器将在与服务关联的各个任务间分配流量。

我们建议您将服务调度器用于长时间运行的无状态服务和应用程序。服务调度器可确保遵循您指定的计划策略并在任务失败时（例如，在底层基础设施因某个原因失败的情况下）重新计划任务。例如，如果底层基础设施出现故障，服务调度器会重新安排任务。您可以使用任务放置策略和约束来自定义调度器的任务放置和终止方式。如果服务中的某个任务停止，调度器将启动一个新的任务来替代它。此过程将一直持续，直到服务根据服务使用的调度策略达到预期任务数。

在容器运行状况检查或负载均衡器目标组运行状况检查失败后，服务计划程序还会替换被确定为运行状况不佳的任务。此替换取决于 `maximumPercent` 和 `desiredCount` 服务定义参数。如果任务被标记为运行状况不佳，则服务计划程序将首先启动替换任务。然后会发生以下情况。
+ 如果替换任务的运行状况为 `HEALTHY`，则服务计划程序将停止运行不正常的任务
+ 如果替换任务的运行状况为 `UNHEALTHY`，则计划程序将停止运行状况不佳的替换任务或现有的运行状况不佳任务，以使任务总数等于 `desiredCount`。

如果 `maximumPercent` 参数限制计划程序先启动替换任务，则计划程序将一次随机停止一个运行状况不佳的任务以释放容量，然后启动替换任务。启动和停止过程将继续，直到所有运行状况不佳的任务都被运行状况正常的任务所替换。替换了所有运行状况不佳的任务并且只有运行正常的任务后，如果任务总数超过 `desiredCount`，则会随机停止运行状况正常的任务，直到任务总数等于 `desiredCount`。有关 `maximumPercent` 和 `desiredCount` 的更多信息，请参阅[服务定义参数](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html)。

服务调度器包括用来限制任务反复启动失败后重新启动的频率的逻辑。如果一个任务尚未进入 `RUNNING` 状态便停止，则服务调度程序会开始降低启动尝试的速度，并发出服务事件消息。此行为可防止在您解决问题之前将不必要的资源用于失败的任务。服务更新后，服务调度器会恢复正常调度行为。有关更多信息，请参阅[Amazon ECS 服务节流逻辑](service-throttle-logic.md)和[查看 Amazon ECS 服务事件消息](service-event-messages.md)。

## 基础设施计算选项
<a name="service-conmpute-options"></a>

有两个计算选项可分发您的任务。
+ capacity provider strategy（容量提供程序策略）会使 Amazon ECS 在一个或多个容量提供商之间分发您的任务。

  如果要在 Amazon ECS 托管实例上运行工作负载，则必须使用容量提供程序策略选项。

  对于 **capacity provider strategy**（容量提供程序策略），控制台会默认选择一个计算选项。下面介绍了控制台用于选择原定设置值的顺序：
  + 如果您的集群已定义原定设置容量提供程序策略，则将选择该策略。
  + 如果您的集群没有定义的原定设置容量提供程序策略，但您确实已将 Fargate 容量提供程序添加到集群中，则选择使用 `FARGATE` 容量提供程序的自定义容量提供程序策略。
  + 如果您的集群没有定义原定设置容量提供程序策略，但您已将一个或多个自动扩缩组容量提供程序添加到集群中，则选中**使用自定义（高级）**选项，且您需要手动定义策略。
  + 如果您的集群没有定义原定设置容量提供程序策略，并且没有向集群添加容量提供程序，则会选择 Fargate 启动类型。
+ 启动类型会让 Amazon ECS 直接在 Fargate 或注册到集群的 EC2 实例上启动我们的任务。

  如果要在 Amazon ECS 托管实例上运行工作负载，则必须使用容量提供程序策略选项。

  默认情况下，该服务会在集群 VPC 的子网中启动。

## 服务自动扩缩
<a name="service-auto-scaling-options"></a>

服务自动扩缩是指自动增加或减少 Amazon ECS 服务中所需任务数的功能。Amazon ECS 利用 Application Auto Scaling 服务来提供此功能。

有关更多信息，请参阅 [自动扩缩 Amazon ECS 服务](service-auto-scaling.md)。

## 服务负载均衡
<a name="service-load-balancing-options"></a>

托管在 AWS Fargate 上的 Amazon ECS 服务支持应用程序负载均衡器、网络负载均衡器和网关负载均衡器。请使用下表了解要使用的负载均衡器类型。


| 负载均衡器类型 | 在这些情况下使用 | 
| --- | --- | 
|  应用程序负载均衡器  | 路由 HTTP/HTTPS（或第 7 层）流量。应用程序负载均衡器提供了一些新功能，这使其非常适合用于 Amazon ECS 服务： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/ecs_services.html) | 
| 网络负载均衡器 | 路由 TCP 或 UDP（或第 4 层）流量。 | 
| Gateway Load Balancer | 路由 TCP 或 UDP（或第 4 层）流量。 使用虚拟设备，例如防火墙、入侵检测和防御系统以及深度数据包检测系统等。 | 

有关更多信息，请参阅 [使用负载均衡分配 Amazon ECS 服务流量](service-load-balancing.md)。

## 互连服务
<a name="service-connecting-options"></a>

如果需要将应用程序连接到作为 Amazon ECS 服务运行的其他应用程序，Amazon ECS 会提供以下无需负载均衡器的方法来实现此目的：
+ Service Connect：支持使用短名称和标准端口进行自动发现的服务到服务通信。
+ 服务发现：服务发现使用 Route 53 为服务创建命名空间，这样便可通过 DNS 发现该服务。
+ Amazon VPC Lattice：VPC Lattice 是一项完全托管式应用程序网络服务，用于跨多个账户和 VPC 连接、保护和监控服务。使用该服务会产生相应费用。

有关更多信息，请参阅 [互连 Amazon ECS 服务](interconnecting-services.md)。

# Amazon ECS 服务部署控制器和策略
<a name="ecs_service-options"></a>

在部署服务之前，请确定部署服务的选项以及服务所使用的功能。

## 计划策略
<a name="service-strategy"></a>

有两种服务计划程序策略可用：
+ `REPLICA`：副本计划策略在集群中放置和维护所需数量的任务。默认情况下，服务计划程序可在多个可用区之间分布任务，但您可以使用任务放置策略和约束自定义任务放置决策。有关更多信息，请参阅 [副本计划策略](#service_scheduler_replica)。
+ `DAEMON`：进程守护程序计划策略只在每个活动容器实例上部署一个任务，以满足您在集群中指定的所有任务放置约束。当使用此策略时，无需指定所需的任务数、任务放置策略，也无需使用服务自动扩缩策略。有关更多信息，请参阅 [进程守护程序计划策略](#service_scheduler_daemon)。
**注意**  
Fargate 任务不支持 `DAEMON` 计划策略。

### 副本计划策略
<a name="service_scheduler_replica"></a>

*副本* 计划策略在集群上放置并维护所需数量的任务。

对于在 Fargate 上运行任务的服务，当服务调度器启动新任务或停止运行任务时，服务调度器会尽力尝试在可用区之间保持平衡。无需指定任务放置策略或约束。

创建在 EC2 实例上运行任务的服务时，您还可选择指定任务放置策略和约束来自定义任务放置决策。如果未指定任务放置策略或约束，则默认情况下，服务调度器会在可用区之间分布任务。该调度器使用以下逻辑：
+ 确定集群中的哪些容器实例可支持服务的任务定义（例如，所需的 CPU、内存、端口和容器实例属性）。
+ 确定哪些容器实例满足为该服务定义的任何放置约束。
+ 如果您的副本服务依赖于进程守护程序服务（例如，在任务可以使用日志记录之前需要运行的进程守护程序日志路由器任务），请创建一个任务放置约束，确保进程守护程序服务任务在副本服务任务开始之前放置在 EC2 实例上。有关更多信息，请参阅 [Amazon ECS 任务放置约束示例](constraint-examples.md)。
+ 若已定义放置策略，请使用该策略，从剩余候选项中选择一个实例。
+ 如果尚未定义放置策略，请使用以下逻辑来平衡集群中各个可用区的任务：
  + 对有效容器实例进行排序。优先考虑在各自的可用区中具有此服务的最小运行任务数的实例。例如，如果 A 区有一个正在运行的服务任务，B 区和 C 区都没有正在运行的服务任务，则认为在 B 区或 C 区中的有效容器实例中最适合放置任务。
  + 基于之前的步骤，将新的服务任务放置在最佳可用区中的有效容器实例上。优先使用具有此服务的最小运行任务数的容器实例。

建议在使用 `REPLICA` 策略时使用服务重新平衡功能，这有助于确保服务的高可用性。

### 进程守护程序计划策略
<a name="service_scheduler_daemon"></a>

*进程守护程序*计划策略只在每个活动容器实例上部署一个任务，以满足集群中指定的所有任务放置约束。服务调度器会评估运行任务的任务放置约束，并停止不满足放置约束的任务。使用此策略时，无需指定预期任务数、任务放置策略，也无需使用 Service Auto Scaling 策略。

Amazon ECS 为进程守护程序任务保留容器实例计算资源，包括 CPU、内存和网络接口。当您在具有其他副本服务的集群上启动进程守护程序服务时，Amazon ECS 会优先考虑进程守护程序任务。这意味着进程守护程序任务是将在实例上首先启动的任务，也是将在所有副本任务停止后最后停止的任务。此策略确保资源不会被待处理的副本任务使用，并且可用于进程守护程序任务。

进程守护程序服务调度器不会将任何任务放置在具有 `DRAINING` 状态的实例上。如果容器实例转换为 `DRAINING` 状态，容器实例上的进程守护程序任务会停止。此服务计划程序还监视何时将新容器实例添加到您的集群，并将进程守护程序任务添加到其中。

当指定了部署配置时，则 `maximumPercent` 参数的值必须为 `100`（以百分比形式指定），如果未设置，则是使用的默认值。`minimumHealthyPercent` 参数的默认值为 `0`（以百分比形式指定）。

更改进程守护程序服务的放置约束时，您必须重新启动该服务。Amazon ECS 会动态更新预留在符合条件的实例上进程守护程序任务的资源。对于现有实例，调度器尝试将任务放在实例上。

当任务定义中的任务大小或容器资源预留变更时，会启动新部署。更新服务或设置任务定义的不同修订版时，也会开始新的部署。Amazon ECS 为进程守护程序选取更新后的 CPU 和内存预留，然后阻止该进程守护程序任务的容量。

如果没有足够的资源用于上述任一情况，则会发生以下情况：
+ 任务放置失败。
+ 将生成一个 CloudWatch 事件。
+ Amazon ECS 通过等待资源变为可用，继续尝试并计划实例上的任务。
+ Amazon ECS 释放不再符合放置约束条件的所有预留实例，并停止相应的进程守护程序任务。

进程守护程序计划策略可用于以下情况：
+ 运行应用程序容器
+ 运行用于记录、监视和跟踪任务的支持容器

使用 Fargate 或者 `CODE_DEPLOY` 或 `EXTERNAL` 部署控制器类型的任务不支持进程守护程序计划策略。

当服务计划程序停止运行任务时，它将尝试在您的集群的可用区之间保持平衡。该计划程序使用以下逻辑：
+ 如果已定义放置策略，请使用该策略来选择要终止的任务。例如，如果服务已定义可用区分布策略，则会选择一项任务终止，以让剩余任务保持最佳分布。
+ 如果尚未定义放置策略，请使用以下逻辑在集群中的可用区之间保持平衡：
  + 对有效容器实例进行排序。优先考虑在各自的可用区中具有此服务的最大运行任务数的实例。例如，如果 A 区有 1 个运行服务任务，B 区和 C 区各有 2 个运行服务任务，则 B 区或 C 区中的容器实例被认为最适合终止任务。
  + 基于之前的步骤，停止最佳可用区中容器实例上的任务。优先使用具有此服务的最大运行任务数的容器实例。

## 部署控制器
<a name="service_deployment-controllers"></a>

部署控制器是决定如何为服务部署任务的机制。有效选项为：
+ ECS

  创建使用 `ECS` 部署控制器的服务时，可在以下部署策略中进行选择：
  + `ROLLING`：创建使用*滚动更新*（`ROLLING`）部署策略的服务时，Amazon ECS 服务计划程序会将当前正在运行的任务替换为新任务。在滚动更新期间 Amazon ECS 在服务中添加或删除的任务数量由服务部署配置控制。

    滚动更新部署最适合以下场景：
    + 渐进式服务更新：需要逐步更新服务，但无需整个服务同时离线。
    + 有限的资源需求：希望避免同时运行两个完整的环境（如蓝绿部署所需）而产生的额外资源成本。
    + 可接受的部署时间：应用程序可以接收较长的部署过程，因为滚动更新会逐一替换任务。
    + 无需即时回滚：服务可以接收需要数分钟而非数秒的回滚过程。
    + 简单的部署流程：更青睐简单直接的部署方法，而无需以复杂的方式管理多个环境、目标组和侦听器。
    + 无需负载均衡器：服务不使用或不需要负载均衡器、应用程序负载均衡器、网络负载均衡器或 Service Connect（蓝绿部署所需内容）。
    + 有状态应用程序：应用程序维护状态难以运行两个并行环境。
    + 成本敏感性：希望通过在部署期间避免运行重复的环境，最大限度地降低部署成本。

    滚动更新是服务的默认部署策略，为许多常见的应用程序场景提供了安全部署与提高资源效率之间的平衡。
  + `BLUE_GREEN`：*蓝绿*部署策略（`BLUE_GREEN`）是一种发布方法，通过运行两个相同的生产环境（即蓝色和绿色）来减少停机时间并降低风险。借助 Amazon ECS 蓝绿部署，可以在将生产流量定向到新的服务修订版之前对其进行验证。此方法提供了一种更安全的部署更改方式，并且能够根据需要快速回滚。

    Amazon ECS 蓝绿部署最适合以下场景：
    + 服务验证：需要在将生产流量定向到新的服务修订版之前对其进行验证时
    + 零停机时间：服务需要实现零停机部署时
    + 即时回滚：需要在检测到问题时使用快速回滚功能时
    + 需要负载均衡器：服务使用应用程序负载均衡器、网络负载均衡器或 Service Connect 时
  + `LINEAR`：*线性*部署策略（`LINEAR`）在指定时间段内以相等百分比增量将流量从当前生产环境逐步转移到新环境。借助 Amazon ECS 线性部署，您可以控制流量转移的速度，并随着生产流量不断增加验证新的服务修订。

    Amazon ECS 线性部署最适合以下场景：
    + 逐步验证：当您希望随着流量增加而逐步验证新服务版本时
    + 性能监控：当您需要时间在部署过程中监控指标和性能时
    + 风险最小化：当您希望以增量方式将新版本暴露于生产流量来最大限度地降低风险时
    + 需要负载均衡器：服务使用应用程序负载均衡器、网络负载均衡器或 Service Connect 时
  + `CANARY`：*金丝雀*部署策略（`CANARY`）首先将一小部分流量转移到新的服务修订，然后在指定的时间段后一次性转移剩余流量。这样，您可以在全面部署之前先对一部分用户测试新版本。

    Amazon ECS 金丝雀部署最适合以下场景：
    + 功能测试：当您想要在全面推出之前对一小部分用户测试新功能时
    + 生产验证：当您需要使用真实的生产流量来验证性能和功能时
    + 影响范围控制：当您想要在新版本中发现问题的情况下最大限度地缩小影响范围时
    + 需要负载均衡器：服务使用应用程序负载均衡器、网络负载均衡器或 Service Connect 时
+ 外部

  使用第三方部署控制器。
+ 蓝绿部署（由 AWS CodeDeploy 提供支持）

  CodeDeploy 会将应用程序的更新版本作为新的替换任务集进行安装，并将生产流量从原始应用程序任务集重新路由到替换任务集。成功部署后，将会终止原始任务集。在向服务发送生产流量之前，可使用此部署控制器验证服务的新部署。

# Amazon ECS 部署失败检测
<a name="deployment-failure-detection"></a>

Amazon ECS 提供了两种部署失败检测方法：
+ 部署断路器
+ CloudWatch Alarms

这两种方法均可配置为在部署失败时自动回滚到上一个已知良好状态。

请考虑以下事项：
+ 这两种方法仅支持滚动更新部署和蓝绿部署类型。
+ 同时使用这两种方法时，任一方法均可触发部署失败检测。
+ 回滚方法要求之前的部署处于“已完成”状态。
+ 如果部署状态更改，会生成 EventBridge 事件。

# Amazon ECS 部署断路器如何检测故障
<a name="deployment-circuit-breaker"></a>

部署断路器是一种滚动更新机制，可确定任务是否达到稳定状态。部署断路器有一个选项，该选项可自动将失败的部署回滚到处于 `COMPLETED` 状态的部署。

当服务部署更改状态时，Amazon ECS 会向 EventBridge 发送服务部署状态更改事件。这提供了一种用于监控服务部署状态的编程方式。有关更多信息，请参阅 [Amazon ECS 服务部署状态更改事件](ecs_service_deployment_events.md)。建议您使用 `SERVICE_DEPLOYMENT_FAILED` 的 `eventName` 创建和监控 EventBridge 规则，以便您可以采取手动操作开始您的部署。有关更多信息，请参阅《Amazon EventBridge 用户指南》**中的 [Getting started with EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html)。

当部署断路器确定部署失败时，它会查找处于 `COMPLETED` 状态的最新部署。这是其用作回滚部署的部署。当回滚开始时，部署将从 `COMPLETED` 更改为 `IN_PROGRESS`。这意味着在达到 `COMPLETED` 状态之前，该部署不能进行其他回滚。当部署断路器找不到处于 `COMPLETED` 状态的部署时，断路器不会启动新任务，部署将停止。

创建服务时，调度器会跟踪分两个阶段启动失败的任务。
+ 第 1 阶段：调度器监控任务以查看它们是否过渡到“正在运行”状态。
  + 成功：部署有可能过渡到“已完成”状态，因为有不止一项任务已过渡到“正在运行”状态。跳过故障标准，断路器进入第 2 阶段。
  + 失败：连续有任务未过渡到“正在运行”状态，部署可能会过渡到“失败”状态。
+ 第 2 阶段：当至少有一个任务处于“正在运行”状态时，部署进入此阶段。断路器对正在评估的当前部署中的任务进行运行状况检查。经过验证的运行状况检查包括 Elastic Load Balancing、AWS Cloud Map 服务运行状况检查和容器运行状况检查。
  + 成功：至少有一个任务处于运行状态且运行状况检查已通过。
  + 失败：由于运行状况检查失败而被替换的任务已达到失败阈值。

对服务使用部署断路器方法时，请注意以下事项。EventBridge 生成规则。
+ `DescribeServices` 响应提供了对部署状态、`rolloutState` 和 `rolloutStateReason` 的深入了解。启动新部署时，部署状态将在 `IN_PROGRESS` 状态开始。当服务达到稳定状态时，部署状态将转换为`COMPLETED`。如果服务未能达到稳定状态并打开了断路器，则部署将转换为 `FAILED` 状态。`FAILED` 状态中的部署不会启动任何新任务。
+ 除了 Amazon ECS 为已启动和已完成的部署发送的服务部署状态更改事件外，Amazon ECS 还将在启用断路器的部署失败时发送事件。这些事件提供了有关部署失败的原因或部署是否由于回滚而启动的详细信息。有关更多信息，请参阅 [Amazon ECS 服务部署状态更改事件](ecs_service_deployment_events.md)。
+ 如果由于以前的部署失败并出现了回滚而启动了新部署，则服务部署状态更改事件的 `reason` 字段将指示部署是由于回滚而启动的。
+ 部署断路器仅支持使用滚动更新（`ECS`）部署控制器的 Amazon ECS 服务。
+ 您必须使用 Amazon ECS 控制台，或者在使用带有 CloudWatch 选项的部署断路器时必须使用 AWS CLI。这种方法的示例是，如果有关更多信息，请参阅**《AWS Command Line Interface 参考》中的 [使用定义的参数创建服务](create-service-console-v2.md#create-custom-service) 和 [create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html)。

以下 `create-service` AWS CLI 示例显示如何在将部署断路器和回滚选项结合使用时创建 Linux 服务。

```
aws ecs create-service \
     --service-name MyService \
     --deployment-controller type=ECS \
     --desired-count 3 \
     --deployment-configuration "deploymentCircuitBreaker={enable=true,rollback=true}" \
     --task-definition sample-fargate:1 \
     --launch-type FARGATE \
     --platform-family LINUX \
     --platform-version 1.4.0 \
     --network-configuration "awsvpcConfiguration={subnets=[subnet-12344321],securityGroups=[sg-12344321],assignPublicIp=ENABLED}"
```

示例：

部署 1 处于 `COMPLETED` 状态。

部署 2 无法启动，所以断路器会回滚到部署 1。部署 1 会过渡到 `IN_PROGRESS` 状态。

部署 3 启动，但没有处于 `COMPLETED` 状态的部署，因此部署 3 无法回滚或启动任务。

## Failure threshold
<a name="failure-threshold"></a>

部署断路器计算阈值，然后使用该值来确定何时将部署移动到 `FAILED` 状态。

部署断路器的最低阈值为 3，最大阈值为 200，并使用以下公式中的值来确定部署失败。

```
Minimum threshold <= 0.5 * desired task count => maximum threshold
```

当计算结果大于最小值 3 但小于最大值 200 时，故障阈值设置为计算的阈值（向上取整）。

**注意**  
您不能更改任何一个阈值。

部署状态检查分两个阶段。

1. 部署断路器监控部署中的任务并检查处于 `RUNNING` 状态的任务。调度器在当前部署中的任务位于 `RUNNING` 状态并进入下一阶段时忽略失败条件。当任务无法到达 `RUNNING` 状态时，部署断路器将失败计数增加 1。当故障计数等于阈值时，部署将标记为 `FAILED`。

1. 当有一个或多个任务处于 `RUNNING` 状态时，进入此阶段。部署断路器对当前部署中的任务的以下资源执行运行状况检查：
   + Elastic Load Balancing 负载均衡器
   + AWS Cloud Map 服务
   + Amazon ECS 容器运行状况检查

   当任务的运行状况检查失败时，部署断路器会将失败计数增加 1。当故障计数等于阈值时，部署将标记为 `FAILED`。

下表提供了一些示例。


| 预期任务计数 | 计算 | Threshold | 
| --- | --- | --- | 
|  1  |  <pre>3 <= 0.5 * 1 => 200</pre>  | 3（计算值低于最低值） | 
|  25  |  <pre>3 <= 0.5 * 25 => 200</pre>  | 13（此值将向上舍入） | 
|  400  |  <pre>3 <= 0.5 * 400 => 200</pre>  | 200 | 
|  800  |  <pre>3 <= 0.5 * 800 => 200</pre>  | 200（计算值大于最高值） | 

例如，当阈值为 3 时，断路器在故障计数设置为 0 的情况下启动。当任务无法到达 `RUNNING` 状态时，部署断路器将失败计数增加 1。当故障计数等于 3 时，部署将标记为 `FAILED`。

有关如何使用回滚选项的其他示例，请参阅 [Announcing Amazon ECS deployment circuit breaker](https://aws.amazon.com/blogs/containers/announcing-amazon-ecs-deployment-circuit-breaker/)（宣布推出 Amazon ECS 部署断路器）。

# CloudWatch 警报如何检测 Amazon ECS 部署故障
<a name="deployment-alarm-failure"></a>

您可以配置 Amazon ECS 以在检测到指定的 CloudWatch 警报已进入 `ALARM` 状态时，将部署设置为失败。

您可以选择设置配置，将失败的部署回滚到上一个完成的部署。

以下 `create-service` AWS CLI 示例显示如何在将部署警报和回滚选项结合使用时创建 Linux 服务。

```
aws ecs create-service \
     --service-name MyService \
     --deployment-controller type=ECS \
     --desired-count 3 \
     --deployment-configuration "alarms={alarmNames=[alarm1Name,alarm2Name],enable=true,rollback=true}" \
     --task-definition sample-fargate:1 \
     --launch-type FARGATE \
     --platform-family LINUX \
     --platform-version 1.4.0 \
     --network-configuration "awsvpcConfiguration={subnets=[subnet-12344321],securityGroups=[sg-12344321],assignPublicIp=ENABLED}"
```

对服务使用 Amazon CloudWatch 警报方法时，请注意以下事项。
+ 生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。Amazon ECS 根据与部署关联的警报配置计算此时间段。您不能设置该值。
+ `deploymentConfiguration` 请求参数现在包含 `alarms` 数据类型。您可以指定警报名称、是否使用该方法以及在警报显示部署故障时是否启动回滚。有关更多信息，请参阅**《Amazon Elastic Container Service API 参考》中的 [CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html)。
+ `DescribeServices` 响应提供了对部署状态、`rolloutState` 和 `rolloutStateReason` 的深入了解。启动新部署时，回滚状态将在 `IN_PROGRESS` 状态开始。当服务达到稳定状态时，烘焙时间完成，回滚状态将转换为 `COMPLETED`。如果服务未能达到稳定状态并且警报已进入 `ALARM` 状态，则部署将转换为 `FAILED` 状态。`FAILED` 状态中的部署不会启动任何新任务。
+ 除了 Amazon ECS 为已启动和已完成的部署发送的服务部署状态更改事件外，Amazon ECS 还将在使用警报的部署失败时发送事件。这些事件提供了有关部署失败的原因或部署是否由于回滚而启动的详细信息。有关更多信息，请参阅 [Amazon ECS 服务部署状态更改事件](ecs_service_deployment_events.md)。
+ 如果由于以前的部署失败并打开了回滚而启动了新部署，则服务部署状态更改事件的 `reason` 字段将指示部署是由于回滚而启动的。
+ 如果您使用部署断路器和 Amazon CloudWatch 警报来检测故障，则两种方法中的任意一个都可以在满足任一方法的条件后立即启动部署失败。当您对启动部署故障的方法使用回滚选项时，会发生回滚。
+ Amazon CloudWatch 警报仅支持使用滚动更新（`ECS`）部署控制器的 Amazon ECS 服务。
+ 您可以使用新 Amazon ECS 控制台或 AWS CLI 来配置此选项。这种方法的示例是，如果有关更多信息，请参阅**《AWS Command Line Interface 参考》中的 [使用定义的参数创建服务](create-service-console-v2.md#create-custom-service) 和 [create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html)。
+ 您可能会注意到，部署状态会长时间处于 `IN_PROGRESS`。其原因是，只有在删除活动部署后 Amazon ECS 才会更改状态，而这种情况要等到烘焙时间之后才会发生。根据您的警报配置，部署所需的时间可能比在不使用警报时长几分钟（即使新的主要任务集已纵向扩展而旧的部署已缩减）。如果您使用 CloudFormation 超时，请考虑延长超时。有关更多信息，请参阅**《AWS CloudFormation 用户指南》中的[在模板中创建等待条件](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-waitcondition.html)。
+ Amazon ECS 调用 `DescribeAlarms` 轮询警报。对 `DescribeAlarms` 调用计入与您的账户相关的 CloudWatch 服务配额。如果您有调用 `DescribeAlarms` 的其他 AWS 服务，则对 Amazon ECS 的轮询警报可能有影响。例如，如果其他服务进行足够 `DescribeAlarms` 调用以达到配额，则该服务会受到限制，Amazon ECS 也会受到限制，无法轮询警报。如果在节流期内生成警报，Amazon ECS 可能会错过警报，也可能不会发生回滚。对部署没有其他影响。有关更多信息，请参阅**《CloudWatch 用户指南》中的 [CloudWatch 服务配额](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.htm)。
+ 如果警报在部署开始时处于 `ALARM` 状态，则 Amazon ECS 在该部署期间不会监控警报（Amazon ECS 将忽略警报配置）。此行为解决了您想要启动新部署来修复初始部署失败的问题。

## 建议的警报
<a name="ecs-deployment-alarms"></a>

我们建议您使用以下警报指标：
+ 如果您使用应用程序负载均衡器，请使用 `HTTPCode_ELB_5XX_Count` 和 `HTTPCode_ELB_4XX_Count` 应用程序负载均衡器指标。这些指标检查 HTTP 峰值。有关更多信息，请参阅**《应用程序负载均衡器用户指南》中的[应用程序负载均衡器的 CloudWatch 指标](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html)。
+ 如果您有现有的应用程序，请使用 `CPUUtilization` 和 `MemoryUtilization` 指标。这些指标检查集群或服务使用的 CPU 和内存百分比。有关更多信息，请参阅 [注意事项](cloudwatch-metrics.md#enable_cloudwatch)。
+ 如果您在任务中使用 Amazon Simple Queue Service 队列，请使用 `ApproximateNumberOfMessagesNotVisible` Amazon SQS 指标。该指标检查队列中延迟且无法立即读取的消息数量。有关更多信息，请参阅**《Amazon Simple Queue Service 开发人员指南》中的 [Amazon SQS 的可用 CloudWatch 指标](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html)。

## 烘焙时间
<a name="deployment-bake-time"></a>

当您对服务部署使用回滚选项时，Amazon ECS 会在目标服务修订部署完成后额外等待一段时间，然后再发送 CloudWatch 警报。这称为烘焙时间。此时间开始于：
+ 目标服务修订的所有任务都在运行且状态良好
+ 源服务修订缩减至 0%

默认烘焙时间少于 5 分钟。烘焙时间到期后，服务部署标记为已完成。

您可以配置滚动部署的烘焙时间。当您使用 CloudWatch 警报检测故障时，如果您更改了烘焙时间，然后决定使用 Amazon ECS 默认设置，则必须手动设置烘焙时间。

# 适用于 Amazon ECS 服务部署的生命周期挂钩
<a name="deployment-lifecycle-hooks"></a>

部署启动后，会经历一系列生命周期阶段。这些阶段可能处于“IN\$1PROGRESS”或已成功等状态。您可以使用生命周期挂钩，这是 Amazon ECS 在指定的生命周期阶段代表您运行的 Lambda 函数。这些函数可以是以下任一项：
+ 异步 API，可在 15 分钟内验证运行状况检查。
+ 轮询 API，可启动另一个异步进程，用于评估生命周期挂钩的完成情况。

函数运行结束后，必须返回 `hookStatus` 才能继续部署。如果未返回 `hookStatus`，或者函数失败，部署将回滚。以下是 `hookStatus` 的值：
+ `SUCCEEDED`：部署将持续到下一个生命周期阶段
+ `FAILED`：部署将回滚到上次成功部署。
+ `IN_PROGRESS`：Amazon ECS 将在短时间内再次运行该函数。默认情况下，时间间隔为 30 秒，但是可以通过在返回 `hookStatus` 的同时一并返回的 `callBackDelay` 来自定义该值。

以下示例演示了如何返回带有自定义回调延迟的 `hookStatus`。在此示例中，Amazon ECS 将在 60 秒（不是默认的 30 秒）后重试此挂钩：

```
{
    "hookStatus": "IN_PROGRESS",
    "callBackDelay": 60
}
```

发生回滚时，Amazon ECS 会为以下生命周期阶段运行生命周期挂钩：
+ PRODUCTION\$1TRAFFIC\$1SHIFT
+ TEST\$1TRAFFIC\$1SHIFT

## 生命周期有效载荷
<a name="service-deployment-lifecycle-payloads"></a>

 为 ECS 服务部署配置生命周期挂钩时，Amazon ECS 会在部署过程的特定阶段调用这些挂钩。每个生命周期阶段都会提供包含当前部署状态相关信息的 JSON 有效载荷。本文档描述了每个生命周期阶段的有效载荷结构。

### 常用有效载荷结构
<a name="common-payload-structure"></a>

 所有生命周期阶段的有效载荷均包含以下常用字段：
+  `serviceArn`：服务的 Amazon 资源名称（ARN）。
+  `targetServiceRevisionArn`：正在部署的目标服务修订版的 ARN。
+  `testTrafficWeights`：服务修订版 ARN 到与其对应的测试流量权重百分比的映射。
+  `productionTrafficWeights`：服务修订版 ARN 到与其对应的生产流量权重百分比的映射。

### 生命周期阶段有效载荷
<a name="lifecycle-stage-payloads"></a>

#### RECONCILE\$1SERVICE
<a name="reconcile-service"></a>

 此阶段发生在部署过程开始时，此时正在对服务进行协调。下面显示了此生命周期阶段的有效载荷示例。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892": 100,
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/78652123": 0
  },
  "productionTrafficWeights": {
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892": 100,
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/78652123": 0
  }
}
```

 **此阶段的预期情况：**
+ 主任务集的比例为 0%

#### PRE\$1SCALE\$1UP
<a name="pre-scale-up"></a>

 此阶段发生在新任务纵向扩展之前。下面显示了此生命周期阶段的有效载荷示例。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {},
  "productionTrafficWeights": {}
}
```

 **此阶段的预期情况：**
+ 绿色服务修订版任务的比例为 0%

#### POST\$1SCALE\$1UP
<a name="post-scale-up"></a>

 此阶段发生在新任务完成纵向扩展且正常运行之后。下面显示了此生命周期阶段的有效载荷示例。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {},
  "productionTrafficWeights": {}
}
```

 **此阶段的预期情况：**
+ 绿色服务修订版任务的比例为 100%
+ 绿色服务修订版中的任务运行正常

#### TEST\$1TRAFFIC\$1SHIFT
<a name="test-traffic-shift"></a>

 此阶段发生在测试流量转移到绿色服务修订任务之后。

下面显示了此生命周期阶段的有效载荷示例。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892": 100,
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/78652123": 0
  },
  "productionTrafficWeights": {}
}
```

 **此阶段的预期情况：**
+ 测试流量正在向绿色服务修订任务转移。

#### POST\$1TEST\$1TRAFFIC\$1SHIFT
<a name="post-test-traffic-shift"></a>

 此阶段发生在测试流量完全转移到新任务之后。

下面显示了此生命周期阶段的有效载荷示例。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {},
  "productionTrafficWeights": {}
}
```

 **此阶段的预期情况：**
+ 100% 的测试流量已向绿色服务修订任务转移。

#### PRODUCTION\$1TRAFFIC\$1SHIFT
<a name="production-traffic-shift"></a>

 此阶段发生在生产流量转移到绿色服务修订任务之后。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {},
  "productionTrafficWeights": {
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892": 100,
    "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/78652123": 0
  }
}
```

 **此阶段的预期情况：**
+ 生产流量正在向绿色服务修订任务转移。

#### POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT
<a name="post-production-traffic-shift"></a>

 此阶段发生在生产流量完全转移到绿色服务修订任务之后。

```
{
  "serviceArn": "arn:aws:ecs:us-west-2:1234567890:service/myCluster/myService",
  "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:1234567890:service-revision/myCluster/myService/01275892",
  "testTrafficWeights": {},
  "productionTrafficWeights": {}
}
```

 **此阶段的预期情况：**
+ 100% 的生产流量已向绿色服务修订任务转移。

### 生命周期阶段类别
<a name="lifecycle-stage-categories"></a>

 生命周期阶段分为两类：

1.  **单次调用阶段**：这些阶段在服务部署期间仅调用一次：
   + PRE\$1SCALE\$1UP
   + POST\$1SCALE\$1UP
   + POST\$1TEST\$1TRAFFIC\$1SHIFT
   + POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT

1.  **重复调用阶段**：这些阶段在服务部署期间可能会被多次调用，例如发生回滚操作时：
   + TEST\$1TRAFFIC\$1SHIFT
   + PRODUCTION\$1TRAFFIC\$1SHIFT

### 生命周期挂钩运行期间的部署状态
<a name="deployment-status-during-lifecycle-hooks"></a>

 生命周期挂钩运行时，所有生命周期阶段的部署状态都将为 `IN_PROGRESS`。


| 生命周期阶段 | 部署状态 | 
| --- | --- | 
| RECONCILE\$1SERVICE | 进行中 | 
| PRE\$1SCALE\$1UP | 进行中 | 
| POST\$1SCALE\$1UP | 进行中 | 
| TEST\$1TRAFFIC\$1SHIFT | 进行中 | 
| POST\$1TEST\$1TRAFFIC\$1SHIFT | 进行中 | 
| PRODUCTION\$1TRAFFIC\$1SHIFT | 进行中 | 
| POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT | 进行中 | 

# 停止 Amazon ECS 服务部署
<a name="stop-service-deployment"></a>

当断路器或 CloudWatch 警报未检测到失败的部署时，您可以手动停止部署。下面的停止类型可供使用：
+ 回滚：此选项将服务部署回滚到上一个服务修订。

  即使没有为回滚选项配置服务部署，您也可以使用此选项。

您可以停止处于以下任意状态的部署。有关服务部署状态的更多信息，请参阅[使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。
+ PENDING：服务部署变为 ROLLBACK\$1REQUESTED 状态，然后开始回滚操作。
+ IN\$1PROGRESS：服务部署变为 ROLLBACK\$1REQUESTED 状态，然后开始回滚操作。
+ STOP\$1REQUESTED：服务部署继续停止。
+ ROLLBACK\$1REQUESTED：服务部署继续执行回滚操作。
+ ROLLBACK\$1IN\$1PROGRESS：服务部署继续执行回滚操作。

## 过程
<a name="stop-service-deployment-procedure"></a>

开始操作之前，请配置查看服务部署所需的权限。有关更多信息，请参阅 [查看 Amazon ECS 服务部署所需的权限](service-deployment-permissions.md)。

------
#### [ Amazon ECS Console ]

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时将显示服务详细信息页面。

1. 在服务详细信息页面上，选择**部署**。

   此时将显示部署页面。

1. 在**正在进行的部署**下，选择**回滚**。然后，在确认窗口中，选择**回滚**。

------
#### [ AWS CLI ]

1. 运行 `list-service-deployments` 以检索服务部署 ARN。

   将 *user-input* 替换为您的值。

   ```
   aws ecs list-service-deployments --cluster cluster-name --service service-name
   ```

   请注意要停止的部署的 `serviceDeploymentArn`。

   ```
   {
       "serviceDeployments": [
           {
               "serviceDeploymentArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/cluster-name/service-name/NCWGC2ZR-taawPAYrIaU5",
               "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/cluster-name/service-name",
               "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/cluster-name",
               "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/cluster-name/service-name/4980306466373577095",
               "status": "SUCCESSFUL"
           }
       ]
   }
   ```

1. 运行 `stop-service-deployments`。使用从 `serviceDeploymentArn` 中返回的 `list-service-deployments`。

   将 *user-input* 替换为您的值。

   ```
   aws ecs stop-service-deployment --service-deployment-arn arn:aws:ecs:region:123456789012:service-deployment/cluster-name/service-name/NCWGC2ZR-taawPAYrIaU5 --stop-type ROLLBACK
   ```

------

## 后续步骤
<a name="stop-service-deployment-next-step"></a>

决定需要对服务进行哪些更改，然后更新服务。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。

# 通过替换任务来部署 Amazon ECS 服务
<a name="deployment-type-ecs"></a>

当创建一项使用*滚动更新*（`ECS`）部署类型的服务时，Amazon ECS 服务调度器会将当前正在运行的任务替换为新任务。在滚动更新期间 Amazon ECS 在服务中添加或删除的任务数量由服务部署配置控制。

Amazon ECS 使用以下参数来确定任务数量：
+ `minimumHealthyPercent` 表示在滚动部署期间或容器实例耗尽时应为服务运行且状态良好的任务数下限，以服务所需的任务数的百分比表示。此值向上取整。例如，如果最小运行状况百分比为 `50`，并且所需的任务计数为 4，则调度器可以在启动两个新任务之前停止两个现有任务。同样，如果最小运行状况百分比为 75%，所需任务计数为 2，则由于结果值也为 2，调度器无法停止任何任务。
+ `maximumPercent` 表示在滚动部署期间或容器实例耗尽时应为服务运行的任务数上限，以服务所需的任务数的百分比表示。此值向下取整。例如，如果最大百分比为 `200` 且目标任务计数为 4，则调度器可以在停止四个现有任务之前启动四个新任务。同样，如果最大百分比为 `125`，且目标任务计数为三，则调度器无法启动任何任务，因为结果值也是三。

在滚动部署期间，当任务运行状况不佳时，Amazon ECS 会替换它们，以维护您的服务的 `minimumHealthyPercent` 并保护可用性。运行状况不佳的任务将使用它们所属的同一服务修订进行替换。这样可以确保源修订中运行状况不佳的任务替换与目标修订中的任务失败无关。如果 `maximumPercent` 设置允许，则计划程序会先启动替换任务，然后再停止运行状况不佳的任务。如果 `maximumPercent` 参数限制计划程序先启动替换任务，则计划程序会一次停止一个运行状况不佳的任务以释放容量，然后再启动替换任务。

**重要**  
设置最小运行状况百分比或最大百分比时，应确保调度器在启动部署时可以停止或启动至少一个任务。如果您的服务由于部署配置无效而停滞的部署，将发送服务事件消息。有关更多信息，请参阅 [因为服务部署配置，服务（*service-name*）无法在部署期间停止或启动任务。更新 minimumHealthyPercent 或 maximumPercent 值，然后重试。](service-event-messages-list.md#service-event-messages-7)。

滚动部署有 2 种方法可以让您快速识别服务部署失败的时间：
+ [Amazon ECS 部署断路器如何检测故障](deployment-circuit-breaker.md)
+ [CloudWatch 警报如何检测 Amazon ECS 部署故障](deployment-alarm-failure.md)

可以单独使用这些方法，也可以一起使用。当同时使用这两种方法时，只要满足任一故障方法的故障标准，部署就会设置为失败。

使用以下准则来帮助确定要使用哪种方法：
+ 断路器 — 若要在任务无法启动时停止部署，请使用此方法。
+ CloudWatch 警报 — 若要根据应用程序指标停止部署，请使用此方法。

两种方法都支持回滚到之前的服务修订版本。

## 容器映像解析
<a name="deployment-container-image-stability"></a>

默认情况下，Amazon ECS 会将任务定义中指定的容器映像标签解析为容器映像摘要。如果您创建的服务要运行和维护单个任务，则该任务将用于为任务中的容器建立映像摘要。如果您创建的服务要运行和维护多个任务，则服务调度器在部署期间启动的第一个任务将用于为任务中的容器建立映像摘要。

如果尝试建立容器映像摘要时失败三次或以上，则部署将继续，但不再进行映像摘要解析。如果启用了部署断路器，则部署还会失败并回滚。

建立容器映像摘要后，Amazon ECS 将使用摘要来启动任何其他所需的任务，以及用于任何未来的服务更新。这会导致服务中的所有任务始终运行相同的容器映像，从而确保软件的版本一致性。

您可以使用容器定义中的 `versionConsistency` 参数为任务中的每个容器配置此行为。有关更多信息，请参阅 [versionConsistency](task_definition_parameters.md#ContainerDefinition-versionconsistency)。

**注意**  
低于 `1.31.0` 版本的 Amazon ECS 代理不支持映像摘要解析。代理版本：`1.31.0``1.69.0`仅支持对推送到 Amazon ECR 存储库的映像进行映像摘要解析。代理版本 `1.70.0` 或更高版本支持所有映像的映像摘要解析。
映像摘要解析的最低 Fargate Linux 平台版本为 `1.3.0`。映像摘要解析的最低 Fargate Windows 平台版本为 `1.0.0`。
Amazon ECS 不会捕获由 Amazon ECS 管理的附加容器摘要，例如 Amazon GuardDuty 安全代理或 Service Connect 代理。
要减少具有多个任务的服务中的与容器映像解析相关的可能延迟，请在 EC2 容器实例上运行 Amazon ECS 代理版本 `1.83.0` 或更高版本。要避免可能的延迟，请在任务定义中指定容器映像摘要。
如果您创建的服务所需任务数为零，则 Amazon ECS 将无法建立容器摘要，直到您触发另一个所需任务数大于零的服务部署。
若要建立更新的映像摘要，可以强制进行新的部署。此更新后的摘要将用于启动新任务，不会影响已在运行的任务。有关强制新部署的更多信息，请参阅 *Amazon ECS API 参考*中的 [forceNewDeployment](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html#ECS-UpdateService-request-forceNewDeployment)。
使用 EC2 容量提供程序时，如果在初始部署期间容量不足以启动任务，则软件版本一致性可能会无法保证。为确保即使在容量有限的情况下也能保持版本一致性，请在任务定义容器配置中明确设置 `versionConsistency: "enabled"`，而不是依赖默认行为。这将导致 Amazon ECS 等到容量可用后再继续部署。

# Amazon ECS 服务参数的最佳实践
<a name="service-options"></a>

为确保应用程序不会停机，按照如下部署过程操作：

1. 启动新的应用程序容器，同时保持现有容器运行。

1. 检查新容器是否正常运行。

1. 停止旧容器。

 根据您的部署配置和集群中空闲的未预留空间量，可能需要多轮操作完成此操作，才能将所有旧任务替换为新任务。

您可以使用两个服务配置选项修改数字：
+ `minimumHealthyPercent`：100%（默认值）

  服务在部署期间必须保持在 `RUNNING` 状态的任务数下限。其表示为向上取整到最近整数的 `desiredCount` 的百分比。此参数使您不必使用额外的集群容量就能部署。
+ `maximumPercent`：200%（默认值）

   服务在部署期间允许处于 `RUNNING` 或 `PENDING` 状态的任务数上限。其表示为向下取整到最近整数的 `desiredCount` 的百分比。

**示例：默认配置选项**

考虑以下服务：它有六个任务，部署在一个拥有总共可容纳八个任务的空间的集群中。默认的服务配置选项不允许部署下降到低于六个所需任务的 100%。

部署过程如下：

1. 目标是替换这六个任务。

1. 计划程序会启动两个新任务，因为默认设置要求有六个正在运行的任务。

   现在有六个现有任务和两个新任务。

1. 计划程序停止两个现有任务。

   现在有四个现有任务和两个新任务。

1. 计划程序启动另外两个新任务。

   现在有四项现有任务和四项新任务。

1. 计划程序关闭两个现有任务。

   现在有两个现有任务和四个新任务。

1. 计划程序启动另外两个新任务。

   现在有两个现有任务和六个新任务

1. 计划程序关闭最后两个现有任务。

   现在有六个新任务。

在上面的示例中，如果您使用选项的默认值，则每启动一个新任务都有 2.5 分钟的等待时间。此外，负载均衡器可能需要等待 5 分钟才能停止旧任务。

**示例：修改 `minimumHealthyPercent`**

您可以通过将 `minimumHealthyPercent` 值设置为 50% 来加快部署速度。

考虑以下服务：它有六个任务，部署在一个拥有总共可容纳八个任务的空间的集群中。部署过程如下：

1. 目标是替换这六个任务。

1. 计划程序停止三个现有任务。

   仍然有三个符合 `minimumHealthyPercent` 值的现有任务在运行。

1. 计划程序启动五个新任务。

   现在有三个现有任务和五个新任务。

1. 计划程序停止剩余的三个任务。

   现在有五个新任务

1. 计划程序启动最后一个新任务。

   现在有六个新任务。

**示例：修改集群可用空间**

您还可以添加额外的可用空间，以便可以运行额外的任务。

考虑以下服务：它有六个任务，部署在一个拥有总共可容纳十个任务的空间的集群中。部署过程如下：

1. 目标是替换现有任务。

1. 计划程序停止三个现有任务。

   现在有三个现有任务。

1. 计划程序启动六个新任务。

   有三个现有任务和六个新任务

1. 计划程序停止三个现有任务。

   现在有六个新任务。

**建议**

当您的任务闲置一段时间并且利用率不高时，请使用以下值作为服务配置选项。
+ `minimumHealthyPercent`：50%
+ `maximumPercent`：200% 

# 创建 Amazon ECS 滚动更新部署
<a name="create-service-console-v2"></a>

创建一个服务以在集群中同时运行并维护指定数量的任务定义实例。如果其中一个任务失败或停止，Amazon ECS 服务调度器会启动另一个任务定义实例来替换它。这有助于保持服务中的预期任务数。

在创建服务之前，请确定以下配置参数：
+ 有两个计算选项可分发您的任务。
  + **capacity provider strategy**（容量提供程序策略）会使 Amazon ECS 在一个或多个容量提供商之间分发您的任务。

    如果要在 Amazon ECS 托管实例上运行工作负载，则必须使用容量提供程序策略选项。
  + **启动类型**会让 Amazon ECS 直接在 Fargate 或注册到集群的 EC2 实例上启动我们的任务。

    如果要在 Amazon ECS 托管实例上运行工作负载，则必须使用容量提供程序策略选项。
+ 任务定义使用 `awsvpc` 网络模式或配置为使用负载均衡器的服务必须具有网络配置。预设情况下，控制台会选择原定设置 Amazon VPC 以及原定设置 Amazon VPC 中的所有子网和原定设置安全组。
+ 放置策略。默认的任务放置策略会在可用区之间平均分配任务。

  我们建议您使用可用区重新平衡来帮助确保服务的高可用性。有关更多信息，请参阅 [在可用区之间平衡 Amazon ECS 服务](service-rebalancing.md)。
+ 当您为服务部署使用 **Launch Type**（启动类型）时，默认情况下，该服务会在集群 VPC 的子网中启动。
+ 对于 **capacity provider strategy**（容量提供程序策略），控制台会默认选择一个计算选项。下面介绍了控制台用于选择原定设置值的顺序：
  + 如果您的集群已定义原定设置容量提供程序策略，则将选择该策略。
  + 如果您的集群没有定义的原定设置容量提供程序策略，但您确实已将 Fargate 容量提供程序添加到集群中，则选择使用 `FARGATE` 容量提供程序的自定义容量提供程序策略。
  + 如果您的集群没有定义原定设置容量提供程序策略，但您已将一个或多个自动扩缩组容量提供程序添加到集群中，则选中**使用自定义（高级）**选项，且您需要手动定义策略。
  + 如果您的集群没有定义原定设置容量提供程序策略，并且没有向集群添加容量提供程序，则会选择 Fargate 启动类型。
+ 默认的部署故障检测默认选项是使用 **Amazon ECS 部署断路器**选项和**故障时回滚**选项。

  有关更多信息，请参阅 [Amazon ECS 部署断路器如何检测故障](deployment-circuit-breaker.md)。
+ 决定是否希望 Amazon ECS 自动增加或减少服务中所需的任务数。有关信息，请参阅[自动扩缩 Amazon ECS 服务](service-auto-scaling.md)。
+ 如果您需要一个应用程序来连接到在 Amazon ECS 中运行的其他应用程序，则请确定适合您的架构的选项。有关更多信息，请参阅 [互连 Amazon ECS 服务](interconnecting-services.md)。
+ 当您创建使用 Amazon ECS 断路器的服务时，Amazon ECS 会创建服务部署和服务修订。这些资源允许您查看有关服务历史记录的详细信息。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。

  有关如何使用 AWS CLI 创建服务的信息，请参阅《AWS Command Line Interface 参考》**中的 [https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html)。

  有关如何使用 AWS CloudFormation 创建服务的信息，请参阅《AWS CloudFormation 用户指南》**中的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html)。

## 使用默认选项创建服务
<a name="create-default-service"></a>

您可以使用控制台快速创建和部署服务。服务具有以下配置：
+ 在与您的集群关联的 VPC 和子网中部署
+ 部署一项任务
+ 使用滚动部署
+ 将容量提供程序策略与您的默认容量提供程序一起使用
+ 使用部署断路器检测故障，并将选项设置为在出现故障时自动回滚部署

要使用默认参数部署服务，请执行以下步骤。

**创建服务（Amazon ECS 控制台）**

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

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

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

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

   此时会显示**创建服务**页面。

1. 在**服务详细信息**下，执行以下操作：

   1. 对于**任务定义**，输入要使用的任务定义系列和修订版次。

   1. 对于 **Service name**（服务名称），为您的服务输入一个名称。

1. 要使用 ECS Exec 调试服务，请在**问题排查配置**下，选择**开启 ECS Exec**。

1. 在**部署配置**下，执行以下操作：

   1. 对于 **Desired tasks**（预期任务），输入要在服务中启动并保留的任务数量。

1. （可选）为了帮助确定您的服务和任务，请展开**标签**部分，然后配置您的标签。

   要让 Amazon ECS 使用集群名称和任务定义标签自动标记全部新启动的任务，选择 **Turn on Amazon ECS managed tags**（启用 Amazon ECS 托管标签），然后选择 **Task definitions**（任务定义）。

   要让 Amazon ECS 使用集群名称和服务标签自动标记全部新启动的任务，选择 **Turn on Amazon ECS managed tags**（启用 Amazon ECS 托管标签），然后选择 **Service**（服务）。

   添加或删除标签。
   + [添加标签] 选择 **Add tag**（添加标签），然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

## 使用定义的参数创建服务
<a name="create-custom-service"></a>

要使用定义的参数创建服务，请执行以下步骤。

**创建服务（Amazon ECS 控制台）**

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

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

   此时会显示**创建服务**页面。

1. 在服务详细信息下，执行以下操作：

   1. 对于**任务定义**，输入要使用的任务定义。然后对于**修订版次**，选择要使用的修订版次。

   1. 对于 **Service name**（服务名称），为您的服务输入一个名称。

1. 对于**现有集群**，选择该集群。

   选择**创建集群**，以在新集群上运行该任务

1. 选择任务在集群基础设施中的分发方式。在**计算配置**下，选择您的选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/create-service-console-v2.html)

1. 要使用 ECS Exec 调试服务，请在**问题排查配置**下，选择**开启 ECS Exec**。

1. 在**部署配置**下，执行以下操作：

   1. 对于 **Service type**（服务类型），选择服务计划策略。
      + 要让计划程序只在每个活动容器实例上部署一个任务，以满足所有任务放置约束，请选择**进程守护程序**。
      + 要让计划程序在集群上放置并维护所需数量的任务，选择 **Replica**（副本）。

   1. 如果您对于 **Desired tasks**（预期任务）使用 **Replica**（副本），输入要在服务中启动并保留的任务数量。

   1. 如果您选择**副本**，要让 Amazon ECS 监控在可用区之间的任务分配情况，并在出现不平衡时重新分配任务，请在**可用区服务重新平衡**下选择**可用区服务重新平衡**。

   1. 对于**运行状况检查宽限期**，输入在任务首次启动后，服务调度程序将忽略运行不正常的弹性负载均衡、VPC Lattice 和容器运行状况检查的时间长度（以秒为单位）。如果没有指定运行状况检查宽限期值，则使用默认值 0。

   1. 确定服务的部署类型。展开**部署选项**，然后指定以下参数。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/create-service-console-v2.html)

   1. 要配置 Amazon ECS 如何检测和处理部署故障，请展开 **Deployment failure detection**（部署故障检测），然后选择您的选项。

      1. 要在任务无法启动时停止部署，请选择 **Use the Amazon ECS deployment circuit breaker**（使用 Amazon ECS 部署断路器）。

         要让软件在部署断路器将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

      1. 要根据应用程序指标停止部署，请选择**使用 CloudWatch 警报**。然后，从 **CloudWatch 警报名称**中选择警报。要创建新报警，请转到 CloudWatch 控制台。

         要让软件在 CloudWatch 警报将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

1. 如果任务定义使用 `awsvpc` 网络模式，则可以指定自定义网络配置。请展开**联网**，然后执行以下操作：

   1. 对于 **VPC**，选择要使用的 VPC。

   1. 对于 **Subnets**（子网），选择 VPC 中的一个或多个子网，任务计划程序在放置任务时会考虑这些子网。

   1. 对于**安全组**，您可以选择现有安全组或创建新安全组。要使用现有安全组，请选择该安全组并移至下一步。要创建新安全组，请选择**创建新安全组**。您必须指定安全组名称、说明，然后为该安全组添加一个或多个入站规则。

   1. 对于**公有 IP**，选择是否向任务的弹性网络接口（ENI）自动分配公有 IP 地址。

      在公有子网中运行时，可以为 AWS Fargate 任务分配一个公有 IP 地址，以便它们具有通往互联网的路由。无法使用此字段为 EC2 任务分配公有 IP。有关更多信息，请参阅 [Fargate 的 Amazon ECS 任务联网选项](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-networking.html)和[为 Amazon ECS 任务分配网络接口](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking-awsvpc.html)。

1. （可选）要使用 Service Connect 与服务进行互连，请展开 **Service Connect**，然后指定以下参数：

   1.  选择**打开 Service Connect**。

   1. 在 **Service Connect configuration**（Service Connect 配置）下，指定客户端模式。
      + 如果您的服务运行的网络客户端应用程序只需要连接到命名空间中的其他服务，请选择**仅限客户端**。
      + 如果您的服务运行网络或 Web 服务应用程序且需要为该服务提供端点并连接到命名空间中的其他服务，请选择 **Client and server**（客户端和服务器）。

   1. 要使用默认集群命名空间以外的命名空间，对于**命名空间**，请选择服务命名空间。这可以是您在 AWS 账户的同一 AWS 区域中单独创建的命名空间，也可以是使用 AWS Resource Access Manager（AWS RAM）与您的账户共享的同一区域中的命名空间。有关共享 AWS Cloud Map 命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)。

   1. （可选）指定日志配置。选择**使用日志收集**。默认选项将容器日志发送到 CloudWatch Logs。其他日志驱动程序选项都使用 AWS FireLens 进行配置。有关更多信息，请参阅 [将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner](using_firelens.md)。

      下面更详细地介绍了每个容器日志目标。
      + **Amazon CloudWatch** – 将任务配置为将容器日志发送到 CloudWatch Logs。提供了默认的日志驱动程序选项，用于代表您创建 CloudWatch 日志组。要指定其他日志组名称，请更改驱动程序选项值。
      + **Amazon Data Firehose** – 将任务配置为将容器日志发送到 Firehose。提供了默认的日志驱动程序选项，这些选项将日志发送到 Firehose 传输流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon Kinesis Data Streams** – 将任务配置为将容器日志发送到 Kinesis Data Streams。提供了默认的日志驱动程序选项，这些选项将日志发送到 Kinesis Data Streams 流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon OpenSearch Service** – 将任务配置为将容器日志发送到 OpenSearch Service 域。必须提供日志驱动程序选项。
      + **Amazon S3** – 将任务配置为将容器日志发送到 Amazon S3 存储桶。提供了默认的日志驱动程序选项，但您必须指定有效的 Amazon S3 存储桶名称。

   1. （可选）要启用访问日志，请按照以下步骤进行操作：

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

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

1. （可选）要使用服务发现与服务进行互连，请展开**服务发现**，然后执行以下操作。

   1. 选择**使用服务发现**。

   1. 要使用新的命名空间，请在**配置命名空间**下选择**创建新命名空间**，然后提供命名空间名称和描述。要使用现有命名空间，请选择**选择现有命名空间**，然后选择要使用的命名空间。

   1. 提供服务发现的服务信息，例如服务的名称和描述。

   1. 要让 Amazon ECS 定期执行容器级别的运行状况检查，请选择**启用 Amazon ECS 任务运行状况传播**。

   1. 对于 **DNS 记录类型**，选择要为服务创建的 DNS 记录类型。Amazon ECS 服务发现仅支持 **A** 和 **SRV** 记录，具体取决于您的任务定义指定的网络模式。有关这些记录类型的更多信息，请参阅《Amazon Route 53 开发人员指南》**中的[支持的 DNS 记录类型](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html)。
      + 如果您的服务任务指定的任务定义使用 `bridge` 或 `host` 网络模式，则只支持类型 **SRV** 记录。选择要与记录关联的容器名称和端口组合。
      + 如果您的服务任务指定的任务定义使用 `awsvpc` 网络模式，请选择 **A** 或 **SRV** 记录类型。如果您选择 **A**，请跳到下一步。如果您选择 **SRV**，请指定可以在其上找到该服务的端口或与该记录关联的容器名称和端口组合。

      对于 **TTL**，请输入 DNS 解析器和 Web 浏览器缓存记录集的时长（以秒为单位）。

1. （可选）要使用 VPC Lattice 与服务互连，请展开 **VPC Lattice**，然后执行以下操作：

   1. 选择**打开 VPC Lattice**

   1. 对于**基础设施角色**，请选择该基础设施角色。

      如果尚未创建该角色，请选择**创建基础设施角色**。

   1. 在**目标组**下，选择一个或多个目标组。您需要选择至少 1 个目标组，最多可选择 5 个目标组。要添加更多目标组，请选择**添加目标组**。为您选择的每个目标组选择**端口名称**、**协议**和**端口**。

      要删除目标组，请选择**移除**。
**注意**  
如果要添加现有目标组，则需要使用 AWS CLI。有关如何使用 AWS CLI 添加目标组的说明，请参阅《AWS Command Line Interface 参考》中的 [register-targets](https://docs.aws.amazon.com/cli/latest/reference/vpc-lattice/register-targets.html)**。
虽然 VPC Lattice 服务可以有多个目标组，但每个目标组只能添加到一个服务中。

   1. 要完成 VPC Lattice 配置，请通过 VPC Lattice 控制台在侦听器默认操作或现有 VPC Lattice 服务的规则中包含您的新目标组。有关更多信息，请参阅 [Listener rules for your VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/listener-rules.html)。

1. （可选）要为您的服务配置负载均衡器，请展开 **Load balancing**（负载均衡）。

   选择负载均衡器。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/create-service-console-v2.html)

1. （可选）要配置服务自动扩缩，请展开**服务自动扩缩**，然后指定以下参数。要使用预测式自动扩缩（这将检查流量中的历史负载数据），请在创建服务后对其进行配置。有关更多信息，请参阅 [使用历史模式通过预测式扩缩来扩展 Amazon ECS 服务](predictive-auto-scaling.md)。

   1. 要使用服务自动扩缩，请选择**服务自动扩缩**。

   1. 对于**最小任务数**，输入供服务自动扩缩使用的任务数的下限。所需计数不会低于此计数。

   1. 对于**最大任务数**，输入供服务自动扩缩使用的任务数的上限。所需计数不会高于此计数。

   1. 选择策略类型。在**扩展策略类型**下，选择以下选项之一。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/create-service-console-v2.html)

1. （可选）要使用默认策略之外的其他任务放置策略，请展开 **Task Placement**（任务放置），然后从以下选项中进行选择。

    有关更多信息，请参阅 [Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。
   + **AZ 均衡分散** – 在各个可用区以及每个可用区中的各个容器实例中分配任务。
   + **AZ 均衡装填** – 在各个可用区以及具有最低可用内存的容器实例中分配任务。
   + **装填** – 根据 CPU 或内存的最低可用量来分配任务。
   + **每个主机一项任务** – 在每个容器实例中最多可放置服务的一个任务。
   + **自定义** – 定义您自己的任务放置策略。

   如果您选择了 **Custom**（自定义），请定义放置任务的算法和任务放置过程中要考虑的规则。
   + 在 **Strategy**（策略）下，对于 **Type**（类型）和 **Field**（字段），选择算法和用于该算法的实体。

     您最多可输入 5 个策略。
   + 在**约束**下，对于**类型**和**表达式**，选择要用于该约束的规则和属性。

     例如，要设置在 T2 实例上放置任务的约束，对于 **Expression**（表达式），输入 **attribute:ecs.instance-type =\$1 t2.\$1**。

     您最多可输入 10 个约束。

1. 如果您的任务使用的数据卷与部署时的配置兼容，则可以通过扩展**卷**来配置该卷。

   卷名称和卷类型在您创建任务定义修订时配置，在创建服务时无法更改。要更新卷名称和类型，您必须创建新的任务定义修订并使用新修订创建服务。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/create-service-console-v2.html)

1. 要使用 ECS Exec 调试服务，请在**问题排查配置**下，选择**开启 ECS Exec**。

1. （可选）为了帮助确定您的服务和任务，请展开**标签**部分，然后配置您的标签。

   要让 Amazon ECS 使用集群名称和任务定义标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**任务定义**。

   要让 Amazon ECS 使用集群名称和服务标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**服务**。

   添加或删除标签。
   + [添加标签] 选择 **Add tag**（添加标签），然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

1. 选择**创建**。

## 后续步骤
<a name="create-service-next-steps"></a>

以下是创建服务之后的额外操作。
+ 配置预测式自动扩缩，这将检查流量中的历史负载数据。有关更多信息，请参阅 [使用历史模式通过预测式扩缩来扩展 Amazon ECS 服务](predictive-auto-scaling.md)。
+ 跟踪部署并查看使用 Amazon ECS 断路器的服务的服务历史记录。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。

# Amazon ECS 蓝/绿部署
<a name="deployment-type-blue-green"></a>

蓝绿部署是一种发布方法，通过运行两个相同的生产环境（称为蓝色和绿色）来减少停机时间并降低风险。借助 Amazon ECS 蓝绿部署，可以在将生产流量定向到新的服务修订版之前对其进行验证。此方法提供了一种更安全的部署更改方式，并且能够根据需要快速回滚。

## 优势
<a name="blue-green-deployment-benefits"></a>

使用蓝绿部署具有以下优势：
+ 通过切换生产环境前的生产流量测试降低风险。在将生产流量定向到新部署之前，可以使用测试流量对其进行验证。
+ 实现零停机时间部署。生产环境在整个部署过程中始终可用，从而确保持续的服务可用性。
+ 检测到问题时轻松回滚。如果绿色部署出现问题，则可以快速恢复到蓝色部署，而不会造成长时间的服务中断。
+ 受控的测试环境。绿色环境提供了独立空间，可以在全面部署之前使用真实流量模式测试新功能。
+ 可预测的部署过程。结构化方法具有明确定义的生命周期阶段，使得部署更加可靠一致。
+ 通过生命周期挂钩进行自动验证。可在部署的各个阶段实施自动测试以验证功能。

## 术语
<a name="blue-green-deployment-terms"></a>

以下是 Amazon ECS 蓝绿部署术语：
+ 烘焙时间：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。
+ 蓝色部署：要被替换的当前生产服务修订版。
+ 绿色部署：要部署的新服务修订版。
+ 生命周期阶段：部署操作中的一系列事件，例如“生产流量转移后”。
+ 生命周期挂钩：一个 Lambda 函数，用于在特定生命周期阶段验证部署。
+ 侦听器：一种 Elastic Load Balancing 资源，可通过所配置的协议和端口检查连接请求。为侦听器定义的规则决定了 Amazon ECS 如何将请求路由到其注册的目标。
+ 规则：与侦听器关联的 Elastic Load Balancing 资源。规则定义了请求的路由方式，由操作、条件和优先级组成。
+ 目标组：一种 Elastic Load Balancing 资源，用于将请求路由到一个或多个已注册目标（例如 EC2 实例）。创建侦听器时，您为其默认操作指定目标组。流量将转发到在侦听器规则中指定的目标组。
+ 流量转移：Amazon ECS 用于将流量从蓝色部署转移到绿色部署的过程。对于 Amazon ECS 蓝绿部署，所有流量都会同时从蓝色服务转移到绿色服务。

## 注意事项
<a name="blue-green-deployment-considerations"></a>

选择部署类型时，请考虑以下因素：
+ 资源使用量：蓝绿部署会暂时同时运行蓝色服务修订版和绿色服务修订版，这可能会使部署期间的资源使用量翻一番。
+ 部署监控：蓝绿部署会提供更详细的部署状态信息，支持您监控部署过程的每个阶段。
+ 回滚：如果检测到问题，蓝绿部署可以更轻松地回滚到先前版本，因为蓝色修订版会一直运行直到烘焙时间到期。
+ 网络负载均衡器生命周期挂钩：如果您使用网络负载均衡器进行蓝绿部署，则 TEST\$1TRAFFIC\$1SHIFT 和 PRODUCTION\$1TRAFFIC\$1SHIFT 生命周期阶段还需要额外 10 分钟。这是因为 Amazon ECS 确保可安全地转移流量。

# Amazon ECS 蓝绿服务部署工作流
<a name="blue-green-deployment-how-it-works"></a>

Amazon ECS 蓝绿部署过程遵循结构化方法，包含六个不同的阶段，可确保安全可靠地进行应用程序更新。在验证应用程序并将其从当前版本（蓝色环境）迁移到新版本（绿色环境）时，每个阶段都有其特定目的。

1. **准备阶段**：在现有的蓝色环境旁创建绿色环境。这包括配置新的服务修订版以及准备目标组。

1. **部署阶段**：将新的服务修订版部署到绿色环境。Amazon ECS 使用更新的服务修订版启动新任务，同时蓝色环境继续传送生产流量。

1. **测试阶段**：使用测试流量路由来验证绿色环境。应用程序负载均衡器将测试请求定向到绿色环境，而生产流量仍保留在蓝色环境中。

1. **流量转移阶段**：根据所配置的部署策略，将生产流量从蓝色环境转移到绿色环境。此阶段包括监控和验证检查点。

1. **监控阶段**：监控烘焙时间内的应用程序运行状况、性能指标和警报状态。检测到问题时将启动回滚操作。

1. **完成阶段**：根据配置，通过终止蓝色环境或针对潜在的回滚场景对其进行维护来完成部署。

## 工作流
<a name="blue-green-deployment-workflow"></a>

下图阐明了全面的蓝绿部署工作流，显示了 Amazon ECS 与应用程序负载均衡器之间的交互：

![\[展示 Amazon ECS 中蓝绿部署过程的综合图，包含详细的组件交互、流量转移阶段和监控检查点\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/blue-green.png)


增强型部署工作流包括以下详细步骤：

1. **初始状态**：蓝色服务（当前生产环境）处理 100% 的生产流量。应用程序负载均衡器只有一个侦听器，其规则可将所有请求路由到包含正常运行的蓝色任务的蓝色目标组。

1. **绿色环境预置**：Amazon ECS 使用更新的任务定义创建新任务。这些任务已注册到新的绿色目标组，但最初不会接收任何流量。

1. **运行状况检查验证**：应用程序负载均衡器对绿色任务执行运行状况检查。仅当绿色任务通过运行状况检查后，部署才会进入下一阶段。

1. **测试流量路由**：若已配置，则应用程序负载均衡器的侦听器规则会将特定的流量模式（例如带有测试标头的请求）路由到绿色环境进行验证，而生产流量仍将保留在蓝色环境中。这是由处理生产流量的同一个侦听器控制的，它将根据请求属性使用不同的规则。

1. **生产流量转移**：根据部署配置，流量从蓝色环境转移到绿色环境。在 ECS 蓝绿部署中，这是一种即时（一次性）转移，100% 的流量都将从蓝色环境转移到绿色环境。应用程序负载均衡器仅使用一个具有侦听器规则的侦听器，这些规则将根据权重控制蓝色目标组与绿色目标组之间的流量分配。

1. **监控与验证**：在整个流量转移过程中，Amazon ECS 会监控 CloudWatch 指标、警报状态和部署运行状况。如果检测到问题，将启动自动回滚触发器。

1. **烘焙时间段**：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。

1. **蓝色环境终止**：成功进行流量转移并验证后，将终止蓝色环境以释放集群资源，或将维护蓝色环境以实现快速回滚功能。

1. **最终状态**：绿色环境成为新的生产环境，可处理 100% 的流量。部署将标记为成功。

## 部署生命周期阶段
<a name="blue-green-deployment-stages"></a>

蓝绿部署过程会经历不同的生命周期阶段（即部署操作中的一系列事件，例如“生产流量转移后”），每个阶段都有特定职责和验证检查点。了解这些阶段有助于监控部署进度并有效排查问题。

 每个生命周期阶段最多可持续 24 小时。建议将该值保持在 24 小时以内。这是因为异步进程需要时间来触发挂钩。当一个阶段达到 24 小时后，系统将超时，导致部署失败，然后会启动回滚。此外，CloudFormation 部署还有其他超时限制。尽管 24 小时的阶段限制仍然有效，但 CloudFormation 会对整个部署强制执行 36 小时的限制。如果整个过程未在 36 小时内完成，CloudFormation 将使部署失败，然后启动回滚。


| 生命周期阶段 | 说明 | 此阶段是否使用生命周期挂钩？ | 
| --- | --- | --- | 
| RECONCILE\$1SERVICE | 仅当启动多个服务修订版处于活动状态的新服务部署时，才会发生此阶段。 | 是 | 
| PRE\$1SCALE\$1UP | 绿色服务修订版尚未启动。蓝色服务修订版正在处理 100% 的生产流量。没有测试流量。 | 是 | 
| SCALE\$1UP | 绿色服务修订版纵向扩展至 100% 并启动新任务的时间。此时绿色服务修订版不传送任何流量。 | 否 | 
| POST\$1SCALE\$1UP | 绿色服务修订版已经启动。蓝色服务修订版正在处理 100% 的生产流量。没有测试流量。 | 是 | 
| TEST\$1TRAFFIC\$1SHIFT | 蓝色服务修订版和绿色服务修订版正在运行。蓝色服务修订版可处理 100% 的生产流量。绿色服务修订版正在将测试流量从 0% 迁移到 100%。 | 是 | 
| POST\$1TEST\$1TRAFFIC\$1SHIFT | 测试流量转移已完成。绿色服务修订版可处理 100% 的测试流量。 | 是 | 
| PRODUCTION\$1TRAFFIC\$1SHIFT | 生产流量正在向绿色服务修订版转移。绿色服务修订版正在将生产流量从 0% 迁移到 100%。 | 是 | 
| POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT | 生产流量转移已完成。 | 是 | 
| BAKE\$1TIME | 蓝色服务修订版和绿色服务修订版同时运行的持续时间。 | 否 | 
| CLEAN\$1UP | 蓝色服务修订版已完全缩减至 0 个运行任务。在此阶段之后，绿色服务修订版将成为生产服务修订版。 | 否 | 

每个生命周期阶段皆包含内置的验证检查点，必须通过这些检查点才能进入下一阶段。如果出现任何验证失败，则可以自动回滚部署以保持服务的可用性和可靠性。

当您使用 Lambda 函数时，该函数必须完成工作，或者在 15 分钟内返回 IN\$1PROGRESS。您可以使用 `callBackDelaySeconds` 来延迟对 Lambda 的调用。有关更多信息，请参阅 GitHub 上的 sample-amazon-ecs-blue-green-deployment-patterns 中的 [app.py 函数](https://github.com/aws-samples/sample-amazon-ecs-blue-green-deployment-patterns/blob/main/ecs-bluegreen-lifecycle-hooks/src/approvalFunction/app.py#L20-L25)。

# Amazon ECS 蓝绿部署所需的资源
<a name="blue-green-deployment-implementation"></a>

要使用支持托管流量转移的蓝绿部署，服务必须使用以下功能之一：
+ Elastic Load Balancing
+ Service Connect

不使用服务发现、Service Connect、VPC Lattice 或 Elastic Load Balancing 的服务也可以使用蓝绿部署，但无法获得任何托管流量转移的优势。

以下列表简要概述了配置 Amazon ECS 蓝绿部署所需的内容：
+ 服务使用应用程序负载均衡器、网络负载均衡器或 Service Connect。配置相应的资源。
  + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
  + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
  + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。
+ 将服务部署控制器设置为 `ECS`。
+ 在服务定义中将部署策略配置为 `blue/green`。
+ 或者，配置其他参数，例如：
  + 新部署的烘焙时间
  + 用于自动回滚的 CloudWatch 警报
  + 用于测试的部署生命周期挂钩（这些挂钩是在指定部署阶段运行的 Lambda 函数）

## 最佳实践
<a name="blue-green-deployment-best-practices"></a>

遵循以下最佳实践，以实现 Amazon ECS 蓝绿部署：
+ 配置适当的运行状况检查，以准确反映应用程序的运行状况。
+ 设置烘焙时间，以便对绿色部署进行充分测试。
+ 实施 CloudWatch 警报，以自动检测问题并触发回滚。
+ 使用生命周期挂钩在每个部署阶段执行自动测试。
+ 确保您的应用程序能够处理同时运行的蓝色和绿色服务修订。
+ 规划足够的集群容量，以便在部署期间处理两个服务修订。
+ 在生产环境中实施回滚程序之前，先对其进行测试。

# 适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源
<a name="alb-resources-for-blue-green"></a>

要将应用程序负载均衡器用于 Amazon ECS 蓝绿部署，需要配置特定的资源，以便在蓝色服务修订版与绿色服务修订版之间进行流量路由。

## 目标组
<a name="alb-target-groups"></a>

对于使用 Elastic Load Balancing 的蓝绿部署，需要创建两个目标组：
+ 一个用于蓝色服务修订版（当前生产流量）的主目标组
+ 一个用于绿色服务修订版（新版本）的备用目标组

两个目标组都应配置以下设置：
+ 目标类型：`IP`（适用于 Fargate 或采用 `awsvpc` 网络模式的 EC2）
+ 协议：`HTTP`（或应用程序使用的协议）
+ 端口：应用程序侦听端口（HTTP 通常为 `80`）
+ VPC：与 Amazon ECS 任务相同的 VPC
+ 运行状况检查设置：配置为正确检查应用程序的运行状况

在蓝绿部署期间，Amazon ECS 会根据部署阶段自动将任务注册到相应的目标组。

**Example 为应用程序负载均衡器创建目标组**  
以下 CLI 命令将创建两个目标组，用于使用应用程序负载均衡器的蓝绿部署：  

```
aws elbv2 create-target-group \
    --name blue-target-group \
    --protocol HTTP \
    --port 80 \
    --vpc-id vpc-abcd1234 \
    --target-type ip \
    --health-check-path / \
    --health-check-protocol HTTP \
    --health-check-interval-seconds 30 \
    --health-check-timeout-seconds 5 \
    --healthy-threshold-count 2 \
    --unhealthy-threshold-count 2

aws elbv2 create-target-group \
    --name green-target-group \
    --protocol HTTP \
    --port 80 \
    --vpc-id vpc-abcd1234 \
    --target-type ip \
    --health-check-path / \
    --health-check-protocol HTTP \
    --health-check-interval-seconds 30 \
    --health-check-timeout-seconds 5 \
    --healthy-threshold-count 2 \
    --unhealthy-threshold-count 2
```

## 应用程序负载均衡器
<a name="alb-load-balancer"></a>

需要创建具有以下配置的应用程序负载均衡器：
+ 方案：面向互联网或内部（视需求而定）
+ IP 地址类型：IPv4
+ VPC：与 Amazon ECS 任务相同的 VPC
+ 子网：至少两个位于不同可用区的子网
+ 安全组：允许通过侦听器端口的流量的安全组

附加到应用程序负载均衡器的安全组必须具有出站规则，允许流量传入附加到 Amazon ECS 任务的安全组。

**Example 创建应用程序负载均衡器**  
以下 CLI 命令将创建用于蓝绿部署的应用程序负载均衡器：  

```
aws elbv2 create-load-balancer \
    --name my-application-load-balancer \
    --type application \
    --security-groups sg-abcd1234 \
    --subnets subnet-12345678 subnet-87654321
```

## 侦听器和规则
<a name="alb-listeners"></a>

对于蓝绿部署，需要在应用程序负载均衡器上配置以下侦听器：
+ 生产侦听器：处理生产流量（通常在端口 80 或 443 上）
  + 一开始，先将流量转发到主目标组（蓝色服务修订版）
  + 部署后，将流量转发到备用目标组（绿色服务修订版）
+ 测试侦听器（可选）：处理测试流量，以便在转移生产流量之前验证绿色服务修订版
  + 可以在不同的端口（例如 8080 或 8443）上进行配置
  + 在测试期间将流量转发到备用目标组（绿色服务修订版）

在蓝绿部署期间，Amazon ECS 会自动更新侦听器规则，以便根据部署阶段将流量路由到相应的目标组。

**Example 创建生产侦听器**  
以下 CLI 命令将在端口 80 上创建生产侦听器，将流量转发到主（蓝色）目标组：  

```
aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:region:123456789012:loadbalancer/app/my-application-load-balancer/abcdef123456 \
    --protocol HTTP \
    --port 80 \
    --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:123456789012:targetgroup/blue-target-group/abcdef123456
```

**Example 创建测试侦听器**  
以下 CLI 命令将在端口 8080 上创建测试侦听器，将流量转发到备用（绿色）目标组：  

```
aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:region:123456789012:loadbalancer/app/my-application-load-balancer/abcdef123456 \
    --protocol HTTP \
    --port 8080 \
    --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:123456789012:targetgroup/green-target-group/ghijkl789012
```

**Example 创建基于路径路由的侦听器规则**  
以下 CLI 命令将创建一条规则，将特定路径的流量转发到绿色目标组进行测试：  

```
aws elbv2 create-rule \
    --listener-arn arn:aws:elasticloadbalancing:region:123456789012:listener/app/my-application-load-balancer/abcdef123456/ghijkl789012 \
    --priority 10 \
    --conditions Field=path-pattern,Values='/test/*' \
    --actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:123456789012:targetgroup/green-target-group/ghijkl789012
```

**Example 创建基于标头路由的侦听器规则**  
以下 CLI 命令将创建一条规则，将带有特定标头的流量转发到绿色目标组进行测试：  

```
aws elbv2 create-rule \
    --listener-arn arn:aws:elasticloadbalancing:region:123456789012:listener/app/my-application-load-balancer/abcdef123456/ghijkl789012 \
    --priority 20 \
    --conditions Field=http-header,HttpHeaderConfig='{Name=X-Environment,Values=[test]}' \
    --actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:123456789012:targetgroup/green-target-group/ghijkl789012
```

## 服务配置
<a name="alb-service-configuration"></a>

必须拥有允许 Amazon ECS 代表您管理集群中负载均衡器资源的权限。有关更多信息，请参阅 [适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。

在为使用 Elastic Load Balancing 的蓝绿部署创建或更新 Amazon ECS 服务时，需要指定以下配置。

将 *user-input* 替换为您的值。

此配置中的关键组件包括：
+ `targetGroupArn`：主目标组（蓝色服务修订版）的 ARN。
+ `alternateTargetGroupArn`：备用目标组（绿色服务修订版）的 ARN。
+ `productionListenerRule`：适用于生产流量的侦听器规则的 ARN。
+ `roleArn`：允许 Amazon ECS 管理 Elastic Load Balancing 资源的角色的 ARN。
+ `strategy`：设置为 `BLUE_GREEN` 以启用蓝绿部署。
+ `bakeTimeInMinutes`：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。
+ `TestListenerRule`：适用于测试流量的侦听器规则的 ARN。此参数为可选参数。

```
{
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/primary-target-group/abcdef123456",
            "containerName": "container-name",
            "containerPort": 80,
            "advancedConfiguration": {
                "alternateTargetGroupArn": "arn:aws:elasticloadbalancing:region:account-id:targetgroup/alternate-target-group/ghijkl789012",
                "productionListenerRule": "arn:aws:elasticloadbalancing:region:account-id:listener-rule/app/load-balancer-name/abcdef123456/listener/ghijkl789012/rule/mnopqr345678",
                "roleArn": "arn:aws:iam::123456789012:role/ecs-elb-role"
            }
        }
    ],
    "deploymentConfiguration": {
        "strategy": "BLUE_GREEN",
        "maximumPercent": 200,
        "minimumHealthyPercent": 100,
        "bakeTimeInMinutes": 5
    }
}
```

## 部署期间的流量流
<a name="alb-traffic-flow"></a>

在使用 Elastic Load Balancing 进行蓝绿部署期间，流量按如下方式在系统中传输：

1. *初始状态*：所有生产流量均路由到主目标组（蓝色服务修订版）。

1. *绿色服务修订版部署*：Amazon ECS 部署新任务并将其注册到备用目标组。

1. *测试流量*：如果配置了测试侦听器，则会将测试流量路由到备用目标组以验证绿色服务修订版。

1. *生产流量转移*：Amazon ECS 更新生产侦听器规则，将流量路由到备用目标组（绿色服务修订版）。

1. *烘焙时间*：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。

1. *完成*：成功部署后，蓝色服务修订版将终止。

如果在部署期间检测到问题，Amazon ECS 可以通过将流量路由回主目标组（蓝色服务修订版）实现自动回滚。

# 适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源
<a name="nlb-resources-for-blue-green"></a>

要将网络负载均衡器用于 Amazon ECS 蓝绿部署，需要配置特定的资源，以便在蓝色服务修订版和绿色服务修订版之间进行流量路由。本节将介绍所需组件及其配置。

如果配置中包含网络负载均衡器，Amazon ECS 会在以下生命周期阶段添加 10 分钟的延迟：
+ TEST\$1TRAFFIC\$1SHIFT
+ PRODUCTION\$1TRAFFIC\$1SHIFT

此延迟用于解决网络负载均衡器的时间问题，该问题可能导致配置的流量权重与数据面板的实际流量路由不一致。

## 目标组
<a name="nlb-target-groups"></a>

对于使用网络负载均衡器的蓝绿部署，需要创建两个目标组：
+ 一个用于蓝色服务修订版（当前生产流量）的主目标组
+ 一个用于绿色服务修订版（新服务修订版）的备用目标组

两个目标组都应配置以下设置：
+ 目标类型：`ip`（适用于 Fargate 或采用 `awsvpc` 网络模式的 EC2）
+ 协议：`TCP`（或应用程序使用的协议）
+ 端口：应用程序侦听端口（HTTP 通常为 `80`）
+ VPC：与 Amazon ECS 任务相同的 VPC
+ 运行状况检查设置：配置为正确检查应用程序的运行状况

  对于 TCP 运行状况检查，网络负载均衡器会与目标建立 TCP 连接。如果连接成功，则视为目标运行正常。

  对于 HTTP/HTTPS 运行状况检查，网络负载均衡器会向目标发送 HTTP/HTTPS 请求并验证响应。

在蓝绿部署期间，Amazon ECS 会根据部署阶段自动将任务注册到相应的目标组。

**Example 为网络负载均衡器创建目标组**  
以下 AWS CLI 命令将创建两个目标组，用于使用网络负载均衡器的蓝绿部署：  

```
aws elbv2 create-target-group \
    --name blue-target-group \
    --protocol TCP \
    --port 80 \
    --vpc-id vpc-abcd1234 \
    --target-type ip \
    --health-check-protocol TCP

aws elbv2 create-target-group \
    --name green-target-group \
    --protocol TCP \
    --port 80 \
    --vpc-id vpc-abcd1234 \
    --target-type ip \
    --health-check-protocol TCP
```

## 网络负载均衡器
<a name="nlb-load-balancer"></a>

需要创建具有以下配置的网络负载均衡器：
+ 方案：面向互联网或内部（视需求而定）
+ IP 地址类型：IPv4
+ VPC：与 Amazon ECS 任务相同的 VPC
+ 子网：至少两个位于不同可用区的子网

与应用程序负载均衡器不同，网络负载均衡器在传输层（第 4 层）运行，不使用安全组。相反，需要确保与 Amazon ECS 任务关联的安全组允许来自网络负载均衡器的流量通过侦听器端口。

**Example 创建网络负载均衡器**  
以下 AWS CLI 命令将创建用于蓝绿部署的网络负载均衡器：  

```
aws elbv2 create-load-balancer \
    --name my-network-load-balancer \
    --type network \
    --subnets subnet-12345678 subnet-87654321
```

## 使用 NLB 进行蓝绿部署的注意事项
<a name="nlb-considerations"></a>

使用网络负载均衡器进行蓝绿部署时，请考虑以下事项：
+ **第 4 层操作**：网络负载均衡器在传输层（第 4 层）运行，不检查应用程序层（第 7 层）的内容。这意味着您无法使用 HTTP 标头或路径进行路由决策。
+ **运行状况检查**：网络负载均衡器运行状况检查仅限于 TCP、HTTP 或 HTTPS 协议。对于 TCP 运行状况检查，网络负载均衡器仅验证是否可以建立连接。
+ **连接保存**：网络负载均衡器会保留客户端的源 IP 地址，可用于安全和日志记录目的。
+ **静态 IP 地址**：网络负载均衡器为每个子网提供静态 IP 地址，可用于列入白名单或将客户端连接到固定 IP 地址。
+ **测试流量**：网络负载均衡器不支持基于内容的路由，因此必须将测试流量发送到与生产流量不同的端口。

## 侦听器和规则
<a name="nlb-listeners"></a>

对于使用网络负载均衡器的蓝绿部署，需要配置以下侦听器：
+ 生产侦听器：处理生产流量（通常在端口 80 或 443 上）
  + 一开始，先将流量转发到主目标组（蓝色服务修订版）
  + 部署后，将流量转发到备用目标组（绿色服务修订版）
+ 测试侦听器（可选）：处理测试流量，以便在转移生产流量之前验证绿色服务修订版
  + 可以在不同的端口（例如 8080 或 8443）上进行配置
  + 在测试期间将流量转发到备用目标组（绿色服务修订版）

与应用程序负载均衡器不同，网络负载均衡器不支持基于内容的路由规则。相反，流量是根据侦听器端口和协议进行路由的。

以下 AWS CLI 命令将为网络负载均衡器创建生产和测试侦听器：

将 *user-input* 替换为您的值。

```
aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:region:123456789012:loadbalancer/net/my-network-lb/1234567890123456 \
    --protocol TCP \
    --port 80 \
    --default-actions Type=forward, TargetGroupArn=arn:aws:elasticloadbalancing:region:123456789012:targetgroup/blue-target-group/1234567890123456

aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:region:123456789012:loadbalancer/net/my-network-lb/1234567890123456 \
    --protocol TCP \
    --port 8080 \
    --default-actions Type=forward, TargetGroupArn=arn:aws:elasticloadbalancing:region:123456789012:targetgroup/green-target-group/1234567890123456
```

## 服务配置
<a name="nlb-service-configuration"></a>

必须拥有允许 Amazon ECS 代表您管理集群中负载均衡器资源的权限。有关更多信息，请参阅 [适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。

在为使用网络负载均衡器的蓝绿部署创建或更新 Amazon ECS 服务时，需要指定以下配置：

将 *user-input* 替换为您的值。

此配置中的关键组件包括：
+ `targetGroupArn`：主目标组（蓝色服务修订版）的 ARN
+ `alternateTargetGroupArn`：备用目标组（绿色服务修订版）的 ARN
+ `productionListenerRule`：适用于生产流量的侦听器的 ARN
+ `testListenerRule`（可选）：适用于测试流量的侦听器的 ARN
+ `roleArn`：允许 Amazon ECS 管理网络负载均衡器资源的角色的 ARN
+ `strategy`：设置为 `BLUE_GREEN` 以启用蓝绿部署
+ `bakeTimeInMinutes`：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间

```
{
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/blue-target-group/1234567890123456",
            "containerName": "container-name",
            "containerPort": 80,
            "advancedConfiguration": {
                "alternateTargetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/green-target-group/1234567890123456",
                "productionListenerRule": "arn:aws:elasticloadbalancing:region:123456789012:listener/net/my-network-lb/1234567890123456/1234567890123456",
                "testListenerRule": "arn:aws:elasticloadbalancing:region:123456789012:listener/net/my-network-lb/1234567890123456/2345678901234567",
                "roleArn": "arn:aws:iam::123456789012:role/ecs-nlb-role"
            }
        }
    ],
    "deploymentConfiguration": {
        "strategy": "BLUE_GREEN",
        "maximumPercent": 200,
        "minimumHealthyPercent": 100,
        "bakeTimeInMinutes": 5
    }
}
```

## 部署期间的流量流
<a name="nlb-traffic-flow"></a>

在使用网络负载均衡器进行蓝绿部署期间，流量按如下方式流经系统：

1. *初始状态*：所有生产流量均路由到主目标组（蓝色服务修订版）。

1. *绿色服务修订版部署*：Amazon ECS 部署新任务并将其注册到备用目标组。

1. *测试流量*：如果配置了测试侦听器，则会将测试流量路由到备用目标组以验证绿色服务修订版。

1. *生产流量转移*：Amazon ECS 更新生产侦听器，将流量路由到备用目标组（绿色服务修订版）。

1. *烘焙时间*：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。

1. *完成*：成功部署后，蓝色服务修订版将终止。

如果在部署期间检测到问题，Amazon ECS 可以通过将流量路由回主目标组（蓝色服务修订版）实现自动回滚。

# 适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源
<a name="service-connect-blue-green"></a>

使用 Service Connect 进行蓝绿部署时，需要配置特定组件，以便在蓝色服务修订版和绿色服务修订版之间启用正确的流量路由。本节将介绍所需组件及其配置。

## 架构概述
<a name="service-connect-blue-green-architecture"></a>

Service Connect 通过自动注入到 Amazon ECS 任务中的托管附加代理，构建了服务发现和服务网格功能。这些代理会处理路由决策、重试和指标收集，而 AWS Cloud Map 则负责提供服务注册表后端。部署已启用 Service Connect 的服务时，该服务会在 AWS Cloud Map 中自行进行注册，客户端服务会通过命名空间发现它。

在标准的 Service Connect 实现中，客户端服务会连接到逻辑服务名称，附加代理则负责处理流向实际服务实例的路由。在蓝绿部署中，此模型会扩展为包含通过 `testTrafficRules` 配置实现的测试流量路由。

在蓝绿部署期间，以下关键组件协同工作：
+ **Service Connect 代理**：服务之间的所有流量均通过 Service Connect 代理传递，该代理会根据配置做出路由决策。
+ **AWS Cloud Map 注册**：蓝色部署和绿色部署都注册到 AWS Cloud Map，但绿色部署最初注册为“测试”端点。
+ **测试流量路由**：Service Connect 配置中的 `testTrafficRules` 决定了如何识别测试流量并将其路由到绿色部署。这是通过**基于标头的路由**实现的，其中请求中的特定 HTTP 标头会将流量定向到测试修订。默认情况下，如果未指定自定义规则，Service Connect 会为基于 HTTP 的协议识别 `x-amzn-ecs-blue-green-test` 标头。
+ **客户端配置**：命名空间中的所有客户端都会自动接收生产和测试路由，但只有与测试规则相匹配的请求才会发送到绿色部署。

这种方法的强大之处在于它处理了迁移期间服务发现的复杂性。随着流量从蓝色部署转移到绿色部署，所有连接和发现机制都会自动更新。无需更新 DNS 记录、重新配置负载均衡器或单独部署服务发现更改，因为服务网格可以处理这一切任务。

## 流量路由和测试
<a name="service-connect-blue-green-traffic-routing"></a>

Service Connect 可为蓝绿部署提供高级流量路由功能，包括基于标头的路由和用于测试场景的客户端别名配置。

### 测试流量标头规则
<a name="service-connect-test-traffic-header-rules"></a>

在蓝绿部署期间，可以配置测试流量标头规则，将特定请求路由到绿色（新）服务修订版以进行测试。如此一来，便可在完成部署之前使用受控流量验证新版本。

Service Connect 使用**基于标头的路由**来识别测试流量。默认情况下，如果未指定自定义规则，Service Connect 会为基于 HTTP 的协议识别 `x-amzn-ecs-blue-green-test` 标头。当请求中存在此标头时，Service Connect 代理会自动将请求路由到绿色部署进行测试。

测试流量标头规则可用于：
+ 将带有特定标头的请求路由到绿色服务修订版
+ 使用一部分流量测试新功能
+ 在完全割接流量之前验证服务行为
+ 实施金丝雀测试策略
+ 在类似生产的环境中执行集成测试

基于标头的路由机制可与现有的应用程序架构无缝配合。客户端服务无需了解蓝绿部署过程，只需在发送测试请求时包含相应的标头，Service Connect 代理会自动处理路由逻辑。

有关如何配置测试流量标头规则的信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [ServiceConnectTestTrafficHeaderRules](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceConnectTestTrafficHeaderRules.html)。

### 标头匹配规则
<a name="service-connect-header-match-rules"></a>

标头匹配规则定义了蓝绿部署期间路由测试流量的标准。可以配置多个匹配条件来精确控制将哪些请求路由到绿色服务修订版。

标头匹配支持：
+ 标头值精确匹配
+ 标头存在性检查
+ 基于模式的匹配
+ 多个标头组合

使用案例示例包括将带有特定用户代理字符串、API 版本或功能标志的请求路由到绿色服务进行测试。

有关标头匹配配置的更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [ServiceConnectTestTrafficHeaderMatchRules](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceConnectTestTrafficHeaderMatchRules.html)。

### 蓝绿部署的客户端别名
<a name="service-connect-client-alias-blue-green"></a>

客户端别名为蓝绿部署期间的服务提供了稳定的 DNS 端点。它们可在蓝色服务修订版与绿色服务修订版之间实现无缝的流量路由，而无需客户端应用程序更改其连接端点。

蓝绿部署期间，客户端别名需满足以下条件：
+ 为客户端连接保持一致的 DNS 名称
+ 支持服务修订版之间的自动流量切换
+ 支持渐进式流量迁移策略
+ 通过将流量重定向到蓝色修订来提供回滚功能

可以为不同的端口或协议配置多个客户端别名，允许复杂的服务架构在部署期间保持连接。

有关客户端别名配置的更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [ServiceConnectClientAlias](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceConnectClientAlias.html)。

### 流量路由的最佳实践
<a name="service-connect-blue-green-best-practices"></a>

使用 Service Connect 实施蓝绿部署的流量路由时，请考虑以下最佳实践：
+ **从基于标头的测试开始**：在切换所有流量之前，使用测试流量标头规则通过受控流量验证绿色服务。
+ **配置运行状况检查**：确保蓝色服务和绿色服务都配置了适当的运行状况检查，防止将流量路由到运行状况不佳的实例。
+ **监控服务指标**：在部署期间跟踪两个服务修订版的关键性能指标，以便尽早发现问题。
+ **规划回滚策略**：配置客户端别名和路由规则，以便在检测到问题时能够快速回滚到蓝色服务。
+ **测试标头匹配逻辑**：在将标头匹配规则应用于生产部署之前，先在非生产环境中对其进行验证。

## Service Connect 蓝绿部署工作流
<a name="service-connect-blue-green-workflow"></a>

了解 Service Connect 如何管理蓝绿部署过程有助于有效实施部署并进行问题排查。以下工作流展示了不同组件在部署的每个阶段的交互方式。

### 部署阶段
<a name="service-connect-deployment-phases"></a>

Service Connect 蓝绿部署会经历几个不同的阶段：

1. **初始状态**：蓝色服务处理 100% 的生产流量。命名空间中的所有客户端服务都通过 Service Connect 中配置的逻辑服务名称连接到蓝色服务。

1. **绿色服务注册**：绿色部署启动后，将在 AWS Cloud Map 中注册为“测试”端点。客户端服务中的 Service Connect 代理会自动接收生产和测试路由配置。

1. **测试流量路由**：包含测试流量标头（例如 `x-amzn-ecs-blue-green-test`）的请求由 Service Connect 代理自动路由到绿色服务。生产流量继续流向蓝色服务。

1. **流量转移准备**：成功测试后，部署过程准备进行生产流量转移。蓝色服务和绿色服务均保持注册状态且运行正常。

1. **生产流量转移**：Service Connect 配置更新为将生产流量路由到绿色服务。无需更新客户端服务或更改 DNS 即可自动执行此操作。

1. **烘焙时间段**：生产流量转移后，蓝色服务修订版和绿色服务修订版同时运行的持续时间。

1. **蓝色服务注销**：成功进行流量转移并验证后，蓝色服务从 AWS Cloud Map 中注销并终止，从而完成部署。

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

Service Connect 代理在管理蓝绿部署期间的流量方面起着至关重要的作用。了解其行为有助于设计有效的测试和部署策略。

蓝绿部署期间的关键代理行为：
+ **自动路由发现**：代理自动从 AWS Cloud Map 发现生产和测试路由，无需重新启动应用程序或更改配置。
+ **基于标头的路由**：代理检查传入的请求标头，并根据配置的测试流量规则将流量路由到相应的服务修订版。
+ **运行状况检查集成**：代理仅将流量路由到运行正常的服务实例，自动将运行状况不佳的任务从路由池中排除。
+ **重试和断路**：代理提供内置的重试逻辑和断路功能，可提高部署期间的恢复能力。
+ **指标收集**：代理收集蓝色服务和绿色服务的详细指标，以便在部署期间进行全面监控。

### 服务发现更新
<a name="service-connect-service-discovery-updates"></a>

使用 Service Connect 进行蓝绿部署的关键优势之一是自动处理服务发现更新。传统的蓝绿部署通常需要复杂的 DNS 更新或负载均衡器重新配置，但 Service Connect 可以透明地管理这些更改。

部署期间，Service Connect 会处理：
+ **命名空间更新**：Service Connect 命名空间自动包含蓝色服务端点和绿色服务端点，并带有相应的路由规则。
+ **客户端配置**：命名空间中的所有客户端服务均自动接收更新的路由信息，无需重新启动或重新部署。
+ **逐步过渡**：服务发现更新会逐渐安全地进行，确保不会中断正在进行的请求。
+ **回滚支持**：如果需要回滚，Service Connect 可以快速恢复服务发现配置，将流量路由回蓝色服务。

# 创建 Amazon ECS 蓝绿部署
<a name="deploy-blue-green-service"></a>

 通过使用 Amazon ECS 蓝绿部署，您可以进行服务更改并测试，然后再在生产环境中实施服务更改。

## 先决条件
<a name="deploy-blue-green-service-prerequisites"></a>

在开始蓝绿部署之前，执行以下操作。

1. 配置相应的权限。
   + 有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。
   + 有关 Lambda 权限的信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)

1. Amazon ECS 蓝绿部署要求服务使用以下功能之一：配置相应的资源。
   + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
   + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
   + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。

1. 决定是否要为生命周期阶段运行 Lambda 函数。
   + PRE\$1SCALE\$1UP
   + POST\$1SCALE\$1UP
   + TEST\$1TRAFFIC\$1SHIFT
   + POST\$1TEST\$1TRAFFIC\$1SHIFT
   + PRODUCTION\$1TRAFFIC\$1SHIFT
   + POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT

   有关更多信息，请参阅《AWS Lambda 开发人员指南》**中的[使用控制台创建 Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#getting-started-create-function)。

## 过程
<a name="deploy-blue-green-service-procedure"></a>

可使用控制台或 AWS CLI 创建 Amazon ECS 蓝绿服务。

------
#### [ Console ]

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

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

   此时会显示**创建服务**页面。

1. 在**服务详细信息**下，执行以下操作：

   1. 对于**任务定义系列**，选择要使用的任务定义。然后，在**任务定义修订**中，输入要使用的修订。

   1. 对于 **Service name**（服务名称），为您的服务输入一个名称。

1. 要在现有集群中运行服务，请为**现有集群**选择集群。要在新集群中运行服务，请选择**创建集群** 

1. 选择任务在集群基础设施中的分发方式。在**计算配置**下，选择您的选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/deploy-blue-green-service.html)

1. 在**部署配置**下，执行以下操作：

   1. 对于**服务类型**，选择**副本**。

   1. 对于 **Desired tasks**（预期任务），输入要在服务中启动并保留的任务数量。

   1. 要让 Amazon ECS 监控可用区之间的任务分配情况，并在出现不平衡时重新分配任务，请在**可用区服务重新平衡**下选择**可用区服务重新平衡**。

   1. 对于**运行状况检查宽限期**，输入在任务首次启动后，服务调度程序将忽略运行状况不佳的 Elastic Load Balancing、VPC Lattice 和容器运行状况检查的时间长度（以秒为单位）。如果没有指定运行状况检查宽限期值，则使用默认值 0。

1. 

   1. 对于**烘焙时间**，输入在蓝色修订服务终止之前蓝色服务修订版和绿色服务修订版同时运行的分钟数。这样可以留出验证和测试时间。

   1. （可选）在部署的特定阶段运行 Lambda 函数。在**部署生命周期挂钩**下，选择要运行生命周期挂钩的阶段。

      要添加生命周期挂钩，请执行以下操作：

      1. 选择**添加**。

      1. 对于 **Lambda 函数**，输入函数名称或 ARN。

      1. 对于**角色**，选择有权调用 Lambda 函数的 IAM 角色。

      1. 对于**生命周期阶段**，选择应运行 Lambda 函数的阶段。

1. 要配置 Amazon ECS 如何检测和处理部署故障，请展开 **Deployment failure detection**（部署故障检测），然后选择您的选项。

   1. 要在任务无法启动时停止部署，请选择 **Use the Amazon ECS deployment circuit breaker**（使用 Amazon ECS 部署断路器）。

      要让软件在部署断路器将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

   1. 要根据应用程序指标停止部署，请选择**使用 CloudWatch 警报**。然后，从 **CloudWatch 警报名称**中选择警报。要创建新报警，请转到 CloudWatch 控制台。

      要让软件在 CloudWatch 警报将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

1. （可选）要使用 Service Connect 与服务进行互连，请展开 **Service Connect**，然后指定以下参数：

   1.  选择**打开 Service Connect**。

   1. 在 **Service Connect configuration**（Service Connect 配置）下，指定客户端模式。
      + 如果您的服务运行的网络客户端应用程序只需要连接到命名空间中的其他服务，请选择**仅限客户端**。
      + 如果您的服务运行网络或 Web 服务应用程序且需要为该服务提供端点并连接到命名空间中的其他服务，请选择 **Client and server**（客户端和服务器）。

   1. 要使用默认集群命名空间以外的命名空间，对于**命名空间**，请选择服务命名空间。这可以是您在 AWS 账户的同一 AWS 区域中单独创建的命名空间，也可以是使用 AWS Resource Access Manager（AWS RAM）与您的账户共享的同一区域中的命名空间。有关共享 AWS Cloud Map 命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)。

   1. （可选）为蓝绿部署配置测试流量标头规则。在**测试流量路由**下，指定以下内容：

      1. 选择**启用测试流量标头规则**，以便在测试期间将特定请求路由到绿色服务修订版。

      1. 对于**标头匹配规则**，配置路由测试流量的条件：
         + **标头名称**：输入要匹配的 HTTP 标头名称（例如 `X-Test-Version` 或 `User-Agent`）。
         + **匹配类型**：选择匹配条件：
           + **精确匹配**：路由标头值与指定值完全匹配的请求
           + **标头存在性**：路由包含指定标头的请求，无论其值如何
           + **模式匹配**：路由标头值与指定模式匹配的请求
         + **标头值**（如果使用精确匹配或模式匹配）：输入要匹配的值或模式。

         可以添加多个标头匹配规则以创建复杂的路由逻辑。与任何已配置规则相匹配的请求将路由到绿色服务修订版进行测试。

      1. 选择**添加标头规则**以配置其他标头匹配条件。
**注意**  
测试流量标头规则有助于在完成全面部署之前使用受控流量验证新功能。这将允许您使用特定请求（例如来自内部测试工具或测试用户的请求）来测试绿色服务修订版，同时维持流向蓝色服务修订版的正常流量。

   1. （可选）指定日志配置。选择**使用日志收集**。默认选项将容器日志发送到 CloudWatch Logs。其他日志驱动程序选项都使用 AWS FireLens 进行配置。有关更多信息，请参阅 [将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner](using_firelens.md)。

      下面更详细地介绍了每个容器日志目标。
      + **Amazon CloudWatch** – 将任务配置为将容器日志发送到 CloudWatch Logs。提供了默认的日志驱动程序选项，用于代表您创建 CloudWatch 日志组。要指定其他日志组名称，请更改驱动程序选项值。
      + **Amazon Data Firehose** – 将任务配置为将容器日志发送到 Firehose。提供了默认的日志驱动程序选项，这些选项将日志发送到 Firehose 传输流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon Kinesis Data Streams** – 将任务配置为将容器日志发送到 Kinesis Data Streams。提供了默认的日志驱动程序选项，这些选项将日志发送到 Kinesis Data Streams 流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon OpenSearch Service** – 将任务配置为将容器日志发送到 OpenSearch Service 域。必须提供日志驱动程序选项。
      + **Amazon S3** – 将任务配置为将容器日志发送到 Amazon S3 存储桶。提供了默认的日志驱动程序选项，但您必须指定有效的 Amazon S3 存储桶名称。

1. （可选）为蓝绿部署配置 **Load balancing**。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/deploy-blue-green-service.html)

1. （可选）为了帮助确定您的服务和任务，请展开**标签**部分，然后配置您的标签。

   要让 Amazon ECS 使用集群名称和任务定义标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**任务定义**。

   要让 Amazon ECS 使用集群名称和服务标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**服务**。

   添加或删除标签。
   + [添加标签] 选择 **Add tag**（添加标签），然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

1. 选择**创建**。

------
#### [ AWS CLI ]

1. 使用以下内容创建名为 `service-definition.json` 的文件。

   将 *user-input* 替换为您的值。

   ```
   {
     "serviceName": "myBlueGreenService",
     "cluster": "arn:aws:ecs:us-west-2:123456789012:cluster/sample-fargate-cluster",
     "taskDefinition": "sample-fargate:1",
     "desiredCount": 5,
     "launchType": "FARGATE",
     "networkConfiguration": {
       "awsvpcConfiguration": {
         "subnets": [
           "subnet-09ce6e74c116a2299",
           "subnet-00bb3bd7a73526788",
           "subnet-0048a611aaec65477"
         ],
         "securityGroups": [
           "sg-09d45005497daa123"
         ],
         "assignPublicIp": "ENABLED"
       }
     },
     "deploymentController": {
       "type": "ECS"
     },
     "deploymentConfiguration": {
       "strategy": "BLUE_GREEN",
       "maximumPercent": 200,
       "minimumHealthyPercent": 100,
       "bakeTimeInMinutes": 2,
       "alarms": {
         "alarmNames": [
           "myAlarm"
         ],
         "rollback": true,
         "enable": true
       },
       "lifecycleHooks": [
         {
           "hookTargetArn": "arn:aws:lambda:us-west-2:7123456789012:function:checkExample",
           "roleArn": "arn:aws:iam::123456789012:role/ECSLifecycleHookInvoke",
           "lifecycleStages": [
             "PRE_SCALE_UP"
           ]
         }
       ]
     },
     "loadBalancers": [
       {
         "targetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/blue-target-group/54402ff563af1197",
         "containerName": "fargate-app",
         "containerPort": 80,
         "advancedConfiguration": {
           "alternateTargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/green-target-group/cad10a56f5843199",
           "productionListenerRule": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-blue-green-demo/32e0e4f946c3c05b/9cfa8c482e204f7d/831dbaf72edb911",
           "roleArn": "arn:aws:iam::123456789012:role/LoadBalancerManagementforECS"
         }
       }
     ]
   }
   ```

1. 运行 `create-service`。

   将 *user-input* 替换为您的值。

   ```
   aws ecs create-service --cli-input-json file://service-definition.json
   ```

   或者，也可以使用以下示例，该示例使用负载均衡器配置创建蓝绿部署服务：

   ```
   aws ecs create-service \
      --cluster "arn:aws:ecs:us-west-2:123456789012:cluster/MyCluster" \
      --service-name "blue-green-example-service" \
      --task-definition "nginxServer:1" \
      --launch-type "FARGATE" \
      --network-configuration "awsvpcConfiguration={subnets=[subnet-12345,subnet-67890,subnet-abcdef,subnet-fedcba],securityGroups=[sg-12345],assignPublicIp=ENABLED}" \
      --desired-count 3 \
      --deployment-controller "type=ECS" \
      --deployment-configuration "strategy=BLUE_GREEN,maximumPercent=200,minimumHealthyPercent=100,bakeTimeInMinutes=0" \
      --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/MyBGtg1/abcdef1234567890,containerName=nginx,containerPort=80,advancedConfiguration={alternateTargetGroupArn=arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/MyBGtg2/0987654321fedcba,productionListenerRule=arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/MyLB/1234567890abcdef/1234567890abcdef,roleArn=arn:aws:iam::123456789012:role/ELBManagementRole}"
   ```

------

## 后续步骤
<a name="deploy-blue-green-service-next-steps"></a>
+ 更新服务以启动部署。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。
+ 监控部署过程，确保其遵循蓝绿模式：
  + 创建绿色服务修订版并进行纵向扩展
  + 将测试流量路由到绿色修订（如果已配置）
  + 向绿色服务修订转移生产流量
  + 烘焙时间结束后，蓝色修订将终止

# 排查 Amazon ECS 蓝绿部署问题
<a name="troubleshooting-blue-green"></a>

以下内容为您提供在使用 Amazon ECS 进行蓝绿部署时可能出现的常见问题的解决方案。以下阶段可能会发生蓝绿部署错误：
+ *同步路径*：响应 `CreateService` 或 `UpdateService` API 调用时立即出现的错误。
+ *异步路径*：出现在 `DescribeServiceDeployments` 的 `statusReason` 字段中并导致部署回滚的错误

**提示**  
您可以将 [Amazon ECS MCP 服务器](ecs-mcp-introduction.md) 与人工智能助手结合使用，通过自然语言监控部署和排查部署问题。

## 负载均衡器配置问题
<a name="troubleshooting-blue-green-load-balancer"></a>

负载均衡器配置是 Amazon ECS 中蓝绿部署的关键组成部分。适当配置侦听器规则、目标组和负载均衡器类型对于成功部署至关重要。本部分介绍可能导致蓝绿部署失败的常见负载均衡器配置问题。

排查负载均衡器问题时，了解侦听器规则与目标组之间的关系十分重要。在蓝绿部署中：
+ 生产侦听器规则会将流量定向到当前处于活动状态（蓝色）的服务版本
+ 可以使用测试侦听器规则在转移生产流量之前验证新的（绿色）服务版本
+ 目标组用于从每个服务版本中注册容器实例
+ 部署过程中，可以通过调整侦听器规则中目标组的权重，将流量逐渐从蓝色服务版本转移到绿色服务版本

### 侦听器规则配置错误
<a name="troubleshooting-blue-green-listener-rules"></a>

以下问题与蓝绿部署的侦听器规则配置不正确有关。

使用应用程序负载均衡器侦听器 ARN 而不是侦听器规则 ARN  
*错误消息*：`productionListenerRule has an invalid ARN format. Must be RuleArn for ALB or ListenerArn for NLB. Got: arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-alb/abc123/def456`  
*解决方案*：使用应用程序负载均衡器时，必须为 `productionListenerRule` 和 `testListenerRule` 指定侦听器规则 ARN，而不是侦听器 ARN。对于网络负载均衡器，则必须使用侦听器 ARN。  
 有关如何查找侦听器 ARN 的更多信息，请参阅《应用程序负载均衡器用户指南》**中的[应用程序负载均衡器的侦听器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html)。规则的 ARN 格式为 `arn:aws:elasticloadbalancing:region:account-id:listener-rule/app/...`。

为生产和测试侦听器使用相同的规则  
*错误消息*：`The following rules cannot be used as both production and test listener rules: arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-alb/abc123/def456/ghi789`  
*解决方案*：您必须为生产和测试流量使用不同的侦听器规则。为路由到测试目标组的测试流量创建单独的侦听器规则。

不与侦听器规则关联的目标组  
*错误消息*：`Service deployment rolled back because of invalid networking configuration: Target group arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/myAlternateTG/abc123 is not associated with either productionListenerRule or testListenerRule.`  
*解决方案*：主要目标组和替代目标组都必须与生产侦听器规则或测试侦听器规则相关联。更新您的负载均衡器配置，以确保两个目标组都与您的侦听器规则适当关联。

应用程序负载均衡器缺少测试侦听器规则  
*错误消息*：`For Application LoadBalancer, testListenerRule is required when productionListenerRule is not associated with both targetGroup and alternateTargetGroup`  
*解决方案*：使用应用程序负载均衡器时，如果两个目标组都不与生产侦听器规则关联，则您必须指定测试侦听器规则。在配置中添加 `testListenerRule`，并确保两个目标组都与生产或测试侦听器规则相关联。有关更多信息，请参阅《应用程序负载均衡器用户指南》**中的[应用程序负载均衡器的侦听器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html)。

### 目标组配置错误
<a name="troubleshooting-blue-green-target-groups"></a>

以下问题与蓝绿部署的目标组配置不正确有关。

侦听器规则中有流量的多个目标组  
*错误消息*：`Service deployment rolled back because of invalid networking configuration. productionListenerRule arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-alb/abc123/def456/ghi789 should have exactly one target group serving traffic but found 2 target groups which are serving traffic`  
*解决方案*：在开始蓝绿部署之前，请确保侦听器规则中只有一个目标组在接收流量（权重不为零）。更新您的侦听器规则配置，将任何不应接收流量的目标组的权重设置为零。

在负载均衡器条目间复制目标组  
*错误消息*：`Duplicate targetGroupArn found: arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/myecs-targetgroup/abc123`  
*解决方案*：每个目标组 ARN 在服务定义的所有负载均衡器条目中必须是唯一的。查看您的配置，并确保为每个负载均衡器条目使用不同的目标组。

生产侦听器规则中出现意外的目标组  
*错误消息*：`Service deployment rolled back because of invalid networking configuration. Production listener rule is forwarding traffic to unexpected target group arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/random-nlb-tg/abc123. Expected traffic to be forwarded to either targetGroupArn: arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/nlb-targetgroup/def456 or alternateTargetGroupArn: arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/nlb-tg-alternate/ghi789`  
*解决方案*：生产侦听器规则正在将流量转发到未在服务定义中指定的目标组。确保将侦听器规则配置为，仅将流量转发到服务定义中指定的目标组。  
有关更多信息，请参阅《应用程序负载均衡器用户指南》**中的[转发操作](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#forward-actions)。

### 负载均衡器类型配置错误
<a name="troubleshooting-blue-green-load-balancer-types"></a>

以下问题与蓝绿部署的负载均衡器类型配置不正确有关。

经典负载均衡器和应用程序负载均衡器或网络负载均衡器的混合配置  
*错误消息*：`All loadBalancers must be strictly either ELBv1 (defining loadBalancerName) or ELBv2 (defining targetGroupArn)`  
经典负载均衡器是 Elastic Load Balancing 的上一代负载均衡器。建议您迁移到当前一代负载均衡器。有关更多信息，请参阅[迁移您的经典负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/migrate-classic-load-balancer.html)。
*解决方案：*或是使用所有的经典负载均衡器，或是使用所有的应用程序负载均衡器和网络负载均衡器。  
对于应用程序负载均衡器和网络负载均衡器，请仅指定 `targetGroupArn` 字段。

将高级配置与经典负载均衡器结合使用  
*错误消息*：`advancedConfiguration field is not allowed with ELBv1 loadBalancers`  
*解决方案*：仅在应用程序负载均衡器和网络负载均衡器中支持蓝绿部署高级配置。如果您使用经典负载均衡器（使用 `loadBalancerName` 指定），则无法使用 `advancedConfiguration` 字段。要么切换到应用程序负载均衡器，要么移除 `advancedConfiguration` 字段。

负载均衡器间的高级配置不一致  
*错误消息*：`Either all or none of the provided loadBalancers must have advancedConfiguration defined`  
*解决方案*：如果您使用多个负载均衡器，则必须为所有负载均衡器定义 `advancedConfiguration`，或者不为其中的任何一个定义。更新您的配置，以确保所有负载均衡器条目的一致性。

蓝绿部署缺少高级配置  
*错误消息*：`advancedConfiguration field is required for all loadBalancers when using a non-ROLLING deployment strategy`  
*解决方案*：将应用程序负载均衡器与蓝绿部署策略结合使用时，必须为所有负载均衡器条目指定 `advancedConfiguration` 字段。将所需的 `advancedConfiguration` 添加到您的负载均衡器配置中。

## 权限问题
<a name="troubleshooting-blue-green-permissions"></a>

以下问题与蓝绿部署权限不足有关。

缺少关于基础设施角色的信任策略  
*错误消息*：`Service deployment rolled back because of invalid networking configuration. ECS was unable to manage the ELB resources due to missing permissions on ECS Infrastructure Role 'arn:aws:iam::123456789012:role/Admin'.`  
*解决方案*：为管理负载均衡器资源而指定的 IAM 角色不具有正确的信任策略。更新角色的信任策略，以允许服务担任角色。信任策略必须包括：    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

负载均衡器角色缺少读取权限  
*错误消息*：`service myService failed to describe target health on target-group myTargetGroup with (error User: arn:aws:sts::123456789012:assumed-role/myELBRole/ecs-service-scheduler is not authorized to perform: elasticloadbalancing:DescribeTargetHealth because no identity-based policy allows the elasticloadbalancing:DescribeTargetHealth action)`  
*解决方案*：用于管理负载均衡器资源的 IAM 角色不具有读取目标运行状况信息的权限。将 `elasticloadbalancing:DescribeTargetHealth` 权限添加到角色的策略。有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。

负载均衡器角色缺少写入权限  
*错误消息*：`service myService failed to register targets in target-group myTargetGroup with (error User: arn:aws:sts::123456789012:assumed-role/myELBRole/ecs-service-scheduler is not authorized to perform: elasticloadbalancing:RegisterTargets on resource: arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/myTargetGroup/abc123 because no identity-based policy allows the elasticloadbalancing:RegisterTargets action)`  
*解决方案*：用于管理负载均衡器资源的 IAM 角色不具有注册目标的权限。将 `elasticloadbalancing:RegisterTargets` 权限添加到角色的策略。有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。

缺少修改侦听器规则的权限  
*错误消息*：`Service deployment rolled back because TEST_TRAFFIC_SHIFT lifecycle hook(s) failed. User: arn:aws:sts::123456789012:assumed-role/myELBRole/ECSNetworkingWithELB is not authorized to perform: elasticloadbalancing:ModifyListener on resource: arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-alb/abc123/def456 because no identity-based policy allows the elasticloadbalancing:ModifyListener action`  
*解决方案*：用于管理负载均衡器资源的 IAM 角色不具有修改侦听器的权限。将 `elasticloadbalancing:ModifyListener` 权限添加到角色的策略。有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。

对于蓝绿部署，建议将 `AmazonECS-ServiceLinkedRolePolicy` 托管策略附加到您的基础设施角色，其中包括管理负载均衡器资源的所有必要权限。

## 生命周期挂钩问题
<a name="troubleshooting-blue-green-lifecycle-hooks"></a>

以下问题与蓝绿部署中的生命周期挂钩有关。

Lambda 挂钩角色的信任策略不正确  
*错误消息*：`Service deployment rolled back because TEST_TRAFFIC_SHIFT lifecycle hook(s) failed. ECS was unable to assume role arn:aws:iam::123456789012:role/Admin`  
*解决方案*：为 Lambda 生命周期挂钩指定的 IAM 角色不具有正确的信任策略。更新角色的信任策略，以允许服务担任角色。信任策略必须包括：    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

Lambda 挂钩返回 FAILED 状态  
*错误消息*：`Service deployment rolled back because TEST_TRAFFIC_SHIFT lifecycle hook(s) failed. Lifecycle hook target arn:aws:lambda:us-west-2:123456789012:function:myHook returned FAILED status.`  
*解决方案*：指定为生命周期挂钩的 Lambda 函数返回 FAILED 状态。查看 Amazon CloudWatch Logs 中的 Lambda 函数日志，以确定失败原因，然后更新函数以正确处理部署事件。

缺少调用 Lambda 函数的权限  
*错误消息*：`Service deployment rolled back because TEST_TRAFFIC_SHIFT lifecycle hook(s) failed. ECS was unable to invoke hook target arn:aws:lambda:us-west-2:123456789012:function:myHook due to User: arn:aws:sts::123456789012:assumed-role/myLambdaRole/ECS-Lambda-Execution is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-west-2:123456789012:function:myHook because no identity-based policy allows the lambda:InvokeFunction action`  
*解决方案*：用于 Lambda 生命周期挂钩的 IAM 角色不具有调用 Lambda 函数的权限。为特定的 Lambda 函数 ARN 向角色的策略添加 `lambda:InvokeFunction` 权限。有关最低权限的更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

Lambda 函数超时或响应无效  
*错误消息*：`Service deployment rolled back because TEST_TRAFFIC_SHIFT lifecycle hook(s) failed. ECS was unable to parse the response from arn:aws:lambda:us-west-2:123456789012:function:myHook due to HookStatus must not be null`  
*解决方案*：Lambda 函数超时，或返回了无效的响应。请确保您的 Lambda 函数返回 `hookStatus` 字段被设置为 `SUCCEEDED` 或 `FAILED` 的有效响应。此外，请检查 Lambda 函数超时是否设置得适合您的验证逻辑。有关更多信息，请参阅 [适用于 Amazon ECS 服务部署的生命周期挂钩](deployment-lifecycle-hooks.md)。  
有效的 Lambda 响应示例：  

```
{
  "hookStatus": "SUCCEEDED",
  "reason": "Validation passed"
}
```

# Amazon ECS 线性部署
<a name="deployment-type-linear"></a>

随着时间推移，线性部署会逐渐以相等增量将流量从旧服务修订转移到新服务修订，使您能够在继续下一步之前监控每个步骤。借助 Amazon ECS 线性部署，您可以控制流量转移的速度，并随着生产流量不断增加验证新的服务修订。这种方法提供了一种受控的方式来部署更改，并且能够监控每个增量的性能。

## 线性部署涉及的资源
<a name="linear-deployment-resources"></a>

下面是 Amazon ECS 线性部署涉及的资源：
+ 流量转移：Amazon ECS 用于转移生产流量的过程。对于 Amazon ECS 线性部署，流量以相等百分比增量转移，每个增量之间的等待时间可配置。
+ 步骤百分比：线性部署期间每个增量中要转移的流量百分比。此字段采用双精度值，有效值是 3.0 到 100.0。
+ 步骤烘焙时间：线性部署期间每个流量转移增量之间等待的持续时间。有效值是 0 到 1440 分钟。
+ 部署烘焙时间：Amazon ECS 将所有生产流量转移到新服务修订后，在终止旧服务修订之前等待的时间（以分钟为单位）。这是生产流量转移后蓝色服务修订和绿色服务修订同时运行的持续时间。
+ 生命周期阶段：部署操作中的一系列事件，例如“生产流量转移后”。
+ 生命周期挂钩：在特定生命周期阶段运行的 Lambda 函数。您可以创建一个函数来验证部署。为 PRODUCTION\$1TRAFFIC\$1SHIFT 配置的 Lambda 函数或生命周期挂钩将在每个生产流量转移步骤中被调用。
+ 目标组：一种 Elastic Load Balancing 资源，用于将请求路由到一个或多个已注册目标（例如 EC2 实例）。创建侦听器时，您为其默认操作指定目标组。流量将转发到在侦听器规则中指定的目标组。
+ 侦听器：一种 Elastic Load Balancing 资源，可通过所配置的协议和端口检查连接请求。为侦听器定义的规则决定了 Amazon ECS 如何将请求路由到其注册的目标。
+ 规则：与侦听器关联的 Elastic Load Balancing 资源。规则定义了请求的路由方式，由操作、条件和优先级组成。

## 注意事项
<a name="linear-deployment-considerations"></a>

选择部署类型时，请考虑以下因素：
+ 资源使用量：线性部署会暂时同时运行蓝色服务修订和绿色服务修订，这可能会使部署期间的资源使用量翻一番。
+ 部署监控：线性部署会提供详细的部署状态信息，允许您监控部署过程的每个阶段和每个流量转移增量。
+ 回滚：如果检测到问题，线性部署可以更轻松地回滚到先前版本，因为蓝色修订会一直运行直到烘焙时间到期。
+ 逐步验证：线性部署允许您随着生产流量不断增加验证新版本，从而增强部署的信心。
+ 部署持续时间：由于流量转移是以增量方式进行的，并且步骤之间存在等待时间，因此线性部署比一次性部署需要更长时间才能完成。

## 线性部署的工作原理
<a name="linear-deployment-how-works"></a>

Amazon ECS 线性部署过程遵循结构化方法，包含六个不同的阶段，可确保安全可靠地进行应用程序更新。在验证应用程序并将其从当前版本（蓝色环境）迁移到新版本（绿色环境）时，每个阶段都有其特定目的。

1. 准备阶段：在现有的蓝色环境旁创建绿色环境。

1. 部署阶段：将新的服务修订版部署到绿色环境。Amazon ECS 使用更新的服务修订版启动新任务，同时蓝色环境继续传送生产流量。

1. 测试阶段：使用测试流量路由来验证绿色环境。应用程序负载均衡器将测试请求定向到绿色环境，而生产流量仍保留在蓝色环境中。

1. 线性流量转移阶段：根据您配置的部署策略，以相等百分比增量将生产流量从蓝色逐渐转移为绿色。

1. 监控阶段：监控烘焙时间内的应用程序运行状况、性能指标和警报状态。检测到问题时将启动回滚操作。

1. 完成阶段：通过终止蓝色环境来完成部署。

线性流量转移阶段遵循下面的步骤：
+ 初始：部署开始时，100% 的流量都路由到蓝色（当前）服务修订。绿色（新）服务修订接收测试流量，但是最初不接收生产流量。
+ 增量流量转移：流量以相等百分比增量从蓝色逐渐转移为绿色。例如，在 10.0% 的步骤配置中，流量转移过程如下：
  + 步骤 1：10.0% 变为绿色，90.0% 变为蓝色
  + 步骤 2：20.0% 变为绿色，80.0% 变为蓝色
  + 步骤 3：30.0% 变为绿色，70.0% 变为蓝色
  + 依此类推，直到 100% 变为绿色
+ 步骤烘焙时间：在每个流量转移增量之间，部署将等待可配置的持续时间（步骤烘焙时间），以便在流量负载增加的情况下监控和验证新修订的性能。请注意，一旦流量转移 100.0% 后，将跳过最后一步烘焙时间。
+ 生命周期挂钩：可选的 Lambda 函数可以在部署期间的各个生命周期阶段执行，以执行自动化验证、监控或自定义逻辑。为 PRODUCTION\$1TRAFFIC\$1SHIFT 配置的 Lambda 函数或生命周期挂钩将在每个生产流量转移步骤中被调用。

## 部署生命周期阶段
<a name="linear-deployment-lifecycle-stages"></a>

线性部署过程会经历不同的生命周期阶段，每个阶段都有特定职责和验证检查点。了解这些阶段有助于监控部署进度并有效排查问题。

每个生命周期阶段最多可持续 24 小时，此外，PRODUCTION\$1TRAFFIC\$1SHIFT 中的每个流量转移步骤最多可持续 24 小时。建议将该值保持在 24 小时以内。这是因为异步进程需要时间来触发挂钩。当一个阶段达到 24 小时后，系统将超时，导致部署失败，然后会启动回滚。

CloudFormation 部署还有其他超时限制。尽管 24 小时的阶段限制仍然有效，但 CloudFormation 会对整个部署强制执行 36 小时的限制。如果整个过程未在 36 小时内完成，CloudFormation 将使部署失败，然后启动回滚。


| 生命周期阶段 | 说明 | 生命周期挂钩支持 | 
| --- | --- | --- | 
| RECONCILE\$1SERVICE | 仅当启动多个服务修订版处于活动状态的新服务部署时，才会发生此阶段。 | 是 | 
| PRE\$1SCALE\$1UP | 绿色服务修订版尚未启动。蓝色服务修订版正在处理 100% 的生产流量。没有测试流量。 | 是 | 
| SCALE\$1UP | 绿色服务修订版纵向扩展至 100% 并启动新任务的时间。此时绿色服务修订版不传送任何流量。 | 否 | 
| POST\$1SCALE\$1UP | 绿色服务修订版已经启动。蓝色服务修订版正在处理 100% 的生产流量。没有测试流量。 | 是 | 
| TEST\$1TRAFFIC\$1SHIFT | 蓝色服务修订版和绿色服务修订版正在运行。蓝色服务修订版可处理 100% 的生产流量。绿色服务修订版正在将测试流量从 0% 迁移到 100%。 | 是 | 
| POST\$1TEST\$1TRAFFIC\$1SHIFT | 测试流量转移已完成。绿色服务修订版可处理 100% 的测试流量。 | 是 | 
| PRODUCTION\$1TRAFFIC\$1SHIFT | 流量以相等百分比增量逐渐从蓝色转移为绿色，直到绿色接收 100% 的流量。每次流量转移都会调用具有 24 小时超时的生命周期挂钩。 | 
| POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT | 生产流量转移已完成。 | 是 | 
| BAKE\$1TIME | 蓝色服务修订版和绿色服务修订版同时运行的持续时间。 | 否 | 
| CLEAN\$1UP | 蓝色服务修订版已完全缩减至 0 个运行任务。在此阶段之后，绿色服务修订版将成为生产服务修订版。 | 否 | 

# Amazon ECS 线性部署所需的资源
<a name="linear-deployment-implementation"></a>

要使用支持托管流量转移的线性部署，服务必须使用以下功能之一：
+ Elastic Load Balancing
+ Service Connect

以下列表简要概述了配置 Amazon ECS 线性部署所需的内容：
+ 服务使用应用程序负载均衡器、网络负载均衡器或 Service Connect。配置相应的资源。
  + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
  + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
  + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。
+ 将服务部署控制器设置为 `ECS`。
+ 在服务定义中将部署策略配置为 `linear`。
+ 或者，配置其他参数，例如：
  + 新部署的烘焙时间
  + 每个增量中要转移的流量百分比。
  + 每个流量转移增量之间等待的持续时间（以分钟为单位）。
  + 用于自动回滚的 CloudWatch 警报
  + 部署生命周期挂钩（这些是在指定的部署阶段运行的 Lambda 函数，例如 BEFORE\$1INSTALL、PRODUCTION\$1TRAFFIC\$1SHIFT 或 POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT）

## 最佳实践
<a name="linear-deployment-best-practices"></a>

请遵循下面的最佳实践以成功进行 Amazon ECS 线性部署：
+ **确保您的应用程序可以处理同时运行的两个服务修订。**
+ **规划足够的集群容量，以便在部署期间处理两个服务修订。**
+ **在生产环境中实施回滚程序之前，先对其进行测试。**
+ 配置适当的运行状况检查，以准确反映应用程序的运行状况。
+ 设置一个烘焙时间，以便充分测试新的服务修订。
+ 实施 CloudWatch 警报，以自动检测问题并触发回滚。
+ 选择步骤百分比和烘焙时间，以平衡部署速度和验证需求。
+ 对关键应用程序使用较小步骤百分比（5-10%），以最大程度地降低风险。
+ 对于需要时间预热或稳定的应用程序，设置更长的步骤烘焙时间。
+ 实施 CloudWatch 警报，以任何流量增量自动检测问题并触发回滚。
+ 在每次流量转移期间密切监控应用程序指标，以便及早检测性能下降。
+ 确保您的应用程序可以处理同时运行的两个服务修订。
+ 在生产环境中实施回滚过程之前，先在不同的流量百分比下对其进行测试。

# 创建 Amazon ECS 线性部署
<a name="deploy-linear-service"></a>

通过使用 Amazon ECS 线性部署，您可以按照指定的时间间隔以相等增量逐渐转移流量。这可以为部署过程的每个步骤提供受控验证。

## 先决条件
<a name="deploy-linear-service-prerequisites"></a>

在开始线性部署之前，请执行以下操作。

1. 配置相应的权限。
   + 有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。
   + 有关最低权限的更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

1. Amazon ECS 线性部署要求服务使用以下功能之一：配置合适的资源。
   + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
   + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
   + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。

## 过程
<a name="deploy-linear-service-procedure"></a>

您可以使用控制台或 AWS CLI 创建 Amazon ECS 线性部署服务。

------
#### [ Console ]

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

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

   此时会显示**创建服务**页面。

1. 在**服务详细信息**下，执行以下操作：

   1. 对于**任务定义系列**，选择要使用的任务定义。然后，在**任务定义修订**中，输入要使用的修订。

   1. 对于 **Service name**（服务名称），为您的服务输入一个名称。

1. 要在现有集群中运行服务，请为**现有集群**选择集群。要在新集群中运行服务，请选择**创建集群** 

1. 选择任务在集群基础设施中的分发方式。在**计算配置**下，选择您的选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/deploy-linear-service.html)

1. 在**部署配置**下，执行以下操作：

   1. 对于**服务类型**，选择**副本**。

   1. 对于 **Desired tasks**（预期任务），输入要在服务中启动并保留的任务数量。

   1. 要让 Amazon ECS 监控可用区之间的任务分配情况，并在出现不平衡时重新分配任务，请在**可用区服务重新平衡**下选择**可用区服务重新平衡**。

   1. 对于**运行状况检查宽限期**，输入在任务首次启动后，服务调度程序将忽略运行状况不佳的 Elastic Load Balancing、VPC Lattice 和容器运行状况检查的时间长度（以秒为单位）。如果没有指定运行状况检查宽限期值，则使用默认值 0。

1. 在**部署配置**下，配置线性部署设置：

   1. 对于**部署策略**，选择**线性**。

   1. 对于**流量增量百分比**，输入每个增量中要转移的流量百分比（例如，10% 以 10% 增量转移流量）。

   1. 对于**增量之间的间隔**，输入每个流量转移增量之间等待的时间（以分钟为单位）。

   1. 对于**烘焙时间**，输入在蓝色修订终止之前，蓝色服务修订和绿色服务修订在最终流量转移之后同时运行的分钟数。

   1. （可选）在部署的特定阶段运行 Lambda 函数。在**部署生命周期挂钩**下，选择要运行生命周期挂钩的阶段。

      要添加生命周期挂钩，请执行以下操作：

      1. 选择**添加**。

      1. 对于 **Lambda 函数**，输入函数名称或 ARN。

      1. 对于**角色**，选择有权调用 Lambda 函数的 IAM 角色。

      1. 对于**生命周期阶段**，选择应运行 Lambda 函数的阶段。

1. 要配置 Amazon ECS 如何检测和处理部署故障，请展开 **Deployment failure detection**（部署故障检测），然后选择您的选项。

   1. 要在任务无法启动时停止部署，请选择 **Use the Amazon ECS deployment circuit breaker**（使用 Amazon ECS 部署断路器）。

      要让软件在部署断路器将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

   1. 要根据应用程序指标停止部署，请选择**使用 CloudWatch 警报**。然后，从 **CloudWatch 警报名称**中选择警报。要创建新报警，请转到 CloudWatch 控制台。

      要让软件在 CloudWatch 警报将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

1. （可选）要使用 Service Connect 与服务进行互连，请展开 **Service Connect**，然后指定以下参数：

   1.  选择**打开 Service Connect**。

   1. 在 **Service Connect configuration**（Service Connect 配置）下，指定客户端模式。
      + 如果您的服务运行的网络客户端应用程序只需要连接到命名空间中的其他服务，请选择**仅限客户端**。
      + 如果您的服务运行网络或 Web 服务应用程序且需要为该服务提供端点并连接到命名空间中的其他服务，请选择 **Client and server**（客户端和服务器）。

   1. 要使用默认集群命名空间以外的命名空间，对于**命名空间**，请选择服务命名空间。这可以是您在 AWS 账户的同一 AWS 区域中单独创建的命名空间，也可以是使用 AWS Resource Access Manager（AWS RAM）与您的账户共享的同一区域中的命名空间。有关共享 AWS Cloud Map 命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)。

   1. （可选）为线性部署配置测试流量标头规则。在**测试流量路由**下，指定以下内容：

      1. 选择**启用测试流量标头规则**，以便在测试期间将特定请求路由到绿色服务修订版。

      1. 对于**标头匹配规则**，配置路由测试流量的条件：
         + **标头名称**：输入要匹配的 HTTP 标头名称（例如 `X-Test-Version` 或 `User-Agent`）。
         + **匹配类型**：选择匹配条件：
           + **精确匹配**：路由标头值与指定值完全匹配的请求
           + **标头存在性**：路由包含指定标头的请求，无论其值如何
           + **模式匹配**：路由标头值与指定模式匹配的请求
         + **标头值**（如果使用精确匹配或模式匹配）：输入要匹配的值或模式。

         可以添加多个标头匹配规则以创建复杂的路由逻辑。与任何已配置规则相匹配的请求将路由到绿色服务修订版进行测试。

      1. 选择**添加标头规则**以配置其他标头匹配条件。
**注意**  
测试流量标头规则有助于在完成全面部署之前使用受控流量验证新功能。这将允许您使用特定请求（例如来自内部测试工具或测试用户的请求）来测试绿色服务修订版，同时维持流向蓝色服务修订版的正常流量。

   1. （可选）指定日志配置。选择**使用日志收集**。默认选项将容器日志发送到 CloudWatch Logs。其他日志驱动程序选项都使用 AWS FireLens 进行配置。有关更多信息，请参阅 [将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner](using_firelens.md)。

      下面更详细地介绍了每个容器日志目标。
      + **Amazon CloudWatch** – 将任务配置为将容器日志发送到 CloudWatch Logs。提供了默认的日志驱动程序选项，用于代表您创建 CloudWatch 日志组。要指定其他日志组名称，请更改驱动程序选项值。
      + **Amazon Data Firehose** – 将任务配置为将容器日志发送到 Firehose。提供了默认的日志驱动程序选项，这些选项将日志发送到 Firehose 传输流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon Kinesis Data Streams** – 将任务配置为将容器日志发送到 Kinesis Data Streams。提供了默认的日志驱动程序选项，这些选项将日志发送到 Kinesis Data Streams 流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon OpenSearch Service** – 将任务配置为将容器日志发送到 OpenSearch Service 域。必须提供日志驱动程序选项。
      + **Amazon S3** – 将任务配置为将容器日志发送到 Amazon S3 存储桶。提供了默认的日志驱动程序选项，但您必须指定有效的 Amazon S3 存储桶名称。

1. （可选）为线性部署配置**负载均衡**。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/deploy-linear-service.html)

1. （可选）为了帮助确定您的服务和任务，请展开**标签**部分，然后配置您的标签。

   要让 Amazon ECS 使用集群名称和任务定义标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**任务定义**。

   要让 Amazon ECS 使用集群名称和服务标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**服务**。

   添加或删除标签。
   + [添加标签] 选择 **Add tag**（添加标签），然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

1. 选择**创建**。

------
#### [ AWS CLI ]

1. 使用以下内容创建名为 `linear-service-definition.json` 的文件。

   将 *user-input* 替换为您的值。

   ```
   {
     "serviceName": "myLinearService",
     "cluster": "arn:aws:ecs:us-west-2:123456789012:cluster/sample-fargate-cluster",
     "taskDefinition": "sample-fargate:1",
     "desiredCount": 5,
     "launchType": "FARGATE",
     "networkConfiguration": {
       "awsvpcConfiguration": {
         "subnets": [
           "subnet-09ce6e74c116a2299",
           "subnet-00bb3bd7a73526788",
           "subnet-0048a611aaec65477"
         ],
         "securityGroups": [
           "sg-09d45005497daa123"
         ],
         "assignPublicIp": "ENABLED"
       }
     },
     "deploymentController": {
       "type": "ECS"
     },
     "deploymentConfiguration": {
       "strategy": "LINEAR",
       "maximumPercent": 200,
       "minimumHealthyPercent": 100,
       "linearConfiguration": {
         "stepPercentage": 10.0,
         "stepBakeTimeInMinutes":6
       },
       "bakeTimeInMinutes": 10,
       "alarms": {
         "alarmNames": [
           "myAlarm"
         ],
         "rollback": true,
         "enable": true
       }
     },
     "loadBalancers": [
       {
         "targetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/blue-target-group/54402ff563af1197",
         "containerName": "fargate-app",
         "containerPort": 80,
         "advancedConfiguration": {
           "alternateTargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/green-target-group/cad10a56f5843199",
           "productionListenerRule": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-linear-demo/32e0e4f946c3c05b/9cfa8c482e204f7d/831dbaf72edb911",
           "roleArn": "arn:aws:iam::123456789012:role/LoadBalancerManagementforECS"
         }
       }
     ]
   }
   ```

1. 运行 `create-service`。

   ```
   aws ecs create-service --cli-input-json file://linear-service-definition.json
   ```

------

## 后续步骤
<a name="deploy-linear-service-next-steps"></a>
+ 更新服务以启动部署。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。
+ 监控部署过程，确保其遵循线性模式：
  + 创建绿色服务修订版并进行纵向扩展
  + 流量以增量方式按指定的时间间隔转移
  + 每个增量等待指定的时间间隔，然后再进行下一次转移
  + 所有流量转移后，烘焙时间开始
  + 烘焙时间结束后，蓝色修订将终止

# Amazon ECS 金丝雀部署
<a name="canary-deployment"></a>

金丝雀部署首先将一小部分流量路由到新修订进行初始测试，然后在金丝雀阶段成功完成后，一次性转移所有剩余流量。借助 Amazon ECS 金丝雀部署，请使用真实的用户流量验证新服务修订，同时最大限度地降低风险。这种方法提供了一种受控方式来部署更改，并且能够监控性能，如果检测到问题则可以快速回滚。

## 金丝雀部署涉及的资源
<a name="canary-deployment-resources"></a>

下面是 Amazon ECS 金丝雀部署涉及的资源：
+ 流量转移：Amazon ECS 用于转移生产流量的过程。对于 Amazon ECS 金丝雀部署，流量分两个阶段转移：首先转移到金丝雀百分比，然后完成部署。
+ 金丝雀百分比：评估期内路由到新版本的流量百分比。
+ 金丝雀烘焙时间：在继续进行全面部署之前监控金丝雀版本的持续时间。
+ 部署烘焙时间：Amazon ECS 将所有生产流量转移到新服务修订后，在终止旧服务修订之前等待的时间（以分钟为单位）。这是生产流量转移后蓝色服务修订和绿色服务修订同时运行的持续时间。
+ 生命周期阶段：部署操作中的一系列事件，例如“生产流量转移后”。
+ 生命周期挂钩：在特定生命周期阶段运行的 Lambda 函数。您可以创建一个函数来验证部署。
+ 目标组：一种 Elastic Load Balancing 资源，用于将请求路由到一个或多个已注册目标（例如 EC2 实例）。创建侦听器时，您为其默认操作指定目标组。流量将转发到在侦听器规则中指定的目标组。
+ 侦听器：一种 Elastic Load Balancing 资源，可通过所配置的协议和端口检查连接请求。为侦听器定义的规则决定了 Amazon ECS 如何将请求路由到其注册的目标。
+ 规则：与侦听器关联的 Elastic Load Balancing 资源。规则定义了请求的路由方式，由操作、条件和优先级组成。

## 注意事项
<a name="canary-deployment-considerations"></a>

选择部署类型时，请考虑以下因素：
+ 资源使用情况：金丝雀部署在评估期间会同时运行原始任务集和金丝雀任务集，从而增加资源使用量。
+ 流量：确保金丝雀百分比产生足够的流量，以便对新版本进行有意义的验证。
+ 监控复杂性：金丝雀部署需要同时监控和比较两个不同版本之间的指标。
+ 回滚速度：金丝雀部署通过将流量转移回原始任务集来实现快速回滚。
+ 风险缓解：金丝雀部署通过将暴露限制在一小部分用户来提供出色的风险缓解措施。
+ 部署持续时间：金丝雀部署包括评估期，这些评估期会延长总体部署时间，但提供了验证机会。

## 金丝雀部署的工作原理
<a name="canary-how-it-works"></a>

Amazon ECS 金丝雀部署过程遵循结构化方法，包含六个不同的阶段，可确保安全可靠地进行应用程序更新。在验证应用程序并将其从当前版本（蓝色环境）迁移到新版本（绿色环境）时，每个阶段都有其特定目的。

1. 准备阶段：在现有的蓝色环境旁创建绿色环境。

1. 部署阶段：将新的服务修订版部署到绿色环境。Amazon ECS 使用更新的服务修订版启动新任务，同时蓝色环境继续传送生产流量。

1. 测试阶段：使用测试流量路由来验证绿色环境。应用程序负载均衡器将测试请求定向到绿色环境，而生产流量仍保留在蓝色环境中。

1. 金丝雀流量转移阶段：在金丝雀阶段，将配置的流量百分比转移到新的绿色服务修订，然后将 100.0% 的流量转移到绿色服务修订

1. 监控阶段：监控烘焙时间内的应用程序运行状况、性能指标和警报状态。检测到问题时将启动回滚操作。

1. 完成阶段：通过终止蓝色环境来完成部署。

金丝雀流量转移阶段遵循下面的步骤：
+ 初始：部署开始时，100% 的流量都路由到蓝色（当前）服务修订。绿色（新）服务修订接收测试流量，但是最初不接收生产流量。
+ 金丝雀流量转移：这是一个两步式流量转移策略。
  + 步骤 1：10.0% 变为绿色，90.0% 变为蓝色
  + 步骤 2：100.0% 变为绿色，0.0% 变为蓝色
+ 金丝雀烘焙时间：在金丝雀流量转移之后等待可配置的持续时间（金丝雀烘焙时间），以便在流量负载增加的情况下监控和验证新修订的性能。
+ 生命周期挂钩：可选的 Lambda 函数可以在部署期间的各个生命周期阶段执行，以执行自动化验证、监控或自定义逻辑。为 PRODUCTION\$1TRAFFIC\$1SHIFT 配置的 Lambda 函数或生命周期挂钩将在每个生产流量转移步骤中被调用。

### 部署生命周期阶段
<a name="canary-deployment-lifecycle-stages"></a>

金丝雀部署过程会经历不同的生命周期阶段，每个阶段都有特定职责和验证检查点。了解这些阶段有助于监控部署进度并有效排查问题。

每个生命周期阶段最多可持续 24 小时，此外，PRODUCTION\$1TRAFFIC\$1SHIFT 中的每个流量转移步骤最多可持续 24 小时。建议将该值保持在 24 小时以内。这是因为异步进程需要时间来触发挂钩。当一个阶段达到 24 小时后，系统将超时，导致部署失败，然后会启动回滚。

CloudFormation 部署还有其他超时限制。尽管 24 小时的阶段限制仍然有效，但 CloudFormation 会对整个部署强制执行 36 小时的限制。如果整个过程未在 36 小时内完成，CloudFormation 将使部署失败，然后启动回滚。


**生命周期阶段**  

| 生命周期阶段 | 说明 | 生命周期挂钩支持 | 
| --- | --- | --- | 
| RECONCILE\$1SERVICE | 仅当启动多个服务修订版处于活动状态的新服务部署时，才会发生此阶段。 | 是 | 
| PRE\$1SCALE\$1UP | 绿色服务修订版尚未启动。蓝色服务修订版正在处理 100% 的生产流量。没有测试流量。 | 是 | 
| SCALE\$1UP | 绿色服务修订版纵向扩展至 100% 并启动新任务的时间。此时绿色服务修订版不传送任何流量。 | 否 | 
| POST\$1SCALE\$1UP | 绿色服务修订版已经启动。蓝色服务修订版正在处理 100% 的生产流量。没有测试流量。 | 是 | 
| TEST\$1TRAFFIC\$1SHIFT | 蓝色服务修订版和绿色服务修订版正在运行。蓝色服务修订版可处理 100% 的生产流量。绿色服务修订版正在将测试流量从 0% 迁移到 100%。 | 是 | 
| POST\$1TEST\$1TRAFFIC\$1SHIFT | 测试流量转移已完成。绿色服务修订版可处理 100% 的测试流量。 | 是 | 
| PRODUCTION\$1TRAFFIC\$1SHIFT | 金丝雀生产流量将路由到绿色修订，并且会调用生命周期挂钩，超时时间为 24 小时。第二步将剩余生产流量转移到绿色修订。 | 是 | 
| POST\$1PRODUCTION\$1TRAFFIC\$1SHIFT | 生产流量转移已完成。 | 是 | 
| BAKE\$1TIME | 蓝色服务修订版和绿色服务修订版同时运行的持续时间。 | 否 | 
| CLEAN\$1UP | 蓝色服务修订版已完全缩减至 0 个运行任务。在此阶段之后，绿色服务修订版将成为生产服务修订版。 | 否 | 

### 配置参数
<a name="canary-configuration-parameters"></a>

金丝雀部署需要以下配置参数：
+ 金丝雀百分比：在金丝雀阶段路由到新服务修订的流量百分比。这使得可以使用受控的生产流量子集进行测试。
+ 金丝雀烘焙时间：将剩余流量转移到新服务修订之前在金丝雀阶段等待的持续时间。这为监控和验证新版本提供了时间。

### 流量管理
<a name="canary-traffic-management"></a>

金丝雀部署使用负载均衡器目标组来管理流量分布：
+ 原始目标组：包含来自当前稳定版本的任务，并接收大部分流量。
+ 金丝雀目标组 ：包含来自新版本的任务，并接收少量流量用于测试。
+ 加权路由：负载均衡器使用加权路由规则，根据配置的金丝雀百分比在目标组之间分配流量。

### 监控和验证
<a name="canary-monitoring-validation"></a>

有效的金丝雀部署依赖于全面监控：
+ 运行状况检查：两个任务集必须通过运行状况检查才能接收流量。
+ 指标比较：比较原始版本和金丝雀版本之间的关键性能指标，例如响应时间、错误率和吞吐量。
+ 自动回滚：配置 CloudWatch 警报，以便在金丝雀版本显示性能下降时自动触发回滚。
+ 手动验证：继续之前，请使用评估期手动查看日志、指标和用户反馈。

### 金丝雀部署的最佳实践
<a name="canary-best-practices"></a>

请遵循这些最佳实践来确保使用服务成功进行金丝雀部署。

#### 选择合适的流量百分比
<a name="canary-traffic-percentage"></a>

在选择金丝雀流量百分比时，请考虑下面的因素：
+ 从小处着手：从 5-10% 的流量开始，以尽量减少问题发生时的影响。
+ 考虑应用程序关键性：对任务关键型应用程序使用较小百分比，对不太重要的服务使用较大百分比。
+ 考虑流量：确保金丝雀百分比产生足够的流量以进行有意义的验证。

#### 设置合适的评估期
<a name="canary-evaluation-time"></a>

根据下面的注意事项配置评估期：
+ 留出足够的时间：设置足够长的评估期以捕获有意义的性能数据，通常为 10-30 分钟。
+ 考虑流量模式：考虑应用程序的流量模式和高峰使用时间。
+ 平衡速度和安全性：较长的评估期提供更多数据，但部署速度较慢。

#### 实施全面监控
<a name="canary-monitoring-setup"></a>

请设置监控以跟踪金丝雀部署性能：
+ 关键指标：监控两个任务集的响应时间、错误率、吞吐量和资源利用率。
+ 基于警报的回滚：配置 CloudWatch 警报，以在指标超过阈值时自动触发回滚。
+ 比较分析：设置控制面板，并排比较原始版本和金丝雀版本之间的指标。
+ 业务指标：包括业务特定的指标，例如转化率或用户参与度以及技术指标。

#### 规划回滚策略
<a name="canary-rollback-strategy"></a>

使用下面的策略为潜在回滚场景做好准备：
+ 自动回滚：根据运行状况检查和性能指标配置自动回滚触发器。
+ 手动回滚过程：当自动触发器无法捕获所有问题时，记录手动回滚的明确过程。
+ 回滚测试：定期测试回滚过程，以确保它们在需要时正常工作。

#### 部署之前彻底验证
<a name="canary-testing-validation"></a>

在继续进行金丝雀部署之前，确保进行彻底验证：
+ 部署前测试：在金丝雀部署之前，彻底测试暂存环境中的更改。
+ 运行状况检查配置：确保运行状况检查准确反映应用程序的就绪情况和功能。
+ 依赖项验证：验证新版本是否与下游和上游服务兼容。
+ 数据一致性：确保数据库架构更改和数据迁移向后兼容。

#### 协调团队参与
<a name="canary-team-coordination"></a>

确保在金丝雀部署期间团队之间进行有效协调：
+ 部署时间段：在工作时间安排金丝雀部署，以便团队能够进行监控和响应。
+ 通信渠道：针对部署状态和问题升级建立明确的通信渠道。
+ 角色分配：定义监控、决策和回滚执行的角色和职责。

# Amazon ECS 金丝雀部署所需的资源
<a name="canary-deployment-implementation"></a>

要使用支持托管流量转移的金丝雀部署，服务必须使用以下功能之一：
+ Elastic Load Balancing
+ Service Connect

以下列表简要概述了配置 Amazon ECS 金丝雀部署所需的内容：
+ 服务使用应用程序负载均衡器、网络负载均衡器或 Service Connect。配置相应的资源。
  + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
  + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
  + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。
+ 将服务部署控制器设置为 `ECS`。
+ 在服务定义中将部署策略配置为 `canary`。
+ 或者，配置其他参数，例如：
  + 新部署的烘焙时间
  + 在金丝雀阶段路由到新服务修订的流量百分比。
  + 将剩余流量转移到新服务修订之前在金丝雀阶段等待的持续时间。
  + 用于自动回滚的 CloudWatch 警报
  + 部署生命周期挂钩（这些挂钩是在指定部署阶段运行的 Lambda 函数）

## 最佳实践
<a name="canary-deployment-best-practices"></a>

请遵循下面的最佳实践以成功进行 Amazon ECS 金丝雀部署：
+ **确保您的应用程序可以处理同时运行的两个服务修订。**
+ **规划足够的集群容量，以便在部署期间处理两个服务修订。**
+ **在生产环境中实施回滚程序之前，先对其进行测试。**
+ 配置适当的运行状况检查，以准确反映应用程序的运行状况。
+ 设置烘焙时间，以便对绿色部署进行充分测试。
+ 实施 CloudWatch 警报，以自动检测问题并触发回滚。
+ 使用生命周期挂钩在每个部署阶段执行自动测试。
+ 从较小金丝雀百分比（5-10%）开始，以最大程度地减少出现问题时的影响。
+ 设置合适的评估期，以便有足够的时间收集有意义的性能数据。
+ 使用 CloudWatch 警报实施全面监控，以触发自动回滚。
+ 配置能够准确反映应用程序的就绪情况和功能的运行状况检查。
+ 在评估期间监控技术指标（响应时间、错误率）和业务指标。
+ 确保您的应用程序可以处理流量拆分，而不会出现会话或状态问题。
+ 规划回滚过程并定期对其进行测试，以确保它们在需要时正常工作。
+ 在工作时间安排金丝雀部署，以便团队可以进行监控和响应。
+ 在金丝雀部署之前，彻底验证暂存环境中的更改。
+ 记录人工干预和回滚决策的明确过程。

# 创建 Amazon ECS 金丝雀部署
<a name="deploy-canary-service"></a>

通过使用 Amazon ECS 金丝雀部署，您可以将一小部分流量转移到新的服务修订（“金丝雀”）。验证部署，然后在指定的时间间隔后一次性转移剩余流量。这种方法允许您在全面部署之前以最小风险测试新功能。

## 先决条件
<a name="deploy-canary-service-prerequisites"></a>

在开始金丝雀部署之前，请执行以下操作。

1. 配置相应的权限。
   + 有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。
   + 有关最低权限的更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

1. Amazon ECS 金丝雀部署要求服务使用以下功能之一：配置合适的资源。
   + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
   + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
   + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。

## 过程
<a name="deploy-canary-service-procedure"></a>

您可以使用控制台或 AWS CLI 创建 Amazon ECS 金丝雀部署服务。

------
#### [ Console ]

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

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

   此时会显示**创建服务**页面。

1. 在**服务详细信息**下，执行以下操作：

   1. 对于**任务定义系列**，选择要使用的任务定义。然后，在**任务定义修订**中，输入要使用的修订。

   1. 对于 **Service name**（服务名称），为您的服务输入一个名称。

1. 要在现有集群中运行服务，请为**现有集群**选择集群。要在新集群中运行服务，请选择**创建集群** 

1. 选择任务在集群基础设施中的分发方式。在**计算配置**下，选择您的选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/deploy-canary-service.html)

1. 在**部署配置**下，执行以下操作：

   1. 对于**服务类型**，选择**副本**。

   1. 对于 **Desired tasks**（预期任务），输入要在服务中启动并保留的任务数量。

   1. 要让 Amazon ECS 监控可用区之间的任务分配情况，并在出现不平衡时重新分配任务，请在**可用区服务重新平衡**下选择**可用区服务重新平衡**。

   1. 对于**运行状况检查宽限期**，输入在任务首次启动后，服务调度程序将忽略运行状况不佳的 Elastic Load Balancing、VPC Lattice 和容器运行状况检查的时间长度（以秒为单位）。如果没有指定运行状况检查宽限期值，则使用默认值 0。

1. 在**部署配置**下，配置金丝雀部署设置：

   1. 对于**部署策略**，选择**金丝雀**。

   1. 对于**金丝雀百分比**，输入要在第一阶段转移到绿色服务修订的流量百分比（例如，初始金丝雀流量为 10%）。

   1. 对于**金丝雀烘焙时间**，输入将剩余流量转移到绿色服务修订之前等待的时间（以分钟为单位）。

   1. 对于**烘焙时间**，输入在蓝色修订终止之前，蓝色服务修订和绿色服务修订在最终流量转移之后同时运行的分钟数。

   1. （可选）在部署的特定阶段运行 Lambda 函数。在**部署生命周期挂钩**下，选择要运行生命周期挂钩的阶段。

      要添加生命周期挂钩，请执行以下操作：

      1. 选择**添加**。

      1. 对于 **Lambda 函数**，输入函数名称或 ARN。

      1. 对于**角色**，选择有权调用 Lambda 函数的 IAM 角色。

      1. 对于**生命周期阶段**，选择应运行 Lambda 函数的阶段。

1. 要配置 Amazon ECS 如何检测和处理部署故障，请展开 **Deployment failure detection**（部署故障检测），然后选择您的选项。

   1. 要在任务无法启动时停止部署，请选择 **Use the Amazon ECS deployment circuit breaker**（使用 Amazon ECS 部署断路器）。

      要让软件在部署断路器将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

   1. 要根据应用程序指标停止部署，请选择**使用 CloudWatch 警报**。然后，从 **CloudWatch 警报名称**中选择警报。要创建新报警，请转到 CloudWatch 控制台。

      要让软件在 CloudWatch 警报将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

1. （可选）要使用 Service Connect 与服务进行互连，请展开 **Service Connect**，然后指定以下参数：

   1.  选择**打开 Service Connect**。

   1. 在 **Service Connect configuration**（Service Connect 配置）下，指定客户端模式。
      + 如果您的服务运行的网络客户端应用程序只需要连接到命名空间中的其他服务，请选择**仅限客户端**。
      + 如果您的服务运行网络或 Web 服务应用程序且需要为该服务提供端点并连接到命名空间中的其他服务，请选择 **Client and server**（客户端和服务器）。

   1. 要使用默认集群命名空间以外的命名空间，对于**命名空间**，请选择服务命名空间。这可以是您在 AWS 账户的同一 AWS 区域中单独创建的命名空间，也可以是使用 AWS Resource Access Manager（AWS RAM）与您的账户共享的同一区域中的命名空间。有关共享 AWS Cloud Map 命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)。

   1. （可选）为金丝雀部署配置测试流量标头规则。在**测试流量路由**下，指定以下内容：

      1. 选择**启用测试流量标头规则**，以便在测试期间将特定请求路由到绿色服务修订版。

      1. 对于**标头匹配规则**，配置路由测试流量的条件：
         + **标头名称**：输入要匹配的 HTTP 标头名称（例如 `X-Test-Version` 或 `User-Agent`）。
         + **匹配类型**：选择匹配条件：
           + **精确匹配**：路由标头值与指定值完全匹配的请求
           + **标头存在性**：路由包含指定标头的请求，无论其值如何
           + **模式匹配**：路由标头值与指定模式匹配的请求
         + **标头值**（如果使用精确匹配或模式匹配）：输入要匹配的值或模式。

         可以添加多个标头匹配规则以创建复杂的路由逻辑。与任何已配置规则相匹配的请求将路由到绿色服务修订版进行测试。

      1. 选择**添加标头规则**以配置其他标头匹配条件。
**注意**  
测试流量标头规则有助于在完成全面部署之前使用受控流量验证新功能。这将允许您使用特定请求（例如来自内部测试工具或测试用户的请求）来测试绿色服务修订版，同时维持流向蓝色服务修订版的正常流量。

   1. （可选）指定日志配置。选择**使用日志收集**。默认选项将容器日志发送到 CloudWatch Logs。其他日志驱动程序选项都使用 AWS FireLens 进行配置。有关更多信息，请参阅 [将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner](using_firelens.md)。

      下面更详细地介绍了每个容器日志目标。
      + **Amazon CloudWatch** – 将任务配置为将容器日志发送到 CloudWatch Logs。提供了默认的日志驱动程序选项，用于代表您创建 CloudWatch 日志组。要指定其他日志组名称，请更改驱动程序选项值。
      + **Amazon Data Firehose** – 将任务配置为将容器日志发送到 Firehose。提供了默认的日志驱动程序选项，这些选项将日志发送到 Firehose 传输流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon Kinesis Data Streams** – 将任务配置为将容器日志发送到 Kinesis Data Streams。提供了默认的日志驱动程序选项，这些选项将日志发送到 Kinesis Data Streams 流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon OpenSearch Service** – 将任务配置为将容器日志发送到 OpenSearch Service 域。必须提供日志驱动程序选项。
      + **Amazon S3** – 将任务配置为将容器日志发送到 Amazon S3 存储桶。提供了默认的日志驱动程序选项，但您必须指定有效的 Amazon S3 存储桶名称。

1. （可选）为金丝雀部署配置**负载均衡**。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/deploy-canary-service.html)

1. （可选）为了帮助确定您的服务和任务，请展开**标签**部分，然后配置您的标签。

   要让 Amazon ECS 使用集群名称和任务定义标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**任务定义**。

   要让 Amazon ECS 使用集群名称和服务标签自动标记全部新启动的任务，选择**开启 Amazon ECS 托管标签**，然后对于**从中传播标签**，选择**服务**。

   添加或删除标签。
   + [添加标签] 选择 **Add tag**（添加标签），然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

1. 选择**创建**。

------
#### [ AWS CLI ]

1. 使用以下内容创建名为 `canary-service-definition.json` 的文件。

   将 *user-input* 替换为您的值。

   ```
   {
     "serviceName": "myCanaryService",
     "cluster": "arn:aws:ecs:us-west-2:123456789012:cluster/sample-fargate-cluster",
     "taskDefinition": "sample-fargate:1",
     "desiredCount": 5,
     "launchType": "FARGATE",
     "networkConfiguration": {
       "awsvpcConfiguration": {
         "subnets": [
           "subnet-09ce6e74c116a2299",
           "subnet-00bb3bd7a73526788",
           "subnet-0048a611aaec65477"
         ],
         "securityGroups": [
           "sg-09d45005497daa123"
         ],
         "assignPublicIp": "ENABLED"
       }
     },
     "deploymentController": {
       "type": "ECS"
     },
     "deploymentConfiguration": {
       "strategy": "CANARY",
       "maximumPercent": 200,
       "minimumHealthyPercent": 100,
       "canaryConfiguration" : {
           "canaryPercent" : 5.0,
           "canaryBakeTime" : 10
       },
       "bakeTimeInMinutes": 10,
       "alarms": {
         "alarmNames": [
           "myAlarm"
         ],
         "rollback": true,
         "enable": true
       }
     },
     "loadBalancers": [
       {
         "targetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/blue-target-group/54402ff563af1197",
         "containerName": "fargate-app",
         "containerPort": 80,
         "advancedConfiguration": {
           "alternateTargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/green-target-group/cad10a56f5843199",
           "productionListenerRule": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-canary-demo/32e0e4f946c3c05b/9cfa8c482e204f7d/831dbaf72edb911",
           "roleArn": "arn:aws:iam::123456789012:role/LoadBalancerManagementforECS"
         }
       }
     ]
   }
   ```

1. 运行 `create-service`。

   ```
   aws ecs create-service --cli-input-json file://canary-service-definition.json
   ```

------

## 后续步骤
<a name="deploy-canary-service-next-steps"></a>

配置好金丝雀部署后，请完成下面的步骤：
+ 更新服务以启动部署。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。
+ 监控部署过程，确保其遵循金丝雀模式：
  + 创建绿色服务修订版并进行纵向扩展
  + 一小部分流量（金丝雀）转移到绿色修订
  + 系统等待指定的金丝雀间隔
  + 剩余流量一次性转移到绿色修订
  + 烘焙时间结束后，蓝色修订将终止

## 部署术语
<a name="deployment-terminology"></a>

整个 Amazon ECS 部署文档中使用了下面的术语：

蓝绿部署  
一种部署策略，它在现有环境（蓝色）旁边创建新环境（绿色），然后在验证后将流量从蓝色切换到绿色。

金丝雀部署  
一种部署策略，它将一小部分流量路由到新版本，同时将大部分流量保持在稳定版本上进行验证。

线性部署  
一种部署策略，随着时间推移以相等增量逐渐将流量从旧版本转移到新版本。

滚动部署  
一种部署策略，逐一将旧版本的实例替换为新版本的实例。

任务集  
部署期间在服务内运行相同任务定义的一组任务。

目标组  
部署期间从负载均衡器接收流量的目标的逻辑分组。

部署控制器  
用于部署新版本服务的方法，例如 Amazon ECS、CodeDeploy 或外部控制器。

回滚  
部署期间检测到问题时恢复到应用程序先前版本的过程。

# 使用第三方控制器部署 Amazon ECS 服务
<a name="deployment-type-external"></a>

*外部*部署类型允许您使用任何第三方部署控制器，以完全控制 Amazon ECS 服务的部署过程。服务的详细信息由服务管理 API 操作（`CreateService`、`UpdateService` 和 `DeleteService`）或任务集管理 API 操作（`CreateTaskSet`、`UpdateTaskSet`、`UpdateServicePrimaryTaskSet` 和 `DeleteTaskSet`）管理。每个 API 操作都会管理服务定义参数的一个子集。

`UpdateService` API 操作更新服务的预期数量和运行状况检查宽限期参数。如果需要更新计算选项、平台版本、负载均衡器详细信息、网络配置或任务定义，您必须创建新任务集。

`UpdateTaskSet` API 操作仅更新任务集的扩展参数。

`UpdateServicePrimaryTaskSet` API 操作修改服务中的哪个任务集是主要任务集。当您调用 `DescribeServices` API 操作时，它将返回为主要任务集指定的所有字段。如果更新服务的主要任务集，新的主要任务集上现有的任何任务集参数值若不同于服务中旧的主要任务集的参数，则在定义新的主要任务集时，这些参数将会更新为新值。如果没有为服务定义任何主要任务集，则在描述服务时，任务集字段将为 null。

## 外部部署注意事项
<a name="deployment-type-external-considerations"></a>

在使用外部部署类型时，请考虑以下内容：
+ 支持的负载均衡器类型是应用程序负载均衡器或网络负载均衡器。
+ Fargate 或 `EXTERNAL` 部署控制器类型均不支持 `DAEMON` 计划策略。
+ Application Autoscaling 与 Amazon ECS 集成，仅支持将 Amazon ECS 服务作为目标。Amazon ECS 支持的可扩展维度是 `ecs:service:DesiredCount`，即 Amazon ECS 服务的任务计数。Application Autoscaling 与 Amazon ECS 任务集并不直接集成。Amazon ECS 任务集会根据 Amazon ECS 服务 `DesiredCount` 来计算 `ComputedDesiredCount`。

## 外部部署工作流
<a name="deployment-type-external-workflow"></a>

以下是在 Amazon ECS 上管理外部部署的基本工作流程。

**使用外部部署控制器管理 Amazon ECS 服务**

1. 创建 Amazon ECS 服务 唯一必需的参数是服务名称。您可以在使用外部部署控制器创建服务时指定以下参数。在服务内创建任务集时将指定所有其他服务参数。  
`serviceName`  
类型：字符串  
是否必需：是  
您的服务的名称。最多能包含 255 个字母（大写和小写字母）、数字、连字符和下划线。一个集群中的服务名称必须唯一，但是您可以为一个区域或多个区域中多个集群中的服务提供相似的名称。  
`desiredCount`  
要在该服务内放置并保持运行的指定任务集任务定义的实例化数量。  
`deploymentConfiguration`  
可选部署参数，用于控制部署期间运行的任务数以及停止和开始任务的顺序。  
`tags`  
类型： 对象数组  
必需：否  
您应用于服务以帮助您对其进行分类和组织的元数据。每个标签都包含您定义的一个键和一个可选值。在服务被删除时，标签也会随之被删除。该服务最多可应用 50 个标签。有关更多信息，请参阅 [为 Amazon ECS 资源添加标签](ecs-using-tags.md)。  
更新服务时，此参数不会触发新的服务部署。    
`key`  
类型：字符串  
长度限制：最小长度为 1。最大长度为 128。  
必需：否  
构成标签的键-值对的一个部分。键是一种常见的标签，行为类似于更具体的标签值的类别。  
`value`  
类型：字符串  
长度限制：最小长度为 0。长度上限为 256。  
必需：否  
构成标签的键-值对的可选部分。值充当标签类别（键）中的描述符。  
`enableECSManagedTags`  
指定是否要为该服务内的任务使用 Amazon ECS 托管标签。有关更多信息，请参阅 [使用标签记账](ecs-using-tags.md#tag-resources-for-billing)。  
`propagateTags`  
类型：字符串  
有效值：`TASK_DEFINITION` \$1 `SERVICE`  
必需：否  
指定是否要将标签从任务定义或服务复制到服务中的任务。如果未指定值，则不会复制标签。只能在创建服务的过程中将标签复制到服务中的任务。要在创建服务或任务以后将标签添加到任务，请使用 `TagResource` API 操作。  
更新服务时，此参数不会触发新的服务部署。  
`schedulingStrategy`  
要使用的计划策略。使用外部部署控制器的服务仅支持 `REPLICA` 计划策略。  
`placementConstraints`  
您的服务中的任务使用的一组放置约束对象。对于每个任务，您可以指定多达 10 种约束（此限制包括任务定义中的约束和这些在运行时指定的约束）。如果您使用的是 Fargate，则不支持任务放置约束。  
`placementStrategy`  
您的服务中的任务所用的放置策略对象。对于每项服务，您最多可以指定 4 种策略。

   下面是使用外部部署控制器创建服务的示例服务定义。

   ```
   {
       "cluster": "",
       "serviceName": "",
       "desiredCount": 0,
       "role": "",
       "deploymentConfiguration": {
           "maximumPercent": 0,
           "minimumHealthyPercent": 0
       },
       "placementConstraints": [
           {
               "type": "distinctInstance",
               "expression": ""
           }
       ],
       "placementStrategy": [
           {
               "type": "binpack",
               "field": ""
           }
       ],
       "schedulingStrategy": "REPLICA",
       "deploymentController": {
           "type": "EXTERNAL"
       },
       "tags": [
           {
               "key": "",
               "value": ""
           }
       ],
       "enableECSManagedTags": true,
       "propagateTags": "TASK_DEFINITION"
   }
   ```

1. 创建初始任务集。任务集包含有关您的服务的以下详细信息：  
`taskDefinition`  
要使用的任务集中的任务的任务定义。  
`launchType`  
类型：字符串  
有效值：`EC2` \$1`FARGATE` \$1`EXTERNAL`  
必需：否  
运行您的服务的启动类型。如果没有指定启动类型，将默认使用默认的 `capacityProviderStrategy`。  
更新服务时，此参数会触发新的服务部署。  
如果指定 `launchType`，必须省略 `capacityProviderStrategy` 参数。  
`platformVersion`  
类型：字符串  
必需：否  
正在运行服务中任务的平台版本。仅为使用 Fargate 启动类型的任务指定平台版本。如果没有指定任何版本，将默认使用最新版本（`LATEST`）。  
更新服务时，此参数会触发新的服务部署。  
AWS Fargate 平台版本用于指代 Fargate 任务基础设施的特定运行时环境。在运行任务或创建服务的过程中指定 `LATEST` 平台版本时，您将获得可用于任务的最新平台版本。当您纵向扩展服务时，这些任务将收到在服务的当前部署中指定的平台版本。有关更多信息，请参阅 [适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。  
不会使用 EC2 启动类型为任务指定平台版本。  
`loadBalancers`  
表示要用于您的服务的负载均衡器的负载均衡器对象。使用外部部署控制器时，仅支持应用程序负载均衡器和网络负载均衡器。如果您使用应用程序负载均衡器，每个任务集仅允许一个应用程序负载均衡器目标组。  
以下代码段显示要使用的示例 `loadBalancer` 对象。  

   ```
   "loadBalancers": [
           {
               "targetGroupArn": "",
               "containerName": "",
               "containerPort": 0
           }
   ]
   ```
指定 `loadBalancer` 对象时，必须指定 `targetGroupArn` 并忽略 `loadBalancerName` 参数。  
`networkConfiguration`  
服务的网络配置。对于使用 `awsvpc` 网络模式接收其自己的弹性网络接口的任务定义，该参数是必需的，其他网络模式不支持该参数。有关 Fargate 联网的更多信息，请参阅 [Fargate 的 Amazon ECS 任务联网选项](fargate-task-networking.md)。  
`serviceRegistries`  
要分配给此服务的服务发现注册表的详细信息。有关更多信息，请参阅 [使用服务发现连接具有 DNS 名称的 Amazon ECS 服务](service-discovery.md)。  
`scale`  
要在任务集中放置并保持运行的任务的预期数量的浮点百分比。该值以服务的 `desiredCount` 的总数的百分比的形式指定。接受的值为 0 到 100 之间的数字。

   以下是为外部部署控制器创建任务集的 JSON 示例。

   ```
   {
       "service": "",
       "cluster": "",
       "externalId": "",
       "taskDefinition": "",
       "networkConfiguration": {
           "awsvpcConfiguration": {
               "subnets": [
                   ""
               ],
               "securityGroups": [
                   ""
               ],
               "assignPublicIp": "DISABLED"
           }
       },
       "loadBalancers": [
           {
               "targetGroupArn": "",
               "containerName": "",
               "containerPort": 0
           }
       ],
       "serviceRegistries": [
           {
               "registryArn": "",
               "port": 0,
               "containerName": "",
               "containerPort": 0
           }
       ],
       "launchType": "EC2",
       "capacityProviderStrategy": [
           {
               "capacityProvider": "",
               "weight": 0,
               "base": 0
           }
       ],
       "platformVersion": "",
       "scale": {
           "value": null,
           "unit": "PERCENT"
       },
       "clientToken": ""
   }
   ```

1. 需要服务更改时，请使用 `UpdateService`、`UpdateTaskSet` 或 `CreateTaskSet` API 操作，具体取决于您要更新的参数。如果创建了任务集，请使用服务中每个任务集的 `scale` 参数以确定要在服务中保持运行的任务数量。例如，如果您有一个包含 `tasksetA` 的服务并且创建一个 `tasksetB`，则您可能在希望向其过渡生产流量之前测试 `tasksetB` 的有效性。您可以将两个任务集的 `scale` 设置为 `100`，并且在您已准备好将所有生产流量过渡到 `tasksetB` 时，您可以将 `tasksetA` 的 `scale` 更新为 `0` 以缩小规模。

# 适用于 Amazon ECS 的 CodeDeploy 蓝绿部署
<a name="deployment-type-bluegreen"></a>

建议使用 Amazon ECS 蓝绿部署。有关更多信息，请参阅 [创建 Amazon ECS 蓝绿部署](deploy-blue-green-service.md)。

*蓝/绿*部署类型使用由 CodeDeploy 控制的蓝/绿部署模型。在向服务发送生产流量之前，请使用此部署类型验证服务的新部署。有关更多信息，请参阅《AWS CodeDeploy 用户指南》**中的[什么是 CodeDeploy](https://docs.aws.amazon.com/codedeploy/latest/userguide/welcome.html)。在部署前验证 Amazon ECS 服务的状态

在蓝绿部署过程中，有三种可转移流量的方法：
+ **金丝雀**：流量将通过两次递增进行转移。您可以从预定义的金丝雀选项中选择，这些选项指定在第一次增量中转移到更新后的任务集的流量百分比以及以分钟为单位的间隔；然后指定在第二次增量中转移剩余的流量。
+ **线性部署** — 流量使用相等的增量转移，在每次递增之间间隔的分钟数相同。您可以从预定义的线性选项中进行选择，这些选项指定在每次增量中转移的流量百分比以及每次增量之间的分钟数。
+ **一次性部署** – 所有流量均从原始任务集一次性地转移到更新后的任务集。

以下是在服务使用蓝/绿部署类型时，Amazon ECS 使用的 CodeDeploy 的组件：

**CodeDeploy 应用程序**  
CodeDeploy 资源集合。这包括一个或多个部署组。

**CodeDeploy 部署组**  
部署设置。这包括以下内容：  
+ Amazon ECS 集群和服务
+ 负载均衡器目标组和侦听器信息
+ 部署回滚策略
+ 流量重新路由设置
+ 原始修订终止设置
+ 部署配置
+ 可设置为停止部署的 CloudWatch 警报配置
+ SNS 或 CloudWatch Events 设置
有关更多信息，请参阅 *AWS CodeDeploy用户手册*中的[使用部署组](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-groups.html)。

**CodeDeploy 部署配置**  
指定在部署期间 CodeDeploy 如何将生产流量路由到您的替换任务集。提供了以下预定义的线性和金丝雀部署配置。您还可以创建自定义的线性和金丝雀部署。有关详细信息，请参见*AWS CodeDeploy 用户手册*中的[使用部署配置](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html)。  
+ **CodeDeployDefault.ECSAllAtOnce**：将所有流量一次性转移到更新后的 Amazon ECS 容器
+ **CodeDeployDefault.ECSLinear10PercentEvery1Minutes**：在所有流量转移之前，每分钟转移 10％ 的流量。
+ **CodeDeployDefault.ECSLinear10PercentEvery3Minutes**：在所有流量转移之前，每 3 分钟转移 10％ 的流量。
+ **CodeDeployDefault.ECSCanary10Percent5Minutes**：在第一个增量中转移 10% 的流量。其余 90% 在五分钟后进行部署。
+ **CodeDeployDefault.ECSCanary10Percent15Minutes**：在第一个增量中转移 10% 的流量。其余 90% 部署在 15 分钟后进行转移。

**修订**  
修订是 CodeDeploy 应用程序规范文件（AppSpec 文件）。在 AppSpec 文件中，指定任务定义的完整 ARN 以及在创建新部署时要将流量路由到的替换任务集的容器和端口。容器名称必须是任务定义中引用的容器名称之一。如果在服务定义中更新了网络配置或平台版本，则还必须在 AppSpec 文件中指定这些详细信息。您也可以指定要在部署生命周期事件期间运行的 Lambda 函数。Lambda 函数允许您在部署期间运行测试和返回指标。有关更多信息，请参阅 *AWS CodeDeploy 用户指南*中的 [AppSpec 文件参考](https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file.html)。

## 注意事项
<a name="deployment-type-bluegreen-considerations"></a>

使用蓝/绿部署类型时，请考虑以下内容：
+ 在初次创建使用蓝/绿部署类型的 Amazon ECS 服务时，将创建一个 Amazon ECS 任务集。
+ 您必须将服务配置为使用应用程序负载均衡器或网络负载均衡器。以下是负载均衡器要求：
  + 您必须将生产侦听器添加到用于路由生产流量的负载均衡器。
  + 可以将可选的测试侦听器添加到负载均衡器，这用于路由测试流量。如果您指定了测试侦听器，则在部署期间 CodeDeploy 会将测试流量路由到替换任务集。
  + 生产和测试侦听器必须属于同一负载均衡器。
  + 您必须为负载均衡器定义一个目标组。目标组通过生产侦听器将流量路由到服务中的原始任务集。
  + 使用网络负载均衡器时，仅支持 `CodeDeployDefault.ECSAllAtOnce` 部署配置。
+ 对于配置为使用服务自动扩缩和蓝绿部署类型的服务，在部署期间不会阻止自动扩缩，但在某些情况下，部署可能会失败。下面将更详细地介绍此行为。
  + 如果服务正在扩展且部署开始，将创建绿色任务集，CodeDeploy 将等待一个小时，让绿色任务集达到稳定状态，在达到稳定状态之前不会转移任何流量。
  + 如果服务处于蓝绿部署过程中，发生了扩展事件，则流量将继续移动 5 分钟。如果服务在 5 分钟内未达到稳定状态，CodeDeploy 将停止部署并将其标记为失败。
+ 使用 Fargate 或 `CODE_DEPLOY` 部署控制器类型的任务不支持 `DAEMON` 调度策略。
+ 当您最初创建 CodeDeploy 应用程序和部署组时，必须指定以下内容：
  + 您必须为负载均衡器定义两个目标组。一个目标组应为在创建 Amazon ECS 服务时为负载均衡器定义的初始目标组。第二个目标组的唯一要求是，它不能与服务所使用的负载均衡器之外的其他负载均衡器相关联。
+ 在为 Amazon ECS 服务创建 CodeDeploy 部署后，CodeDeploy 会在该部署中创建*替换任务集*（或*绿色任务集*）。如果您将测试侦听器添加到了负载均衡器，则 CodeDeploy 会将测试流量路由到替换任务集。此时您可以运行任何验证测试。然后，CodeDeploy 会根据部署组的流量重新路由设置将生产流量从原始任务集重新路由到替换任务集。

## 所需的 IAM 权限
<a name="deployment-type-bluegreen-IAM"></a>

通过将 Amazon ECS 和 CodeDeploy API 组合使用以进行蓝绿部署。用户必须拥有这些服务的相应权限，才能在 AWS 管理控制台 或 AWS CLI 或 SDK 中使用 Amazon ECS 蓝/绿部署。

除了用于创建和更新服务的标准 IAM 权限之外，Amazon ECS 还需要以下权限。这些权限已添加到 `AmazonECS_FullAccess` IAM 策略。有关更多信息，请参阅 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess)。
+ `codedeploy:CreateApplication`
+ `codedeploy:CreateDeployment`
+ `codedeploy:CreateDeploymentGroup`
+ `codedeploy:GetApplication`
+ `codedeploy:GetDeployment`
+ `codedeploy:GetDeploymentGroup`
+ `codedeploy:ListApplications`
+ `codedeploy:ListDeploymentGroups`
+ `codedeploy:ListDeployments`
+ `codedeploy:StopDeployment`
+ `codedeploy:GetDeploymentTarget`
+ `codedeploy:ListDeploymentTargets`
+ `codedeploy:GetDeploymentConfig`
+ `codedeploy:GetApplicationRevision`
+ `codedeploy:RegisterApplicationRevision`
+ `codedeploy:BatchGetApplicationRevisions`
+ `codedeploy:BatchGetDeploymentGroups`
+ `codedeploy:BatchGetDeployments`
+ `codedeploy:BatchGetApplications`
+ `codedeploy:ListApplicationRevisions`
+ `codedeploy:ListDeploymentConfigs`
+ `codedeploy:ContinueDeployment`
+ `sns:ListTopics`
+ `cloudwatch:DescribeAlarms`
+ `lambda:ListFunctions`

**注意**  
除了运行任务和服务所需的标准 Amazon ECS 权限外，用户还需要 `iam:PassRole` 权限，以使用 IAM 角色执行任务。

CodeDeploy 需要调用 Amazon ECS API、修改 Elastic Load Balancing、调用 Lambda 函数和描述 CloudWatch 警报的权限，以及代表您修改服务的预期数量的权限。在创建使用蓝/绿部署类型的 Amazon ECS 服务之前，您必须先创建一个 IAM 角色 (`ecsCodeDeployRole`)。有关更多信息，请参阅 [Amazon ECS CodeDeploy IAM 角色](codedeploy_IAM_role.md)。

# 将 CodeDeploy 蓝绿部署迁移到 Amazon ECS 蓝绿部署
<a name="migrate-codedeploy-to-ecs-bluegreen"></a>

CodeDeploy 蓝绿部署和 Amazon ECS 蓝绿部署提供类似的功能，但它们在配置和管理方式上有所不同。

## CodeDeploy 蓝绿部署概述
<a name="codedeploy-bluegreen-overview"></a>

使用 CodeDeploy 创建 Amazon ECS 服务时，需要：

1. 使用生产侦听器和测试侦听器（可选）创建负载均衡器。每个侦听器均配置一条（默认）规则，将所有流量路由到单个目标组（主目标组）。

1. 创建 Amazon ECS 服务，将其配置为使用侦听器和目标组，并将 `deploymentController` 类型设置为 `CODE_DEPLOY`。服务创建后，会生成注册到指定目标组的（蓝色）任务集。

1. 创建 CodeDeploy 部署组（作为 CodeDeploy 应用程序的一部分），并配置以下详细信息：Amazon ECS 集群、服务名称、负载均衡器侦听器、两个目标组（生产侦听器规则中使用的主目标组和用于替换任务的辅助目标组）、服务角色（授予 CodeDeploy 操作 Amazon ECS 和 Elastic Load Balancing 资源的权限）以及用于控制部署行为的各个参数。

使用 CodeDeploy 时，通过 `CreateDeployment()` 来部署新版本的服务，指定 CodeDeploy 应用程序名称、部署组名称以及 AppSpec 文件，该文件会提供新版本的详细信息以及可选的生命周期挂钩。CodeDeploy 部署会创建替换（绿色）任务集，并将其任务注册到辅助目标组。当此任务集正常运行后，即可用于测试（可选）和生产。在这两种情况下，重新路由都是通过更改相应的侦听器规则以指向与绿色任务集关联的辅助目标组来实现的。回滚则是通过将生产侦听器规则改回指向主目标组来实现的。

## Amazon ECS 蓝绿部署概述
<a name="ecs-bluegreen-overview"></a>

使用 Amazon ECS 蓝绿部署时，部署配置是 Amazon ECS 服务本身的一部分：

1. 必须预先配置负载均衡器的生产侦听器，其规则需包含两个目标组，权重分别为 1 和 0。

1. 需要指定以下资源或更新服务资源：
   + 此侦听器规则的 ARN 
   + 两个目标组
   + 一个 IAM 角色，用于授予 Amazon ECS 调用 Elastic API 的权限
   + 一个可选的 IAM 角色，用于运行 Lambda 函数
   + 将 `deploymentController` 类型设置为 `ECS`，并将 `deploymentConfiguration.strategy` 设置为 `BLUE_GREEN`。这将创建一个（蓝色）服务部署，其任务已注册到主目标组。

借助 Amazon ECS 蓝绿部署，可通过调用 Amazon ECS `UpdateService()` 并传递新修订的详细信息来创建新的服务修订版。服务部署会创建新的（绿色）服务修订版任务，并将其注册到辅助目标组。Amazon ECS 会通过切换侦听器规则的权重来处理重新路由和回滚操作。

## 关键实施差异
<a name="implementation-differences"></a>

虽然这两种方法都会创建初始任务集，但底层实施却有所不同：
+ CodeDeploy 使用任务集，而 Amazon ECS 使用服务修订版。Amazon ECS 任务集的构造较旧，已被 Amazon ECS 服务修订版和部署取代。后者有助于更清楚地了解部署过程以及服务部署和服务修订版历史记录。
+ 使用 CodeDeploy 时，生命周期挂钩将指定为提供给 `CreateDeployment()` 的 AppSpec 文件的一部分。这意味着挂钩可以在不同部署之间更改。使用 Amazon ECS 蓝绿部署时，会将挂钩指定为服务配置的一部分，任何更新都需要调用 `UpdateService()`。
+ CodeDeploy 和 Amazon ECS 蓝绿部署都使用 Lambda 来实现挂钩，但预期的输入和输出有所不同。

  使用 CodeDeploy 时，函数必须调用 `PutLifecycleEventHookExecutionStatus()` 才能返回挂钩状态，状态可以是 `SUCCEEDED`，也可以是 `FAILED`。使用 Amazon ECS 时，Lambda 响应用于指示挂钩状态。
+ CodeDeploy 以一次性调用的形式调用每个挂钩，并期望在一小时内返回最终执行状态。Amazon ECS 挂钩更灵活，因为它们可以返回 `IN_PROGRESS` 指示符，这表示必须重复调用该挂钩，直到返回 `SUCCEEDED` 或 `FAILED`。有关更多信息，请参阅 [适用于 Amazon ECS 服务部署的生命周期挂钩](deployment-lifecycle-hooks.md)。

## 迁移方法
<a name="migration-paths"></a>

从 CodeDeploy 蓝绿部署迁移到 Amazon ECS 蓝绿部署主要有三种方法。每种方法在复杂性、风险、回滚功能和潜在停机时间方面都有不同的特征。

### 重复使用 CodeDeploy 所使用的同一 Elastic Load Balancing 资源
<a name="inplace-update"></a>

更新现有的 Amazon ECS 服务，以使用具有蓝绿部署策略的 Amazon ECS 部署控制器，而不是 CodeDeploy 部署控制器。使用此方法时，请考虑以下几点：
+ 迁移过程更简单，因为是在更新现有的 Amazon ECS 服务部署控制器和部署策略。
+ 如果配置和迁移正确，则不会出现停机时间。
+ 回滚需要还原服务修订版。
+ 没有并行的蓝绿配置，因而风险较高。

需使用 CodeDeploy 所使用的同一负载均衡器侦听器和目标组。如果您正在使用 CloudFormation，请参阅 [将 CloudFormation CodeDeploy 蓝绿部署模板迁移到 Amazon ECS 蓝绿部署 CloudFormation 模板](migrate-codedeploy-to-ecs-bluegreen-cloudformation-template.md)。

1. 修改生产/测试侦听器的默认规则，使其包含备用目标组，并将主目标组的权重设置为 1，将备用目标组的权重设置为 0。

   对于 CodeDeploy，附加到服务的负载均衡器的侦听器配置有一条（默认）规则，将所有流量路由到单个目标组。对于 Amazon ECS 蓝绿部署，负载均衡器侦听器必须预先配置一条规则，该规则应包含两个带权重的目标组。主要目标组的权重必须设置为 1，备用目标组的权重必须设置为 0。

1. 通过调用 `UpdateService` API 并将参数设置为，将参数 `deploymentController` 设置为 `ECS`，将参数 `deploymentStrategy` 设置为 `BLUE_GREEN`，来更新现有的 Amazon ECS 服务。指定目标组、备用目标组、生产侦听器及可选测试侦听器的 ARN。

1. 确认服务是否按照预期运行。

1. 删除此 Amazon ECS 服务的 CodeDeploy 设置，因为现在使用的是 Amazon ECS 蓝绿部署。

### 使用现有负载均衡器的新服务
<a name="new-service-existing-lb"></a>

此方法使用蓝绿策略进行迁移。

使用此方法时，请考虑以下几点：
+ 中断时间极短。仅在 Elastic Load Balancing 端口交换期间进行。
+ 回滚需要还原 Elastic Load Balancing 端口交换。
+ 存在并行配置，因而风险较低。因此，可在流量转移之前进行测试。

1. 保持 CodeDeploy 设置中的侦听器、目标组和 Amazon ECS 服务不变，以便在需要时可以轻松回滚到此设置。

1. 在现有负载均衡器下创建新的目标组和新的侦听器（使用与原始侦听器不同的端口）。然后，创建一个与现有 Amazon ECS 服务相匹配的新 Amazon ECS 服务，不同之处在于，需将 `ECS` 用作部署控制器，将 `BLUE_GREEN` 用作部署策略，并传递新目标组的 ARN 和新侦听器规则的 ARN。

1. 通过向服务手动发送 HTTP 流量来验证新设置。如果一切正常，则交换原始侦听器和新侦听器的端口，将流量路由到新设置。

1. 验证新设置，如果一切继续按预期运行，则删除 CodeDeploy 设置。

### 使用新负载均衡器的新服务
<a name="new-service-new-lb"></a>

与上一种方法类似，此方法也使用蓝绿策略进行迁移。主要区别在于，从 CodeDeploy 设置切换到 Amazon ECS 蓝绿设置是在负载均衡器上方的反向代理层进行的。反向代理层的实施示例有 Route 53 和 CloudFront。

此方法适用于已经拥有此反向代理层的客户，并且与服务的所有通信都是通过该层进行的（例如，在负载均衡器级别没有直接通信）。

使用此方法时，请考虑以下几点：
+ 需要反向代理层。
+ 迁移过程更为复杂，因为需要更新现有的 Amazon ECS 服务部署控制器和部署策略。
+ 中断时间极短。仅在 Elastic Load Balancing 端口交换期间进行。
+ 回滚需要撤销代理配置更改。
+ 存在并行配置，因而风险较低。因此，可在流量转移之前进行测试。

1. 保持现有的 CodeDeploy 设置不变（负载均衡器、侦听器、目标组、Amazon ECS 服务和 CodeDeploy 部署组）。

1. 创建为 Amazon ECS 蓝绿部署配置的新负载均衡器、目标组和侦听器。

   配置相应的资源。
   + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
   + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。

1. 创建新服务，将 `ECS` 作为部署控制器，将 `BLUE_GREEN` 作为部署策略，并指向新的负载均衡器资源。

1. 使用新的负载均衡器进行测试，验证新设置。

1. 更新反向代理配置，将流量路由到新负载均衡器。

1. 观察新的服务修订版，如果一切继续按预期运行，则删除 CodeDeploy 设置。

## 后续步骤
<a name="post-migration-considerations"></a>

迁移到 Amazon ECS 蓝绿部署后：
+ 更新部署脚本和 CI/CD 管道，以使用 Amazon ECS `UpdateService` API，而不是 CodeDeploy `CreateDeployment` API。
+ 更新监控和警报，以跟踪 Amazon ECS 服务部署，而不是 CodeDeploy 部署。
+ 考虑对新的部署流程实施自动测试，以确保其按预期运行。

# 从 CodeDeploy 蓝绿服务部署迁移到 Amazon ECS 蓝绿服务部署
<a name="migrate-code-deploy-to-ecs-blue-green"></a>

 通过使用 Amazon ECS 蓝绿部署，您可以进行服务更改并测试，然后再在生产环境中实施服务更改。

必须为 Amazon ECS 蓝绿部署创建新的生命周期挂钩。

## 先决条件
<a name="migrate-code-deploy-to-ecs-blue-green-prerequisites"></a>

在开始蓝绿部署之前，执行以下操作。

1. 将 Amazon ECS CodeDeploy IAM 角色替换为以下权限。
   + 有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。
   + 有关最低权限的更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

1. 关闭 CodeDeploy 自动化。有关更多信息，请参阅《CodeDeploy 用户指南》**中的[在 CodeDeploy 中使用部署组](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-groups.html)。

1. 确保拥有 CodeDeploy 蓝绿部署中的以下信息。可在 Amazon ECS 蓝绿部署中重复使用以下信息：
   + 生产目标组
   + 生产侦听器
   + 生产规则
   + 测试目标组

     这是绿色服务修订版的目标组。

1. 确保应用程序负载均衡器目标组与侦听器规则正确关联：
   + 如果不使用测试侦听器，则两个目标组（生产和测试）都必须与生产侦听器规则相关联。
   + 如果使用测试侦听器，则必须将一个目标组关联到生产侦听器规则，并将另一个目标组关联到测试侦听器规则。

   如果未满足此要求，服务部署将失败并出现以下错误：`Service deployment rolled back because of invalid networking configuration. Both targetGroup and alternateTargetGroup must be associated with the productionListenerRule or testListenerRule.`

1. 确认服务没有正在进行的服务部署。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。

1. Amazon ECS 蓝绿部署要求服务使用以下功能之一：配置相应的资源。
   + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
   + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
   + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。

1. 决定是否要在 Amazon ECS 蓝绿部署的各个阶段为生命周期阶段运行 Lambda 函数。
   + 纵向扩展前
   + 纵向扩展后
   + 测试流量转移
   + 测试流量转移后
   + 生产流量转移
   + 生产流量转移后

   为每个生命周期阶段创建 Lambda 函数。有关更多信息，请参阅《AWS Lambda 开发人员指南》**中的[使用控制台创建 Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#getting-started-create-function)。

有关更新服务部署控制器的更多信息，请参阅[更新 Amazon ECS 服务参数](update-service-parameters.md)。

## 过程
<a name="migrate-code-deploy-to-ecs-procedure"></a>

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

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

   此时将显示集群详细信息页面。

1. 从**服务**选项卡中，选择服务。

   此时将显示服务详细信息页面。

1. 在横幅中，选择**更新部署控制器类型**。

   将显示**迁移部署控制器类型**页面。

1. 展开**新建**，然后指定以下参数。

   1. 对于**部署控制器类型**，选择 **ECS**。

   1. 对于**部署策略**，选择**蓝绿部署**。

   1. 对于**烘焙时间**，输入蓝色服务修订版和绿色服务修订版同时运行的时间。

   1. 要在生命周期阶段运行 Lambda 函数，请在**部署生命周期挂钩**下为每个唯一的 Lambda 函数执行以下操作：

      1. 选择**添加**。

         对每个要运行的唯一函数重复此操作。

      1. 对于 **Lambda 函数**，输入函数名称。

      1. 对于**角色**，选择在先决条件中创建的具有蓝绿权限的角色。

         有关更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

      1. 对于**生命周期阶段**，选择 Lambda 函数运行的阶段。

      1.  （可选）对于**挂钩详细信息**，输入包含挂钩相关信息的键值对。

1. 展开 **Load Balancing**，然后配置以下内容：

   1. 对于**角色**，选择在先决条件中创建的具有蓝绿权限的角色。

      有关更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

   1. 对于**侦听器**，从 CodeDeploy 蓝绿部署中选择生产侦听器。

   1. 对于**生产规则**，从 CodeDeploy 蓝绿部署中选择生产规则。

   1. 对于**测试规则**，从 CodeDeploy 蓝绿部署中选择测试规则。

   1. 对于**目标组**，从 CodeDeploy 蓝绿部署中选择生产目标组。

   1. 对于**备用目标组**，从 CodeDeploy 蓝绿部署中选择测试目标组。

1. 选择**更新**。

## 后续步骤
<a name="migrate-code-deploy-to-ecs-blue-green-next-steps"></a>
+ 更新服务以启动部署。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。
+ 监控部署过程，确保其遵循蓝绿模式：
  + 创建绿色服务修订版并进行纵向扩展
  + 将测试流量路由到绿色修订（如果已配置）
  + 向绿色服务修订转移生产流量
  + 烘焙时间结束后，蓝色修订将终止

# 将 CloudFormation CodeDeploy 蓝绿部署模板迁移到 Amazon ECS 蓝绿部署 CloudFormation 模板
<a name="migrate-codedeploy-to-ecs-bluegreen-cloudformation-template"></a>

将使用适用于 Amazon ECS 服务的 CodeDeploy 蓝绿部署的 CloudFormation 模板迁移到使用原生 Amazon ECS 蓝绿部署策略的模板。迁移遵循“重复使用 CodeDeploy 所使用的同一 Elastic Load Balancing 资源”的方法。有关更多信息，请参阅 [将 CodeDeploy 蓝绿部署迁移到 Amazon ECS 蓝绿部署](migrate-codedeploy-to-ecs-bluegreen.md)。

## 源模板
<a name="source-template"></a>

此模板使用 `AWS::CodeDeployBlueGreen` 转换和 `AWS::CodeDeploy::BlueGreen` 挂钩为 Amazon ECS 服务实现蓝绿部署。

### 来源
<a name="code-deploy-source"></a>

这是使用 CodeDeploy 蓝绿部署的完整 CloudFormation 模板。有关更多信息，请参阅《AWS CloudFormation 用户指南**》中的[蓝绿部署模板示例](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/blue-green-template-example.html#blue-green-template-example.json)：

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "Vpc": {
      "Type": "AWS::EC2::VPC::Id"
    },
    "Subnet1": {
      "Type": "AWS::EC2::Subnet::Id"
    },
    "Subnet2": {
      "Type": "AWS::EC2::Subnet::Id"
    }
  },
  "Transform": [
    "AWS::CodeDeployBlueGreen"
  ],
  "Hooks": {
    "CodeDeployBlueGreenHook": {
      "Type": "AWS::CodeDeploy::BlueGreen",
      "Properties": {
        "TrafficRoutingConfig": {
          "Type": "TimeBasedCanary",
          "TimeBasedCanary": {
            "StepPercentage": 15,
            "BakeTimeMins": 5
          }
        },
        "Applications": [
          {
            "Target": {
              "Type": "AWS::ECS::Service",
              "LogicalID": "ECSDemoService"
            },
            "ECSAttributes": {
              "TaskDefinitions": [
                "BlueTaskDefinition",
                "GreenTaskDefinition"
              ],
              "TaskSets": [
                "BlueTaskSet",
                "GreenTaskSet"
              ],
              "TrafficRouting": {
                "ProdTrafficRoute": {
                  "Type": "AWS::ElasticLoadBalancingV2::Listener",
                  "LogicalID": "ALBListenerProdTraffic"
                },
                "TargetGroups": [
                  "ALBTargetGroupBlue",
                  "ALBTargetGroupGreen"
                ]
              }
            }
          }
        ]
      }
    }
  },
  "Resources": {
    "ExampleSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Security group for ec2 access",
        "VpcId": {"Ref": "Vpc"},
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "CidrIp": "0.0.0.0/0"
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 8080,
            "ToPort": 8080,
            "CidrIp": "0.0.0.0/0"
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "ALBTargetGroupBlue": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties": {
        "HealthCheckIntervalSeconds": 5,
        "HealthCheckPath": "/",
        "HealthCheckPort": "80",
        "HealthCheckProtocol": "HTTP",
        "HealthCheckTimeoutSeconds": 2,
        "HealthyThresholdCount": 2,
        "Matcher": {
          "HttpCode": "200"
        },
        "Port": 80,
        "Protocol": "HTTP",
        "Tags": [
          {
            "Key": "Group",
            "Value": "Example"
          }
        ],
        "TargetType": "ip",
        "UnhealthyThresholdCount": 4,
        "VpcId": {"Ref": "Vpc"}
      }
    },
    "ALBTargetGroupGreen": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties": {
        "HealthCheckIntervalSeconds": 5,
        "HealthCheckPath": "/",
        "HealthCheckPort": "80",
        "HealthCheckProtocol": "HTTP",
        "HealthCheckTimeoutSeconds": 2,
        "HealthyThresholdCount": 2,
        "Matcher": {
          "HttpCode": "200"
        },
        "Port": 80,
        "Protocol": "HTTP",
        "Tags": [
          {
            "Key": "Group",
            "Value": "Example"
          }
        ],
        "TargetType": "ip",
        "UnhealthyThresholdCount": 4,
        "VpcId": {"Ref": "Vpc"}
      }
    },
    "ExampleALB": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties": {
        "Scheme": "internet-facing",
        "SecurityGroups": [
          {"Ref": "ExampleSecurityGroup"}
        ],
        "Subnets": [
          {"Ref": "Subnet1"},
          {"Ref": "Subnet2"}
        ],
        "Tags": [
          {
            "Key": "Group",
            "Value": "Example"
          }
        ],
        "Type": "application",
        "IpAddressType": "ipv4"
      }
    },
    "ALBListenerProdTraffic": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Properties": {
        "DefaultActions": [
          {
            "Type": "forward",
            "ForwardConfig": {
              "TargetGroups": [
                {
                  "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
                  "Weight": 1
                }
              ]
            }
          }
        ],
        "LoadBalancerArn": {"Ref": "ExampleALB"},
        "Port": 80,
        "Protocol": "HTTP"
      }
    },
    "ALBListenerProdRule": {
      "Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
      "Properties": {
        "Actions": [
          {
            "Type": "forward",
            "ForwardConfig": {
              "TargetGroups": [
                {
                  "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
                  "Weight": 1
                }
              ]
            }
          }
        ],
        "Conditions": [
          {
            "Field": "http-header",
            "HttpHeaderConfig": {
              "HttpHeaderName": "User-Agent",
              "Values": [
                "Mozilla"
              ]
            }
          }
        ],
        "ListenerArn": {"Ref": "ALBListenerProdTraffic"},
        "Priority": 1
      }
    },
    "ECSTaskExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Sid": "",
              "Effect": "Allow",
              "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
        ]
      }
    },
    "BlueTaskDefinition": {
      "Type": "AWS::ECS::TaskDefinition",
      "Properties": {
        "ExecutionRoleArn": {"Fn::GetAtt": ["ECSTaskExecutionRole", "Arn"]},
        "ContainerDefinitions": [
          {
            "Name": "DemoApp",
            "Image": "nginxdemos/hello:latest",
            "Essential": true,
            "PortMappings": [
              {
                "HostPort": 80,
                "Protocol": "tcp",
                "ContainerPort": 80
              }
            ]
          }
        ],
        "RequiresCompatibilities": [
          "FARGATE"
        ],
        "NetworkMode": "awsvpc",
        "Cpu": "256",
        "Memory": "512",
        "Family": "ecs-demo"
      }
    },
    "ECSDemoCluster": {
      "Type": "AWS::ECS::Cluster",
      "Properties": {}
    },
    "ECSDemoService": {
      "Type": "AWS::ECS::Service",
      "Properties": {
        "Cluster": {"Ref": "ECSDemoCluster"},
        "DesiredCount": 1,
        "DeploymentController": {
          "Type": "EXTERNAL"
        }
      }
    },
    "BlueTaskSet": {
      "Type": "AWS::ECS::TaskSet",
      "Properties": {
        "Cluster": {"Ref": "ECSDemoCluster"},
        "LaunchType": "FARGATE",
        "NetworkConfiguration": {
          "AwsVpcConfiguration": {
            "AssignPublicIp": "ENABLED",
            "SecurityGroups": [
              {"Ref": "ExampleSecurityGroup"}
            ],
            "Subnets": [
              {"Ref": "Subnet1"},
              {"Ref": "Subnet2"}
            ]
          }
        },
        "PlatformVersion": "1.4.0",
        "Scale": {
          "Unit": "PERCENT",
          "Value": 100
        },
        "Service": {"Ref": "ECSDemoService"},
        "TaskDefinition": {"Ref": "BlueTaskDefinition"},
        "LoadBalancers": [
          {
            "ContainerName": "DemoApp",
            "ContainerPort": 80,
            "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"}
          }
        ]
      }
    },
    "PrimaryTaskSet": {
      "Type": "AWS::ECS::PrimaryTaskSet",
      "Properties": {
        "Cluster": {"Ref": "ECSDemoCluster"},
        "Service": {"Ref": "ECSDemoService"},
        "TaskSetId": {"Fn::GetAtt": ["BlueTaskSet", "Id"]}
      }
    }
  }
}
```

## 迁移步骤
<a name="migration-steps"></a>

### 移除 CodeDeploy 特定资源
<a name="remove-codedeploy-resources"></a>

不再需要以下属性：
+ `AWS::CodeDeployBlueGreen` 转换
+ `CodeDeployBlueGreenHook` 挂钩
+ `GreenTaskDefinition` 和 `GreenTaskSet` 资源（这些资源将由 Amazon ECS 管理）
+ `PrimaryTaskSet` 资源（Amazon ECS 将在内部管理任务集）

### 重新配置负载均衡器侦听器
<a name="reconfigure-load-balancer"></a>

修改 `ALBListenerProdTraffic` 资源，使用带有两个目标组的转发操作：

```
{
  "DefaultActions": [
    {
      "Type": "forward",
      "ForwardConfig": {
        "TargetGroups": [
          {
            "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
            "Weight": 1
          },
          {
            "TargetGroupArn": {"Ref": "ALBTargetGroupGreen"},
            "Weight": 0
          }
        ]
      }
    }
  ]
}
```

### 更新部署属性
<a name="update-ecs-service"></a>

更新并添加以下内容：
+ 将 `DeploymentController` 属性从 `EXTERNAL` 更改为 `ECS`。
+ 添加 `Strategy` 属性并将其设置为 BLUE\$1GREEN。
+ 添加 `BakeTimeInMinutes` 属性。

  ```
  {
    "DeploymentConfiguration": {
      "MaximumPercent": 200,
      "MinimumHealthyPercent": 100,
      "DeploymentCircuitBreaker": {
        "Enable": true,
        "Rollback": true
      },
      "BakeTimeInMinutes": 5,
      "Strategy": "BLUE_GREEN"
    }
  }
  ```
+ 将负载均衡器配置添加到服务：

  ```
  {
    "LoadBalancers": [
      {
        "ContainerName": "DemoApp",
        "ContainerPort": 80,
        "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
        "AdvancedConfiguration": {
          "AlternateTargetGroupArn": {"Ref": "ALBTargetGroupGreen"},
          "ProductionListenerRule": {"Ref": "ALBListenerProdRule"},
          "RoleArn": {"Fn::GetAtt": ["ECSInfrastructureRoleForLoadBalancers", "Arn"]}
        }
      }
    ]
  }
  ```
+ 将任务定义引用添加到服务：

  ```
  {
    "TaskDefinition": {"Ref": "BlueTaskDefinition"}
  }
  ```

### 创建 AmazonECSInfrastructureRolePolicyForLoadBalancers 角色
<a name="create-ecs-service-role"></a>

添加允许 Amazon ECS 管理负载均衡器资源的新 IAM 角色。有关更多信息，请参阅 [适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。

## 测试建议
<a name="testing-recommendations"></a>

1. 将迁移后的模板部署到非生产环境。

1. 确认服务是否使用初始配置正确部署。

1. 通过更新任务定义并观察蓝绿部署过程来测试部署。

1. 确认流量是否在蓝色部署和绿色部署之间正确转移。

1. 通过强制触发部署失败来测试回滚功能。

## 迁移后的模板
<a name="migrated-template"></a>

### 最终模板
<a name="ecs-bluegreen-template"></a>

这是使用 Amazon ECS 蓝绿部署的完整 CloudFormation 模板：

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "Vpc": {
      "Type": "AWS::EC2::VPC::Id"
    },
    "Subnet1": {
      "Type": "AWS::EC2::Subnet::Id"
    },
    "Subnet2": {
      "Type": "AWS::EC2::Subnet::Id"
    }
  },
  "Resources": {
    "ExampleSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Security group for ec2 access",
        "VpcId": {"Ref": "Vpc"},
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "CidrIp": "0.0.0.0/0"
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 8080,
            "ToPort": 8080,
            "CidrIp": "0.0.0.0/0"
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "ALBTargetGroupBlue": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties": {
        "HealthCheckIntervalSeconds": 5,
        "HealthCheckPath": "/",
        "HealthCheckPort": "80",
        "HealthCheckProtocol": "HTTP",
        "HealthCheckTimeoutSeconds": 2,
        "HealthyThresholdCount": 2,
        "Matcher": {
          "HttpCode": "200"
        },
        "Port": 80,
        "Protocol": "HTTP",
        "Tags": [
          {
            "Key": "Group",
            "Value": "Example"
          }
        ],
        "TargetType": "ip",
        "UnhealthyThresholdCount": 4,
        "VpcId": {"Ref": "Vpc"}
      }
    },
    "ALBTargetGroupGreen": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties": {
        "HealthCheckIntervalSeconds": 5,
        "HealthCheckPath": "/",
        "HealthCheckPort": "80",
        "HealthCheckProtocol": "HTTP",
        "HealthCheckTimeoutSeconds": 2,
        "HealthyThresholdCount": 2,
        "Matcher": {
          "HttpCode": "200"
        },
        "Port": 80,
        "Protocol": "HTTP",
        "Tags": [
          {
            "Key": "Group",
            "Value": "Example"
          }
        ],
        "TargetType": "ip",
        "UnhealthyThresholdCount": 4,
        "VpcId": {"Ref": "Vpc"}
      }
    },
    "ExampleALB": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties": {
        "Scheme": "internet-facing",
        "SecurityGroups": [
          {"Ref": "ExampleSecurityGroup"}
        ],
        "Subnets": [
          {"Ref": "Subnet1"},
          {"Ref": "Subnet2"}
        ],
        "Tags": [
          {
            "Key": "Group",
            "Value": "Example"
          }
        ],
        "Type": "application",
        "IpAddressType": "ipv4"
      }
    },
    "ALBListenerProdTraffic": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Properties": {
        "DefaultActions": [
          {
            "Type": "forward",
            "ForwardConfig": {
              "TargetGroups": [
                {
                  "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
                  "Weight": 1
                },
                {
                  "TargetGroupArn": {"Ref": "ALBTargetGroupGreen"},
                  "Weight": 0
                }
              ]
            }
          }
        ],
        "LoadBalancerArn": {"Ref": "ExampleALB"},
        "Port": 80,
        "Protocol": "HTTP"
      }
    },
    "ALBListenerProdRule": {
      "Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
      "Properties": {
        "Actions": [
          {
            "Type": "forward",
            "ForwardConfig": {
              "TargetGroups": [
                {
                  "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
                  "Weight": 1
                },
                {
                  "TargetGroupArn": {"Ref": "ALBTargetGroupGreen"},
                  "Weight": 0
                }
              ]
            }
          }
        ],
        "Conditions": [
          {
            "Field": "http-header",
            "HttpHeaderConfig": {
              "HttpHeaderName": "User-Agent",
              "Values": [
                "Mozilla"
              ]
            }
          }
        ],
        "ListenerArn": {"Ref": "ALBListenerProdTraffic"},
        "Priority": 1
      }
    },
    "ECSTaskExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Sid": "",
              "Effect": "Allow",
              "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
        ]
      }
    },
    "ECSInfrastructureRoleForLoadBalancers": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Sid": "AllowAccessToECSForInfrastructureManagement",
              "Effect": "Allow",
              "Principal": {
                "Service": "ecs.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/AmazonECSInfrastructureRolePolicyForLoadBalancers"
        ]
      }
    },
    "BlueTaskDefinition": {
      "Type": "AWS::ECS::TaskDefinition",
      "Properties": {
        "ExecutionRoleArn": {"Fn::GetAtt": ["ECSTaskExecutionRole", "Arn"]},
        "ContainerDefinitions": [
          {
            "Name": "DemoApp",
            "Image": "nginxdemos/hello:latest",
            "Essential": true,
            "PortMappings": [
              {
                "HostPort": 80,
                "Protocol": "tcp",
                "ContainerPort": 80
              }
            ]
          }
        ],
        "RequiresCompatibilities": [
          "FARGATE"
        ],
        "NetworkMode": "awsvpc",
        "Cpu": "256",
        "Memory": "512",
        "Family": "ecs-demo"
      }
    },
    "ECSDemoCluster": {
      "Type": "AWS::ECS::Cluster",
      "Properties": {}
    },
    "ECSDemoService": {
      "Type": "AWS::ECS::Service",
      "Properties": {
        "Cluster": {"Ref": "ECSDemoCluster"},
        "DesiredCount": 1,
        "DeploymentController": {
          "Type": "ECS"
        },
        "DeploymentConfiguration": {
          "MaximumPercent": 200,
          "MinimumHealthyPercent": 100,
          "DeploymentCircuitBreaker": {
            "Enable": true,
            "Rollback": true
          },
          "BakeTimeInMinutes": 5,
          "Strategy": "BLUE_GREEN"
        },
        "NetworkConfiguration": {
          "AwsvpcConfiguration": {
            "AssignPublicIp": "ENABLED",
            "SecurityGroups": [
              {"Ref": "ExampleSecurityGroup"}
            ],
            "Subnets": [
              {"Ref": "Subnet1"},
              {"Ref": "Subnet2"}
            ]
          }
        },
        "LaunchType": "FARGATE",
        "PlatformVersion": "1.4.0",
        "TaskDefinition": {"Ref": "BlueTaskDefinition"},
        "LoadBalancers": [
          {
            "ContainerName": "DemoApp",
            "ContainerPort": 80,
            "TargetGroupArn": {"Ref": "ALBTargetGroupBlue"},
            "AdvancedConfiguration": {
              "AlternateTargetGroupArn": {"Ref": "ALBTargetGroupGreen"},
              "ProductionListenerRule": {"Ref": "ALBListenerProdRule"},
              "RoleArn": {"Fn::GetAtt": ["ECSInfrastructureRoleForLoadBalancers", "Arn"]}
            }
          }
        ]
      }
    }
  }
}
```

# 从 CodeDeploy 蓝绿服务部署迁移到 Amazon ECS 滚动更新服务部署
<a name="migrate-code-deploy-to-ecs-rolling"></a>

 可以将服务部署从 CodeDeploy 蓝绿部署迁移到 Amazon ECS 滚动更新部署。此举有助于摆脱对 CodeDeploy 的依赖，转而使用集成部署。

Amazon ECS 服务计划程序会将当前正在运行的任务替换为新任务。在滚动更新期间 Amazon ECS 在服务中添加或删除的任务数量由服务部署配置控制。

## 先决条件
<a name="migrate-code-deploy-to-ecs-rolling-prerequisites"></a>

在开始蓝绿部署之前，执行以下操作。

1. 将不再需要 Amazon ECS CodeDeploy IAM 角色。

1. 关闭 CodeDeploy 自动化。有关更多信息，请参阅《CodeDeploy 用户指南》**中的[在 CodeDeploy 中使用部署组](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-groups.html)。

1. 确认服务没有正在进行的服务部署。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。

有关更新服务部署控制器的更多信息，请参阅[更新 Amazon ECS 服务参数](update-service-parameters.md)。

## 过程
<a name="migrate-code-deploy-to-ecs-rolling-procedure"></a>

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

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

   此时将显示集群详细信息页面。

1. 从**服务**选项卡中，选择服务。

   此时将显示服务详细信息页面。

1. 在横幅中，选择**迁移**。

   将显示**更新部署配置**页面。

1. 展开**部署选项**，然后指定以下参数。

   1. 对于**部署控制器类型**，选择 **ECS**。

   1. 对于**部署策略**，选择**滚动更新**。

   1. 对于**Min running tasks**（最小运行任务数），输入服务中在部署期间必须保持 `RUNNING` 状态的任务数的下限，以所需任务数的百分比表示（四舍五入到最接近的整数）。有关更多信息，请参阅[部署配置](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html#sd-deploymentconfiguration)。

   1. 对于 **Max running tasks**（最大运行任务数），输入部署期间 `RUNNING` 或 `PENDING` 状态下允许的服务中任务数的上限，以所需任务数的百分比表示（四舍五入到最接近的整数）。

1. 展开 **Load Balancing**，然后配置以下内容：

   1. 对于**角色**，选择在先决条件中创建的具有蓝绿权限的角色。

      有关更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

   1. 对于**侦听器**，从 CodeDeploy 蓝绿部署中选择生产侦听器。

   1. 对于**目标组**，从 CodeDeploy 蓝绿部署中选择生产目标组。

1. 选择**更新**。

## 后续步骤
<a name="migrate-code-deploy-to-ecs-rolling-next-steps"></a>

必须更新服务才能使更改生效。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。

# 更新 Amazon ECS 部署策略
<a name="migrate-deployment-strategies"></a>

Amazon ECS 支持多种部署策略来更新服务。可以根据应用程序需求，在这些策略之间迁移。本主题将介绍如何在滚动部署与蓝绿部署之间迁移。

## 了解 Amazon ECS 部署策略
<a name="deployment-strategies-overview"></a>

在部署策略之间迁移之前，了解每种策略的工作原理及其主要区别非常重要：

**滚动部署**  
在滚动部署中，Amazon ECS 会将当前运行的应用程序版本替换为新版本。服务计划程序将使用最高和最低运行正常百分比参数来确定部署策略。  
滚动部署更易于设置，但对部署过程和流量路由的控制较少。

**蓝/绿部署**  
在蓝绿部署中，Amazon ECS 会在现有版本（蓝色）旁边创建服务的新版本（绿色）。这样，就可以在将生产流量路由到新版本之前对其进行验证。  
蓝绿部署可以更好地控制部署过程，包括流量转移、测试和回滚功能。

## 最佳实践
<a name="migration-best-practices"></a>

在部署策略之间迁移时，请遵循以下最佳实践：
+ **在非生产环境中测试**：在将更改应用于生产服务之前，务必在非生产环境中测试更新。
+ **制定回滚计划**：制定回滚计划，防止更新不按预期运行。
+ **在迁移期间进行监控**：在迁移期间和迁移之后密切监控服务，确保其继续正常运行。
+ **更新文档**：更新部署文档以反映新的部署策略。
+ **考虑流量影响**：了解更新可能如何影响服务流量，并进行相应的规划。

# 将部署策略从滚动更新更新为 Amazon ECS 蓝绿部署
<a name="update-rolling-to-bluegreen"></a>

如果希望在生产环境中实施服务更改之前进行服务更改并测试，可以从滚动更新部署迁移到 Amazon ECS 蓝绿部署。

## 先决条件
<a name="update-rolling-to-bluegreen-prerequisites"></a>

在将服务从滚动部署迁移到蓝绿部署之前，请确保满足以下条件：
+  等待当前所有部署完成。
+ 使用滚动部署策略的现有 Amazon ECS 服务。
+ 如果有多个传送流量的服务修订版，Amazon ECS 会在迁移期间尝试将流量整合到单个修订中。如果此操作失败，可能需要将服务手动更新为使用单个修订，然后再进行迁移。
+ 配置相应的权限。
  + 有关 Elastic Load Balancing 权限的信息，请参阅[适用于负载均衡器的 Amazon ECS 基础设施 IAM 角色](AmazonECSInfrastructureRolePolicyForLoadBalancers.md)。
  + 有关最低权限的更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。
+ 根据配置，需要执行以下操作之一：
  + 如果服务使用 Elastic Load Balancing，请使用新的“advancedConfiguration”更新服务并启动滚动部署。
  + 如果服务使用 Service Connect，请更新服务并启动滚动部署。
  + 如果服务同时使用 Elastic Load Balancing 和 Service Connect，请执行上述两个步骤（可以使用单个 UpdateService 请求）。
  + 如果服务不使用上述任何一项，则无需进行其他操作。
+ Amazon ECS 蓝绿部署要求服务使用以下功能之一。配置相应的资源。
  + 应用程序负载均衡器：有关更多信息，请参阅[适用于蓝绿部署、线性部署和金丝雀部署的应用程序负载均衡器资源](alb-resources-for-blue-green.md)。
  + 网络负载均衡器：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的网络负载均衡器资源](nlb-resources-for-blue-green.md)。
  + Service Connect：有关更多信息，请参阅[适用于 Amazon ECS 蓝绿部署、线性部署和金丝雀部署的 Service Connect 资源](service-connect-blue-green.md)。

## 过程
<a name="update-rolling-to-bluegreen-procedure"></a>

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

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

1. 在**集群**页面上，选择包含要迁移的服务的集群。

   将显示集群详细信息页面。

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

1. 选择服务，然后选择**更新**。

   将显示更新服务页面。

1. 展开**部署选项**，然后执行以下操作：

1. 对于**部署策略**，选择**蓝绿部署**。

1. 配置蓝绿部署设置：

   1. 对于**烘焙时间**，输入在蓝色修订服务终止之前蓝色服务修订版和绿色服务修订版同时运行的分钟数。

      这样可以留出验证和测试时间。

   1. （可选）配置 Lambda 函数以在部署的特定阶段运行。在**部署生命周期挂钩**下，为以下阶段配置 Lambda 函数：
      + **纵向扩展前**：在纵向扩展绿色服务修订版之前运行
      + **纵向扩展后**：在纵向扩展绿色服务修订版之后运行
      + **测试流量转移**：在将测试流量路由到绿色服务修订版期间运行
      + **测试流量转移后**：在将测试流量路由到绿色服务修订版之后运行
      + **生产流量转移**：在将生产流量路由到绿色服务修订版期间运行
      + **生产流量转移后**：在将生产流量路由到绿色服务修订版之后运行

      要添加生命周期挂钩，请执行以下操作：

      1. 选择**添加**。

      1. 对于 **Lambda 函数**，输入函数名称或 ARN。

      1. 对于**角色**，选择有权调用 Lambda 函数的 IAM 角色。

      1. 对于**生命周期阶段**，选择应运行 Lambda 函数的阶段。

      1. 可选：对于**挂钩详细信息**，输入键值对以提供有关挂钩的其他信息。

1. 配置负载均衡器设置：

   1. 在 **Load balancing** 下，验证服务是否配置为使用负载均衡器。

   1. 对于**目标组**，选择生产（蓝色）环境的主目标组。

   1. 对于**备用目标组**，选择测试（绿色）环境的目标组。

   1. 对于**生产侦听器规则**，选择用于路由生产流量的侦听器规则。

   1. 可选：对于**测试侦听器规则**，选择用于将测试流量路由到绿色环境的侦听器规则。

   1. 对于**角色**，选择允许 Amazon ECS 管理负载均衡器的 IAM 角色。

1. 查看配置更改，然后选择**更新**。

## 后续步骤
<a name="update-rolling-to-bluegreen-next-steps"></a>
+ 更新服务以启动部署。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。
+ 监控部署过程，确保其遵循蓝绿模式：
  + 创建绿色服务修订版并进行纵向扩展
  + 将测试流量路由到绿色修订（如果已配置）
  + 向绿色服务修订转移生产流量
  + 烘焙时间结束后，蓝色修订将终止

# 将部署策略从 Amazon ECS 蓝绿部署更新为滚动更新
<a name="update-bluegreen-to-rolling"></a>

可以将蓝绿部署迁移到滚动更新部署。

迁移到滚动部署时，请注意以下事项：
+ **流量处理**：利用滚动部署，新任务将在通过运行状况检查后立即开始接收流量。不像蓝绿部署那样有独立的测试阶段。
+ **资源效率**：滚动部署通常比蓝绿部署使用的资源更少，因为它们会以增量方式替换任务，而不是创建完全重复的环境。
+ **回滚复杂性**：与蓝绿部署相比，滚动部署的回滚更为复杂。如果需要回滚，必须使用先前的任务定义启动新的部署。
+ **部署速度**：滚动部署的完成时间可能比蓝绿部署更长，尤其是对于包含许多任务的服务。
+ **负载均衡器配置**：现有的负载均衡器配置将继续支持滚动部署，但流量转移行为会有所不同。

## 先决条件
<a name="update-bluegreen-to-rolling-prerequisites"></a>

在将服务从蓝绿部署迁移到滚动部署之前，请确保满足以下条件：
+ 使用蓝绿部署策略的现有 Amazon ECS 服务
+ 该服务没有正在进行的部署（等待任何当前部署完成）
+ 清楚地了解服务在滚动部署下的行为方式

**注意**  
如果服务正在进行部署，则无法将其迁移到滚动部署。等待当前所有部署完成，然后再继续操作。

## 迁移过程
<a name="update-bluegreen-to-rolling-procedure"></a>

按照以下步骤将 Amazon ECS 服务从蓝绿部署迁移到滚动部署：

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

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

1. 在**集群**页面上，选择包含要迁移的服务的集群。

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

1. 选择要迁移的服务，然后选择**更新**。

1. 在**更新服务**页面上，导航到**部署选项**部分，必要时将其展开。

1. 对于**部署策略**，选择**滚动更新**。

1. 配置滚动部署设置：

   1. 对于**最低正常运行百分比**，输入部署期间必须保持在 `RUNNING` 状态的任务的最小百分比。该值是作为服务所需任务数的百分比指定的。

   1. 对于**最高正常运行百分比**，输入部署期间允许处于 `RUNNING` 或 `PENDING` 状态的任务的最大百分比。该值是作为服务所需任务数的百分比指定的。

1. 可选：在**部署失败检测**下，配置 Amazon ECS 如何检测和处理部署失败：

   1. 要启用部署断路器，请选择**使用部署断路器**。

   1. 要自动回滚失败的部署，请选择**失败时回滚**。

1. 查看配置更改，然后选择**更新**以保存更改并将服务迁移到滚动部署。

Amazon ECS 将更新服务配置以使用滚动部署策略。下次更新服务时，将使用滚动部署流程。

**注意**  
从蓝绿部署迁移到滚动部署时，Amazon ECS 会通过以下方式处理迁移：  
识别当前正在传送流量的有效服务修订版。
保持现有的负载均衡器配置，但更改新部署的处理方式。
为服务做好准备，应对将来的滚动部署。

## 后续步骤
<a name="update-bluegreen-to-rolling-next-steps"></a>
+ 更新服务以启动部署。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。

# 对 Amazon ECS 部署策略更新进行问题排查
<a name="troubleshooting-deployment-controller-migration"></a>

本节提供在迁移部署策略时可能遇到的常见问题的解决方案。

## 多个服务修订版或任务集
<a name="troubleshooting-multiple-task-sets"></a>

以下问题与部署存在多个服务修订版有关。

更新 ECS 部署控制器时存在多个任务集  
*错误消息*：`Updating the deployment controller is not supported when there are multiple tasksets in the service. Please ensure your service has only one taskset and try again.`  
*解决方案*：尝试更改具有多个有效任务集的服务的部署控制器类型时，会发生此错误。要解决 `CODE_DEPLOY` 或 `EXTERNAL` 部署控制器中出现的此问题，请执行以下操作：  

1. 检查当前任务集：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].taskSets"
   ```

1. 等待任何正在进行的部署完成。

1. 强制实施新部署以清理任务集：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --force-new-deployment
   ```

1. 如有必要，请手动删除额外的任务集：

   ```
   aws ecs delete-task-set --cluster your-cluster-name --service your-service-name --task-set task-set-id
   ```

1. 当只剩下一个任务集后，重新尝试更新部署控制器。
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

更新 `ECS` 部署控制器时缺少主任务集  
*错误消息*：`Updating the deployment controller requires a primary taskset in the service. Please ensure your service has a primary taskset and try again.`  
*解决方案*：尝试更改没有主任务集的服务部署控制器类型时，会发生此错误。要解决此问题，请执行以下操作：  

1. 验证服务状态和任务集。如果服务中存在任务集，则应将其标记为 `ACTIVE`。

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].taskSets[*].[status,id]
   ```

   如果服务中没有处于 `ACTIVE` 状态的任务集，请迁移部署。有关更多信息，请参阅[迁移方法](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/migrate-codedeploy-to-ecs-bluegreen.html#migration-paths)。

1. 如果服务没有正在运行的任务，请通过更新服务来部署至少一个任务：

   ```
   aws ecs update-service-primary-task-set --cluster your-cluster-name --service your-service-name --primary-task-set your-taskset-id
   ```

   这会将服务中的（先前为 `ACTIVE`）任务集标记为 `PRIMARY` 状态。

1. 等待任务达到稳定的运行状态。可以通过以下方式查看状态：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].deployments"
   ```

1. 当服务拥有主任务集且任务正在运行后，重新尝试更新部署控制器。
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

## 部署失败检测类型和部署控制器不匹配
<a name="troubleshooting-failure-detection"></a>

以下问题与部署失败检测类型和部署控制器不匹配有关。

使在非 ECS 控制器上使用部署断路器  
*错误消息*：`Deployment circuit breaker feature is only supported with ECS deployment controller. Update to ECS deployment controller and try again.`  
*解决方案*：尝试在未使用 `ECS` 部署控制器的服务上启用部署断路器功能时，会发生此错误。部署断路器仅与 `ECS` 部署控制器兼容。  

1. 检查服务的当前部署控制器：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].deploymentController"
   ```

1. 更新服务以使用 `ECS` 部署控制器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-controller type=ECS
   ```

1. 服务使用 `ECS` 部署控制器后，启用部署断路器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-configuration "deploymentCircuitBreaker={enable=true,rollback=true}"
   ```
有关更多信息，请参阅 [Amazon ECS 部署断路器如何检测故障](deployment-circuit-breaker.md)。

在非 ECS 控制器上使用基于警报的回滚  
*错误消息*：`Alarm based rollback feature is only supported with ECS deployment controller. Update to ECS deployment controller and try again.`  
*解决方案*：尝试在未使用 `ECS` 部署控制器的服务上配置基于警报的回滚时，会发生此错误。基于警报的回滚功能仅与 `ECS` 部署控制器兼容。  

1. 检查服务的当前部署控制器：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].deploymentController"
   ```

1. 更新服务以使用 `ECS` 部署控制器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-controller type=ECS
   ```

1. 服务使用 `ECS` 部署控制器后，配置基于警报的回滚：

   ```
   aws ecs update-service --cluster your-cluster-name --services your-service-name --deployment-configuration "alarms={alarmNames=[your-alarm-name],enable=true,rollback=true}"
   ```
有关更多信息，请参阅 [CloudWatch 警报如何检测 Amazon ECS 部署故障](deployment-alarm-failure.md)。

## Service Connect 和部署控制器不匹配
<a name="troubleshooting-service-connect-mismatch"></a>

以下问题与 Service Connect 和部署控制器不匹配有关。

在 `EXTERNAL` 控制器上使用 Service Connect  
*错误消息*：`The EXTERNAL deployment controller type is not supported for services using Service Connect.`  
*解决方案*：尝试在启用了 Service Connect 的服务上使用 `EXTERNAL` 部署控制器时，会发生此错误。`EXTERNAL` 控制器与 Service Connect 不兼容。  

1. 检查服务是否启用了 Service Connect：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].serviceConnectConfiguration"
   ```

1. 如果需要使用 `EXTERNAL` 部署控制器，请通过更新服务来禁用 Service Connect：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --service-connect-configuration "{}"
   ```

1. 或者，如果必须使用 Service Connect，请改用 `ECS` 部署控制器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-controller type=ECS
   ```
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

在非 ECS 控制器上使用 Service Connect  
*错误消息*：`Service Connect feature is only supported with ECS (rolling update) deployment controller. Update to ECS deployment controller and try again.`  
*解决方案*：尝试在未使用 `ECS` 部署控制器的服务上启用 Service Connect 时，会发生此错误。Service Connect 功能仅与 `ECS` 部署控制器兼容。  

1. 检查服务的当前部署控制器：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].deploymentController"
   ```

1. 更新服务以使用 ECS 部署控制器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-controller type=ECS
   ```

1. 服务使用 ECS 部署控制器后，启用 Service Connect：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --service-connect-configuration "enabled=true,namespace=your-namespace"
   ```
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

## 控制器类型和计划策略不匹配
<a name="troubleshooting-controller-type-scheduling"></a>

以下问题与控制器类型和计划策略不匹配有关。

将 `CODE_DEPLOY` 控制器与 `DAEMON` 计划策略结合使用  
*错误消息*：`The CODE_DEPLOY deployment controller type is not supported for services using the DAEMON scheduling strategy.`  
*解决方案*：尝试将 CODE\$1DEPLOY 部署控制器与使用 `DAEMON` 计划策略的服务结合使用时，会发生此错误。`CODE_DEPLOY` 控制器仅与 `REPLICA` 计划策略兼容。  

1. 检查服务的当前计划策略：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].schedulingStrategy"
   ```

1. 如果需要蓝绿部署，请将服务更改为使用 `REPLICA` 计划策略：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --scheduling-strategy REPLICA
   ```

1. 或者，如果必须使用 `DAEMON` 计划策略，请改用 `ECS` 部署控制器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-controller type=ECS
   ```
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

将 EXTERNAL 与 DAEMON 计划策略结合使用  
*错误消息*：`The EXTERNAL deployment controller type is not supported for services using the DAEMON scheduling strategy.`  
*解决方案*：尝试将 EXTERNAL 部署控制器与使用 DAEMON 计划策略的 ECS 服务结合使用时，会发生此错误。EXTERNAL 控制器仅与 REPLICA 计划策略兼容。  

1. 检查服务的当前计划策略：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].schedulingStrategy"
   ```

1. 如果需要使用 `EXTERNAL` 部署控制器，请将服务更改为使用 `REPLICA` 调度策略：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --scheduling-strategy REPLICA
   ```

1. 或者，如果必须使用 `DAEMON` 计划策略，请改用 `ECS` 部署控制器：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --deployment-controller type=ECS
   ```
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

具有外部启动类型的服务注册表  
*错误消息*：`Service registries are not supported for external launch type.`  
*解决方案*：尝试为使用 `EXTERNAL` 启动类型的服务配置服务发现（服务注册表）时，会发生此错误。服务发现与 `EXTERNAL` 启动类型不兼容。  

1. 检查服务的当前启动类型：

   ```
   aws ecs describe-services --cluster your-cluster-name --services your-service-name --query "services[0].launchType"
   ```

1. 如果需要使用服务发现，请将服务更改为使用 `EC2` 或 `FARGATE` 启动类型：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --launch-type FARGATE
   ```

1. 或者，如果必须使用 `EXTERNAL` 启动类型，请删除服务注册表配置：

   ```
   aws ecs update-service --cluster your-cluster-name --service your-service-name --service-registries "[]"
   ```
有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。

## 恢复部署控制器更新
<a name="troubleshooting-revert"></a>

如果决定要恢复到之前的部署控制器，可以执行以下操作之一：
+ 如果使用的是 CloudFormation，可以使用之前的模板创建新堆栈。有关更多信息，请参阅《CloudFormation 用户指南**》中的[通过 CloudFormation 控制台创建堆栈](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html)。
+ 如果使用的是 Amazon ECS 控制台或 AWS CLI，可以更新服务。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。

  如果使用了 update-service 命令，请使用 `--deployment-controller` 选项并将其设置为之前的部署控制器。

# 使用 Amazon ECS 服务部署查看服务历史记录
<a name="service-deployment"></a>

服务部署可让您全面了解部署。服务部署可提供有关服务的以下信息：
+ 当前部署的工作负载配置（源服务修订版本）
+ 要部署的工作负载配置（目标服务修订）
+ 部署状态
+ 断路器检测到的失败的任务数
+ 处于警报状态的 CloudWatch 警报
+ 服务部署何时启动和完成
+ 回滚（如果发生）的详细信息

有关服务部署属性的信息，请参阅[Amazon ECS 服务部署中包含的属性](service-deployment-property.md)。

服务部署是只读的，每个部署都有唯一的 ID。

服务部署分为三个阶段：


| 舞台 | 定义 | 关联状态 | 
| --- | --- | --- | 
| 待处理 | 服务部署已创建，但尚未启动 | PENDING | 
| 持续 | 正在进行服务部署 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-deployment.html)  | 
| Completed  | 服务部署已完成（成功或失败） |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-deployment.html)  | 

可以使用服务部署来了解服务的生命周期，并确定是否需要采取任何行动。例如，如果发生回滚，则可能需要调查服务部署并查看服务事件。

您可以使用控制台、API 和 AWS CLI，查看在 2024 年 10 月 25 日当天或之后创建的部署的最近 90 天历史记录。

您可以停止尚未完成的部署。有关更多信息，请参阅 [停止 Amazon ECS 服务部署](stop-service-deployment.md)。

## 服务部署生命周期
<a name="service-deployments-lifecycle"></a>

发生以下任何操作时，Amazon ECS 会自动创建新的服务部署：
+ 用户创建服务。
+ 用户更新服务并使用强制新部署选项。
+ 用户更新一个或多个需要部署的服务属性。

在部署期间，Amazon ECS 会更新以下服务部署属性以反映服务部署的进度：
+ 状态
+ 正在运行的任务数量

  服务修订中指示的正在运行的任务数可能不等于实际正在运行的任务数。此数字表示部署完成时正在运行的任务数。例如，如果您独立于服务部署启动任务，则这些任务不会计入服务修订的正在运行的任务。
+ 断路器故障检测：
  + 启动失败的任务数
+ CloudWatch 警报故障检测
  + 处于活动状态的警报
+ 回滚信息：
  + 启动时间
  + 回滚的原因
  + 用于回滚的服务修订的 ARN
+ 状态原因

当您删除服务时，Amazon ECS 会删除相应服务部署。

## 服务部署状态
<a name="service-deployments-states"></a>

服务部署以 `PENDING` 状态启动。

下图显示了可能在 `PENDING` 状态之后发生的服务部署状态：`IN_PROGRESS`、`ROLLBACK_REQUESTED`、`SUCCESSFUL`、`STOP_REQUESTED`、`ROLLBACK_IN_PROGRESSS`、`ROLLBACK_FAILED`、`ROLLBACK_SUCCESSFUL` 和 `STOPPED`。

![\[服务部署的 STOP_REQUESTED、SUCCESSFUL 和 ROLLBACK_IN_PROGRESS 状态可能在 IN_PROGRESS 状态之后发生。\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/images/service-deployment-states.png)


以下信息提供了有关服务部署状态的详细信息：
+ `PENDING`：服务部署已创建，但尚未启动。

  状态可以变为 `IN_PROGRESS`、`ROLLBACK_REQUESTED`、`STOP_REQUESTED` 或 `STOPPED`。
+ `IN_PROGRESS`：服务部署正在进行。

  状态可以变为 `SUCCESSFUL`、`STOP_REQUESTED`、`ROLLBACK_REQUESTED`、`ROLLBACK_IN_PROGRESS` 或 `STOPPED`。
+ `STOP_REQUESTED`：发生以下任一情况时，服务部署状态将变为 `STOP_REQUESTED`：
  + 用户启动新的服务部署。
  + 故障检测机制（基于断路器或警报）未使用回滚选项，并且服务未达到 `SUCCESSFUL` 状态。

  此状态将变为 `STOPPED`。
+  `ROLLBACK_REQUESTED`：当用户通过控制台、API 或 CLI 请求回滚时，服务部署状态将变为 `ROLLBACK_REQUESTED`。

  状态可以变为 `SUCCESSFUL`、`ROLLBACK_IN_PROGRESS` 和 `STOPPED`。
+ `SUCCESSFUL`：服务部署成功完成时，服务部署状态变为 `SUCCESSFUL`。
+  `ROLLBACK_IN_PROGRESS`：故障检测机制（基于断路器或警报）使用回滚选项，并且服务失败时，服务部署状态将变为 `ROLLBACK_IN_PROGRESS`。

   此状态将变为 `ROLLBACK_SUCCESSFUL` 或 `ROLLBACK_FAILED`。

# Amazon ECS 服务部署中包含的属性
<a name="service-deployment-property"></a>

服务部署中包含以下属性。


| 属性 | 说明 | 
| --- | --- | 
|  服务部署 ARN  |  服务部署的 ARN。  | 
| 服务 ARN |  此服务部署的服务 ARN。  | 
|  集群 ARN  |  托管服务的集群的 ARN。  | 
| 服务部署创建时间 | 创建服务部署的时间。 | 
| 服务部署启动时间 | 启动服务部署的时间。 | 
|  服务部署完成时间  | 完成服务部署的时间。 | 
| 服务部署停止时间 | 停止服务部署的时间。 | 
| 服务部署更新时间 | 上次更新服务部署的时间。 | 
| 源服务修订 |  当前正在运行的服务修订。 有关所包含属性的信息，请参阅[Amazon ECS 服务修订中包含的属性](service-revision-property.md)。  | 
| 部署配置 | 部署参数包括断路器配置、确定的警报。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-deployment-property.html) | 
| 目标服务修订 | 要部署的服务修订。部署成功完成后，目标服务修订变为正在运行的服务修订。 | 
| 服务部署状态 | 服务部署状态。有效值为 PENDING、SUCCESSFUL、STOPPED、STOP\$1REQUESTED、STOP\$1IN\$1PROGRESS、IN\$1PROGRESS、ROLLBACK\$1IN\$1PROGRESS、ROLLBACK\$1SUCCESSFUL、和 ROLLBACK\$1FAILED。 | 
| 服务部署状态信息 | 有关服务部署为何处于当前状态的信息。例如，断路器检测到故障。 | 
|  回滚信息 | 部署失败时服务部署使用的回滚选项。 | 
| 服务部署断路器选项 | 决定服务部署失败的断路器。 | 
| 服务部署的 CloudWatch 警报 | 用于确定服务部署何时失败的 CloudWatch 警报。 | 

# 查看 Amazon ECS 服务部署所需的权限
<a name="service-deployment-permissions"></a>

 当您遵循授予最低权限的最佳实践时，需要添加额外的权限，才能在控制台中查看服务部署。

您需要执行以下操作的权限：
+ ListServiceDeployments
+ DescribeServiceDeployments
+ DescribeServiceRevisions

您需要访问以下资源的权限：
+ 服务
+ 服务部署
+ 服务修订

以下示例策略包含所需的权限，并将操作限制到特定服务。

将 `account`、`cluster-name` 和 `service-name` 替换为您的值。

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

****  

```
{
"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "ecs:ListServiceDeployments",
            "ecs:DescribeServiceDeployments",
            "ecs:DescribeServiceRevisions"
        ],
        "Resource": [
            "arn:aws:ecs:us-east-1:123456789012:service/cluster-name/service-name",
            "arn:aws:ecs:us-east-1:123456789012:service-deployment/cluster-name/service-name/*",
            "arn:aws:ecs:us-east-1:123456789012:service-revision/cluster-name/service-name/*"
            ]
        }
   ]
}
```

------

# 查看 Amazon ECS 服务部署
<a name="view-service-deployment"></a>

您可以查看在 2024 年 10 月 25 日当天或之后创建的部署的最近 90 天历史记录。服务部署可能为下列任意状态：
+ 进行中 
+ 待处理
+ Completed

 您可以使用此信息来确定是否需要更新服务的部署方式或服务修订。有关所包含属性的信息，请参阅[Amazon ECS 服务部署中包含的属性](service-deployment-property.md)。

开始操作之前，请配置查看服务部署所需的权限。有关更多信息，请参阅 [查看 Amazon ECS 服务部署所需的权限](service-deployment-permissions.md)。

------
#### [ Amazon ECS Console ]

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时将显示服务详细信息页面。

1. 在服务详细信息页面上，选择**部署**。

1. 选择要查看的服务部署。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/view-service-deployment.html)

   此时将显示服务部署详细信息页面。

1. （可选）比较服务修订以查看差异。

   在**服务修订**下，选择**比较版本**，然后选择 2 个版本进行比较。

   服务修订将并行显示，并突出显示差异。

------
#### [ AWS CLI ]

1. 运行 `list-service-deployments` 以检索服务部署 ARN。

   将变量替换为您自己的值。

   ```
   aws ecs list-service-deployments --cluster cluster-name --service service-name
   ```

   记下要查看的部署的 serviceDeploymentArn。

   ```
   {
       "serviceDeployments": [
           {
               "serviceDeploymentArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/example/sd-example/NCWGC2ZR-taawPAYrIaU5",
               "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/example/sd-example",
               "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/example",
               "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/example/sd-example/4980306466373577095",
               "status": "SUCCESSFUL"
           }
       ]
   }
   ```

1. 运行 `describe-service-deployments`。使用从 `serviceDeploymentArn` 中返回的 `list-service-deployments`。

   将变量替换为您自己的值。

   ```
   aws ecs describe-service-deployments --service-deployment-arns arn:aws:ecs:region:123456789012:service-deployment/cluster-name/service-name/NCWGC2ZR-taawPAYrIaU5
   ```

------

## 后续步骤
<a name="view-service-deployment-next-step"></a>

您可以查看部署中服务修订的详细信息。有关更多信息，请参阅 [查看 Amazon ECS 服务修订详细信息](view-service-revision.md)。

# Amazon ECS 服务修订
<a name="service-revision"></a>

服务修订包含 Amazon ECS 尝试部署的工作负载配置的记录。每当您创建或部署服务时，Amazon ECS 都会自动创建并捕获您尝试在服务修订中部署的配置。

 服务修订是只读的，并且具有唯一的标识符。有关所包含属性的信息，请参阅[Amazon ECS 服务修订中包含的属性](service-revision-property.md)。

 服务修订具有以下优势：
+ 在服务部署期间，您可以将当前部署的服务修订（源）与正在部署的服务修订（目标）进行比较。
+ 当您使用回滚选项进行服务部署时，Amazon ECS 会自动将服务部署回滚到上次成功部署的服务修订。
+ 服务修订包含一个资源中的工作负载配置记录。

## 服务修订生命周期
<a name="service-revisions-lifecycle"></a>

当您创建服务或更新会启动部署的服务属性时，Amazon ECS 会自动创建新的服务修订。

 Amazon ECS 不会为回滚操作创建新的服务修订。Amazon ECS 使用上次成功的服务修订进行回滚。

服务修订是不可变的。

当您删除服务时，Amazon ECS 会删除相应服务修订。

您可以使用控制台、API 和 CLI 查看在 2024 年 10 月 25 日当天或之后创建的服务修订。

# Amazon ECS 服务修订中包含的属性
<a name="service-revision-property"></a>

服务修订中包含以下属性。


| 资源 | 说明 | 
| --- | --- | 
|  服务 ARN  |  标识服务的 ARN。  | 
|  集群 ARN  |  托管服务的集群的 ARN。  | 
|  任务定义 ARN  |  服务任务所用的任务定义的 ARN。  | 
|  服务注册表  |  用于服务发现的服务注册表的详细信息。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| 容量提供程序 |  容量提供程序策略的详细信息。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| 容器映像 |  有关容器映像的详细信息。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| Networking |  服务的网络配置。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| 启动类型 | 用于服务的计算选项。 | 
| 特定于 Fargate 的属性 |  使用 Fargate 时，这是有关 Fargate 版本的信息。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| 在部署时配置的 Amazon EBS 卷 |  在任务定义中指定为启动时配置的卷的配置。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
|  Service Connect |  Service Connect 配置。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| 服务负载均衡器 |  路由服务流量的负载均衡器。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-revision-property.html)  | 
| 运行时监控 | 指示运行时监控是否已开启。 | 
| 创建日期 |  创建服务修订的日期。  | 
| VPC Lattice |  服务修订的 VPC Lattice 配置。  | 

# 查看 Amazon ECS 服务修订详细信息
<a name="view-service-revision"></a>

您可以查看有关在 2024 年 10 月 25 日当天或之后创建的以下服务修订类型的信息：
+ 源：当前部署的工作负载配置
+ 目标：要部署的工作负载配置

------
#### [ Amazon ECS Console ]

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时将显示服务详细信息页面。

1. 在服务详细信息页面上，选择**部署**。

1. 选择要查看的服务修订。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/view-service-revision.html)

------
#### [ AWS CLI ]

1. 运行 `describe-service-deployments` 以检索服务修订 ARN。

   将变量替换为您自己的值。

   ```
   aws ecs describe-service-deployments --service-deployment-arns arn:aws:ecs:region:account-id:service/cluster-name/service-name/NCWGC2ZR-taawPAYrIaU5
   ```

   注意 `sourceServiceRevisions` 或 `targetServiceRevisions` 的 `arn`。

   ```
   {
       "serviceDeployments": [
           {
               "serviceDeploymentArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/example/sd-example/NCWGC2ZR-taawPAYrIaU5",
               "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/example/sd-example",
               "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/example",
               "updatedAt": "2024-09-10T16:49:35.572000+00:00",
               "sourceServiceRevision": {
                   "arn": "arn:aws:ecs:us-west-2:123456789012:service-revision/example/sd-example/4980306466373578954",
                   "requestedTaskCount": 0,
                   "runningTaskCount": 0,
                   "pendingTaskCount": 0
               },
               "targetServiceRevision": {
                   "arn": "arn:aws:ecs:us-west-2:123456789012:service-revision/example/sd-example/4980306466373577095",
                   "requestedTaskCount": 0,
                   "runningTaskCount": 0,
                   "pendingTaskCount": 0
               },
               "status": "IN_PROGRESS",
               "deploymentConfiguration": {
                   "deploymentCircuitBreaker": {
                       "enable": false,
                       "rollback": false
                   },
                   "maximumPercent": 200,
                   "minimumHealthyPercent": 100
               }
           }
       ],
       "failures": []
   }
   ```

1. 运行 `describe-service-revisions`。使用从 `arn` 中返回的 `describe-service-deployments`。

   将变量替换为您自己的值。

   ```
   aws ecs describe-service-revisions --service-revision-arns arn:aws:ecs:region:123456789012:service-revision/cluster-name/service-name/4980306466373577095
   ```

------

# 在可用区之间平衡 Amazon ECS 服务
<a name="service-rebalancing"></a>

从 2025 年 9 月 5 日起，Amazon ECS 将为所有符合该功能要求的服务提供可用区重新平衡功能。当服务采用“可用区分布”作为首次任务分配策略时，或者当没有置放策略时，该服务即合格。

为了帮助您的应用程序实现高可用性，我们建议将您的多任务服务配置在多个可用区之间运行。对于指定其第一个放置策略为可用区分布的服务，AWS 会尽最大努力在可用的可用区之间均匀分配服务任务。

但是，有时在一个可用区中运行的任务数可能与其他可用区中运行的任务数不同，例如发生可用区中断之后。要解决这种任务不平衡问题，您可以启用可用区重新平衡功能。

通过重新平衡可用区，Amazon ECS 可以持续监控每项服务在可用区之间的任务分配。当 Amazon ECS 检测到任务分配不均匀时，它会自动采取措施在可用区之间重新平衡工作负载。这包括在运行最少任务的可用区中启动新任务，以及在过载的可用区中终止任务。

这种重新分配可确保任意一个可用区都不会成为故障点，从而有助于保持容器化应用程序的总体可用性。自动重新平衡过程无需手动干预，从而缩短了事件发生后的恢复时间。

下面概述了可用区重新平衡过程：

1. Amazon ECS 在达到稳定状态后开始对服务进行监控，并查看每个可用区中运行的任务数。

1. 当 Amazon ECS 检测到每个可用区中运行的任务数不平衡时，它会执行以下操作：
   + 发送服务事件，指示可用区重新平衡已启动。
   + 在运行任务数量最少的可用区中启动任务
   + 在运行任务数量最多的可用区中终止任务。
   + 调度程序会等待新启动的任务变为 `HEALTHY` 和 `RUNNING` 状态，然后再终止过载的可用区中的任务。
   + 发送包含可用区重新平衡结果的服务事件。

## Amazon ECS 如何检测任务未平均分配
<a name="service-rebalancing-imbalance"></a>

Amazon ECS 通过将服务所需任务数除以已配置可用区数来确定每个可用区中运行的任务数是否不平衡。如果所需任务数没有平均分配，则 Amazon ECS 会将剩余的任务平均分配到已配置的可用区。每个可用区必须至少有一个任务。

例如，假设一项 Amazon ECS 服务为两个可用区配置了两个所需的任务数。在这种情况下，所需的任务数平均分配。均衡分配即每个可用区一个任务。如果可用区 1 中有两个任务，而可用区 2 中有零个任务，则 Amazon ECS 将在可用区 2 中启动一个任务，然后在可用区 1 中停止一个任务，从而启动重新平衡。

现在，假设一项 Amazon ECS 服务为两个可用区配置了三个所需的任务数。在这种情况下，所需的任务数无法平均分配。均衡分配是可用区 1 中有一个任务而可用区 2 中有两个任务，因为每个可用区至少有一个任务，并将剩余的任务放在可用区 2 中。

假设一项 Amazon ECS 服务为三个可用区配置了五个所需的任务数。在这种情况下，所需的任务数无法平均分配。均衡分配是可用区 1 中有一个任务，可用区 2 和 3 中各有两个任务。考虑到每个可用区各有一个任务后，剩下的两个任务将平均分配到各个可用区。

## 配置可用区重新平衡的注意事项
<a name="service-rebalancing-configurations"></a>

要配置可用区重新平衡时，请考虑以下事项：
+ 可用区重新平衡支持 Fargate 和 EC2 容量提供程序，并且在 Amazon ECS 托管实例上受支持。对于 Fargate，Amazon ECS 将自动在可用区之间重新分配任务以保持平衡。对于 EC2 容量提供程序，Amazon ECS 会尽最大努力在现有容器实例之间重新平衡任务，同时兼顾您定义的放置策略和限制。但是，在重新平衡过程中，Amazon ECS 无法在未充分利用的可用区中启动新实例，因此，只能对现有容器实例进行重新平衡。
+ 可用区重新平衡适用于以下配置：
  + 使用 `Replica` 策略的服务
  + 将可用区分布指定为第一个任务放置策略或未指定放置策略的服务。
+ 您不能将可用区重新平衡用于满足以下任何条件的服务：
  + 使用 `Daemon` 策略
  + 使用 `EXTERNAL` 启动类型（ECS Anywhere）
  + 使用 100% 作为 `maximumPercent` 值
  + 使用经典负载均衡器
  + 使用 `attribute:ecs.availability-zone` 作为任务放置约束

## 可用区重新平衡的放置策略和放置约束
<a name="service-rebalancing-placement-constraints"></a>

放置策略决定了 Amazon ECS 如何选择容器实例和可用区来终止任务放置。任务放置约束是确定是否允许在特定容器实例上运行任务的规则。

对于 EC2，您可以将放置策略和放置约束与可用区重新平衡配合使用。但是，要使可用区重新平衡正常运行，必须首先指定可用区分布放置策略。

可用区重新平衡与各种放置策略组合兼容。例如，您可以创建一种策略，其首先在多个可用区之间平均分配任务，然后根据每个可用区内的内存装填任务。在这种情况下，由于首先指定了可用区分布策略，因此可用区重新平衡能正常运行。

值得注意的是，如果放置策略阵列中的第一个策略不是可用区分布组件，则可用区重新平衡将无法正常运行。这一要求可确保任务分配的主要重点是保持可用区之间的平衡，这对于确保高可用性至关重要。

有关任务放置策略和约束的更多信息，请参阅[Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。

使用 Fargate 的任务不支持任务放置策略和约束。Fargate 将尽最大努力将任务分散到各个可访问的可用区。如果容量提供程序同时包含 Fargate 和 Fargate Spot，则每个容量提供程序的分散行为是独立的。

以下示例策略可在多个可用区中平均分配任务，然后根据每个可用区内的内存装填任务。由于首先指定了 `spread` 策略，因此可用区重新平衡能够与服务兼容。

```
"placementStrategy": [
    {
        "field": "attribute:ecs.availability-zone",
        "type": "spread"
    },
    {
        "field": "memory",
        "type": "binpack"
    }
]
```

## 开启可用区重新平衡
<a name="service-rebalancing-use"></a>

您需要为新服务和现有服务启用可用区重新平衡。

您可以使用控制台、API、AWS CLI 和 CloudFormation 启用和禁用可用区重新平衡。

在创建请求和更新请求中，`AvailabilityZoneRebalancing` 的默认行为有所不同：
+ 对于创建服务请求，当没有为 `AvailabilityZoneRebalancing` 指定值时，Amazon ECS 会将该值默认为 `ENABLED`。
+ 对于更新服务请求，当没有为 `AvailabilityZoneRebalancing` 指定值时，Amazon ECS 会将该值默认为现有服务的 `AvailabilityZoneRebalancing` 值。如果该服务从未设置过 `AvailabilityZoneRebalancing` 值，则 Amazon ECS 会将其视为 `DISABLED`。


| 服务类型 | API | 控制台 | CLI | 
| --- | --- | --- | --- | 
| 现有 | [UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html) |  [更新 Amazon ECS 服务](update-service-console-v2.md)  | [update-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html) | 
| New | [CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateService.html) |  [创建 Amazon ECS 滚动更新部署](create-service-console-v2.md)  | [create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html) | 

以下示例显示了如何在创建新服务时启用服务重新平衡：

```
aws ecs create-service \
    --cluster my-cluster \
    --service-name my-service \
    --task-definition my-task-definition:1 \
    --desired-count 6 \
    --availability-zone-rebalancing ENABLED
```

# 跟踪 Amazon ECS 可用区重新平衡
<a name="track-service-rebalancing"></a>

您可以在控制台中或通过调用 `describe-services` 来验证是否为服务启用了可用区重新平衡。以下示例可用于通过 CLI 查看状态。

响应将为 `ENABLED` 或 `DISABLED`。

```
aws ecs describe-services \
    --services service-name \
    --cluster cluster-name \
    --query services[0].availabilityZoneRebalancing
```

## 服务事件
<a name="service-info-events"></a>

Amazon ECS 会发送服务操作事件，以帮助您了解可用区重新平衡生命周期。


| 事件 | 场景 | Type | 了解详情 | 
| --- | --- | --- | --- | 
| SERVICE\$1REBALANCING\$1STARTED | Amazon ECS 会启动可用区重新平衡操作 | INFO | [服务（*service-name*）未与*可用区 1* 中的 *number-tasks* 个任务、*可用区 2* 中的 *number-tasks* 个任务和*可用区 3* 中的 *number-tasks* 个任务进行可用区平衡。正在进行可用区重新平衡。](service-rebalancing-event-messages-list.md#service-rebalancing-started) | 
| SERVICE\$1REBALANCING\$1COMPLETED | 可用区重新平衡操作完成 |  INFO | [服务（*service-name*）已与*可用区 1* 中的 *number-tasks* 个任务、*可用区 2* 中的 *number-tasks* 个任务和*可用区 3* 中的 *number-tasks* 个任务进行可用区平衡。](service-rebalancing-event-messages-list.md#service-rebalancing-completed) | 
| TASKS\$1STARTED | 在可用区重新平衡操作中，Amazon ECS 成功启动任务 | INFO | [*service-name* 已在*可用区*启动 *number-tasks* 个任务进行可用区重新平衡：*task-ids*。](service-rebalancing-event-messages-list.md#service-rebalancing-tasks-started) | 
| TASKS\$1STOPPED | 在可用区重新平衡操作中，Amazon ECS 成功停止任务 | INFO | [由于可用区重新平衡，*service-name* 已停止在*可用区*中运行的 *number-tasks* 个任务：*task-id*。](service-rebalancing-event-messages-list.md#service-rebalancing-tasks-stopped) | 
| SERVICE\$1TASK\$1PLACEMENT\$1FAILURE | 在可用区重新平衡操作中，Amazon ECS 启动任务失败 | ERROR | 对于 EC2，请参阅[服务（*‬service-name*‭）无法在*可用区*中下达任务，因为没有满足所有条件的容器实例。](service-rebalancing-event-messages-list.md#service-rebalancing-placement-failure-instance) 对于 Fargate，请参阅[服务（*service-name*）无法在*可用区*中下达任务。](service-rebalancing-event-messages-list.md#service-rebalancing-placement-failure) | 
| TASKSET\$1SCALE\$1IN\$1FAILURE\$1BY\$1TASK\$1PROTECTION | 由于正在使用任务保护，可用区重新平衡操作已被阻止。 | INFO | [服务（*service-name*）无法进行可用区重新平衡，因为 *task-set-name* 由于 *reason* 无法横向缩减。](service-rebalancing-event-messages-list.md#service-rebalancing-task-protection-failure) | 
| SERVICE\$1REBALANCING\$1STOPPED | 可用区重新平衡操作停止。Amazon ECS 会发送更多事件，当中会提供更多信息。 | INFO | [服务（*service-name*）已停止可用区重新平衡。](service-rebalancing-event-messages-list.md#service-rebalancing-operation-stopped) | 

## 任务状态更改事件
<a name="task-state-change-events"></a>

Amazon ECS 会为在重新平衡过程中启动的每项任务发送一个任务状态更改事件（`START`）。

Amazon ECS 会为在重新平衡过程中停止的每项任务发送一个任务状态更改事件（`STOPPED`）。原因将设置为 `Availability-zone rebalancing initiated by (deployment ecs-svc/deployment-id)`。

有关事件的更多信息，请参阅 [Amazon ECS 任务状态更改事件](ecs_task_events.md)。

## 对服务重新平衡进行问题排查
<a name="service-rebalancing-troubleshooting"></a>

如果遇到服务重新平衡问题，请考虑以下问题排查步骤：

重新平衡无法启动  
验证：  
+ 服务已启用重新平衡
+ 服务使用受支持的配置（请参阅[配置可用区重新平衡的注意事项](#service-rebalancing-configurations)）
+ 服务已达到稳定状态

重新平衡期间任务放置失败  
如果出现 `SERVICE_TASK_PLACEMENT_FAILURE` 事件：  
+ 对于 EC2：检查目标可用区中是否有可用的容器实例
+ 对于 Fargate：检查是否存在限制任务放置的资源约束或服务配额
+ 查看任务放置限制，确保其不会妨碍正确分配任务

重新平衡意外停止  
如果出现 `SERVICE_REBALANCING_STOPPED` 事件：  
+ 检查是否存在可能阻止操作的任务保护
+ 查找可能中断重新平衡的并发服务部署
+ 检查服务事件，了解有关重新平衡停止原因的更多信息

## 服务重新平衡的最佳实践
<a name="service-rebalancing-best-practices"></a>

遵循以下最佳实践以充分利用服务重新平衡：
+ **监控重新平衡操作**：设置 CloudWatch 警报以监控与重新平衡相关的服务事件，从而快速发现任何问题。
+ **考虑性能影响**：请注意，重新平衡操作可能会暂时增加资源使用量，因为新任务会在旧任务停止之前启动。
+ **策略性地使用任务保护**：如果在重新平衡期间有不应终止的关键任务，请考虑使用任务保护。
+ **规划 EC2 容量**：对于 EC2，确保所有可用区都有足够的容器实例来支持有效的重新平衡。
+ **测试重新平衡行为**：在生产环境中依赖重新平衡之前，在非生产环境中测试服务在重新平衡操作期间的行为。

# 使用负载均衡分配 Amazon ECS 服务流量
<a name="service-load-balancing"></a>

您可以选择将服务配置为使用弹性负载均衡来为服务中的任务平均分配流量。

**注意**  
当您使用任务集时，该集中的所有任务都必须配置为使用 Elastic Load Balancing 或不使用 Elastic Load Balancing。

托管在 AWS Fargate 上的 Amazon ECS 服务支持应用程序负载均衡器、网络负载均衡器和网关负载均衡器。请使用下表了解要使用的负载均衡器类型。


| 负载均衡器类型 | 在这些情况下使用 | 
| --- | --- | 
|  应用程序负载均衡器  | 路由 HTTP/HTTPS（或第 7 层）流量。应用程序负载均衡器提供了一些新功能，这使其非常适合用于 Amazon ECS 服务： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/service-load-balancing.html) | 
| 网络负载均衡器 | 路由 TCP 或 UDP（或第 4 层）流量。 | 
| Gateway Load Balancer | 路由 TCP 或 UDP（或第 4 层）流量。 使用虚拟设备，例如防火墙、入侵检测和防御系统以及深度数据包检测系统等。 | 

我们建议您为您的 Amazon ECS 服务使用应用程序负载均衡器，以便您可以利用这些最新功能，除非您的服务需要仅适用于网络负载均衡器或网关负载均衡器的功能。有关 Elastic Load Balancing 和这些类型的负载均衡器之间区别的更多信息，请参阅 [Elastic Load Balancing 用户指南](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/)。

利用负载均衡器，您可以按实际用量付费。有关更多信息，请参阅 [Elastic Load Balancing 定价](https://aws.amazon.com/elasticloadbalancing/pricing/)。

# 优化 Amazon ECS 的负载均衡器运行状况检查参数
<a name="load-balancer-healthcheck"></a>

负载均衡器仅将请求路由至负载均衡器的可用区中的正常运行目标。每个目标都会注册到一个目标组。负载均衡器使用目标组的运行状况检查设置来检查每个目标的运行状况。在注册目标后，目标必须通过一次运行状况检查才会被视为正常。Amazon ECS 会监控负载均衡器。负载均衡器定期向 Amazon ECS 容器发送运行状况检查。Amazon ECS 代理会监控并等待负载均衡器报告容器的运行状况。它会在认为容器处于正常运行状态之前执行此操作。

两个 Elastic Load Balancing 运行状况检查参数对部署速度产生影响：
+ 运行状况检查间隔：确定单个容器的运行状况检查之间的大致间隔时间（以秒为单位）。默认情况下，负载均衡器每 30 秒检查一次。

  此参数的名称为：
  + 在 Elastic Load Balancing API 中为 `HealthCheckIntervalSeconds`
  + 在 Amazon EC2 控制台上为**间隔**
+ 运行状况正常阈值计数：确定将不正常容器运行状况视为正常之前需要的连续运行状况检查成功次数。默认情况下，负载均衡器需要五次通过运行状况检查才能报告目标容器运行状况正常。

  此参数的名称为：
  + 在 Elastic Load Balancing API 中为 `HealthyThresholdCount`
  + Amazon EC2 控制台上的**运行状况正常阈值**

**重要提示：**对于新注册的目标，无论健康阈值计数设置如何，都只需要一次成功的运行状况检查即可视为目标正常运行。健康阈值计数仅在目标从不正常状态恢复为正常状态时适用。

在默认设置下，如果目标变得不正常然后又恢复，确定容器运行状况的总时间为 2 分钟 30 秒（`30 seconds * 5 = 150 seconds`）。

如果您的服务在不到 10 秒内启动并稳定下来，则可以加快运行状况检查过程。要加快此进程，请缩短运行状况检查间隔和减少健康阈值计数。
+ `HealthCheckIntervalSeconds`（Elastic Load Balancing API 名称）或**间隔**（Amazon EC2 控制台名称）：5
+ `HealthyThresholdCount`（Elastic Load Balancing API 名称）或**运行状况正常阈值**（Amazon EC2 控制台名称）：2

使用此设置，运行状况检查过程需要 10 秒，而默认时间为 2 分 30 秒。

有关 Elastic Load Balancing 运行状况检查参数的更多信息，请参阅《Elastic Load Balancing 用户指南》** 中的[目标组的运行状况检查](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html)。

# 优化 Amazon ECS 的负载均衡器连接耗尽参数
<a name="load-balancer-connection-draining"></a>

为了便于优化，客户端会保持与容器服务的活动连接。这样，来自该客户端的后续请求就可以重复使用现有连接。当您想停止流向容器的流量时，可以通知负载均衡器。负载均衡器会定期检查客户端是否关闭了保持活动连接。Amazon ECS 监控负载均衡器，并等待负载均衡器报告保持活动连接已关闭的情况（目标处于 `UNUSED` 状态）。

负载均衡器等待将目标移至 `UNUSED` 状态的时间为取消注册延迟。您可以配置以下负载均衡器参数来加快部署速度。
+ `deregistration_delay.timeout_seconds`：300（默认值）

当您的服务响应时间小于 1 秒时，请将参数设置为以下值，使负载均衡器在中断客户端和后端服务之间的连接之前只等待 5 秒：
+ `deregistration_delay.timeout_seconds`：5 

**注意**  
当您的服务具有长期请求（例如文件上传缓慢或流式传输连接）时，请勿将该值设置为 5 秒。

## SIGTERM 响应能力
<a name="sigterm"></a>

Amazon ECS 首先向任务发送停止信号，通知应用程序需要完成并关闭。可以使用 STOPSIGNAL 指令在容器映像中定义此信号，默认为 SIGTERM。然后，Amazon ECS 会发送一条 SIGKILL 消息。当应用程序忽略 SIGTERM 时，Amazon ECS 服务必须等待发送终止该进程的 SIGKILL 信号。

Amazon ECS 等待发送 SIGKILL 消息的时间由以下 Amazon ECS 代理选项确定：
+ `ECS_CONTAINER_STOP_TIMEOUT`：30（默认值）

  有关容器代理参数的更多信息，请参阅 GitHub 上的 [Amazon ECS 容器代理](https://github.com/aws/amazon-ecs-agent/blob/master/README.md)。

要加快等待时间，请将 Amazon ECS 代理参数设置为以下值：
+ `ECS_CONTAINER_STOP_TIMEOUT`：2

  如果您的应用程序花费的时间超过 1 秒，则请将该值乘以 2，然后将该数字用作值。

在本例中，Amazon ECS 会等待 2 秒钟让容器关闭，然后 Amazon ECS 会在应用程序未停止时发送 SIGKILL 消息。

您也可以修改应用程序代码以捕获 SIGTERM 信号，并对其做出反应。以下是 JavaScript 中的示例：

```
process.on('SIGTERM', function() { 
  server.close(); 
})
```

此代码会导致 HTTP 服务器停止侦听任何新请求，完成回答任何正在处理的请求，然后 Node.js 进程因事件循环没有可进行的操作而终止。鉴于此，如果该进程只需 500 毫秒即可完成其正在处理的请求，则它会提前终止，而不必等待停止超时并收到 SIGKILL。

# 使用 Amazon ECS 的应用程序负载均衡器
<a name="alb"></a>

应用程序负载均衡器在应用程序层（HTTP/HTTPS）作出路由决策，支持基于路径的路由，并且可以将请求路由到您的集群中每个容器实例上的一个或多个端口。应用程序负载均衡器支持动态主机端口映射。例如，如果任务的容器定义指定端口 80 为 NGINX 容器端口，并指定端口 0 为主机端口，则从容器实例的临时端口范围（例如，在最新的经 Amazon ECS 优化的 AMI 上，为 32768 到 61000）中动态选择主机端口。在任务负载均衡器时，NGINX 容器将作为实例 ID 和端口组合注册到应用程序负载均衡器，并且流量将分配到与该容器对应的实例 ID 和端口。此动态映射可让您在同一容器实例上拥有来自单个服务的多个任务。有关更多信息，请参阅[应用程序负载均衡器用户指南](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/)。

有关设置参数以加快部署速度的最佳实践的信息，请参阅：
+ [优化 Amazon ECS 的负载均衡器运行状况检查参数](load-balancer-healthcheck.md)
+ [优化 Amazon ECS 的负载均衡器连接耗尽参数](load-balancer-connection-draining.md)

将应用程序负载均衡器与 Amazon ECS 结合使用时，请考虑以下事项：
+ Amazon ECS 需要与服务相关的 IAM 角色，该角色提供在创建和停止任务时向负载均衡器注册和注销目标所需的权限。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。
+ 对于仅 IPv6 配置中的服务，必须将应用程序负载均衡器的目标组 IP 地址类型设置为 `dualstack` 或 `dualstack-without-public-ipv4`。
+ 如果服务具有使用 `awsvpc` 网络模式的任务，在为服务创建目标组时，必须选择 `ip` 作为目标类型，而不是`instance`。这是因为使用 `awsvpc` 网络模式的任务与弹性网络接口而不是 Amazon EC2 实例关联。
+ 如果服务需要访问多个负载均衡端口（如某项 HTTP/HTTPS 服务需要端口 80 和端口 443），可以配置两个侦听器。一个侦听器负责将请求转发给服务的 HTTPS，另一个侦听器负责将 HTTP 请求重定向到适当的 HTTPS 端口。有关更多信息，请参阅《应用程序负载均衡器用户指南》**中的[为应用程序负载均衡器创建侦听器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-listener.html)。
+ 您的负载均衡器子网配置必须包含容器实例所在的所有可用区。
+ 创建服务后，无法从 AWS 管理控制台 更改负载均衡器配置。您只能使用 AWS Copilot、AWS CloudFormation、AWS CLI 或 SDK 来修改 `ECS` 滚动部署控制器的负载均衡器配置，而不是 AWS CodeDeploy 蓝/绿或外部控制器。当您添加、更新或删除负载均衡器配置时，Amazon ECS 会使用更新后的 Elastic Load Balancing 配置启动新部署。这将导致任务注册到负载均衡器或从负载均衡器取消注册。我们建议您在更新 Elastic Load Balancing 配置之前在测试环境中对此进行验证。有关如何修改配置的信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)。
+ 如果服务任务未达到负载均衡器运行状况检查标准，则系统会停止并重启该任务。此过程将持续到您的服务达到预期的运行任务的数量。
+ 如果您的支持负载均衡器的服务出现问题，请参阅 [对 Amazon ECS 中的服务负载均衡器进行故障排除](troubleshoot-service-load-balancers.md)。
+ 使用 `instance` 目标类型时，任务和负载均衡器必须位于同一 VPC 中。使用 `ip` 目标类型时，支持跨 VPC 连接。
+ 为每项服务使用唯一的目标组。

  为多个服务使用同一个目标组可能会导致服务部署期间出现问题。
+ 您必须指定与应用程序负载均衡器关联的目标组。

有关如何创建应用程序负载均衡器的信息，请参阅*应用程序负载均衡器*中的[创建应用程序负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-application-load-balancer.html)

# 对 Amazon ECS 使用网络负载均衡器
<a name="nlb"></a>

网络负载均衡器在传输层（TCP/SSL）制定路由决策。它每秒可以处理数百万个请求。在负载均衡器收到连接后，它会使用流式哈希路由算法从目标组中选择一个目标作为默认规则。它尝试在侦听器配置中指定的端口上打开一个到该选定目标的 TCP 连接。它将不修改标头的情况下转发请求。网络负载均衡器支持动态主机端口映射。例如，如果任务的容器定义指定端口 80 为 NGINX 容器端口，并指定端口 0 为主机端口，则从容器实例的临时端口范围（例如，在最新的经 Amazon ECS 优化的 AMI 上，为 32768 到 61000）中动态选择主机端口。在启动任务时，NGINX 容器将作为实例 ID 和端口组合注册到网络负载均衡器，并且流量将分配到与该容器对应的实例 ID 和端口。此动态映射可让您在同一容器实例上拥有来自单个服务的多个任务。有关网络负载均衡器的更多信息，请参阅[网络负载均衡器用户指南](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/)。

有关设置参数以加快部署速度的最佳实践的信息，请参阅：
+ [优化 Amazon ECS 的负载均衡器运行状况检查参数](load-balancer-healthcheck.md)
+ [优化 Amazon ECS 的负载均衡器连接耗尽参数](load-balancer-connection-draining.md)

将网络负载均衡器与 Amazon ECS 结合使用时，请考虑以下事项：
+ Amazon ECS 需要与服务相关的 IAM 角色，该角色提供在创建和停止任务时向负载均衡器注册和注销目标所需的权限。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。
+ 附加到一项服务的目标组不能超过五个。
+ 对于仅 IPv6 配置中的服务，必须将网络负载均衡器的目标组 IP 地址类型设置为 `dualstack`。
+ 如果服务具有使用 `awsvpc` 网络模式的任务，在为服务创建目标组时，必须选择 `ip` 作为目标类型，而不是`instance`。这是因为使用 `awsvpc` 网络模式的任务与弹性网络接口而不是 Amazon EC2 实例关联。
+ 您的负载均衡器子网配置必须包含容器实例所在的所有可用区。
+ 创建服务后，无法从 AWS 管理控制台 更改负载均衡器配置。您只能使用 AWS Copilot、AWS CloudFormation、AWS CLI 或 SDK 来修改 `ECS` 滚动部署控制器的负载均衡器配置，而不是 AWS CodeDeploy 蓝/绿或外部控制器。当您添加、更新或删除负载均衡器配置时，Amazon ECS 会使用更新后的 Elastic Load Balancing 配置启动新部署。这将导致任务注册到负载均衡器或从负载均衡器取消注册。我们建议您在更新 Elastic Load Balancing 配置之前在测试环境中对此进行验证。有关如何修改配置的信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)。
+ 如果服务任务未达到负载均衡器运行状况检查标准，则系统会停止并重启该任务。此过程将持续到您的服务达到预期的运行任务的数量。
+ 当使用将 IP 地址配置为目标且禁用的客户端 IP 保留的网络负载均衡器时，请求将被视为来自网关负载均衡器的私有 IP 地址。这意味着，只要您允许目标安全组中的传入请求和运行状况检查，网关负载均衡器后面的服务就会有效地向世界开放。
+ 对于 Fargate 任务，您必须使用平台版本 `1.4.0`（Linux）或 `1.0.0`（Windows）。
+ 如果您的支持负载均衡器的服务出现问题，请参阅 [对 Amazon ECS 中的服务负载均衡器进行故障排除](troubleshoot-service-load-balancers.md)。
+ 使用 `instance` 目标类型时，任务和负载均衡器必须位于同一 VPC 中。使用 `ip` 目标类型时，支持跨 VPC 连接。
+ 网络负载均衡器客户端 IP 地址保留与 Fargate 目标兼容。
+ 为每项服务使用唯一的目标组。

  为多个服务使用同一个目标组可能会导致服务部署期间出现问题。
+ 您必须指定与网络负载均衡器关联的目标组。

有关如何创建网络负载均衡器的信息，请参阅*网络负载均衡器*中的[创建网络负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/create-network-load-balancer.html)

**重要**  
如果服务的任务定义使用 `awsvpc` 网络模式（为 Fargate 所需），则必须选择 `ip` 而不是 `instance` 作为目标类型。这是因为使用 `awsvpc` 网络模式的任务与弹性网络接口而不是 Amazon EC2 实例关联。  
如果实例具有以下实例类型，则不能用实例 ID 注册实例：C1、CC1、CC2、CG1、CG2、CR1、G1、G2、HI1、HS1、M1、M2、M3 和 T1。可以用 IP 地址注册这些类型的实例。

# 对 Amazon ECS 使用网关负载均衡器
<a name="glb"></a>

网关负载均衡器在 Open Systems Interconnection（OSI）模型的第四层运行，网络层。它侦听所有端口上的所有 IP 数据包，并将流量转发到侦听器规则中指定的目标组。使用 5 元组（对于 TCP/UDP 流）或 3 元组（对于非 TCP/UDP 流）来保持流向特定目标设备的粘性。例如，如果任务的容器定义指定端口 80 为 NGINX 容器端口，并指定端口 0 为主机端口，则从容器实例的临时端口范围（例如，在最新的经 Amazon ECS 优化的 AMI 上，为 32768 到 61000）中动态选择主机端口。在启动任务时，NGINX 容器将作为实例 ID 和端口组合注册到网关负载均衡器，并且流量将分配到与该容器对应的实例 ID 和端口。此动态映射可让您在同一容器实例上拥有来自单个服务的多个任务。有关更多信息，请参阅*网关负载均衡器*中的[什么是网关负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/gateway/introduction.html)。

有关设置参数以加快部署速度的最佳实践的信息，请参阅：
+ [优化 Amazon ECS 的负载均衡器运行状况检查参数](load-balancer-healthcheck.md)
+ [优化 Amazon ECS 的负载均衡器连接耗尽参数](load-balancer-connection-draining.md)

将网关负载均衡器与 Amazon ECS 结合使用时，请考虑以下事项：
+ Amazon ECS 需要与服务相关的 IAM 角色，该角色提供在创建和停止任务时向负载均衡器注册和注销目标所需的权限。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。
+ 对于仅 IPv6 配置中的服务，必须将网关负载均衡器的目标组 IP 地址类型设置为 `dualstack`。
+ 如果服务的任务使用非 `awsvpc` 网络模式，则不支持网关负载均衡器。
+ 您的负载均衡器子网配置必须包含容器实例所在的所有可用区。
+ 创建服务后，无法从 AWS 管理控制台 更改负载均衡器配置。您只能使用 AWS Copilot、AWS CloudFormation、AWS CLI 或 SDK 来修改 `ECS` 滚动部署控制器的负载均衡器配置，而不是 AWS CodeDeploy 蓝/绿或外部控制器。当您添加、更新或删除负载均衡器配置时，Amazon ECS 会使用更新后的 Elastic Load Balancing 配置启动新部署。这将导致任务注册到负载均衡器或从负载均衡器取消注册。我们建议您在更新 Elastic Load Balancing 配置之前在测试环境中对此进行验证。有关如何修改配置的信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)。
+ 如果服务任务未达到负载均衡器运行状况检查标准，则系统会停止并重启该任务。此过程将持续到您的服务达到预期的运行任务的数量。
+ 当使用将 IP 地址配置为目标的网关负载均衡器时，请求将被视为来自网关负载均衡器的私有 IP 地址。这意味着，只要您允许目标安全组中的传入请求和运行状况检查，网关负载均衡器后面的服务就会有效地向世界开放。
+ 对于 Fargate 任务，您必须使用平台版本 `1.4.0`（Linux）或 `1.0.0`（Windows）。
+ 如果您的支持负载均衡器的服务出现问题，请参阅 [对 Amazon ECS 中的服务负载均衡器进行故障排除](troubleshoot-service-load-balancers.md)。
+ 使用 `instance` 目标类型时，任务和负载均衡器必须位于同一 VPC 中。使用 `ip` 目标类型时，支持跨 VPC 连接。
+ 为每项服务使用唯一的目标组。

  为多个服务使用同一个目标组可能会导致服务部署期间出现问题。
+ 您必须指定与网关负载均衡器关联的目标组。

有关如何创建网关负载均衡器的信息，请参阅《网关负载均衡器》**中的[网关负载均衡器入门](https://docs.aws.amazon.com/elasticloadbalancing/latest/gateway/getting-started.html)

**重要**  
如果服务的任务定义使用 `awsvpc` 网络模式（为 Fargate 所需），则必须选择 `ip` 而不是 `instance` 作为目标类型。这是因为使用 `awsvpc` 网络模式的任务与弹性网络接口而不是 Amazon EC2 实例关联。  
如果实例具有以下实例类型，则不能用实例 ID 注册实例：C1、CC1、CC2、CG1、CG2、CR1、G1、G2、HI1、HS1、M1、M2、M3 和 T1。可以用 IP 地址注册这些类型的实例。

# 将多个目标组注册到 Amazon ECS 服务
<a name="register-multiple-targetgroups"></a>

当您在服务定义中指定多个目标组时，Amazon ECS 服务可以为来自多个负载均衡器的流量提供服务并公开多个负载平衡端口。

要创建一个指定多个目标组的服务，您必须使用 Amazon ECS API、开发工具包、AWS CLI 或 CloudFormation 模板创建该服务。在创建服务后，您可以使用 AWS 管理控制台查看服务以及注册到服务的目标组。您必须使用 `[UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)` 修改现有服务的负载均衡器配置。

可以使用以下格式在服务定义中指定多个目标组。有关服务定义的完整语法，请参阅[服务定义模板](sd-template.md)。

```
"loadBalancers":[
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_1/1234567890123456",
      "containerName":"container_name",
      "containerPort":container_port
   },
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_2/6543210987654321",
      "containerName":"container_name",
      "containerPort":container_port
   }
]
```

## 注意事项
<a name="multiple-targetgroups-considerations"></a>

在服务定义中指定多个目标组时，应注意以下事项：
+ 对于使用应用程序负载均衡器或网络负载均衡器的服务，附加到一个服务的目标组不能超过五个。
+ 仅在以下条件下，才支持在服务定义中指定多个目标组：
  + 服务必须使用应用程序负载均衡器或网络负载均衡器。
  + 该服务必须使用（`ECS`）部署控制器类型。这可以是 Amazon ECS 本机/蓝绿部署，也可以是滚动更新部署。
+ 包含使用 Fargate 和 EC2 启动类型的任务的服务支持多个目标组。
+ 当您创建一个指定多个目标组的服务时，必须创建 Amazon ECS 服务相关角色。通过省略 API 请求中的 `role` 参数或 CloudFormation 中的 `Role` 属性来创建角色。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。

## 示例服务定义
<a name="multiple-targetgroups-examples"></a>

下面是一些在服务定义中指定多个目标组的示例使用案例。有关服务定义的完整语法，请参阅[服务定义模板](sd-template.md)。

### 为内部和外部流量使用独立的负载均衡器
<a name="multiple-targetgroups-example1"></a>

在以下使用案例中，服务对相同的容器和端口使用两个独立的负载均衡器，一个用于内部流量，另一个用于面向互联网的流量。

```
"loadBalancers":[
   //Internal ELB
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_1/1234567890123456",
      "containerName":"nginx",
      "containerPort":8080
   },
   //Internet-facing ELB
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_2/6543210987654321",
      "containerName":"nginx",
      "containerPort":8080
   }
]
```

### 从同一容器公开多个端口
<a name="multiple-targetgroups-example1"></a>

在以下使用案例中，服务使用一个负载均衡器，但从同一容器公开多个端口。例如，Jenkins 容器可能会为 Jenkins Web 接口公开端口 8080，为 API 公开端口 50000。

```
"loadBalancers":[
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_1/1234567890123456",
      "containerName":"jenkins",
      "containerPort":8080
   },
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_2/6543210987654321",
      "containerName":"jenkins",
      "containerPort":50000
   }
]
```

### 从多个容器公开端口
<a name="multiple-targetgroups-example3"></a>

在以下使用案例中，服务使用一个负载均衡器和两个目标组从单独的容器公开端口。

```
"loadBalancers":[
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_1/1234567890123456",
      "containerName":"webserver",
      "containerPort":80
   },
   {  
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_2/6543210987654321",
      "containerName":"database",
      "containerPort":3306
   }
]
```

# 自动扩缩 Amazon ECS 服务
<a name="service-auto-scaling"></a>

*自动扩缩*是指自动增加或减少 Amazon ECS 服务中所需任务数的功能。Amazon ECS 利用 Application Auto Scaling 服务来提供此功能。有关更多信息，请参阅 [Application Auto Scaling 用户指南](https://docs.aws.amazon.com/autoscaling/application/userguide/what-is-application-auto-scaling.html)。

Amazon ECS 发布 CloudWatch 指标与服务的平均 CPU 和内存使用率。有关更多信息，请参阅 [Amazon ECS 服务利用率指标](service_utilization.md)。您可以使用这些指标和其他 CloudWatch 指标横向扩展您的服务（添加更多任务）以应对高峰期的高需求，并横向缩减您的服务（运行更少的任务）以降低低利用率期间的成本。

Amazon ECS 服务自动扩缩支持以下类型的自动扩缩：
+ [使用目标指标来扩展 Amazon ECS 服务](service-autoscaling-targettracking.md) – 根据特定指标的目标值，增加或减少服务运行的任务数。这与恒温器保持家里温度的方式类似。您选择一个温度，恒温器将完成所有其他工作。
+ [使用基于 CloudWatch 警报的预定义增量扩展 Amazon ECS 服务](service-autoscaling-stepscaling.md) – 根据一组扩缩调整，增加或减少服务运行的任务数，这些调整称为分布调整，将根据警报严重程度发生变化。
+ [使用计划操作扩展 Amazon ECS 服务](service-autoscaling-schedulescaling.md) – 根据日期和时间增加或减少服务运行的任务数。
+ [使用历史模式通过预测式扩缩来扩展 Amazon ECS 服务](predictive-auto-scaling.md)：根据历史负载数据分析增加或减少服务运行的任务数，来检测流量中的每日或每周模式。

   

## 注意事项
<a name="auto-scaling-concepts"></a>

使用扩缩策略时，请注意以下事项：
+ Amazon ECS 每隔 1 分钟向 CloudWatch 发送一次指标数据。在集群和服务将指标发送到 CloudWatch 之前，指标不可用，并且您无法为不存在的指标创建 CloudWatch 警报。
+ 扩展策略支持冷却时间。这是等待上一个扩展活动生效的秒数。
  + 对于横向扩展事件，目的是持续（但不过度）横向扩展。服务自动扩缩使用步进扩展策略成功横向扩展后，它将开始计算冷却时间。除非启动更大的横向扩展或冷却时间结束，否则扩缩策略不会再次增加所需容量。尽管此横向扩展冷却时间有效，但启动横向扩展活动所添加的容量将计算为下一个横向扩展活动所需容量的一部分。
  + 对于横向缩减事件，目的是以保守方式进行横向缩减以保护应用程序的可用性，因此在冷却时间过期之前阻止横向缩减活动。但是，如果另一个警报在横向缩减冷却时间内启动了横向扩展活动，服务自动扩缩将立即对目标进行横向扩展。在这种情况下，横向缩减冷却时间停止而不完成。
+ 服务计划程序始终遵守预期数量，但只要您的服务拥有活动的扩缩策略和警报，服务自动扩缩就会更改您手动设置的预期数量。
+ 如果设置的服务的预期数量低于其最小容量值，并且警报启动了横向扩展活动，则服务自动扩缩会将预期数量增至最小容量值，然后基于与警报关联的扩展策略继续按需横向扩展。但是，横向缩减活动将不会调整预期数量，因为它已低于最小容量值。
+ 如果设置的服务的预期数量高于其最大容量值，并且警报启动了横向缩减活动，则服务自动扩缩会将预期数量横向扩展至最大容量值，然后基于与警报关联的扩展策略继续按需横向缩减。但是，横向扩展活动将不会调整预期数量，因为它已高于最大容量值。
+ 在扩展活动期间，服务中实际运行的任务计数是服务自动扩缩用作其起点的值（而不是预期数量）。这是应有的处理容量。这可防止无法满足的过度（失控）扩展，例如，没有足够的容器实例资源来放置其他任务。如果稍后提供容器实例容量，则正在等待的扩展活动将能够继续，随后其他扩展活动可在冷却时间后继续。
+ 如果您希望在没有要完成的工作时将任务计数扩展到零，请将最小容量设置为 0。对于目标跟踪扩展策略，当实际容量为 0 且度量指示存在工作负载需求时，服务自动扩缩会等待发送一个数据点，然后再扩展。在这种情况下，它将按可能的最小量扩展作为起点，然后根据实际运行的任务计数恢复扩展。
+ Application Auto Scaling 可在 Amazon ECS 部署正在进行时关闭横向缩减流程。但是，在部署过程中，除非暂停，否则将继续发生横向扩展进程。此行为不适用于使用外部部署控制器的 Amazon ECS 服务。有关更多信息，请参阅 [服务自动扩缩和部署](#service-auto-scaling-deployments)。
+ Amazon ECS 任务有数个 Application Auto Scaling 选项。目标跟踪是最易于使用的模式。有了它，您所需要做的就是为指标设置一个目标值，例如 CPU 平均利用率。然后，自动定标器会自动管理实现该值所需的任务数量。使用分步扩展，您可以更快地对需求变化做出反应，因为您可以定义扩展指标的特定阈值，以及在超过阈值时要添加或删除的任务数量。并且，更重要的是，您可以通过最大限度地减少突破阈值警报的时间来对需求变化做出快速反应。

有关服务自动扩缩最佳实践的更多信息，请参阅[优化 Amazon ECS 服务自动扩缩](capacity-autoscaling-best-practice.md)。

## 服务自动扩缩和部署
<a name="service-auto-scaling-deployments"></a>

Application Auto Scaling 可在 Amazon ECS 部署正在进行时关闭横向缩减流程。但是，在部署过程中，除非暂停，否则将继续发生横向扩展进程。此行为不适用于使用外部部署控制器的 Amazon ECS 服务。如果要在部署正在进行的过程中暂停横向扩展进程，请执行以下步骤。

1. 调用 [describe-scalable-targets](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/describe-scalable-targets.html) 命令，在 Application Auto Scaling 中指定与可扩展目标关联的服务的资源 ID（例如：`service/default/sample-webapp`)。记录输出。调用下一个命令时，您将用到它。

1. 调用 [register-scalable-target](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/register-scalable-target.html) 命令，指定资源 ID、命名空间和可伸缩维度。指定 `true` 代表 `DynamicScalingInSuspended` 和 `DynamicScalingOutSuspended`。

1. 部署完成后，您可以调用 [register-scalable-target](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/register-scalable-target.html) 命令恢复扩展。

有关更多信息，请参阅[暂停和恢复 Application Auto Scaling 的扩缩](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-suspend-resume-scaling.html)。

# 使用目标指标来扩展 Amazon ECS 服务
<a name="service-autoscaling-targettracking"></a>

在使用目标跟踪扩展策略时，您可以选择一个指标并设置一个目标值。Amazon ECS服务自动扩缩创建和管理控扩缩策略的 CloudWatch 警报，并根据指标和目标值计算扩缩调整。扩展策略根据需要增加或删除服务任务，将指标保持在指定的目标值或接近指定的目标值。除了将指标保持在目标值附近以外，目标跟踪扩展策略还会根据由于负载模式波动而造成的指标波动进行调节，并最大限度减少服务中运行的任务数发生快速波动的情况。

目标跟踪策略让您无需手动定义 CloudWatch 警报和扩缩调整。Amazon ECS 会根据您设置的目标自动处理此问题。

使用目标跟踪策略时，请注意以下事项：
+ 目标跟踪扩展策略假设它应该在指定指标高于目标值时执行横向扩展。因此，不能使用目标跟踪扩展策略在指定指标低于目标值时横向扩展。
+ 当指定指标数据不足时，目标跟踪扩展策略不会执行扩展。它不会执行横向缩减，因为它不会将数据不足解读为使用率低。
+ 您可能会看到目标值与实际指标数据点之间存在差距。这是因为服务自动扩缩在确定要添加或删除多少容量时将始终通过向上或向下舍入保守地进行操作，以免添加的容量不足或删除的容量过多。
+ 为了确保应用程序可用性，服务会针对指标尽快按比例扩展，但缩减过程相对缓慢。
+ Application Auto Scaling 可在 Amazon ECS 部署正在进行时关闭横向缩减流程。但是，在部署过程中，除非暂停，否则将继续发生横向扩展进程。此行为不适用于使用外部部署控制器的 Amazon ECS 服务。有关更多信息，请参阅 [服务自动扩缩和部署](service-auto-scaling.md#service-auto-scaling-deployments)。
+ 您可以为 Amazon ECS 服务创建多个目标跟踪扩展策略，但前提是它们分别使用不同的指标。服务自动扩缩的目的是始终优先考虑可用性，因此其行为会有所不同，具体取决于目标跟踪策略是否已准备好横向扩展或横向缩减。如果任何目标跟踪策略已准备好进行横向扩展，它将横向扩展服务；但仅在所有目标跟踪策略（启用了横向缩减部分）准备好横向缩减时才执行横向缩减。
+ 请勿编辑或删除服务自动扩缩 为目标跟踪缩放策略管理的 CloudWatch 报警。当您删除扩展策略时，服务自动扩缩将自动删除相应的警报。
+ 蓝绿部署类型不支持目标跟踪扩展策略的 `ALBRequestCountPerTarget` 指标。

有关目标跟踪扩展策略的更多信息，请参阅《Application Auto Scaling 用户指南》**中的[目标跟踪扩展策略](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-target-tracking.html)。

# 为 Amazon ECS 服务自动扩缩创建目标跟踪扩缩策略
<a name="target-tracking-create-policy"></a>

创建目标跟踪扩缩策略，让 Amazon ECS 自动增加或减少服务中的所需任务数。目标跟踪是根据目标指标值进行的。

## 控制台
<a name="target-tracking-create-policy-aws-console"></a>

1. 除了用于创建和更新服务的标准 IAM 权限之外，您还需要额外权限。有关更多信息，请参阅 [Amazon ECS 服务自动扩缩所需的 IAM 权限](auto-scaling-IAM.md)。

1. 请确定要用于策略的指标。可供使用的指标如下：
   +  **ECSServiceAverageCPUUtilization**：服务应使用的平均 CPU 使用率。
   + **ECSServiceAverageMemoryUtilization**：服务应使用的平均内存使用率。
   + **ALBRequestCountPerTarget**：任务理想情况下应接收的平均每分钟请求数。

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**设置任务数**。

1. 在 **Amazon ECS 服务任务计数**下，选择**使用自动扩缩**。

   此时将显示**任务计数部分**。

   1. 对于**最小任务数**，输入供服务自动扩缩使用的任务数的下限。所需计数不会低于此计数。

   1. 对于**最大值**，输入供服务自动扩缩使用的任务数的上限。所需计数不会高于此计数。

   1. 选择**保存**。

      此时将显示策略页面。

1. 选择**创建扩缩策略**。

   此时将显示**创建策略**页面。

1. 对于**扩展策略类型**，选择**目标跟踪**。

1. 对于 **Policy name**（策略名称），请输入策略的名称。

1. 对于**指标类型**，从选项列表中选择指标。

1. 在**目标利用率**中，输入 Amazon ECS 应保留的任务百分比的目标值。服务自动扩缩可横向扩展您的容量直到平均利用率达到目标利用率，或直到达到您指定的最大任务数。

1. 在**其他设置**下，执行以下操作

   1. 对于**横向缩减冷却时间**，请输入在一个横向缩减活动完成之后、另一个横向缩减活动开始之前的时长（以秒为单位）。

   1. 对于**横向扩展冷却时间**，请输入等待先前的横向扩展活动生效的时长（以秒为单位）。

   1. 要仅创建横向扩展策略，请选择**禁用横向缩减**。

1. 选择**创建扩缩策略**。

## AWS CLI
<a name="target-tracking-create-policy-aws-cli"></a>

1. 使用 [register-scalable-target](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/register-scalable-target.html) 命令将 Amazon ECS 服务注册为可扩展目标。

1. 使用 [put-scaling-policy](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/put-scaling-policy.html) 命令创建扩展策略。

# 使用基于 CloudWatch 警报的预定义增量扩展 Amazon ECS 服务
<a name="service-autoscaling-stepscaling"></a>

利用分布扩缩策略，可以创建和管理调用扩缩过程的 CloudWatch 警报。当警报被触发时，Amazon ECS 会启动与该警报关联的扩缩策略。步进扩缩策略使用一组调整（称为步进调整）来扩展任务。调整的大小将根据超出警报阈值的规模而变化。
+ 如果违例超过第一个阈值，Amazon ECS 将应用第一步调整。
+ 如果违例超过第二个阈值，Amazon ECS 将应用第二步调整，以此类推。

强烈建议您使用目标跟踪扩缩策略，根据类似于平均 CPU 利用率或每个目标的平均请求数等指标进行扩展。使用目标跟踪，可以通过在容量增加时减少以及在容量减少时增加的指标，按比例横向扩展或缩减任务数。这有助于确保 Amazon ECS 密切遵循应用程序的需求曲线。

# 为 Amazon ECS 服务自动扩缩创建步进扩缩策略
<a name="step-scaling-create-policy"></a>

创建步进扩缩策略，以便 Amazon ECS 自动增加或减少服务中所需的任务数。步进扩缩基于一组扩缩调整（称作步进调整），这些调整因警报违例大小而异。

## 控制台
<a name="step-scaling-create-policy-aws-console"></a>

1. 除了用于创建和更新服务的标准 IAM 权限之外，您还需要额外权限。有关更多信息，请参阅 [Amazon ECS 服务自动扩缩所需的 IAM 权限](auto-scaling-IAM.md)。

1. 请确定要用于策略的指标。可供使用的指标如下：
   +  **ECSServiceAverageCPUUtilization**：服务应使用的平均 CPU 使用率。
   + **ECSServiceAverageMemoryUtilization**：服务应使用的平均内存使用率。
   + **ALBRequestCountPerTarget**：任务理想情况下应接收的平均每分钟请求数。

1. 为指标创建 CloudWatch 警报。有关更多信息，请参阅 *Amazon CloudWatch 用户指南*中的[根据静态阈值创建 CloudWatch 告警](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ConsoleAlarms.html)。

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**设置任务数**。

1. 在 **Amazon ECS 服务任务计数**下，选择**使用自动扩缩**。

   此时将显示**任务计数部分**。

   1. 对于**最小任务数**，输入供服务自动扩缩使用的任务数的下限。所需计数不会低于此计数。

   1. 对于**最大值**，输入供服务自动扩缩使用的任务数的上限。所需计数不会高于此计数。

   1. 选择**保存**。

      此时将显示策略页面。

1. 选择**创建扩缩策略**。

   此时将显示**创建策略**页面。

1. 对于**扩缩策略类型**，选择**步进扩缩**。

1. 配置横向扩展属性。在**添加任务的步骤**下，执行以下操作：

   1. 对于 **Policy name**（策略名称），请输入策略的名称。

   1. 在 **CloudWatch 警报名称**中，选择 CloudWatch 警报。

   1. 对于**指标聚合类型**，选择如何将所选指标与定义的阈值进行比较。

   1. 对于**调整类型**，选择是基于任务数的变化还是基于任务百分比的变化进行调整。

   1. 对于**要采取的操作**，输入要采取的操作的值。

      选择**添加步骤**以添加其他操作。

1. 配置横向缩减属性。在**移除任务的步骤**下，执行以下操作：

   1. 对于 **Policy name**（策略名称），请输入策略的名称。

   1. 在 **CloudWatch 警报名称**中，选择 CloudWatch 警报。

   1. 对于**指标聚合类型**，选择如何将所选指标与定义的阈值进行比较。

   1. 对于**调整类型**，选择是基于任务数的变化还是基于任务百分比的变化进行调整。

   1. 对于**要采取的操作**，输入要采取的操作的值。

      选择**添加步骤**以添加其他操作。

1. 对于**冷却时间**，输入等待先前的扩展活动生效的时间（以秒为单位）。对于添加策略，该时间是在横向扩展活动之后，扩展策略阻止横向缩减活动并限制一次可以横向扩展的任务数量的时间。对于移除策略，该时间是横向缩减活动结束后，在另一个横向缩减活动可以开始前经过的时间。

1. 选择**创建扩缩策略**。

## AWS CLI
<a name="step-scaling-create-policy-aws-cli"></a>

1. 使用 [register-scalable-target](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/register-scalable-target.html) 命令将 Amazon ECS 服务注册为可扩展目标。

1. 使用 [put-scaling-policy](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/put-scaling-policy.html) 命令创建扩展策略。

# 使用计划操作扩展 Amazon ECS 服务
<a name="service-autoscaling-schedulescaling"></a>

通过计划的扩展，您可以根据可预测的负载变化，通过创建在特定时间增加或减少任务数的计划操作，为应用程序设置自动扩缩。这使您可以主动扩展应用程序，以适应可预测的负载变化。

利用这些计划的扩展操作，您可以优化成本和性能。您的应用程序有足够多的任务来处理一周中间的流量高峰，但不会在其他时间过度预置任务数。

您可以同时使用计划的扩展和扩缩策略，以获得主动和被动扩展方法的优势。运行计划的扩展操作后，扩缩策略可以继续决定是否进一步扩展任务数。这有助于确保您有足够多的任务来处理应用程序的负载。当您的应用程序扩展以满足需求时，当前容量必须在计划操作设置的最小任务数和最大任务数范围内。

您可以使用 AWS CLI 配置计划扩展。有关使用计划的扩展的更多信息，请参阅《Application Auto Scaling 用户指南》**中的[计划的扩展](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-scheduled-scaling.html)。

# 为 Amazon ECS 服务自动扩缩创建计划操作
<a name="scheduled-action-create-policy"></a>

创建计划操作，可让 Amazon ECS 根据日期和时间增加或减少服务运行的任务数。

## 控制台
<a name="scheduled-action-policy-aws-console"></a>

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**服务自动扩缩**。

   此时将显示“服务自动扩缩”页面。

1. 如果您尚未配置服务自动扩缩，请选择**设置任务数**。

   此时将显示 **Amazon ECS 服务任务数**部分。

   在 **Amazon ECS 服务任务数**下，选择**使用服务自动扩缩来调整服务所需的任务数**。

   此时将显示**任务计数部分**。

   1. 对于**最小任务数**，输入供服务自动扩缩使用的任务数的下限。所需计数不会低于此计数。

   1. 对于**最大值**，输入供服务自动扩缩使用的任务数的上限。所需计数不会高于此计数。

   1. 选择**选择“保存”**。

      此时将显示策略页面。

1. 选择**计划操作**，然后选择**创建**。

   此时将显示**创建计划操作**页面。

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

1. 对于**时区**，请选择时区。

   列出的所有时区均来自 IANA 时区数据库。有关详细信息，请参阅 [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。

1. 对于**启动时间**，输入操作启动的**日期**和**时间**。

   如果您选择了循环计划，则开始时间将定义循环系列中第一个计划操作的运行时间。

1. 对于**循环**，请选择下列可用选项之一。
   + 要按重复性计划进行扩展，请选择 Amazon ECS 运行计划操作的频率。
     + 如果您选择以 **Rate** 开头的选项，则将为您创建 cron 表达式。
     + 如果您选择 **Cron**，请输入 cron 表达式，此表达式指定了执行操作的时间。
   + 如果只想扩展一次，请选择**一次**。

1. 在**任务调整**下，执行以下操作：
   + 在**最小值**中，输入服务应运行的最小任务数。
   + 在**最大值**中，输入服务应运行的最大任务数。

1. 选择**创建计划操作**。

## CLI
<a name="scheduled-action-aws-cli"></a>

按如下所示，使用 AWS CLI 为服务配置计划的扩展策略。将每个*用户输入占位符*替换为您自己的信息。

**示例：仅扩展一次**  
使用以下 [put-scheduled-action](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/put-scheduled-action.html) 命令和 `--start-time "YYYY-MM-DDThh:mm:ssZ"`，以及 `--MinCapacity` 和（或）`--MaxCapacity` 选项。

```
aws application-autoscaling put-scheduled-action --service-namespace ecs \
  --resource-id service/my-cluster/my-service \
  --scheduled-action-name my-one-time-schedule \
  --start-time 2021-01-30T12:00:00 \
  --scalable-target-action MinCapacity=3,MaxCapacity=10
```

**示例：根据周期性计划来计划扩展**  
使用以下 [put-scheduled-action](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/put-scheduled-action.html) 命令。将 *user input* 替换为您的值。

```
aws application-autoscaling put-scheduled-action --service-namespace ecs \
  --resource-id service/my-cluster/my-service \
  --scheduled-action-name my-recurring-action \
  --schedule "rate(5 hours)" \
  --start-time 2021-01-30T12:00:00 \
  --end-time 2021-01-31T22:00:00 \
  --scalable-target-action MinCapacity=3,MaxCapacity=10
```

指定的周期性计划会基于 UTC 时区运行。要指定不同的时区，请包含 `--time-zone` 选项和 IANA 时区的名称，如下例所示。

```
--time-zone "America/New_York"
```

有关详细信息，请参阅 [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。

# 使用历史模式通过预测式扩缩来扩展 Amazon ECS 服务
<a name="predictive-auto-scaling"></a>

预测式扩缩可查看流量中过去的负载数据，以分析每日或每周的模式。然后，它会使用此分析来预测未来的需求，并根据需要主动增加服务中的任务。

预测式自动扩缩在以下情况中最有用。
+ 周期性流量：正常营业时间内的高资源利用率以及晚上和周末的低资源利用率。
+ 重复的打开和关闭工作负载模式：例如批处理、测试或定期数据分析。
+ 初始化需要很长时间的应用程序：会造成明显延迟的横向扩展事件期间，这可能会影响应用程序性能。

如果应用程序需要很长时间才能初始化并且存在流量定期增长的情况，则应考虑使用预测式扩缩。这将通过主动增加任务数以应对预测的负载，从而帮助您更快地扩展，而不是仅使用目标跟踪或步进扩缩等动态扩缩策略。预测式扩缩还可帮助您避免过度预置任务数的风险，从而节省成本。

例如，考虑在营业时间内具有高利用率以及夜间具有低利用率的应用程序。在每个工作日开始时，预测式扩缩可以在流量第一次涌入之前横向扩展任务。这有助于您的应用程序在利用率较低的时期内保持高可用性和性能。您不必等待动态扩展来响应不断变化的流量。您也不必花时间查看应用程序的负载模式，并尝试使用计划的扩展计划适当的任务。

预测式扩展是一种服务级别功能，它可独立于底层计算容量（例如 EC2 或 Fargate）的扩展来扩展服务任务。对于 Fargate，AWS 会根据任务要求管理和自动扩展底层容量。对于 EC2 容量，您可以使用自动扩缩组容量提供程序，根据任务的扩展要求来自动扩展底层 EC2 实例。

**Topics**
+ [预测式扩缩概览](#predictive-auto-scaling-overview)
+ [创建预测性扩展策略](predictive-scaling-create-policy.md)
+ [评估预测性扩展策略](predictive-scaling-graphs.md)
+ [覆盖预测](predictive-scaling-overriding-forecast-capacity.md)
+ [使用自定义指标](predictive-scaling-custom-metrics.md)

## 预测式扩展在 Amazon ECS 中的工作原理
<a name="predictive-auto-scaling-overview"></a>

您可以在本页了解使用预测式扩缩的注意事项、预测式扩缩的工作原理以及相关使用限制。

### 使用预测式扩缩的注意事项
<a name="predictive-auto-scaling-considerations"></a>
+ 您需要确保预测式扩缩适合您的工作负载。您可以通过在**仅预测**模式下配置扩缩策略来确认这一点，并查看控制台有何建议。在开始使用预测式扩缩之前，您应该评估预测和建议。
+ 预测式扩缩至少需要 24 小时的历史数据才能开始预测。可用的历史数据越多，预测就越有效，最理想的时间范围是两周。当您删除 Amazon ECS 服务并创建新服务时，还需要等待 24 小时，预测式扩缩才能生成新预测。加快此过程的方法之一是使用自定义指标来聚合新旧 Amazon ECS 服务的指标。
+ 选择一个负载指标，该指标应准确代表应用程序的全部负载，并且是应用程序中对扩缩最重要的方面。
+ 借助采用预测式扩缩的动态扩缩，您可以紧密跟踪应用程序的需求，进而可以在平缓期间进行横向缩减并在流量意外增加时横向扩展。当多个扩缩策略处于活动状态时，每个策略将独立确定所需任务数，而所需任务数将设置为其中最大的任务数。
+ 您可以将预测式扩缩与动态扩缩策略（例如目标跟踪或步进扩缩）一起使用，以便应用程序就可以根据实时和历史模式进行扩展。预测式扩缩本身并不能横向缩减您的任务。
+ 如果您在调用 `register-scalable-target` API 时使用自定义角色，则可能会收到一条错误消息，提示预测式扩缩策略只能在启用 SLR 的情况下生效。在这种情况下，您应该再次调用 `register-scalable-target`，但不要使用 role-arn。注册可扩展目标时使用 SLR 并调用 `put-scaling-policy` API。

### 预测式扩展的工作方式
<a name="predictive-auto-scaling-details"></a>

要使用预测式扩缩，请创建预测式扩缩策略，指定要监控和分析的 CloudWatch 指标。预测式扩缩至少需要 24 小时的数据才能开始预测未来值。

创建策略后，预测性扩展将开始分析最多过去 14 天的指标数据，以确定模式。此分析可用于生成未来 48 小时的每小时需求预测。最新的 CloudWatch 数据将用于每 6 小时更新一次预测。随着新数据的出现，预测式扩缩会不断提高未来预测的准确性。

首次启用预测性扩展时，该功能将在*仅预测*模式下运行。它以这种模式生成预测，但它不会根据这些预测扩展 Amazon ECS 服务。这使您可以评估预测的准确性和适用性。您可以使用 `GetPredictiveScalingForecast` API 操作或 AWS 管理控制台 查看预测数据。

当您决定开始使用预测式扩缩时，请将扩缩策略切换到*预测和扩展*模式。在此模式下会发生以下情况。

Amazon ECS 服务默认会根据该小时的预测进行扩展。您可以在 `PutScalingPolicy` API 操作中使用 `SchedulingBufferTime` 属性选择提前启动。这会使新任务在预测的需求之前启动，并使其有时间启动并准备好处理流量。

### 最大任务数限制
<a name="predictive-scaling-maximum-tasks-limit"></a>

注册 Amazon ECS 服务以进行扩缩时，您会定义每项服务可启动的最大任务数。默认情况下，设置扩缩策略后，这些策略无法将任务数增加到高于最大限制。

或者，您可以允许在预测接近或超过 Amazon ECS 服务的最大任务数时，自动增加服务的最大任务数。

**警告**  
允许自动增加最大任务数时应谨慎行事。如果不对增加的最大任务数进行监控和管理，则可能导致启动的任务数超出预期。然后，增加的最大任务数将变为 Amazon ECS 服务新的正常最大任务数，直到您手动对其进行更新。最大任务数不会自动降回到原来的最大值。

### 支持的区域
<a name="predictive-auto-scaling-supported-regions"></a>
+ 美国东部（弗吉尼亚州北部）
+ 美国东部（俄亥俄州）
+ 美国西部（北加利福尼亚）
+ 美国西部（俄勒冈州）
+ 非洲（开普敦）
+ 亚太地区（香港）
+ 亚太地区（雅加达）
+ 亚太地区（孟买）
+ 亚太地区（大阪）
+ 亚太地区（首尔）
+ 亚太地区（新加坡）
+ 亚太地区（悉尼）
+ 亚太地区（东京）
+ 加拿大（中部）
+ 中国（北京）
+ 中国（宁夏）
+ 欧洲地区（法兰克福）
+ 欧洲地区（爱尔兰）
+ 欧洲地区（伦敦）
+ 欧洲地区（米兰）
+ 欧洲地区（巴黎）
+ 欧洲地区（斯德哥尔摩）
+ 中东（巴林）
+ 南美洲（圣保罗）
+ AWS GovCloud（美国东部）
+ AWS GovCloud（美国西部）

# 为 Amazon ECS 服务自动扩缩创建预测式扩缩策略
<a name="predictive-scaling-create-policy"></a>

创建预测性扩缩策略，以便 Amazon ECS 根据历史数据自动增加或减少服务运行的任务数。

**注意**  
一项新服务需要提供至少 24 小时的数据，然后才能生成预测。

## 控制台
<a name="predictive-scaling-policy-aws-console"></a>

1. 除了用于创建和更新服务的标准 IAM 权限之外，您还需要额外权限。有关更多信息，请参阅 [Amazon ECS 服务自动扩缩所需的 IAM 权限](auto-scaling-IAM.md)。

1. 请确定要用于策略的指标。可供使用的指标如下：
   +  **ECSServiceAverageCPUUtilization**：服务应使用的平均 CPU 使用率。
   + **ECSServiceAverageMemoryUtilization**：服务应使用的平均内存使用率。
   + **ALBRequestCountPerTarget**：任务理想情况下应接收的平均每分钟请求数。

   您也可以使用自定义指标。您需要定义以下值：
   + 负载：该指标应准确代表应用程序的全部负载，并且是应用程序中对扩展最重要的方面。
   + 扩缩指标：衡量应用程序理想利用率的最佳预测指标。

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**服务自动扩缩**，然后选择**设置任务数**。

1. 在 **Amazon ECS 服务任务计数**下，选择**使用自动扩缩**。

   此时将显示**任务计数部分**。

   1. 对于**最小任务数**，输入供服务自动扩缩使用的任务数的下限。所需计数不会低于此计数。

   1. 对于**最大值**，输入供服务自动扩缩使用的任务数的上限。所需计数不会高于此计数。

   1. 选择**保存**。

      此时将显示策略页面。

1. 选择**创建扩缩策略**。

   此时将显示**创建策略**页面。

1. 对于**扩缩策略类型**，选择**预测式扩缩**。

1. 对于 **Policy name**（策略名称），请输入策略的名称。

1. 对于**指标对**，从选项列表中选择指标。

   如果您选择了**每目标的应用程序负载均衡器请求计数**，请在**目标组**中选择目标组。**每目标的应用程序负载均衡器请求计数**仅在您已为服务附加应用程序负载均衡器目标组时才支持。

   如果您选择**自定义指标对**，请从**负载指标**和**扩缩指标**的列表中选择单个指标。

1. 在**目标利用率**中，输入 Amazon ECS 应保留的任务百分比的目标值。服务自动扩缩可横向扩展您的容量直到平均利用率达到目标利用率，或直到达到您指定的最大任务数。

1. 选择**创建扩缩策略**。

## AWS CLI
<a name="predictive-scaling-policy-aws-cli"></a>

使用 AWS CLI 按如下方式为 Amazon ECS 服务配置预测式扩缩策略。将每个*用户输入占位符*替换为您自己的信息。

有关您可以指定的 CloudWatch 指标的更多信息，请参阅《Amazon EC2 Auto Scaling API 参考》**中的 [PredictiveScalingMetricSpecification](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_PredictiveScalingMetricSpecification.html)。

### 示例 1：具有预定义内存的预测式扩缩策略。
<a name="predictive-scaling-cli-example-one"></a>

以下是具有预定义内存配置的策略的示例。

```
cat policy.json
{
    "MetricSpecifications": [
        {
            "TargetValue": 40,
            "PredefinedMetricPairSpecification": {
                "PredefinedMetricType": "ECSServiceMemoryUtilization"
            }
        }
    ],
    "SchedulingBufferTime": 3600,
    "MaxCapacityBreachBehavior": "HonorMaxCapacity",
    "Mode": "ForecastOnly"
}
```

以下示例演示了如何通过运行指定配置文件的 [put-scaling-policy](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/put-scaling-policy.html) 命令来创建策略。

```
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--region us-east-1 \
--policy-name predictive-scaling-policy-example \
--resource-id service/MyCluster/test \
--policy-type PredictiveScaling \
--scalable-dimension ecs:service:DesiredCount \
--predictive-scaling-policy-configuration file://policy.json
```

如果成功，该命令会返回策略的 ARN。

```
{
    "PolicyARN": "arn:aws:autoscaling:us-east-1:012345678912:scalingPolicy:d1d72dfe-5fd3-464f-83cf-824f16cb88b7:resource/ecs/service/MyCluster/test:policyName/predictive-scaling-policy-example",
    "Alarms": []
}
```

### 示例 2：具有预定义 CPU 的预测式扩缩策略。
<a name="predictive-scaling-cli-example-two"></a>

以下是具有预定义 CPU 配置的策略的示例。

```
cat policy.json
{
    "MetricSpecifications": [
        {
            "TargetValue": 0.00000004,
            "PredefinedMetricPairSpecification": {
                "PredefinedMetricType": "ECSServiceCPUUtilization"
            }
        }
    ],
    "SchedulingBufferTime": 3600,
    "MaxCapacityBreachBehavior": "HonorMaxCapacity",
    "Mode": "ForecastOnly"
}
```

以下示例演示了如何通过运行指定配置文件的 [put-scaling-policy](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/put-scaling-policy.html) 命令来创建策略。

```
aws aas put-scaling-policy \
--service-namespace ecs \
--region us-east-1 \
--policy-name predictive-scaling-policy-example \
--resource-id service/MyCluster/test \
--policy-type PredictiveScaling \
--scalable-dimension ecs:service:DesiredCount \
--predictive-scaling-policy-configuration file://policy.json
```

如果成功，该命令会返回策略的 ARN。

```
{
    "PolicyARN": "arn:aws:autoscaling:us-east-1:012345678912:scalingPolicy:d1d72dfe-5fd3-464f-83cf-824f16cb88b7:resource/ecs/service/MyCluster/test:policyName/predictive-scaling-policy-example",
    "Alarms": []
}
```

# 评估 Amazon ECS 的预测式扩缩策略
<a name="predictive-scaling-graphs"></a>

在使用预测式扩缩策略扩展服务之前，请在 Amazon ECS 控制台中查看您策略的建议和其他数据。这很重要，因为在确定预测准确之前，您不希望使用预测扩展策略来扩展实际容量。

如果服务是新的，则需要留出 24 小时让服务创建第一次预测。

当 AWS 创建预测时，会使用历史数据。如果服务还没有太多最近的历史数据，预测式扩缩可能会使用从当前可用的历史聚合中创建的聚合数据临时回填预测。预测会在策略创建日期前最多回填两周。

## 查看您的预测性扩展建议
<a name="view-predictive-scaling-recommendations"></a>

为了进行有效的分析，服务自动扩缩应至少有两个预测式扩缩策略可供比较。（但您仍可以查看单个策略的调查结果。） 创建多个策略时，您可以对使用一个指标的策略和使用另一个指标的策略进行评估。您还可以评估不同目标值和指标组合的影响。创建预测式扩缩策略后，Amazon ECS 会立即开始评估哪种策略可以更好地扩缩您的组。

**在 Amazon ECS 控制台中查看建议**

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**服务自动扩缩**。

1. 选择预测式扩缩策略，然后依次选择**操作**、**预测式扩缩**、**查看建议**。

   您可以查看有关策略的详细信息以及我们的建议。该建议告诉您预测性扩展策略是否比不使用预测性扩展策略做得更好。

   如果您不确定预测性扩展策略是否适合您的组，请查看**可用性影响**和**成本影响**列以选择正确的策略。每列的信息告诉您该策略的影响。
   + **可用性影响**：描述与不使用策略相比，该策略是否可以通过预置足够的任务来处理工作负载，从而避免对可用性的负面影响。
   + **成本影响**：描述与不使用策略相比，该策略是否可以通过不过度预置任务而避免对您的成本产生负面影响。过度预置会导致您的任务未得到充分利用或处于闲置状态，这只会增加对成本的影响。

   如果您有多个策略，则在以较低成本提供最大可用性优势的策略名称旁边显示**最佳预测**标签。对可用性的影响给予了更多的重视。

1. （可选）要选择所需的建议结果时间段，请从**评估期**下拉列表中选择您需要的值：**2 天**、**1 周**或**2 周**。默认情况下，评估期为过去两周。更长的评估期可为建议结果提供更多的数据点。但是，如果您的负载模式发生了变化，例如在需求异常之后，添加更多数据点可能不会改善结果。在这种情况下，您可以通过查看最新数据来获得更有针对性的建议。

**注意**  
仅为处于**仅预测**模式的策略生成建议。当策略在整个评估期内处于**仅预测**模式时，建议功能的效果会更好。如果您在**预测和扩展**模式下启动策略，稍后将其切换为**仅预测**模式，则该策略的调查结果可能会有偏差。这是因为该策略已经为实际容量做出了贡献。

## 查看预测性扩展监控图表
<a name="review-predictive-scaling-monitoring-graphs"></a>

在控制台中，您可以查看前几天、几周或几个月的预测，以便可视化策略在一段时间内的表现如何。在决定是否让策略扩展实际任务数时，您还可以使用这些信息来评估预测的准确性。

**在 Amazon ECS 控制台中查看预测式扩缩监控图表**

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**服务自动扩缩**。

1. 选择预测式扩缩策略，然后依次选择**操作**、**预测式扩缩**、**查看图表**。

1. 在**监控**部分中，您可以根据实际值查看策略对过去和未来负载和容量的预测。**负载**图表显示所选负载指标的负载预测和实际值。**容量**图表显示策略预测的任务数。它还包括启动任务的实际数量。垂直线将历史值与未来预测分开。创建策略后不久，这些图表可用。

1. （可选）要更改图表中显示的历史数据量，请从页面顶部的**评估期**下拉列表中选择您的首选值。评估期不会以任何方式转换此页面上的数据。它只会更改显示的历史数据量。

**比较**负载**图表中的数据**  
每条水平线代表一小时间隔内报告的一组不同的数据点：

1. **实际观测负载**使用所选负载指标的 SUM 统计数据来显示过去每小时的总负载。

1. **策略预测的负载**显示每小时的负载预测。该预测基于前两周的实际负载观测结果。

**比较**容量**图表中的数据**  
每条水平线代表一小时间隔内报告的一组不同的数据点：

1. **实际观测任务数**显示 Amazon ECS 服务过去的实际容量，这取决于您的其他扩缩策略和所选时间段内有效的最小组大小。

1. **策略预测的容量**显示当策略处于**预测和扩展**模式时，您在每个小时开始时期望拥有的基准容量。

1. **推断的所需任务数**显示将扩缩指标维持在所选择目标值的理想任务数。

1. **最小任务数**显示服务中的最小任务数。

1. **最大容量**显示服务中的最大任务数。

为了计算推断的所需容量，我们首先假设每个任务在指定目标值下的利用率相等。实际上，任务数的利用并不均等。但是，通过假设任务之间的利用率分布均匀，我们可以对所需的容量进行可能的估计。然后计算任务数需求，与您在预测式扩缩策略中使用的扩缩指标成反比。换句话说，随着任务数的增加，扩缩指标会以相同的速率减少。例如，如果任务数翻倍，则扩缩指标必定会减少一半。

推断的所需容量的公式：

 `sum of (actualServiceUnits*scalingMetricValue)/(targetUtilization)`

例如，我们在给定一小时内使用 `actualServiceUnits`（`10`）和 `scalingMetricValue`（`30`）。然后，我们采用您在预测扩展策略（`60`）中指定的 `targetUtilization`，计算同一小时的推断所需容量。这会返回值 `5`。这意味着 5 是推断出的维持容量所需的容量，与扩展指标的目标值成反比。

**注意**  
您可以使用各种杠杆来调整和提高应用程序的成本节约和可用性。  
您可以使用预测性扩展来计算基准容量，使用动态扩展来处理额外的容量。动态扩展独立于预测性扩展，会根据当前的利用率横向缩减和横向扩展。首先，Amazon ECS 会计算每个非计划的扩展策略的建议任务数。然后，它会根据提供最多任务的策略进行扩展。
要允许在负载减少时进行横向缩减，服务应始终至少有一个启用了横向缩减部分的动态扩缩策略。
您可以通过确保最小和最大容量不太严格来提高扩展性能。如果策略中包含的推荐任务数不在最小和最大容量范围内，则将阻止横向缩减和横向扩展。

# 使用 CloudWatch 监控 Amazon ECS 的预测式扩缩指标
<a name="predictive-scaling-monitoring"></a>

您可以使用 Amazon CloudWatch 监控预测式扩缩相关数据。预测式扩缩策略将收集用于预测未来负载的数据。收集的数据会定期自动存储在 CloudWatch 中，并可用于直观地显示策略在一段时间内的表现。您还可以创建 CloudWatch 警报，以便在性能指标的变化超出所定义的限制时通知您。

## 可视化显示历史预测数据
<a name="visualize-historical-forecast-data"></a>

预测式扩缩策略的负载预测数据可以在 CloudWatch 中查看，并且在单个图表中直观地显示与其他 CloudWatch 指标对比的预测时，这些数据非常有用。您还可以查看更大的时间范围的情况，以了解长期的趋势。您可以访问长达 15 个月的历史指标，以更好地了解您的策略性能。

**使用 CloudWatch 控制台查看历史预测数据**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，选择 **Metrics**（指标），然后选择 **All metrics**（所有指标）。

1. 选择**应用程序自动扩缩**指标命名空间。

1. 选择**预测式扩缩负载预测**。

1. 在搜索字段中，输入预测式扩缩策略的名称或 Amazon ECS 服务组的名称，然后按 Enter 键以筛选结果。

1. 要为指标绘制图表，请选中该指标旁的复选框。要更改图表的名称，请选择铅笔图标。要更改时间范围，请选择某个预定义的值或选择 **custom**。有关更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[绘制指标图表](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/graph_a_metric.html)。

1. 要更改统计数据，请选择 **Graphed metrics**（已绘制图表指标）选项卡。选择列标题或单个值，然后选择其他统计数据。尽管您可以为每个指标选择任何统计数据，但并非所有的统计数据都对 **PredictiveScalingLoadForecast** 指标有用。例如，**平均**、**最小**和**最大**统计数据非常有用，但**总和**统计数据用处不大。

1. 要在图表中添加其他指标，请在 **All**（全部）下选择 **Browse**（浏览），找到特定的指标，然后选中它旁边的复选框。您最多可以添加 10 个指标。

1. （可选）要将此图表添加到 CloudWatch 控制面板，请选择 **Actions**（操作），然后选择 **Add to dashboard**（添加到控制面板）。

## 使用指标数学创建准确度指标
<a name="create-accuracy-metrics"></a>

借助指标数学，您可以查询多个 CloudWatch 指标并使用数学表达式来创建基于这些指标的新时间序列。您可以在 CloudWatch 控制台上直观显示生成的时间序列，并将其添加到控制面板中。有关指标数学的更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[使用指标数学](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html)。

借助指标数学，您能够以不同方式绘制服务自动扩缩为预测式横向缩减而生成的数据。这可帮助您监控随时间变化的策略性能，并帮助您了解是否可以改进指标组合。

例如，您可以使用指标数学表达式来监控[平均绝对百分比误差](https://en.wikipedia.org/wiki/Mean_absolute_percentage_error)（MAPE）。MAPE 指标可帮助监控在给定预测时段内预测值与实际观测值之间的差异。MAPE 值的变化可能表明随着应用性质的变化，策略的性能是否会随着时间的推移而下降。MAPE 增加说明着预测值和实际值之间的差异加大。

**示例：指标数学表达式**

要开始使用此类图表，您可以创建一个与下例中类似的指标数学表达式。



这不是单个指标，而是一组针对 `MetricDataQueries` 的指标数据查询结构。`MetricDataQueries` 中的每一项都会获取一个指标或执行一个数学表达式。第一项 `e1` 是一个数学表达式。指定的表达式将 `ReturnData` 参数设置为 `true`，这最终会生成单个时间序列。对于所有其他指标，`ReturnData` 值为 `false`。

在此例中，指定的表达式使用实际值和预测值作为输入，并返回新指标（MAPE）。`m1` 是包含实际负载值的 CloudWatch 指标（假设 CPU 利用率是最初为名为 `my-predictive-scaling-policy` 的策略指定的负载指标）。`m2` 是包含预测负载值的 CloudWatch 指标。MAPE 指标的数学语法如下所示：

*（（实际值：预测值）/（实际值）的绝对值）的平均值*

### 可视化显示准确度指标并设置警报
<a name="visualize-accuracy-metrics-set-alarms"></a>

要可视化显示准确度指标数据，请在 CloudWatch 控制台中选择 **Metrics**（指标）选项卡。您可以在此处绘制数据图表。有关更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[将数学表达式添加到 CloudWatch 图表](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html#adding-metrics-expression-console)。

您还可以在 **Metrics**（指标）部分为您监控的指标设置警报。在 **Graphed metrics**（绘制的指标）选项卡中，选择 **Actions**（操作）列下的 **Create alarm**（创建警报）。**Create alarm**（创建警报）图标用一个小铃铛表示。有关通知选项的更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[根据指标数学表达式创建 CloudWatch 告警](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Create-alarm-on-metric-math-expression.html)和[将警报更改通知用户](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Notify_Users_Alarm_Changes.html)。

您也可以使用 [GetMetricData](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricData.html) 和 [PutMetricAlarm](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricAlarm.html) 以使用指标数学执行计算，并基于输出创建警报。

# 使用计划操作来覆盖 Amazon ECS 的预测值
<a name="predictive-scaling-overriding-forecast-capacity"></a>

有时，您可能会获得有关未来应用程序需求的其他信息，预测计算无法考虑这些信息。例如，预测计算值可能会低估即将开展的市场营销活动所需的容量。您可以使用计划操作在未来时段内临时覆盖预测。计划操作可以循环运行，也可以在出现一次性需求波动的特定日期和时间运行。

例如，您可以创建一个任务数高于预测值的计划操作。在运行时，Amazon ECS 会更新服务中的最小任务数。由于预测性扩缩是针对任务数进行优化的，因此最小任务数高于预测值的计划操作将会被执行。这样可以防止任务数低于预期数量。要停止覆盖预测值，请使用第二个计划操作将最小任务数恢复为原始设置。

以下过程概述了在将来期间覆盖预测的步骤。

**Topics**
+ [步骤 1：（可选）分析时间序列数据](#analyzing-time-series-data)
+ [步骤 2：创建两个计划操作](#scheduling-capacity)

**重要**  
本主题假设您尝试覆盖预测，以扩展到比预测更高的容量。如果需要在不受预测性扩缩策略干扰的情况下暂时减少任务数，则请改用*仅预测*模式。使用“仅预测”模式时，预测性扩缩将会继续生成预测，但不会自动增加任务数。然后，您可以监控资源利用率，并根据需要手动减少所需任务数。

## 步骤 1：（可选）分析时间序列数据
<a name="analyzing-time-series-data"></a>

首先分析预测时间序列数据。这是一个可选步骤，但如果您想了解预测的详细信息，它会很有帮助。

1. **检索预测**

   创建预测后，您可以查询预测中的特定时间段。查询的目的是获得特定时间段的时间序列数据的完整视图。

   您的查询最多可以包含两天的未来预测数据。如果您已经使用了一段时间预测式扩展，您还可以访问过去的预测数据。但是，开始和结束时间之间的最长持续时间为 30 天。

   若要使用 [get-predictive-scaling-forecast](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/get-predictive-scaling-forecast.html) AWS CLI 命令获取预测，请在命令中提供以下参数：
   + 在 `resource-id` 参数中输入集群的名称。
   + 在 `--policy-name` 参数中输入策略的名称。
   + 在 `--start-time` 参数中输入开始时间以仅返回在指定时间或之后的预测数据。
   + 在 `--end-time` 参数中输入结束时间以仅返回在指定时间之前的预测数据。

   ```
   aws application-autoscaling get-predictive-scaling-forecast \
       --service-namespace ecs \
       --resource-id service/MyCluster/test \
       --policy-name cpu40-predictive-scaling-policy \
       --scalable-dimension ecs:service:DesiredCount \
       --start-time "2021-05-19T17:00:00Z" \
       --end-time "2021-05-19T23:00:00Z"
   ```

   如果成功，该命令将返回类似于以下示例的数据。

   ```
   {
       "LoadForecast": [
           {
               "Timestamps": [
                   "2021-05-19T17:00:00+00:00",
                   "2021-05-19T18:00:00+00:00",
                   "2021-05-19T19:00:00+00:00",
                   "2021-05-19T20:00:00+00:00",
                   "2021-05-19T21:00:00+00:00",
                   "2021-05-19T22:00:00+00:00",
                   "2021-05-19T23:00:00+00:00"
               ],
               "Values": [
                   153.0655799339254,
                   128.8288551285919,
                   107.1179447150675,
                   197.3601844551528,
                   626.4039934516954,
                   596.9441277518481,
                   677.9675713779869
               ],
               "MetricSpecification": {
                   "TargetValue": 40.0,
                   "PredefinedMetricPairSpecification": {
                       "PredefinedMetricType": "ASGCPUUtilization"
                   }
               }
           }
       ],
       "CapacityForecast": {
           "Timestamps": [
               "2021-05-19T17:00:00+00:00",
               "2021-05-19T18:00:00+00:00",
               "2021-05-19T19:00:00+00:00",
               "2021-05-19T20:00:00+00:00",
               "2021-05-19T21:00:00+00:00",
               "2021-05-19T22:00:00+00:00",
               "2021-05-19T23:00:00+00:00"
           ],
           "Values": [
               2.0,
               2.0,
               2.0,
               2.0,
               4.0,
               4.0,
               4.0
           ]
       },
       "UpdateTime": "2021-05-19T01:52:50.118000+00:00"
   }
   ```

   此响应包括两个预测：`LoadForecast` 和 `CapacityForecast`。`LoadForecast` 显示每小时负载预测。`CapacityForecast` 显示每小时处理预测负载所需的容量的预测值，同时保持 `TargetValue` 为 40.0（平均 CPU 利用率为 40%）。

1. **确定目标时间段**

   确定应发生一次性需求波动的小时数。请记住，预测中显示的日期和时间以 UTC 为单位。

## 步骤 2：创建两个计划操作
<a name="scheduling-capacity"></a>

接下来，在应用程序的负载高于预测负载的特定时间段内创建两个计划操作。例如，如果您的营销活动会在有限时间段内使网站的流量增加，则可计划一个一次性操作以在其启动时更新最小容量。然后，安排另一个操作，以便在事件结束时将最小容量返回到原始设置。

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

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

1. 在“集群详细信息”页面，找到**服务**部分，然后选择服务。

   此时系统会显示服务详细信息页面。

1. 选择**服务自动扩缩**。

   此时将显示策略页面。

1. 选择**计划操作**，然后选择**创建**。

   此时将显示**“创建计划”操作**页面。

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

1. 对于**时区**，请选择时区。

   列出的所有时区均来自 IANA 时区数据库。有关详细信息，请参阅 [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。

1. 对于**启动时间**，输入操作启动的**日期**和**时间**。

1. 对于**循环**，选择**一次**。

1. 对于**任务调整**下的“最小值”，输入一个小于或等于最大任务数的值。

1. 选择**创建计划操作**。

   此时将显示策略页面。

1. 配置第二个计划操作，以在事件结束时将最小任务数恢复为原始设置。预测性扩缩只能在设置的**最小值**小于预测值时扩缩任务数。

**为一次性事件创建两个计划操作（AWS CLI）**  
要使用 AWS CLI 创建计划操作，请使用 [put-scheduled-update-group-action](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/put-scheduled-update-group-action.html) 命令。

例如，让我们定义一个时间表，在 5 月 19 日下午 5:00 时保持最少三个实例的容量，持续 8 小时。以下命令显示如何实现此方案。

第一个 [put-scheduled-update-group-action](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/put-scheduled-update-group-action.html) 命令指示 Amazon EC2 Auto Scaling 在 2021 年 5 月 19 日 UTC 下午 5:00 更新指定自动扩缩组的最小容量。

```
aws autoscaling put-scheduled-update-group-action --scheduled-action-name my-event-start \
  --auto-scaling-group-name my-asg --start-time "2021-05-19T17:00:00Z" --minimum-capacity 3
```

第二个命令指示 Amazon EC2 Auto Scaling 将该组的最小容量设置为 2021 年 5 月 20 日 UTC 上午 1:00。

```
aws autoscaling put-scheduled-update-group-action --scheduled-action-name my-event-end \
  --auto-scaling-group-name my-asg --start-time "2021-05-20T01:00:00Z" --minimum-capacity 1
```

将这些计划操作添加到自动扩缩组后，Amazon EC2 Auto Scaling 将执行以下操作：
+ 2021 年 5 月 19 日下午 5:00，第一个计划的操作将运行。如果组中当前已少于三个实例，则该组会扩展到三个实例。在此期间和接下来的八小时内，如果预测容量高于实际容量，或者如果有动态扩展策略生效，Amazon EC2 Auto Scaling 可以继续横向扩展。
+ 2021 年 5 月 20 日上午 1:00，将运行第二个计划的操作。这将在事件结束时将最小容量恢复为其原始设置。

### 根据重复性计划进行扩展
<a name="scheduling-recurring-actions"></a>

要覆盖每周相同时间段的预测，请创建两个计划操作，并使用 cron 表达式提供时间和日期逻辑。

此 cron 表达式格式包含五个空格分隔的字段：[Minute] [Hour] [Day\$1of\$1Month] [Month\$1of\$1Year] [Day\$1of\$1Week]。字段可以包含任何允许的值，包括特殊字符。

例如，下面的 cron 表达式在每周二上午 6:30 运行操作。星号用作通配符，以匹配字段的所有值。

```
30 6 * * 2
```

### 另请参阅
<a name="scheduling-scaling-see-also"></a>

有关如何管理计划操作的更多信息，请参阅[使用计划操作扩展 Amazon ECS 服务](service-autoscaling-schedulescaling.md)。

# 面向 Amazon ECS 的使用自定义指标的高级预测式扩缩策略
<a name="predictive-scaling-custom-metrics"></a>

在预测式扩缩策略中，您可以使用预定义指标或自定义指标。当预定义指标（例如 CPU、内存等）不足以充分描述应用程序负载时，自定义指标非常有用。

使用自定义指标创建预测式扩缩策略时，您可以指定由 AWS 提供的其他 CloudWatch 指标。或者，您可以指定自己定义和发布的指标。您还可以使用指标数学来聚合现有的指标并将其转换为 AWS 会不自动跟踪的新时间序列。例如，通过计算新的总和或平均值来组合数据中的值时，该操作称为*执行聚合*。生成的数据称为*聚合*。

以下部分包含了有关如何为构造策略的 JSON 结构的最佳实践和示例。

## 先决条件
<a name="predictive-scaling-custom-metrics-prerequisites"></a>

要将自定义指标添加到预测性扩缩策略，您必须具有 `cloudwatch:GetMetricData` 权限。

要指定自己的指标而不是 AWS 提供的指标，您必须首先将您的指标发布到 CloudWatch。有关更多信息，请参阅 *Amazon CloudWatch 用户指南*中的[发布自定义指标](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html)。

如果发布自己的指标，请确保以至少五分钟的频率发布数据点。根据所需的时间长度从 CloudWatch 中检索数据点。例如，负载指标规范以每小时为指标来衡量应用程序的负载。CloudWatch 使用您已发布的指标数据在任意一小时期间提供单个数据值，其方法是将所有数据点与每个一小时内的时间戳聚合起来。

## 最佳实践
<a name="predictive-scaling-custom-metrics-best-practices"></a>

以下最佳实践可帮助您更有效地使用自定义指标：
+ 对于负载指标规范，最有用的指标是作为一个整体表示自动扩缩组负载的指标。
+ 对于扩缩指标规范，要扩展的最有用指标是每个任务指标的平均吞吐量或利用率。
+ 目标利用率必须与扩展指标的类型匹配。例如，对于使用 CPU 利用率的策略配置，这是目标百分比。
+ 如果未遵循这些建议，那么时间序列的预测未来值可能会不正确。要验证数据是否正确，您可以在控制台中查看预测值。或者，在创建预测式扩缩策略之后，请检查对 [GetPredictiveScalingForecast](https://docs.aws.amazon.com/autoscaling/application/APIReference/API_GetPredictiveScalingForecast.html) API 的调用返回的 `LoadForecast` 对象。
+ 我们强烈建议您在仅预测模式下配置预测式横向缩减，以便在预测式扩展启动主动扩展之前对预测进行评估。

## 限制
<a name="predicitve-scaling-custom-metrics-limitations"></a>
+ 您可以在一个指标规范中查询最多 10 个指标的数据点。
+ 为满足此限制，一个表达式算作一个指标。

## 排查使用自定义指标的预测式扩缩策略的问题
<a name="predictive-scaling-custom-metrics-troubleshooting"></a>

如果在使用自定义指标时出现问题，建议您执行以下操作：
+ 如果您在使用搜索表达式时在蓝绿部署中遇到问题，请确保您创建的搜索表达式是在寻找部分匹配项而不是完全匹配项。此外，请检查您的查询是否只查找在特定应用程序中运行的自动扩缩组。有关搜索表达式语法的更多信息，请参阅 *Amazon CloudWatch 用户指南*中的 [CloudWatch 搜索表达式语法](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/search-expression-syntax.html)。
+ [put-scaling-policy](https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/put-scaling-policy.html) 命令会在您创建扩缩策略时对表达式进行验证。但是，此命令有可能无法识别所检测错误的确切原因。要修复这些问题，请解决您在 [get-metric-data](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-data.html) 命令请求的回应中收到的错误。您还可以通过 CloudWatch 控制台对表达式进行问题排查。
+ 如果 `MetricDataQueries` 自行指定 SEARCH() 函数，而没有像 SUM() 这样的数学函数，则必须为 `ReturnData` 指定 `false`。原因在于搜索表达式可能返回多个时间序列，而基于表达式的指标规范仅可以返回一个时间序列。
+ 搜索表达式中涉及的所有指标均应该具有相同的分辨率。

# 使用 Amazon ECS 为预测式扩缩自定义指标构建 JSON
<a name="predictive-scaling-custom-metrics-example"></a>

以下部分包含了有关如何配置预测行扩缩以从 CloudWatch 查询数据的示例。配置此选项有两种不同的方法，您选择的方法会影响您为预测性扩缩策略构造 JSON 时使用的格式。使用指标数学时，JSON 格式会根据所执行的指标数学进一步变化。

1. 要创建直接从 AWS 提供的其他 CloudWatch 指标或您发布到 CloudWatch 的指标中获取数据的策略，请参阅 [包含自定义负载和扩缩指标的预测式扩缩策略示例（使用 AWS CLI）](#predictive-scaling-custom-metrics-example1)。

## 包含自定义负载和扩缩指标的预测式扩缩策略示例（使用 AWS CLI）
<a name="predictive-scaling-custom-metrics-example1"></a>

要通过 AWS CLI 使用自定义负载和扩缩指标创建预测性扩缩策略，请将 `--predictive-scaling-configuration` 的参数存储在名为 `config.json` 的 JSON 文件中。

您可以将以下示例中的可替换值替换为您的指标和目标利用率值，从而开始添加自定义指标。

```
{
  "MetricSpecifications": [
    {
      "TargetValue": 50,
      "CustomizedScalingMetricSpecification": {
        "MetricDataQueries": [
          {
            "Id": "scaling_metric",
            "MetricStat": {
              "Metric": {
                "MetricName": "MyUtilizationMetric",
                "Namespace": "MyNameSpace",
                "Dimensions": [
                  {
                    "Name": "MyOptionalMetricDimensionName",
                    "Value": "MyOptionalMetricDimensionValue"
                  }
                ]
              },
              "Stat": "Average"
            }
          }
        ]
      },
      "CustomizedLoadMetricSpecification": {
        "MetricDataQueries": [
          {
            "Id": "load_metric",
            "MetricStat": {
              "Metric": {
                "MetricName": "MyLoadMetric",
                "Namespace": "MyNameSpace",
                "Dimensions": [
                  {
                    "Name": "MyOptionalMetricDimensionName",
                    "Value": "MyOptionalMetricDimensionValue"
                  }
                ]
              },
              "Stat": "Sum"
            }
          }
        ]
      }
    }
  ]
}
```

有关更多信息，请参阅《Amazon EC2 Auto Scaling API 参考》**中的 [MetricDataQuery](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_MetricDataQuery.html)。

**注意**  
以下是一些可以帮助您查找 CloudWatch 指标的指标名称、命名空间、维度和统计数据的其他资源：  
有关 AWS 服务可用指标的更多信息，请参阅 *Amazon CloudWatch 用户指南*中的[发布 CloudWatch 指标的 AWS 服务](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html)。
要获取带有 AWS CLI 的 CloudWatch 指标的确切指标名称、命名空间和维度（如果适用），请参阅[列出指标](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/list-metrics.html)。

要创建此策略，请运行 [put-scaling-policy](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/put-scaling-policy.html) 命令并将此 JSON 文件作为输入，如下例所示。

```
aws application-autoscaling put-scaling-policy --policy-name my-predictive-scaling-policy \
  --auto-scaling-group-name my-asg --policy-type PredictiveScaling \
  --predictive-scaling-configuration file://config.json
```

如果成功，此命令将返回策略的 Amazon 资源名称（ARN）。

```
{
  "PolicyARN": "arn:aws:autoscaling:region:account-id:scalingPolicy:2f4f5048-d8a8-4d14-b13a-d1905620f345:autoScalingGroupName/my-asg:policyName/my-predictive-scaling-policy",
  "Alarms": []
}
```

# 使用指标数学表达式
<a name="predictive-scaling-math-expression"></a>

以下部分提供有关在策略中如何针对预测式扩缩策略使用指标数学的信息。

## 了解指标数学
<a name="predictive-scaling-custom-metrics-math"></a>

如果您想要做的只是聚合现有指标数据，那么 CloudWatch 指标数学可以节省向 CloudWatch 发布另一个指标的精力和成本。您可以使用 AWS 提供的任何指标，还可以使用定义为应用程序一部分的指标。

有关更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[使用指标数学](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html)。

如果您选择在预测性扩展策略中使用指标数学表达式，请考虑以下几点：
+ 指标数学运算使用指标名称、命名空间和维度键/值对指标的唯一组合的数据点。
+ 您可以使用任意算术运算符（\$1 - \$1 / ^）、统计函数（例如 AVG 或 SUM）或 CloudWatch 支持的其他函数。
+ 您可以在数学表达式的公式中同时使用指标和其他数学表达式的结果。
+ 指标数学表达式可以由不同的聚合组成。但是，得到最终聚合结果的最佳实践是针对扩展指标使用 `Average` 以及针对负载指标使用 `Sum`。
+ 指标规范中使用的任何表达式最终都必须返回一个单个时间序列。

要使用指标数学，请执行以下操作：
+ 选择一个或多个 CloudWatch 指标。然后，创建表达式。有关更多信息，请参阅《Amazon CloudWatch 用户指南》**中的[使用指标数学](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html)。
+ 使用 CloudWatch 控制台或 CloudWatch [GetMetricData](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricData.html) API 验证指标数学表达式是否有效。

## 使用指标数学组合指标的预测性扩缩策略示例（AWS CLI）
<a name="custom-metrics-ex2"></a>

有时，您可能需要首先以某种方式处理其数据，而不是直接指定指标。例如，您可能有一个从 Amazon SQS 队列中提取工作的应用程序，并且可能希望使用队列中的项目数作为预测性扩展的标准。队列中的消息数不仅仅定义您需要的实例数。因此，需要执行更多工作来创建可用于计算每个实例的积压的指标。

以下示例是适用于此场景的预测扩展策略示例。它指定了基于 Amazon SQS `ApproximateNumberOfMessagesVisible` 指标的扩展和负载指标，即可从队列中获取的用于检索的消息数量。它还使用 Amazon EC2 Auto Scaling `GroupInServiceInstances` 指标和数学表达式，计算扩展指标的每个实例的积压。

```
aws application-autoscaling put-scaling-policy --policy-name my-sqs-custom-metrics-policy \
  --policy-type PredictiveScaling \
  --predictive-scaling-configuration file://config.json
  --service-namespace ecs \
  --resource-id service/MyCluster/test \
  "MetricSpecifications": [
    {
      "TargetValue": 100,
      "CustomizedScalingMetricSpecification": {
        "MetricDataQueries": [
          {
            "Label": "Get the queue size (the number of messages waiting to be processed)",
            "Id": "queue_size",
            "MetricStat": {
              "Metric": {
                "MetricName": "ApproximateNumberOfMessagesVisible",
                "Namespace": "AWS/SQS",
                "Dimensions": [
                  {
                    "Name": "QueueName",
                    "Value": "my-queue"
                  }
                ]
              },
              "Stat": "Sum"
            },
            "ReturnData": false
          },
          {
            "Label": "Get the group size (the number of running instances)",
            "Id": "running_capacity",
            "MetricStat": {
              "Metric": {
                "MetricName": "GroupInServiceInstances",
                "Namespace": "AWS/AutoScaling",
                "Dimensions": [
                  {
                    "Name": "AutoScalingGroupName",
                    "Value": "my-asg"
                  }
                ]
              },
              "Stat": "Sum"
            },
            "ReturnData": false
          },
          {
            "Label": "Calculate the backlog per instance",
            "Id": "scaling_metric",
            "Expression": "queue_size / running_capacity",
            "ReturnData": true
          }
        ]
      },
      "CustomizedLoadMetricSpecification": {
        "MetricDataQueries": [
          {
            "Id": "load_metric",
            "MetricStat": {
              "Metric": {
                "MetricName": "ApproximateNumberOfMessagesVisible",
                "Namespace": "AWS/SQS",
                "Dimensions": [
                  {
                    "Name": "QueueName",
                    "Value": "my-queue"
                  }
                ],
              },
              "Stat": "Sum"
            },
            "ReturnData": true
          }
        ]
      }
    }
  ]
}
```

该示例返回策略的 ARN。

```
{
  "PolicyARN": "arn:aws:autoscaling:region:account-id:scalingPolicy:2f4f5048-d8a8-4d14-b13a-d1905620f345:autoScalingGroupName/my-asg:policyName/my-sqs-custom-metrics-policy",
  "Alarms": []
}
```

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


****  

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

考虑以下示例。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1. 完成服务创建过程。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

------

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

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

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

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

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

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

------

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

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

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

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

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

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

------

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

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

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

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

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

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

------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1. 完成服务创建过程。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

****  

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

------

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

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

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

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

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

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

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

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

****  

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

------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   示例：

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

   示例响应：

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

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

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

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

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

以下是 Service Connect 的先决条件：
+ 验证安装并配置了最新版本的 AWS CLI。有关更多信息，请参阅[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ 您的 IAM 用户具有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 策略示例中指定的必需权限。
+ 您已创建要使用的 VPC、子网、路由表和安全组。有关更多信息，请参阅 [创建虚拟私有云](get-set-up-for-amazon-ecs.md#create-a-vpc)。
+ 您有一个名为 `ecsTaskExecutionRole` 的任务执行角色，并且 `AmazonECSTaskExecutionRolePolicy` 托管策略已附加到该角色。此角色允许 Fargate 将 NGINX 应用程序日志和 Service Connect 代理日志写入 Amazon CloudWatch Logs。有关更多信息，请参阅 [创建任务执行 角色](task_execution_IAM_role.md#create-task-execution-role)。

## 第 1 步：创建集群
<a name="create-service-connect-cluster"></a>

请按照以下步骤创建 Amazon ECS 集群和命名空间。

**要创建 Amazon ECS 集群和 AWS Cloud Map 命名空间。**

1. 创建要使用的名为 `tutorial` 的 Amazon ECS 集群。参数 `--service-connect-defaults` 设置集群的默认命名空间。在示例输出中，此账户和 AWS 区域 中不存在名称 `service-connect` 的 AWS Cloud Map 命名空间，因此命名空间由 Amazon ECS 创建。命名空间是在账户中的 AWS Cloud Map 中创建的，所有其他命名空间都可见，因此请使用表明目的的名称。

   ```
   aws ecs create-cluster --cluster-name tutorial --service-connect-defaults namespace=service-connect
   ```

   输出：

   ```
   {
       "cluster": {
           "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
           "clusterName": "tutorial",
           "serviceConnectDefaults": {
               "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
           },
           "status": "PROVISIONING",
           "registeredContainerInstancesCount": 0,
           "runningTasksCount": 0,
           "pendingTasksCount": 0,
           "activeServicesCount": 0,
           "statistics": [],
           "tags": [],
           "settings": [
               {
                   "name": "containerInsights",
                   "value": "disabled"
               }
           ],
           "capacityProviders": [],
           "defaultCapacityProviderStrategy": [],
           "attachments": [
               {
                   "id": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
                   "type": "sc",
                   "status": "ATTACHING",
                   "details": []
               }
           ],
           "attachmentsStatus": "UPDATE_IN_PROGRESS"
       }
   }
   }
   ```

1. 验证集群是否已创建：

   ```
   aws ecs describe-clusters --clusters tutorial
   ```

   输出：

   ```
   {
       "clusters": [
           {
               "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
               "clusterName": "tutorial",
               "serviceConnectDefaults": {
                   "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
               },
               "status": "ACTIVE",
               "registeredContainerInstancesCount": 0,
               "runningTasksCount": 0,
               "pendingTasksCount": 0,
               "activeServicesCount": 0,
               "statistics": [],
               "tags": [],
               "settings": [],
               "capacityProviders": [],
               "defaultCapacityProviderStrategy": []
           }
       ],
       "failures": []
   }
   ```

1. （可选）验证命名空间是否是在 AWS Cloud Map 中创建的。您可以使用在 AWS Cloud Map 中创建的 AWS 管理控制台 或普通 AWS CLI 配置。

   例如，使用 AWS CLI：

   ```
   aws servicediscovery get-namespace --id ns-EXAMPLE
   ```

   输出：

   ```
   {
       "Namespace": {
           "Id": "ns-EXAMPLE",
           "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE",
           "Name": "service-connect",
           "Type": "HTTP",
           "Properties": {
               "DnsProperties": {
                   "SOA": {}
               },
               "HttpProperties": {
                   "HttpName": "service-connect"
               }
           },
           "CreateDate": 1661749852.422,
           "CreatorRequestId": "service-connect"
       }
   }
   ```

## 步骤 2：为服务器创建服务
<a name="create-service-connect-nginx-server"></a>

Service Connect 功能旨在互连 Amazon ECS 上的多个应用程序。这些应用程序中至少有一个需要提供 Web 服务才能连接。在此步骤中，您将创建：
+ 使用未经修改的官方 NGINX 容器映像并包括 Service Connect 配置的任务定义。
+ Amazon ECS 服务定义，用于配置 Service Connect，从而为该服务的流量提供服务发现和服务网格代理。该配置重复使用集群配置中的默认命名空间，以减少您为每项服务所做的服务配置量。
+ Amazon ECS 服务。它使用任务定义运行一项任务，并为 Service Connect 代理插入一个额外的容器。代理侦听任务定义的容器端口映射中的端口。在 Amazon ECS 中运行的客户端应用程序中，客户端任务中的代理侦听与任务定义端口名、服务发现名称或服务客户端别名以及来自客户端别名的端口号的出站连接。

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

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

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

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

      任务定义包含任务 IAM 角色，因为该服务已启用 ECS Exec。
**重要**  
此任务定义使用 `logConfiguration` 从 `stdout` 和 `stderr` 向 Amazon CloudWatch Logs 发送 nginx 输出。此任务执行角色不具有创建 CloudWatch Logs 日志组所需的额外权限。使用 AWS 管理控制台 或 AWS CLI 在 CloudWatch Logs 中创建日志组。如果您不想将 nginx 日志发送到 CloudWatch Logs，可以删除 `logConfiguration`。  
用您的 AWS 账户 ID 替换任务执行角色中的 AWS 账户 ID。

      ```
      {
          "family": "service-connect-nginx",
          "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
          "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
          "networkMode": "awsvpc",
          "containerDefinitions": [
              {
              "name": "webserver",
              "image": "public.ecr.aws/docker/library/nginx:latest",
              "cpu": 100,
              "portMappings": [
                  {
                      "name": "nginx",
                      "containerPort": 80,
                      "protocol": "tcp", 
                      "appProtocol": "http"
                  }
              ],
              "essential": true,
              "logConfiguration": {
                  "logDriver": "awslogs",
                  "options": {
                      "awslogs-group": "/ecs/service-connect-nginx",
                      "awslogs-region": "region", 
                      "awslogs-stream-prefix": "nginx"
                  }
              }
              }
          ],
          "cpu": "256",
          "memory": "512"
      }
      ```

   1. 使用 `service-connect-nginx.json` 文件注册任务定义：

      ```
      aws ecs register-task-definition --cli-input-json file://service-connect-nginx.json
      ```

1. 创建服务：

   1. 使用您将要创建的 Amazon ECS 服务的内容，创建名为 `service-connect-nginx-service.json` 的文件。此示例会使用在上一步中创建的任务定义。由于示例任务定义使用 `awsvpc` 网络模式，`awsvpcConfiguration` 是必需的。

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

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

      此服务使用 `logConfiguration` 将 Service Connect 代理输出从 `stdout` 和 `stderr` 发送到 Amazon CloudWatch Logs。此任务执行角色不具有创建 CloudWatch Logs 日志组所需的额外权限。使用 AWS 管理控制台 或 AWS CLI 在 CloudWatch Logs 中创建日志组。我们建议您创建此日志组并将代理日志存储在 CloudWatch Logs 中。如果您不想将代理日志发送到 CloudWatch Logs，可以删除 `logConfiguration`。

      ```
      {
          "cluster": "tutorial",
          "deploymentConfiguration": {
              "maximumPercent": 200,
              "minimumHealthyPercent": 0
          },
          "deploymentController": {
              "type": "ECS"
          },
          "desiredCount": 1,
          "enableECSManagedTags": true,
          "enableExecuteCommand": true,
          "launchType": "FARGATE",
          "networkConfiguration": {
              "awsvpcConfiguration": {
                  "assignPublicIp": "ENABLED",
                  "securityGroups": [
                      "sg-EXAMPLE"
                  ],
                  "subnets": [
                      "subnet-EXAMPLE",
                      "subnet-EXAMPLE",
                      "subnet-EXAMPLE"
                  ]
                 }
          },
          "platformVersion": "LATEST",
          "propagateTags": "SERVICE",
          "serviceName": "service-connect-nginx-service",
          "serviceConnectConfiguration": {
              "enabled": true,
              "services": [
                  {
                      "portName": "nginx",
                      "clientAliases": [
                          {
                              "port": 80
                          }
                      ],
                      "tls": {
                         "issuerCertificateAuthority": {
                            "awsPcaAuthorityArn": "certificateArn"
                         }, 
                         "kmsKey": "kmsKey", 
                         "roleArn": "iamRoleArn"
                      }
                  }
              ],
              "logConfiguration": {
                  "logDriver": "awslogs",
                  "options": {
                      "awslogs-group": "/ecs/service-connect-proxy",
                      "awslogs-region": "region",
                      "awslogs-stream-prefix": "service-connect-proxy"
                  }
              }
          },
          "taskDefinition": "service-connect-nginx"
      }
      ```

   1. 使用 `service-connect-nginx-service.json` 文件创建服务：

      ```
      aws ecs create-service --cluster tutorial --cli-input-json file://service-connect-nginx-service.json
      ```

      输出：

      ```
      {
          "service": {
              "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/tutorial/service-connect-nginx-service",
              "serviceName": "service-connect-nginx-service",
              "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
              "loadBalancers": [],
              "serviceRegistries": [],
              "status": "ACTIVE",
              "desiredCount": 1,
              "runningCount": 0,
              "pendingCount": 0,
              "launchType": "FARGATE",
              "platformVersion": "LATEST",
              "platformFamily": "Linux",
              "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
              "deploymentConfiguration": {
                  "deploymentCircuitBreaker": {
                      "enable": false,
                      "rollback": false
                  },
                  "maximumPercent": 200,
                  "minimumHealthyPercent": 0
              },
              "deployments": [
                  {
                      "id": "ecs-svc/3763308422771520962",
                      "status": "PRIMARY",
                      "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
                      "desiredCount": 1,
                      "pendingCount": 0,
                      "runningCount": 0,
                      "failedTasks": 0,
                      "createdAt": 1661210032.602,
                      "updatedAt": 1661210032.602,
                      "launchType": "FARGATE",
                      "platformVersion": "1.4.0",
                      "platformFamily": "Linux",
                      "networkConfiguration": {
                          "awsvpcConfiguration": {
                              "assignPublicIp": "ENABLED",
                              "securityGroups": [
                                  "sg-EXAMPLE"
                              ],
                              "subnets": [
                                  "subnet-EXAMPLEf",
                                  "subnet-EXAMPLE",
                                  "subnet-EXAMPLE"
                              ]
                          }
                      },
                      "rolloutState": "IN_PROGRESS",
                      "rolloutStateReason": "ECS deployment ecs-svc/3763308422771520962 in progress.",
                      "failedLaunchTaskCount": 0,
                      "replacedTaskCount": 0,
                      "serviceConnectConfiguration": {
                          "enabled": true,
                          "namespace": "service-connect",
                          "services": [
                              {
                                  "portName": "nginx",
                                  "clientAliases": [
                                      {
                                          "port": 80
                                      }
                                  ]
                              }
                          ],
                          "logConfiguration": {
                              "logDriver": "awslogs",
                              "options": {
                                  "awslogs-group": "/ecs/service-connect-proxy",
                                  "awslogs-region": "us-west-2",
                                  "awslogs-stream-prefix": "service-connect-proxy"
                              },
                              "secretOptions": []
                          }
                      },
                      "serviceConnectResources": [
                          {
                              "discoveryName": "nginx",
                              "discoveryArn": "arn:aws:servicediscovery:us-west-2:123456789012:service/srv-EXAMPLE"
                          }
                      ]
                  }
              ],
              "roleArn": "arn:aws:iam::123456789012:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
              "version": 0,
              "events": [],
              "createdAt": 1661210032.602,
              "placementConstraints": [],
              "placementStrategy": [],
              "networkConfiguration": {
                  "awsvpcConfiguration": {
                      "assignPublicIp": "ENABLED",
                      "securityGroups": [
                          "sg-EXAMPLE"
                      ],
                      "subnets": [
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE"
                      ]
                  }
              },
              "schedulingStrategy": "REPLICA",
              "enableECSManagedTags": true,
              "propagateTags": "SERVICE",
              "enableExecuteCommand": true
          }
      }
      ```

      您提供的 `serviceConnectConfiguration` 出现在输出的第一个*部署*中。当您以需要更改任务的方式更改 ECS 服务时，Amazon ECS 会创建新的部署。

## 步骤 3：验证是否可以连接
<a name="create-service-connect-verify"></a>

要验证 Service Connect 是否已配置并正常运行，请按照以下步骤从外部应用程序连接到 Web 服务。然后，查看 CloudWatch 中 Service Connect 代理创建的其他指标。

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

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

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

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

  ```
  $ curl -v 10.0.19.50:80/
  *   Trying 10.0.19.50:80...
  * Connected to 10.0.19.50 (10.0.19.50) port 80 (#0)
  > GET / HTTP/1.1
  > Host: 10.0.19.50
  > User-Agent: curl/7.79.1
  > Accept: */*
  >
  * Mark bundle as not supporting multiuse
  < HTTP/1.1 200 OK
  < server: envoy
  < date: Tue, 23 Aug 2022 03:53:06 GMT
  < content-type: text/html
  < content-length: 612
  < last-modified: Tue, 16 Apr 2019 13:08:19 GMT
  < etag: "5cb5d3c3-264"
  < accept-ranges: bytes
  < x-envoy-upstream-service-time: 0
  <
  <!DOCTYPE html>
  <html>
  <head>
  <title>Welcome to nginx!</title>
  <style>
      body {
          width: 35em;
          margin: 0 auto;
          font-family: Tahoma, Verdana, Arial, sans-serif;
      }
  </style>
  </head>
  <body>
  <h1>Welcome to nginx!</h1>
  <p>If you see this page, the nginx web server is successfully installed and
  working. Further configuration is required.</p>
  
  <p>For online documentation and support please refer to
  <a href="http://nginx.org/">nginx.org</a>.<br/>
  Commercial support is available at
  <a href="http://nginx.com/">nginx.com</a>.</p>
  
  <p><em>Thank you for using nginx.</em></p>
  </body>
  </html>
  ```

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

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

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

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


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

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

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

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

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

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

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

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

# 创建使用服务发现的 Amazon ECS 服务
<a name="create-service-discovery"></a>

了解如何创建包含 Fargate 任务的务，该任务将服务发现和 AWS CLI 结合使用。

有关支持服务发现的 AWS 区域 的列表，请参阅 [使用服务发现连接具有 DNS 名称的 Amazon ECS 服务](service-discovery.md)。

有关支持 Fargate 的区域的信息，请参阅 [Amazon ECS 在 AWS Fargate 上的支持区域](AWS_Fargate-Regions.md)。

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

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

在开始本教程之前，请确保满足以下先决条件：
+ 安装并配置了最新版本的 AWS CLI。有关更多信息，请参阅[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ 完成 [设置以使用 Amazon ECS](get-set-up-for-amazon-ecs.md) 中所述的步骤。
+ 您的 IAM 用户具有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 策略示例中指定的必需权限。
+ 您至少创建了一个 VPC 和一个安全组。有关更多信息，请参阅 [创建虚拟私有云](get-set-up-for-amazon-ecs.md#create-a-vpc)。

## 步骤 1：在 AWS Cloud Map 中创建服务发现资源
<a name="create-service-discovery-namespace"></a>

按照以下步骤创建服务发现命名空间和服务发现服务：

1. 创建一个私有 Cloud Map 服务发现命名空间。此示例会创建一个名为 `tutorial` 的命名空间。将 *vpc-abcd1234* 替换为现有 VPC 之一的 ID。

   ```
   aws servicediscovery create-private-dns-namespace \
         --name tutorial \
         --vpc vpc-abcd1234
   ```

   此命令的输出如下。

   ```
   {
       "OperationId": "h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e"
   }
   ```

1. 使用上一步输出中的 `OperationId`，验证私有命名空间是否已经成功创建。记下命名空间 ID，因为您在后续命令中会使用它。

   ```
   aws servicediscovery get-operation \
         --operation-id h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e
   ```

   输出如下所示。

   ```
   {
       "Operation": {
           "Id": "h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e",
           "Type": "CREATE_NAMESPACE",
           "Status": "SUCCESS",
           "CreateDate": 1519777852.502,
           "UpdateDate": 1519777856.086,
           "Targets": {
              "NAMESPACE": "ns-uejictsjen2i4eeg"
           }
       }
   }
   ```

1. 使用上一步输出中的 `NAMESPACE` ID 创建服务发现服务。此示例创建一个名为 `myapplication` 的服务。记下服务 ID 和 ARN，因为您会在后续命令中使用它们。

   ```
   aws servicediscovery create-service \
         --name myapplication \
         --dns-config "NamespaceId="ns-uejictsjen2i4eeg",DnsRecords=[{Type="A",TTL="300"}]" \
         --health-check-custom-config FailureThreshold=1
   ```

   输出如下所示。

   ```
   {
       "Service": {
          "Id": "srv-utcrh6wavdkggqtk",
           "Arn": "arn:aws:servicediscovery:region:aws_account_id:service/srv-utcrh6wavdkggqtk",
           "Name": "myapplication",
           "DnsConfig": {
               "NamespaceId": "ns-uejictsjen2i4eeg",
               "DnsRecords": [
                   {
                       "Type": "A",
                       "TTL": 300
                   }
               ]
           },
           "HealthCheckCustomConfig": {
               "FailureThreshold": 1
           },
           "CreatorRequestId": "e49a8797-b735-481b-a657-b74d1d6734eb"
       }
   }
   ```

## 步骤 2：创建 Amazon ECS 资源
<a name="create-service-discovery-cluster"></a>

使用以下步骤创建您的 Amazon ECS 集群、任务定义和服务：

1. 创建 Amazon ECS 集群。此示例会创建一个名为 `tutorial` 的集群。

   ```
   aws ecs create-cluster \
         --cluster-name tutorial
   ```

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

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

      ```
      {
          "family": "tutorial-task-def",
              "networkMode": "awsvpc",
              "containerDefinitions": [
                  {
                      "name": "sample-app",
                      "image": "public.ecr.aws/docker/library/httpd:2.4",
                      "portMappings": [
                          {
                              "containerPort": 80,
                              "hostPort": 80,
                              "protocol": "tcp"
                          }
                      ],
                      "essential": true,
                      "entryPoint": [
                          "sh",
                          "-c"
                      ],
                      "command": [
                          "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                      ]
                  }
              ],
              "requiresCompatibilities": [
                  "FARGATE"
              ],
              "cpu": "256",
              "memory": "512"
      }
      ```

   1. 使用 `fargate-task.json` 注册任务定义。

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

1. 按照以下步骤创建 ECS 服务：

   1. 使用您将要创建的 ECS 服务的内容，创建名为 `ecs-service-discovery.json` 的文件。此示例会使用在上一步中创建的任务定义。由于示例任务定义使用 `awsvpc` 网络模式，`awsvpcConfiguration` 是必需的。

      创建 ECS 服务时，请指定 Fargate 和支持服务发现的 `LATEST` 平台版本。在 AWS Cloud Map 中创建服务发现服务时，`registryArn` 是返回的 ARN。`securityGroups` 和 `subnets` 必须属于用于创建 Cloud Map 命名空间的 VPC。您可以从 Amazon VPC 控制台获取安全组和子网 ID。

      ```
      {
          "cluster": "tutorial",
          "serviceName": "ecs-service-discovery",
          "taskDefinition": "tutorial-task-def",
          "serviceRegistries": [
             {
                "registryArn": "arn:aws:servicediscovery:region:aws_account_id:service/srv-utcrh6wavdkggqtk"
             }
          ],
          "launchType": "FARGATE",
          "platformVersion": "LATEST",
          "networkConfiguration": {
             "awsvpcConfiguration": {
                "assignPublicIp": "ENABLED",
                "securityGroups": [ "sg-abcd1234" ],
                "subnets": [ "subnet-abcd1234" ]
             }
          },
          "desiredCount": 1
      }
      ```

   1. 使用 `ecs-service-discovery.json` 创建 ECS 服务。

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

## 步骤 3：验证 AWS Cloud Map 中的服务发现
<a name="create-service-discovery-verify"></a>

您可以通过查询您的服务发现信息来验证所有内容是否已正确创建。配置服务发现后，您可以使用 AWS Cloud Map API 操作或从 VPC 内的实例调用 `dig`。按照以下步骤进行操作：

1. 通过使用服务发现服务 ID，列出服务发现实例。记下用于资源清理的实例 ID（以粗体标记）。

   ```
    aws servicediscovery list-instances \
          --service-id srv-utcrh6wavdkggqtk
   ```

   输出如下所示。

   ```
   {
       "Instances": [
           {
               "Id": "16becc26-8558-4af1-9fbd-f81be062a266",
               "Attributes": {
                   "AWS_INSTANCE_IPV4": "172.31.87.2"
                   "AWS_INSTANCE_PORT": "80", 
                   "AVAILABILITY_ZONE": "us-east-1a", 
                   "REGION": "us-east-1", 
                   "ECS_SERVICE_NAME": "ecs-service-discovery", 
                   "ECS_CLUSTER_NAME": "tutorial", 
                   "ECS_TASK_DEFINITION_FAMILY": "tutorial-task-def"
               }
           }
       ]
   }
   ```

1. 使用服务发现命名空间、服务和 ECS 集群名称等其他参数来查询有关服务发现实例的详细信息。

   ```
   aws servicediscovery discover-instances \
         --namespace-name tutorial \
         --service-name myapplication \
         --query-parameters ECS_CLUSTER_NAME=tutorial
   ```

1. 在 Route 53 托管区域中为服务发现服务创建的 DNS 记录可使用以下 AWS CLI 命令进行查询：

   1. 使用命名空间 ID 获取有关命名空间的信息，其中包括 Route 53 托管区域 ID。

      ```
      aws servicediscovery \
            get-namespace --id ns-uejictsjen2i4eeg
      ```

      输出如下所示。

      ```
      {
          "Namespace": {
              "Id": "ns-uejictsjen2i4eeg",
              "Arn": "arn:aws:servicediscovery:region:aws_account_id:namespace/ns-uejictsjen2i4eeg",
              "Name": "tutorial",
              "Type": "DNS_PRIVATE",
              "Properties": {
                   "DnsProperties": {
                      "HostedZoneId": "Z35JQ4ZFDRYPLV"
                  }
              },
              "CreateDate": 1519777852.502,
              "CreatorRequestId": "9049a1d5-25e4-4115-8625-96dbda9a6093"
          }
      }
      ```

   1. 使用上一步中的 Route 53 托管区域 ID（请参阅粗体文本），获取托管区域的资源记录集。

      ```
      aws route53 list-resource-record-sets \
            --hosted-zone-id Z35JQ4ZFDRYPLV
      ```

1. 您还可以使用 `dig` 从 VPC 中的实例查询 DNS。

   ```
   dig +short myapplication.tutorial
   ```

## 步骤 4：清除
<a name="create-service-discovery-cleanup"></a>

完成本教程后，清除相关资源，以避免因未使用的资源产生费用。按照以下步骤进行操作：

1. 使用您之前记下的服务 ID 和实例 ID，注销服务发现服务实例。

   ```
   aws servicediscovery deregister-instance \
         --service-id srv-utcrh6wavdkggqtk \
         --instance-id 16becc26-8558-4af1-9fbd-f81be062a266
   ```

   输出如下所示。

   ```
   {
       "OperationId": "xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv"
   }
   ```

1. 使用上一步输出中的 `OperationId`，验证服务发现服务实例是否已成功注消。

   ```
   aws servicediscovery get-operation \ 
         --operation-id xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv
   ```

   ```
   {
     "Operation": {
           "Id": "xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv",
           "Type": "DEREGISTER_INSTANCE",
           "Status": "SUCCESS",
           "CreateDate": 1525984073.707,
           "UpdateDate": 1525984076.426,
           "Targets": {
               "INSTANCE": "16becc26-8558-4af1-9fbd-f81be062a266",
               "ROUTE_53_CHANGE_ID": "C5NSRG1J4I1FH",
               "SERVICE": "srv-utcrh6wavdkggqtk"
           }
       }
   }
   ```

1. 使用服务 ID 删除服务发现服务。

   ```
   aws servicediscovery delete-service \ 
         --id srv-utcrh6wavdkggqtk
   ```

1. 使用命名空间 ID 删除服务发现命名空间。

   ```
   aws servicediscovery delete-namespace \ 
         --id ns-uejictsjen2i4eeg
   ```

   输出如下所示。

   ```
   {
       "OperationId": "c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj"
   }
   ```

1. 使用上一步输出中的 `OperationId`，验证服务发现命名空间是否已成功删除。

   ```
   aws servicediscovery get-operation \ 
         --operation-id c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj
   ```

   输出如下所示。

   ```
   {
       "Operation": {
           "Id": "c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj",
           "Type": "DELETE_NAMESPACE",
           "Status": "SUCCESS",
           "CreateDate": 1525984602.211,
           "UpdateDate": 1525984602.558,
           "Targets": {
               "NAMESPACE": "ns-rymlehshst7hhukh",
               "ROUTE_53_CHANGE_ID": "CJP2A2M86XW3O"
           }
       }
   }
   ```

1. 将 Amazon ECS 服务的预期数量更新为 `0`。您必须执行此操作才能在下一步中删除该服务。

   ```
   aws ecs update-service \
         --cluster tutorial \
         --service ecs-service-discovery \
         --desired-count 0
   ```

1. 删除 Amazon ECS 服务。

   ```
   aws ecs delete-service \
         --cluster tutorial \
         --service ecs-service-discovery
   ```

1. 删除 Amazon ECS 集群。

   ```
   aws ecs delete-cluster \
         --cluster tutorial
   ```

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1. 选择 **VPC**。

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

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

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

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

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

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

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

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

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

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

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

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

   输出示例：

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

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

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

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

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

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

# 保护您的 Amazon ECS 任务不被横向缩减事件终止
<a name="task-scale-in-protection"></a>

您可以使用 Amazon ECS 任务缩容保护来保护任务，防止任务因服务自动扩缩或部署导致的横向缩减事件而终止。

某些应用程序需要一种机制来保护任务关键型任务不会在利用率低的时段或服务部署期间因横向缩减事件而终止。例如：
+ 您有一个队列处理异步应用程序，例如视频转码任务，即使累积服务利用率很低，其中某些任务也需要运行数小时。
+ 您的游戏应用程序将游戏服务器作为 Amazon ECS 任务运行，即使所有用户都已注销，该任务也需要继续运行，以减少服务器重启的启动延迟。
+ 部署新的代码版本时，需要任务才能继续运行，因为重新处理会很昂贵。

若要防止属于您的服务的任务在横向缩减事件中终止，请将该 `ProtectionEnabled` 属性设置为 `true`。如果将 `ProtectionEnabled` 设置为 true，则默认情况下任务的保护期为 2 小时。然后您可以使用 `ExpiresInMinutes` 属性来自定义保护期限。您可以保护您的任务最少 1 分钟，最多 2880 分钟（48 小时）。如果您使用的是 AWS CLI，则可以指定 `--protection-enabled` 选项。

任务完成其必要工作后，您可以将该 `ProtectionEnabled` 属性设置为 `false`，从而允许任务因随后的横向缩减事件而终止。如果您使用的是 AWS CLI，则可以指定 `--no-protection-enabled` 选项。

## 任务缩容保护机制
<a name="task-scale-in-protection-mechanisms"></a>

您可以使用 Amazon ECS 容器代理端点或 Amazon ECS API 设置和获取任务缩容保护。
+ **Amazon ECS 容器代理端点**

  对于那些可以自行确定是否需要保护的任务，我们建议使用 Amazon ECS 容器代理端点。将此方法用于基于队列或任务处理的工作负载。

  当容器开始处理工作时（例如，通过使用 SQS 消息），您可以通过容器内的任务缩容保护端点路径 `$ECS_AGENT_URI/task-protection/v1/state` 设置 `ProtectionEnabled` 属性。在横向缩减事件期间，Amazon ECS 不会终止此任务。当您的任务完成它的工作后，您可以使用相同的端点清除 `ProtectionEnabled` 属性，从而使任务有资格在随后的横向缩减事件期间终止。

  有关 Amazon ECS 容器代理端点的更多信息，请参阅[Amazon ECS 任务缩容保护端点](task-scale-in-protection-endpoint.md)。
+ **Amazon ECS API**

  如果您的应用程序具有跟踪活动任务状态的组件，则可以使用 Amazon ECS API 来设置和检索任务缩容保护。使用 `UpdateTaskProtection` 将一个或多个任务标记为受保护。使用 `GetTaskProtection` 检索保护状态。

  这种方法的示例是，如果您的应用程序将游戏服务器会话作为 Amazon ECS 任务托管。当用户登录到服务器上的会话（任务）时，您可以将该任务标记为受保护。用户注销后，您可以清除专门针对此任务的保护，也可以定期清除对不再处于活动会话状态的类似任务的保护，具体取决于您保留空闲服务器的要求。

  有关更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [UpdateTaskProtection](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateTaskProtection.html) 和 [GetTaskProtection](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_GetTaskProtection.html)。

您可以将这两种方法结合起来。例如，使用 Amazon ECS 代理端点从容器内设置任务保护，并使用 Amazon ECS API 移除对外部控制器服务的任务保护。

## 注意事项
<a name="task-scale-in-protection-considerations"></a>

在使用任务缩容保护之前，请注意以下几点：
+ 只有通过服务部署的任务才支持任务缩容保护。
+ 对于从 Amazon ECS 托管实例上运行的服务部署的任务，支持任务缩容保护。
+ 建议使用 Amazon ECS 容器代理端点，因为 Amazon ECS 代理具有内置的重试机制和更简单的接口。
+ 您可以通过在已开启保护的任务上调用 `UpdateTaskProtection` 来重置任务缩容保护到期时间。
+ 确定任务需要多长时间才能完成其必要工作，并相应地设置 `expiresInMinutes` 属性。如果您设置的保护到期时间超过必要的时间，则将产生成本，并在部署新任务时面临延迟。
+ Amazon ECS 容器代理 `1.65.0` 或更高版本支持任务缩容保护。通过将代理更新为最新版本，您可以使用较旧版本的 Amazon ECS 容器代理在 Amazon EC2 实例上添加对此功能的支持。有关更多信息，请参阅 [更新 Amazon ECS 容器代理](ecs-agent-update.md)。
+ 部署注意事项：
  + 如果服务使用滚动更新，则将创建新任务，但运行旧版本的任务要等到 `protectionEnabled` 清除或过期后才会终止。您可以将部署配置中的 `maximumPercentage` 参数调整为允许在保护旧任务时创建新任务的值。
  + 如果应用了蓝绿更新，则包含受保护任务的蓝色部署不会被移除（如果任务有 `protectionEnabled`）。流量将转移到即将出现的新任务，而较旧的任务只有在 `protectionEnabled` 被清除或过期时才会被删除。根据 CodeDeploy 或 CloudFormation 更新的超时时间，部署可能会超时，较旧的蓝色任务可能仍然存在。
  + 如果您使用 CloudFormation，则更新堆栈有 3 小时的超时时间。因此，如果您将任务保护设置为 3 小时以上，则您的 CloudFormation 部署可能会导致故障和回滚。

    在您的旧任务受到保护期间，CloudFormation 堆栈会显示 `UPDATE_IN_PROGRESS`。如果任务缩容保护被移除或在 3 小时内过期，则您的部署将成功并变为 `UPDATE_COMPLETE` 状态。如果部署在 `UPDATE_IN_PROGRESS` 状态停滞超过 3 个小时，将会失败并显示 `UPDATE_FAILED` 状态，然后将回滚到旧任务集。
  + 如果受保护的任务使部署（滚动或蓝绿）无法达到稳定状态，Amazon ECS 将发送服务事件，以便您可以采取补救措施。在尝试更新任务的保护状态时，如果您收到 `DEPLOYMENT_BLOCKED` 错误消息，则表示该服务的受保护任务数量超过了该服务所需的任务数。要纠正这个错误，可以执行下列操作：
    + 等待当前的任务保护过期。然后设置任务保护。
    + 确定哪些任务可以停止。然后，对这些任务使用 `UpdateTaskProtection` 并将 `protectionEnabled` 选项设置为 `false`。
    + 增加服务的所需任务计数，以大于受保护任务的数量。

## 任务缩容保护所需的 IAM 权限
<a name="task-scale-in-protection-iam"></a>

该任务必须拥有具有以下权限的 Amazon ECS 任务角色：
+ `ecs:GetTaskProtection`：允许 Amazon ECS 容器代理调用 `GetTaskProtection`。
+ `ecs:UpdateTaskProtection`：允许 Amazon ECS 容器代理调用 `UpdateTaskProtection`。

# Amazon ECS 任务缩容保护端点
<a name="task-scale-in-protection-endpoint"></a>

Amazon ECS 容器代理自动将 `ECS_AGENT_URI` 环境变量注入 Amazon ECS 任务的容器中，以提供与容器代理 API 端点交互的方法。

对于那些可以自行确定是否需要保护的任务，我们建议使用 Amazon ECS 容器代理端点。

当容器开始处理工作时，您可以使用容器内的任务缩容保护端点路径 `$ECS_AGENT_URI/task-protection/v1/state` 设置 `protectionEnabled` 属性。

使用从容器内向此 URI 发出的 PUT 请求以设置任务缩容保护。向此 URI 发出的 GET 请求将返回任务的当前保护状态。

## 任务缩容保护请求参数
<a name="task-scale-in-protection-request"></a>

您可以使用具有以下请求参数的 `${ECS_AGENT_URI}/task-protection/v1/state` 端点设置任务缩容保护。

`ProtectionEnabled`  
指定 `true` 以标记一个保护任务。指定 `false` 以移除保护并使任务符合终止条件。  
类型：布尔值  
是否必需：是

`ExpiresInMinutes`  
任务受保护的分钟数。您可以指定最少 1 分钟到最多 2,880 分钟（48 小时）。在这段时间内，您的任务不会因来自服务自动扩缩或部署的横向缩减事件而终止。在这段时间过后，`protectionEnabled` 参数将设置为 `false`。  
如果您未指定时间，则任务将自动保护 120 分钟（2 小时）。  
类型：整数  
必需：否

以下示例显示了如何设置不同持续时间的任务保护。

**如何在默认时间段内保护任务的示例**

此示例显示了如何在 2 小时的默认时间段内保护任务。

```
curl --request PUT --header 'Content-Type: application/json' ${ECS_AGENT_URI}/task-protection/v1/state --data '{"ProtectionEnabled":true}'
```

**如何保护任务 60 分钟的示例**

此示例显示了如何使用 `expiresInMinutes` 参数保护任务 60 分钟。

```
curl --request PUT --header 'Content-Type: application/json' ${ECS_AGENT_URI}/task-protection/v1/state --data '{"ProtectionEnabled":true,"ExpiresInMinutes":60}'      
```

**如何保护任务 24 小时的示例**

此示例显示了如何使用 `expiresInMinutes` 参数保护任务 24 小时。

```
curl --request PUT --header 'Content-Type: application/json' ${ECS_AGENT_URI}/task-protection/v1/state --data '{"ProtectionEnabled":true,"ExpiresInMinutes":1440}'      
```

**Windows 容器示例**

对于 Windows 容器，可以使用 PowerShell 的 `Invoke-RestMethod` cmdlet 而不是 curl。以下示例显示了与之前 curl 命令等效的 PowerShell 命令。

**如何在默认时间段内保护 Windows 容器任务的示例**

此示例显示了如何使用 PowerShell 在 2 小时的默认时间段内保护任务。

```
Invoke-RestMethod -Uri $env:ECS_AGENT_URI/task-protection/v1/state -Method Put -Body '{"ProtectionEnabled":true}' -ContentType 'application/json'
```

**如何保护 Windows 容器任务 60 分钟的示例**

此示例显示了如何在 PowerShell 中使用 `expiresInMinutes` 参数保护任务 60 分钟。

```
Invoke-RestMethod -Uri $env:ECS_AGENT_URI/task-protection/v1/state -Method Put -Body '{"ProtectionEnabled":true,"ExpiresInMinutes":60}' -ContentType 'application/json'
```

**如何保护 Windows 容器任务 24 小时的示例**

此示例显示了如何在 PowerShell 中使用 `expiresInMinutes` 参数保护任务 24 小时。

```
Invoke-RestMethod -Uri $env:ECS_AGENT_URI/task-protection/v1/state -Method Put -Body '{"ProtectionEnabled":true,"ExpiresInMinutes":1440}' -ContentType 'application/json'
```

PUT 请求返回以下响应。

```
{
  "protection": {
    "ExpirationDate": "2023-12-20T21:57:44.837Z",
    "ProtectionEnabled": true,
    "TaskArn": "arn:aws:ecs:us-west-2:111122223333:task/1234567890abcdef0"
  }
}
```

## 任务缩容保护响应参数
<a name="task-scale-in-protection-response"></a>

以下信息返回自 JSON 响应中的任务缩容保护端点 `${ECS_AGENT_URI}/task-protection/v1/state`。

`ExpirationDate`  
任务保护到期的 epoch 时间。如果任务未受到保护，则此值为 null。

`ProtectionEnabled`  
任务的保护状态。如果为任务启用了横向缩减保护，则值为 `true`。否则为 `false`。

`TaskArn`  
容器所属的任务的完整 Amazon 资源名称（ARN）。

以下示例显示了针对受保护的任务返回的详细信息。

```
curl --request GET ${ECS_AGENT_URI}/task-protection/v1/state
```

对于 Windows 容器，请使用以下 PowerShell 命令获取保护状态：

```
Invoke-RestMethod -Uri $env:ECS_AGENT_URI/task-protection/v1/state -Method Get
```

```
{
    "protection":{
        "ExpirationDate":"2023-12-20T21:57:44Z",
        "ProtectionEnabled":true,
        "TaskArn":"arn:aws:ecs:us-west-2:111122223333:task/1234567890abcdef0"
    }
}
```

发生故障时会返回以下信息。

`Arn`  
任务的 Amazon 资源名称（ARN）。

`Detail`  
与故障相关的详细信息。

`Reason`  
失败的原因。

以下示例显示了针对未受保护的任务返回的详细信息。

```
{
    "failure":{
        "Arn":"arn:aws:ecs:us-west-2:111122223333:task/1234567890abcdef0",
        "Detail":null,
        "Reason":"TASK_NOT_VALID"
    }
}
```

出现异常时会返回以下信息。

`requestID`  
导致异常的 Amazon ECS API 调用的 AWS 请求 ID。

`Arn`  
任务或服务的 Amazon 资源名称（ARN）全名。

`Code`  
错误代码。

`Message`  
错误消息。  
如果出现 `RequestError` 或 `RequestTimeout` 错误，则很可能遇到了联网问题。尝试用于 Amazon ECS 的 VPC 端点。

以下示例显示了发生错误时返回的详细信息。

```
{
    "requestID":"12345-abc-6789-0123-abc",
    "error":{
        "Arn":"arn:aws:ecs:us-west-2:555555555555:task/my-cluster-name/1234567890abcdef0",
        "Code":"AccessDeniedException",
        "Message":"User: arn:aws:sts::444455556666:assumed-role/my-ecs-task-role/1234567890abcdef0 is not authorized to perform: ecs:GetTaskProtection on resource: arn:aws:ecs:us-west-2:555555555555:task/test/1234567890abcdef0 because no identity-based policy allows the ecs:GetTaskProtection action"
    }    
}
```

如果 Amazon ECS 代理由于网络问题或 Amazon ECS 控制面板关闭等原因无法从 Amazon ECS 端点获得响应，则会出现以下错误。

```
{
  "error": {
    "Arn": "arn:aws:ecs:us-west-2:555555555555:task/my-cluster-name/1234567890abcdef0",
    "Code": "RequestCanceled",
    "Message": "Timed out calling Amazon ECS Task Protection API"
  }
}
```

当 Amazon ECS 代理收到来自 Amazon ECS 的节流异常时，就会出现以下错误。

```
{
  "requestID": "12345-abc-6789-0123-abc",
  "error": {
    "Arn": "arn:aws:ecs:us-west-2:555555555555:task/my-cluster-name/1234567890abcdef0",
    "Code": "ThrottlingException",
    "Message": "Rate exceeded"
  }
}
```

# 将故障注入功能用于 Amazon ECS 和 Fargate 工作负载
<a name="fault-injection"></a>

对于 Amazon EC2 和 Fargate 上的 Amazon ECS，都可以使用故障注入功能来测试其应用程序对某些受损场景的响应。您可以使用这些测试提供的信息来优化应用程序的性能和韧性。

启用故障注入功能后，Amazon ECS 容器代理会允许任务访问新的故障注入端点。您需要通过将 `enableFaultInjection` 任务定义参数的值设置为 `true`，从而主动开启后才能使用故障注入功能。默认值为 `false`。

```
{
    ...
   "enableFaultInjection": true
}
```

**注意**  
故障注入仅适用于使用 `awsvpc` 或 `host` 网络模式的任务。  
故障注入功能不支持 Windows。

有关如何在 AWS 管理控制台中启用故障注入的信息，请参阅[使用控制台创建 Amazon ECS 任务定义](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-task-definition.html)。

您需要在 AWS Fault Injection Service 中启用此功能才能进行测试。有关更多信息，请参阅[使用 AWS FIS aws:ecs:task 操作](https://docs.aws.amazon.com/fis/latest/userguide/ecs-task-actions.html)。

**注意**  
如果不使用新的 Amazon ECS 优化型 AMI，或者您有自定义 AMI，请安装以下依赖项：  
`tc`
`sch_netem` 内核模块

# Amazon ECS 故障注入端点
<a name="fault-injection-endpoints"></a>

Amazon ECS 容器代理自动将 `ECS_AGENT_URI` 环境变量注入 Amazon ECS 任务的容器中，以提供与容器代理 API 端点交互的方法。每个端点都包含一个 `/start`、`/stop` 和 `/status` 端点。这些端点仅接受来自已启用故障注入功能的任务的请求，并且每个端点的速率限制为每个容器每 **5** 秒 **1** 个请求。超过此限制将会导致错误。

**注意**  
需要使用 Amazon ECS 代理 `version 1.88.0+` 才能使用故障注入端点。

用于故障注入的三个端点如下：
+ [网络黑洞端口端点](#fis-endpoint-blackhole-ports)
+ [网络丢包端点](#fis-endpoint-packet-loss)
+ [网络延迟端点](#fis-endpoint-latency)

请求成功会生成响应代码 `200`，并且调用 `/start` 端点时会生成一条 `running` 消息，调用 `/stop` 端点时会生成一条 `stopped` 消息，调用 `/status` 端点时会生成一条 `running` 或 `not-running` 消息。

```
{
    "Status": <string>
}
```

请求失败则会返回以下错误代码之一：
+ `400`：请求错误
+ `409`：故障注入请求与另一个正在运行的故障冲突
+ `429`：请求被节流
+ `500`：服务器出现意外错误

```
{
	"Error":  <string message> 
}
```

**注意**  
一次只能注入一个网络延迟故障或一个网络丢包故障。如果尝试注入多个故障，则会导致请求被拒绝。

## 网络黑洞端口端点
<a name="fis-endpoint-blackhole-ports"></a>

`{ECS_AGENT_URI}/fault/v1/network-blackhole-port` 端点会丢弃任务网络命名空间中特定端口和协议的入站或出站流量，并且兼容两种模式：
+ **awsvpc**：更改将应用于任务网络命名空间
+ **host**：更改将应用于容器实例的默认网络命名空间

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-blackhole-port/start
<a name="fis-endpoint-blackhole-ports-start"></a>

此端点会启动网络黑洞端口故障注入，并且具有以下参数：

**端口：**  
用于黑洞端口故障注入的指定端口。

类型：整数

是否必需：是

**协议**  
用于黑洞端口故障注入的协议。

类型：字符串

有效值：`tcp | udp`

是否必需：是

**TrafficType**  
故障注入使用的流量类型。

类型：字符串

有效值：`ingress | egress`

是否必需：是

**SourcesToFilter**  
不受故障影响的 IPv4 或 IPv6 地址或 CIDR 数据块的 JSON 数组。

类型：字符串数组

必需：否

以下示例请求使用 `start` 端点（请将*红色*的值替换为您自己的值）：

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-blackhole-port/start

Http method:POST

Request payload: 
{
    "Port": 1234,
    "Protocol": "tcp|udp",
    "TrafficType": "ingress|egress"
    "SourcesToFilter": ["${IP1}", "${IP2}", ...],
}
```

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-blackhole-port/stop
<a name="fis-endpoint-blackhole-ports-stop"></a>

此端点会停止请求中指定的故障。此端点具有以下参数：

**端口：**  
受应停止的故障影响的端口。

类型：整数

是否必需：是

**协议**  
要用于停止故障的协议。

类型：字符串

有效值：`tcp | udp`

是否必需：是

**TrafficType**  
故障注入使用的流量类型。

类型：字符串

有效值：`ingress | egress`

是否必需：是

以下示例请求使用 `stop` 端点（请将*红色*的值替换为您自己的值）：

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-blackhole-port/stop

Http method: POST

Request payload: 
{
    "Port": 1234,
    "Protocol": "tcp|udp",
    "TrafficType": "ingress|egress", 
}
```

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-blackhole-port/status
<a name="fis-endpoint-blackhole-ports-status"></a>

此端点用于检查故障注入的状态。此端点具有以下参数：

**端口：**  
用于检查故障状态的受影响端口。

类型：整数

是否必需：是

**协议**  
检查故障状态时要使用的协议。

类型：字符串

有效值：`tcp | udp`

是否必需：是

**TrafficType**  
故障注入使用的流量类型。

类型：字符串

有效值：`ingress | egress`

是否必需：是

以下示例请求使用 `status` 端点（请将*红色*的值替换为您自己的值）：

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-blackhole-port/status

Http method: POST

Request payload: 
{
   "Port": 1234,
   "Protocol": "tcp|udp",
   "TrafficType": "ingress|egress",
}
```

## 网络延迟端点
<a name="fis-endpoint-latency"></a>

`{ECS_AGENT_URI}/fault/v1/network-latency` 端点将针对指向特定源的流量为任务的网络接口添加延迟和抖动。此端点兼容两种模式：
+ **awsvpc**：更改将应用于任务网络接口
+ **host**：更改将应用于默认网络接口

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-latency/start
<a name="fis-endpoint-latency-start"></a>

此 `/start` 端点会启动网络延迟故障注入，并且具有以下参数：

**DelayMilliseconds**  
添加到该网络接口以用于故障注入的延迟毫秒数。

类型：整数

是否必需：是

**JitterMilliseConds**  
添加到该网络接口以用于故障注入的抖动毫秒数。

类型：整数

是否必需：是

**来源**  
用于故障注入的目标 IPv4 或 IPv6 地址或 CIDR 数据块的 JSON 数组。

类型：字符串数组

是否必需：是

**SourcesToFilter**  
不受故障影响的 IPv4 或 IPv6 地址或 CIDR 数据块的 JSON 数组。`SourcesToFilter` 的优先级高于 `Sources`。

类型：字符串数组

必需：否

以下示例请求使用 `/start` 端点（请将*红色*的值替换为您自己的值）：

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-latency/start

Http method: POST

Request payload: 
{
    "DelayMilliseconds": 123,
    "JitterMilliseconds": 123,
    "Sources": ["${IP1}", "${IP2}", ...],
    "SourcesToFilter": ["${IP1}", "${IP2}", ...],
}
```

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-latency/stop and /status
<a name="fis-endpoint-latency-stop-status"></a>

`{ECS_AGENT_URI}/fault/v1/network-latency/stop` 端点会停止该故障，然后 `{ECS_AGENT_URI}/fault/v1/network-latency/status` 会检查故障的状态。

以下两个示例请求使用 `/stop` 和 `/status` 端点。两者都使用 `POST HTTP` 方法。

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-latency/stop
```

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-latency/status
```

## 网络丢包端点
<a name="fis-endpoint-packet-loss"></a>

`{ECS_AGENT_URI}/fault/v1/network-packet-loss` 端点将为指定的网络接口添加丢包。此端点兼容两种模式：
+ **awsvpc**：更改将应用于任务网络接口
+ **host**：更改将应用于默认网络接口

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-packet-loss/start
<a name="fis-endpoint-packet-loss-start"></a>

此 `/start` 端点会启动丢包故障注入，并且具有以下参数：

**LossPercent**  
丢包率

类型：整数

是否必需：是

**来源**  
用于故障注入测试的 IPv4 或 IPv6 地址或 CIDR 数据块的 JSON 数组。

类型：字符串数组

是否必需：是

**SourcesToFilter**  
不受故障影响的 IPv4 或 IPv6 地址或 CIDR 数据块的 JSON 数组。`SourcesToFilter` 的优先级高于 `Sources`。

类型：字符串数组

必需：否

以下示例请求使用 `start` 端点（请将*红色*的值替换为您自己的值）：

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-packet-loss/start

Http method: POST

{
    "LossPercent": 6,  
    "Sources": ["${IP1}", "${IP2}", ...],
    "SourcesToFilter": ["${IP1}", "${IP2}", ...],
}
```

### \$1ECS\$1AGENT\$1URI\$1/fault/v1/network-packet-loss/stop and /status
<a name="fis-endpoint-packet-loss-stop-status"></a>

`{ECS_AGENT_URI}/fault/v1/network-packet-loss/stop` 端点会停止该故障，然后 `{ECS_AGENT_URI}/fault/v1/network-packet-loss/status` 会检查故障的状态。一次仅支持一种故障类型。

以下两个示例请求使用 `/stop` 和 `/status` 端点。两者都使用 `POST HTTP` 方法。

```
Endpoint: ${ECS_AGENT_URI}/fault/v1/network-packet-loss/stop
```

```
Endpoint: ${{ECS_AGENT_URI}/fault/v1/network-packet-loss/status
```

# 更新 Amazon ECS 服务参数
<a name="update-service-parameters"></a>

创建服务后，有时可能需要更新服务参数，例如任务数。

当服务计划程序启动新任务时，它会使用以下逻辑确定集群中的任务置放。
+ 确定集群中的哪些容器实例可支持服务的任务定义。例如，它们具有所需的 CPU、内存、端口和容器实例属性。
+ 默认情况下，即使您可以选择不同的置放策略，服务计划程序也会尝试以这种方式在可用区之间平衡任务。
  + 按与实例位于同一可用区中具有此服务运行的任务数最少的顺序对有效容器实例进行排序。例如，如果 A 区有一个正在运行的服务任务，B 区和 C 区都没有正在运行的服务任务，则认为在 B 区或 C 区中的有效容器实例中最适合放置任务。
  + 将新的服务任务放在最佳可用区中的有效容器实例上（基于之前的步骤），并优先使用具有此服务的最小数量的运行任务的容器实例。

当服务计划程序停止运行任务时，它将尝试使用以下逻辑在集群的可用区之间保持均衡：
+ 按与实例位于同一可用区中具有此服务运行的任务数最多的顺序对容器实例进行排序。例如，如果 A 区有 1 个正在运行的服务任务，B 区和 C 区各有 2 个正在运行的服务任务，则认为 B 区或 C 区中的容器实例最适合终止任务。
+ 在最佳可用区中的容器实例上停止任务（基于之前的步骤），并优先使用具有此服务的最大数量的运行任务的容器实例。

使用列表来确定是否可以更改服务参数。

**可用区再平衡**  
指示是否对服务使用可用区域重新平衡。  
您可以更改此参数以进行滚动部署。

**容量提供程序策略**  
容量提供程序策略的详细信息。您可以在创建集群、运行任务或更新服务时设置容量提供程序。  
使用 Fargate 时，容量提供程序为 `FARGATE` 或 `FARGATE_SPOT`。  
当您使用 Amazon EC2 时，容量提供程序为自动扩缩组。  
您可以更改容量提供程序以进行滚动部署和蓝绿部署。  
以下列表提供了有效的转换：  
+ 将 Fargate 更新为自动扩缩组容量提供程序。
+ 将 EC2 更新为 Fargate 容量提供程序。
+ 将 Fargate 容量提供程序更新为自动扩缩组容量提供程序。
+ 将 Amazon EC2 容量提供程序更新为 Fargate 容量提供程序。
+ 将自动扩缩组或 Fargate 容量提供程序更新回启动类型。使用 CLI 或 API 时，您将在 `capacityProviderStrategy` 参数中传递一个空列表。

**集群**  
您无法更改集群名称。

**部署配置**  
部署配置包括 CloudWatch 警报、用于检测故障的断路器以及所需的配置。  
部署断路器属性确定如果服务无法达到稳定状态，服务部署是否会失败。如果使用部署断路器，服务部署将转变为失败状态并停止启动新任务。如果使用回滚选项，当服务部署失败时，服务将回滚到成功完成的最后一个部署。  
当您更新使用 Amazon ECS 断路器的服务时，Amazon ECS 会创建服务部署和服务修订。这些资源允许您查看有关服务历史记录的详细信息。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。  
服务计划程序将使用最小正常百分比和最大百分比参数（在服务的部署配置中）确定部署策略。  
如果服务使用滚动更新（`ECS`）部署类型，**最小正常百分比**以预期任务数的百分比形式表示部署期间必须保持在 `RUNNING` 状态的服务中的任务数的下限（向上取整到最近的整数）。如果服务包含使用 EC2 的任务，则在任何容器实例处于 `DRAINING` 状态时，此参数也适用。可以使用此参数进行部署，而无需使用额外的集群容量。例如，如果您的服务的预期任务数为 4，最小正常百分比为 50%，则计划程序可能在开始两个新任务之前停止两个现有任务以释放集群容量。如果未使用负载均衡器的服务状态为 `RUNNING`，则服务认为任务正常运行。如果使用负载均衡器的服务任务处于 `RUNNING` 状态，并且该负载均衡器将其报告为正常，则服务认为这些任务正常运行。最小正常百分比的默认值为 100%。  
如果服务使用滚动更新（`ECS`）部署类型，则**最大百分比**参数将以预期任务数的百分比形式表示部署期间允许处于 `PENDING`、`RUNNING` 或 `STOPPING` 状态的服务中任务数的上限（向下取整到最近的整数）。如果服务包含使用 EC2 的任务，则在任何容器实例处于 `DRAINING` 状态时，此参数也适用。可以使用此参数定义部署批次大小。例如，如果您的服务的预期任务数为 4，最大百分比值为 200%，则计划程序可能在停止 4 个旧任务之前开始 4 个新任务。这样做的前提是具有执行此操作所需的集群资源。最大百分比的默认值为 200%。  
当服务计划程序在更新期间替换某个任务时，服务首先会从负载均衡器（如果使用了）中删除此任务并等待连接耗尽。然后，将向此任务中运行的容器发出 **docker stop** 的等效项。这将产生 `SIGTERM` 信号和 30 秒的超时，此后，将发送 `SIGKILL` 并强制停止容器。如果容器正常处理了 `SIGTERM` 信号并在收到信号后的 30 秒内退出，则不会发送任何 `SIGKILL` 信号。服务计划程序将启动并停止您的最小正常百分比和最大百分比设置定义的任务。  
在容器运行状况检查或负载均衡器目标组运行状况检查失败后，服务计划程序还会替换被确定为运行状况不佳的任务。此替换取决于 `maximumPercent` 和 `desiredCount` 服务定义参数。如果任务被标记为运行状况不佳，则服务计划程序将首先启动替换任务。然后会发生以下情况。  
+ 如果替换任务的运行状况为 `HEALTHY`，则服务计划程序将停止运行不正常的任务
+ 如果替换任务的运行状况为 `UNHEALTHY`，则计划程序将停止运行状况不佳的替换任务或现有的运行状况不佳任务，以使任务总数等于 `desiredCount`。
如果 `maximumPercent` 参数限制计划程序先启动替换任务，则计划程序将一次随机停止一个运行状况不佳的任务以释放容量，然后启动替换任务。启动和停止过程将继续，直到所有运行状况不佳的任务都被运行状况正常的任务所替换。替换了所有运行状况不佳的任务并且只有运行正常的任务后，如果任务总数超过 `desiredCount`，则会随机停止运行状况正常的任务，直到任务总数等于 `desiredCount`。有关 `maximumPercent` 和 `desiredCount` 的更多信息，请参阅[服务定义参数](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html)。

**部署控制器**  
要用于该服务的部署控制器。部署控制器有三种类型：  
+ `ECS`
+ `EXTERNAL`
+ `CODE_DEPLOY`
更新服务时，可以更新其使用的部署控制器。以下列表提供了有效的转换：  
+ 从 CodeDeploy 蓝绿部署（`CODE_DEPLOY`）更新为 ECS 滚动部署或蓝绿部署（`ECS`）。
+ 从 CodeDeploy 蓝绿部署（`CODE_DEPLOY`）更新为外部部署（`EXTERNAL`）。
+ 从 ECS 滚动部署或蓝绿部署（`ECS`）更新为外部部署（`EXTERNAL`）。
+ 从外部部署（`EXTERNAL`）更新为 ECS 滚动部署或蓝绿部署（`ECS`）。
更新服务的部署控制器时，请考虑以下事项：  
+ 如果服务使用的是 VPC Lattice 或 Amazon ECS Service Connect，则无法将其部署控制器从 `ECS` 更新为任何其他控制器。
+ 如果服务有正在进行的服务部署，则无法更新其部署控制器。
+ 如果服务上没有负载均衡器，则无法将其部署控制器更新为 `CODE_DEPLOY`。
+ 如果 `deploymentConfiguration` 包含警报、部署断路器或 `BLUE_GREEN` 部署策略，则无法将服务的部署控制器从 `ECS` 更新为任何其他控制器。有关更多信息，请参阅 [Amazon ECS 服务部署控制器和策略](ecs_service-options.md)。
+ 如果将服务的部署控制器从 `ECS` 更新为任何其他控制器，Amazon ECS 将不会使用容器定义中为 `versionConsistency` 指定的值。
+ 如果将服务的部署控制器从 `ECS` 更新为任何其他控制器，`UpdateService` 和 `DescribeService` API 响应仍将返回 `deployments` 而非 `taskSets`。有关 `UpdateService` 和 `CreateService` 的更多信息，请参阅《Amazon ECS API 参考》**中的 [UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Service.html) 和 [CreateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Service.html)。
+ 如果服务使用滚动更新部署策略，将部署控制器从 `ECS` 更新为任何其他控制器将改变 `deploymentConfiguration` 中 `maximumPercent` 值的使用方式。`maximumPercent` 不再仅用作滚动更新部署中总任务的上限，而是用于替换运行状况不佳的任务。有关计划程序如何替换运行状况不佳的任务的更多信息，请参阅 [Amazon ECS 服务](ecs_services.md)。
+ 如果将服务的部署控制器从 `ECS` 更新为任何其他部署控制器，则在负载均衡器配置中指定的任何 `advancedConfiguration` 都将被忽略。有关更多信息，请参阅《Amazon ECS API 参考》**中的 [LoadBalancer](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LoadBalancer.html) 和 [AdvancedConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_AdvancedConfiguration.html)。
使用 CloudFormation 更新服务的部署控制器时，请根据所执行的迁移类型考虑以下事项。  
+ 如果 CloudFormation 模板包含 `EXTERNAL` 部署控制器信息以及 `TaskSet` 和 `PrimaryTaskSet` 资源，并且在从 `EXTERNAL` 更新到 `ECS` 时从模板中删除了任务集资源，则在部署控制器更新为 `ECS` 之后，`DescribeTaskSet` 和 `DeleteTaskSet` API 调用将返回 400 错误。这会导致 CloudFormation 任务集资源删除失败，即使 CloudFormation 堆栈转换为 `UPDATE_COMPLETE` 状态，也会失败。有关更多信息，请参阅《AWS CloudFormation 用户指南》中的[资源已从堆栈中移除但未删除](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html#troubleshooting-errors-resource-removed-not-deleted)。要解决此问题，请使用 Amazon ECS `DeleteTaskSet` API 直接删除任务集。有关如何删除任务集的更多信息，请参阅《Amazon Elastic Container Service API 参考****》中的 [DeleteTaskSet](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DeleteTaskSet.html)。
+ 如果使用新任务定义从 `CODE_DEPLOY` 迁移到 `ECS`，并且 CloudFormation 执行回滚操作，则 Amazon ECS `UpdateService` 请求将失败并出现以下错误：

  ```
  Resource handler returned message: "Invalid request provided: Unable to update 
  task definition on services with a CODE_DEPLOY deployment controller. Use AWS 
  CodeDeploy to trigger a new deployment. (Service: Ecs, Status Code: 400, 
  Request ID: 0abda1e2-f7b3-4e96-b6e9-c8bc585181ac) (SDK Attempt Count: 1)" 
  (RequestToken: ba8767eb-c99e-efed-6ec8-25011d9473f0, HandlerErrorCode: InvalidRequest)
  ```
+ 从 `ECS` 成功迁移到 `EXTERNAL` 部署控制器后，需要手动删除 `ACTIVE` 任务集，因为 Amazon ECS 将不再管理该部署。有关如何删除任务集的信息，请参阅《Amazon Elastic Container Service API 参考**》中的 [DeleteTaskSet](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DeleteTaskSet.html)。

**预期任务计数**  
在您的服务中置放并保持运行的实例化任务数量。  
如果要暂时停止服务，请将该值设置为 0。然后，当您准备好启动服务时，请使用原始值更新该服务。  
您可以更改此参数以进行滚动部署和蓝绿部署。

**启用托管标签**  
确定是否要为该服务中的任务启用 Amazon ECS 托管标签。  
只有在更新后启动的任务才会反映更新。要更新所有任务的标签，请使用强制部署选项。  
您可以更改此参数以进行滚动部署和蓝绿部署。

**启用 ECS Exec**  
确定是否使用 Amazon ECS Exec。  
如果您不想覆盖创建服务时设置的值，则可以在执行此操作时将其设置为空。  
您可以更改此参数以进行滚动部署。

**运行状况检查宽限期**  
任务首次启动后的一段时间（以秒为单位），在此段时间内，Amazon ECS 服务计划程序将忽略未正常运行的 Elastic Load Balancing、VPC Lattice 和容器运行状况检查。如果没有指定运行状况检查宽限期值，则使用默认值 `0`。如果不使用任何运行状况检查，则未使用 `healthCheckGracePeriodSeconds`。  
如果服务的任务需要一段时间才能启动和响应运行状况检查，则您可以指定最长 2147483647 秒（大约 69 年）的运行状况检查宽限期。在此期间，Amazon ECS 服务计划程序忽略运行状况检查状态。此宽限期可防止服务计划程序将由于时间不足尚未启动的任务标记为不正常并停止它们。  
您可以更改此参数以进行滚动部署和蓝绿部署。

**负载均衡器**  
更新负载均衡器时，必须使用服务相关角色。  
Elastic Load Balancing 负载均衡器对象列表。它包含负载均衡器名称、容器名称和要从负载均衡器访问的容器端口。容器名称与在容器定义中显示的名称相同。  
Amazon ECS 不会自动更新与 Elastic Load Balancing 负载均衡器或 Amazon ECS 容器实例关联的安全组。  
当您添加、更新或删除负载均衡器配置时，Amazon ECS 会使用更新后的 Elastic Load Balancing 配置启动新任务，然后在新任务运行时停止旧任务。  
对于使用滚动更新的服务，您可以添加、更新或删除 Elastic Load Balancing 目标组。您可以从单个目标组更新为多个目标组，也可以从多个目标组更新为单个目标组。  
对于使用蓝绿部署的服务，您可以通过 CodeDeploy 使用 `[CreateDeployment](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_CreateDeployment.html)` 更新 Elastic Load Balancing 目标组。请注意，蓝绿部署不支持多个目标组。有关详细信息，请参阅[向服务注册多个目标组](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/register-multiple-targetgroups.html)。  
对于使用外部部署控制器的服务，您可以使用 [CreateTaskSet](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateTaskSet.html) 添加、更新或删除负载均衡器。请注意，外部部署不支持多个目标组。有关详细信息，请参阅[向服务注册多个目标组](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/register-multiple-targetgroups.html)。  
传递一个空列表以删除负载均衡器。  
您可以更改此参数以进行滚动部署。

**网络配置**  
服务网络配置。  
您可以更改此参数以进行滚动部署。

**置放约束**  
用于更新要使用的服务的任务置放约束对象数组。如果未指定任何值，则服务的现有置放约束将保持不变。如果指定了该值，它将覆盖为服务定义的所有现有置放约束。要删除所有现有置放约束，请指定空数组。  
您可以为每个任务指定最多 10 个约束。此限制包括任务定义中的约束以及在运行时指定的约束。  
您可以更改此参数以进行滚动部署和蓝绿部署。

**置放策略**  
用于更新要使用的服务的任务置放策略对象。如果未指定任何值，则服务的现有置放策略将保持不变。如果指定了该值，则它将覆盖为服务定义的现有置放策略。要删除现有的置放策略，请指定一个空对象。  
您可以更改此参数以进行滚动部署和蓝绿部署。

**平台版本**  
运行您的服务的 Fargate 平台版本。  
使用 Linux 平台版本的服务无法更新为使用 Windows 平台版本，反之亦然。  
您可以更改此参数以进行滚动部署。

**传播标签**  
确定是否要将标签从任务定义或服务传播到任务。如果未指定任何值，则不会传播标签。  
只有在更新后启动的任务才会反映更新。要更新所有任务的标签，请将 `forceNewDeployment` 设置为 `true`，以便 Amazon ECS 使用更新的标签启动新任务。  
您可以更改此参数以进行滚动部署和蓝绿部署。

**Service Connect 配置**  
Amazon ECS Service Connect 的配置。此参数决定服务如何连接到应用程序中的其他服务。  
您可以更改此参数以进行滚动部署。

**服务注册表**  
更新服务注册表时，必须使用服务相关角色。  
要分配给此服务的服务发现注册表的详细信息。有关更多信息，请参阅[服务发现](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html)。  
当您添加、更新或删除服务注册表配置时，Amazon ECS 会使用更新后的服务注册表配置启动新任务，然后在新任务运行时停止旧任务。  
传递一个空列表以删除服务注册表。  
您可以更改此参数以进行滚动部署。

**任务定义**  
用于服务的任务定义和修订。  
如果要在任务定义中更改容器使用的端口，您可能需要更新容器实例的安全组以使用更新后的端口。  
如果您更新服务的任务定义，则在负载均衡器中指定的容器名称和容器端口必须保留在任务定义中。  
容器映像拉取行为因计算选项而异。有关更多信息，请参阅以下任一文档：  
+ [面向 Amazon ECS 的 AWS Fargate 架构](AWS_Fargate.md)
+ [Amazon ECS 的 EC2 容量架构](launch-type-ec2.md)
+ [Amazon ECS 的外部（Amazon ECS Anywhere）](launch-type-external.md)
您可以更改此参数以进行滚动部署。

**卷配置**  
为 `configuredAtLaunch` 的卷的详细信息。当任务定义中的 `configuredAtLaunch` 设置为 `true` 时，此服务参数会为服务中的每个任务配置一个 Amazon EBS 卷，该卷将在部署期间创建并附加。您可以在 [ServiceManagedEBSVolumeConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ServiceManagedEBSVolumeConfiguration.html) 中配置大小、卷类型、IOPS、吞吐量、快照和加密。卷的 `name` 必须与任务定义中的 `name` 相匹配。如果设置为空，则不会触发任何新部署。否则，如果此配置与现有配置不同，则会触发新的部署。  
您可以更改此参数以进行滚动部署。

**VPC Lattice 配置**  
服务的 VPC Lattice 配置。这定义了您的服务如何与 VPC Lattice 集成以进行服务间通信。  
您可以更改此参数以进行滚动部署。

## AWS CDK 注意事项
<a name="cdk-considerations"></a>

AWS CDK 不跟踪资源状态。它不知道您是在创建还是更新服务。客户应使用转义孵化直接访问 ecs `Service` L1 构造。

有关转义孵化的信息，请参阅《AWS Cloud Development Kit (AWS CDK) v2 开发人员指南》**中的[自定义 AWS 构造库中的构造](https://docs.aws.amazon.com/cdk/v2/guide/cfn-layer.html#develop-customize-escape)。

要将现有服务迁移到 `ecs.Service` 构造中，请执行以下操作：

1. 使用转义孵化访问 `Service` L1 构造。

1. 在 `Service` L1 构造中手动设置以下属性。

   如果您的服务使用 Amazon EC2 容量：
   + `daemon?`
   + `placementConstraints?`
   + `placementStrategies?`
   + 如果使用 `awsvpc` 网络模式，则需要设置 `vpcSubnets?` 和 `securityGroups?` 构造。

   如果您的服务使用 Fargate：
   + `FargatePlatformVersion`
   + `vpcSubnets?` 和 `securityGroups?` 构造。

1. 按如下方式设置 `launchType`：

   ```
   const cfnEcsService = service.node.findChild('Service') as ecs.CfnService;
   cfnEcsService.launchType = "FARGATE";
   ```

要从启动类型迁移到容量提供程序，请执行以下操作：

1. 使用转义孵化访问 `Service` L1 构造。

1. 添加 `capacityProviderStrategies?` 构造。

1. 部署服务。

# 更新 Amazon ECS 服务
<a name="update-service-console-v2"></a>

创建服务后，有时可能需要更新服务参数，例如任务数。

当您更新使用 Amazon ECS 断路器的服务时，Amazon ECS 会创建服务部署和服务修订。这些资源允许您查看有关服务历史记录的详细信息。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。

## 先决条件
<a name="update-service-prerequisites"></a>

更新服务前，请确认您的部署类型可以更改哪些服务参数。要获得参数的完整列表，请参阅[更新 Amazon ECS 服务参数](update-service-parameters.md)。

## 过程
<a name="update-service-procedure"></a>

------
#### [ Console ]

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

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

1. 在集群详细信息页面上的**服务**部分，选中服务旁边的复选框，然后选择**更新**。

1. 要让您的服务开始新的部署，请选择 **Force new deployment**（强制执行新部署）。

1. 对于**任务定义**，选择任务定义系列和修订。
**重要**  
控制台验证所选任务定义系列和修订与定义的计算配置兼容。如果收到警告，请验证任务定义兼容性和您选择的计算配置。

1. 如果您对于 **Desired tasks**（预期任务）使用 **Replica**（副本），输入要在服务中启动并保留的任务数量。

1. 如果您选择**副本**，要让 Amazon ECS 监控在可用区之间的任务分配情况，并在出现不平衡时重新分配任务，请在**可用区服务重新平衡**下选择**可用区服务重新平衡**。

1. 对于**Min running tasks**（最小运行任务数），输入服务中在部署期间必须保持 `RUNNING` 状态的任务数的下限，以所需任务数的百分比表示（四舍五入到最接近的整数）。有关更多信息，请参阅[部署配置](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html#sd-deploymentconfiguration)。

1. 对于 **Max running tasks**（最大运行任务数），输入部署期间 `RUNNING` 或 `PENDING` 状态下允许的服务中任务数的上限，以所需任务数的百分比表示（四舍五入到最接近的整数）。

1. 要配置服务的任务部署方式，请展开**部署选项**，然后配置选项。

   1. 对于**部署控制器类型**，指定服务部署控制器。Amazon ECS 控制台支持以下控制器类型：`ECS`。

   1. 对于**部署策略**，选择 Amazon ECS 用于部署服务新版本的策略。

   1. 根据选择的**部署策略**，执行以下操作：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/update-service-console-v2.html)

   1. 要在生命周期阶段运行 Lambda 函数，请在**部署生命周期挂钩**下为每个唯一的 Lambda 函数执行以下操作：

      1. 选择**添加**。

         对每个要运行的唯一函数重复此操作。

      1. 对于 **Lambda 函数**，输入函数名称。

      1. 对于**角色**，选择在先决条件中创建的具有蓝绿权限的角色。

         有关更多信息，请参阅 [Amazon ECS 蓝绿部署中 Lambda 函数所需的权限](blue-green-permissions.md)。

      1. 对于**生命周期阶段**，选择 Lambda 函数运行的阶段。

      1.  （可选）对于**挂钩详细信息**，输入包含挂钩相关信息的键值对。

1. 要配置 Amazon ECS 如何检测和处理部署故障，请展开 **Deployment failure detection**（部署故障检测），然后选择您的选项。

   1. 要在任务无法启动时停止部署，请选择 **Use the Amazon ECS deployment circuit breaker**（使用 Amazon ECS 部署断路器）。

      要让软件在部署断路器将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

   1. 要根据应用程序指标停止部署，请选择**使用 CloudWatch 警报**。然后，从 **CloudWatch 警报名称**中选择警报。要创建新报警，请转到 CloudWatch 控制台。

      要让软件在 CloudWatch 警报将部署设置为故障状态时自动将部署回滚到上次完成的部署状态，请选择**故障时回滚**。

1. 要更改计算选项，请展开**计算配置**，然后执行以下操作：

   1. 对于 AWS Fargate 上的服务，请在 **Platform version**（平台版本）中选择新版本。

   1. 对于使用容量提供程序策略的服务，请对**容量提供程序策略**执行以下操作：
      + 要添加其他容量提供程序，请选择**添加更多**。然后，对于**容量提供程序**，请选择容量提供程序。
      + 要移除容量提供程序，请在容量提供商程序的右侧选择**删除**。

      使用自动扩缩组容量提供程序的服务无法更新为使用 Fargate 容量提供程序。使用 Fargate 容量提供程序的服务无法更新为使用自动扩缩组容量提供程序。

1. （可选）要配置服务自动扩缩，请展开**服务自动扩缩**，然后指定以下参数。要使用预测式自动扩缩（这将检查流量中的历史负载数据），请在创建服务后对其进行配置。有关更多信息，请参阅 [使用历史模式通过预测式扩缩来扩展 Amazon ECS 服务](predictive-auto-scaling.md)。

   1. 要使用服务自动扩缩，请选择**服务自动扩缩**。

   1. 对于**最小任务数**，输入供服务自动扩缩使用的任务数的下限。所需计数不会低于此计数。

   1. 对于**最大任务数**，输入供服务自动扩缩使用的任务数的上限。所需计数不会高于此计数。

   1. 选择策略类型。在**扩展策略类型**下，选择以下选项之一。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/update-service-console-v2.html)

1. （可选）要使用 Service Connect，请选择 **Turn on Service Connect**（开启 Service Connect），然后指定以下内容：

   1. 在 **Service Connect configuration**（Service Connect 配置）下，指定客户端模式。
      + 如果您的服务运行的网络客户端应用程序只需要连接到命名空间中的其他服务，请选择**仅限客户端**。
      + 如果您的服务运行网络或 Web 服务应用程序且需要为该服务提供端点并连接到命名空间中的其他服务，请选择 **Client and server**（客户端和服务器）。

   1. 要使用默认集群命名空间以外的命名空间，对于**命名空间**，请选择服务命名空间。这可以是您在 AWS 账户的同一 AWS 区域中单独创建的命名空间，也可以是使用 AWS Resource Access Manager（AWS RAM）与您的账户共享的同一区域中的命名空间。有关共享 AWS Cloud Map 命名空间的更多信息，请参阅《AWS Cloud Map 开发人员指南》**中的 [Cross-account AWS Cloud Map namespace sharing](https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html)

   1. （可选）指定日志配置。选择**使用日志收集**。默认选项将容器日志发送到 CloudWatch Logs。其他日志驱动程序选项都使用 AWS FireLens 进行配置。有关更多信息，请参阅 [将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner](using_firelens.md)。

      下面更详细地介绍了每个容器日志目标。
      + **Amazon CloudWatch** – 将任务配置为将容器日志发送到 CloudWatch Logs。提供了默认的日志驱动程序选项，用于代表您创建 CloudWatch 日志组。要指定其他日志组名称，请更改驱动程序选项值。
      + **Amazon Data Firehose** – 将任务配置为将容器日志发送到 Firehose。提供了默认的日志驱动程序选项，这些选项将日志发送到 Firehose 传输流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon Kinesis Data Streams** – 将任务配置为将容器日志发送到 Kinesis Data Streams。提供了默认的日志驱动程序选项，这些选项将日志发送到 Kinesis Data Streams 流。要指定其他传输流名称，请更改驱动程序选项值。
      + **Amazon OpenSearch Service** – 将任务配置为将容器日志发送到 OpenSearch Service 域。必须提供日志驱动程序选项。
      + **Amazon S3** – 将任务配置为将容器日志发送到 Amazon S3 存储桶。提供了默认的日志驱动程序选项，但您必须指定有效的 Amazon S3 存储桶名称。

   1. 要启用访问日志，请按照以下步骤进行操作：

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

      1. 要在访问日志中包括查询参数，请选择**包括查询参数**。
**注意**  
要禁用访问日志，请在**格式**中选择**无**。

1. 如果您的任务使用的数据卷与部署时的配置兼容，则可以通过扩展**卷**来配置该卷。

   卷名称和卷类型在您创建任务定义修订时配置，在更新服务时无法更改。要更新卷名称和类型，您必须创建新的任务定义修订并使用新修订更新服务。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/update-service-console-v2.html)

1. （可选）为了帮助识别您的服务，请展开**标签**部分，然后配置您的标签。
   + [添加标签] 选择**添加标签**，然后执行以下操作：
     + 对于 **Key（键）**，输入键名称。
     + 对于**值**，输入键值。
   + [删除标签] 在标签旁，选择**删除标签**。

1. 选择**更新**。

------
#### [ AWS CLI ]
+ 运行 `update-service`。有关运行该命令的信息，请参阅《AWS Command Line Interface Reference》中的 [update-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html)。

  以下 `update-service` 示例将服务 `my-http-service` 所需的任务计数更新为 2。

  将 *user-input* 替换为您的值。

  ```
  aws ecs update-service \
      --cluster MyCluster \
      --service my-http-service \
      --desired-count 2
  ```

------

## 后续步骤
<a name="update-service-next-steps"></a>

跟踪部署并查看使用 Amazon ECS 断路器的服务的服务历史记录。有关更多信息，请参阅 [使用 Amazon ECS 服务部署查看服务历史记录](service-deployment.md)。

# 更新 Amazon ECS 服务以使用容量提供程序
<a name="update-service-managed-instances"></a>

如果您已有服务使用 Amazon EC2 或 Fargate 启动类型，并且您想要使用 Amazon ECS 托管实例，则需要更新服务以使用您的 Amazon ECS 托管实例容量提供程序。

## 先决条件
<a name="update-service-managed-instances-prerequisites"></a>

为您的 Amazon ECS 托管实例创建容量提供程序。有关更多信息，请参阅 [为 Amazon ECS 托管实例创建容量提供程序](create-capacity-provider-managed-instances.md)。

## 过程
<a name="update-service-managed-instances-procedure"></a>

------
#### [ Console ]

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

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

1. 在集群详细信息页面上的**服务**部分，选中服务旁边的复选框，然后选择**更新**。

1. 选择**强制新部署**。

1. 在**计算配置**下，选择容量提供程序策略。然后，选择下列选项之一：
   + 如果您的 Amazon ECS 托管实例容量提供程序是默认容量提供程序，请选择**使用集群默认值**。
   + 如果您的 Amazon ECS 托管实例容量提供程序不是默认容量提供程序，请选择**使用自定义值（高级）**。选择您的 Amazon ECS 托管实例容量提供程序，然后对于**权重**，请选择 1。

1. 选择**更新**。

------
#### [ AWS CLI ]
+ 运行 `update-service`。有关运行该命令的信息，请参阅《AWS Command Line Interface Reference》中的 [update-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html)。

  将 *user-input* 替换为您的值。

  ```
  aws ecs update-service \
      --cluster my-cluster \
      --service my-service \
      --capacity-provider-strategy capacityProvider=my-managed-instance-capacity-provider,weight=1 \
      --force-new-deployment
  ```

------

# 使用控制台删除 Amazon ECS 服务
<a name="delete-service-v2"></a>

以下是删除服务的一些原因：
+ 已不再需要该应用程序
+ 您正在将服务迁移到新环境
+ 该应用程序不经常使用
+ 该应用程序使用的资源超出了需求，您正在努力优化成本

在删除之前，服务会自动缩减到零。与服务关联的负载均衡器资源或服务发现资源不受服务删除的影响。要删除 Elastic Load Balancing 资源，请参阅以下主题之一，具体取决于负载均衡器类型：[删除应用程序负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-delete.html)或[删除网络负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-delete.html)。

当您删除服务时，Amazon ECS 会删除该服务的所有服务部署和服务修订。

删除服务后，如果仍有需要清除的运行任务，服务状态会从 `ACTIVE` 转变为 `DRAINING`，并且服务在控制台或 `ListServices` API 操作中不再可见。所有任务都变为 `STOPPING` 或 `STOPPED` 状态后，服务状态将从 `DRAINING` 变为 `INACTIVE`。处于 `DRAINING` 或 `INACTIVE` 状态的服务仍然可使用 `DescribeServices` API 操作查看。

**重要**  
如果您尝试创建与处于 `ACTIVE` 或 `DRAINING` 状态的现有服务同名的新服务，则会收到错误消息。

**过程**

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

1. 在 **Clusters**（集群）页面上，选择服务的集群。

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

1. 在 **Cluster : *name***（集群：名称）页面上，选择 **Services**（服务）选项卡。

1. 选择服务，然后选择 **Delete**（删除）。

1. 要删除没有缩减至零任务的服务，请选择**强制删除服务**。

1. 在确认提示符处，输入 **delete**，然后选择**删除**。

# 将 Amazon ECS 短服务 ARN 迁移到长 ARN
<a name="service-arn-migration"></a>

Amazon ECS 为每个服务分配一个唯一的 Amazon 资源名称（ARN）。2021 年之前创建的服务采用短 ARN 格式：

 `arn:aws:ecs:region:aws_account_id:service/service-name`

Amazon ECS 已将 ARN 格式更改为包含集群名称。这是一种长 ARN 格式：

`arn:aws:ecs:region:aws_account_id:service/cluster-name/service-name`

您的服务必须使用长 ARN 格式才能标记服务。

可以将短 ARN 格式的服务迁移到长 ARN 格式，而无需重新创建服务。您可以使用 API、CLI 或控制台。您不能撤消迁移操作。

迁移过程是无缝的，可确保服务零停机时间。迁移期间：
+ **服务可用性**：服务继续正常运行，流量或功能不会中断。
+ **正在运行的任务**：现有任务可以继续运行，不会中断。如果启用了 `taskLongArnFormat` 账户设置，迁移后启动的新任务将使用长 ARN 格式。
+ **容器实例**：容器实例不受服务 ARN 迁移的影响，可以继续正常运行。
+ **服务配置**：所有服务设置，包括任务定义、网络和负载均衡器配置，均保持不变。

如果要使用 CloudFormation 标记简短 ARN 格式的服务，则必须使用 API、CLI 或控制台迁移该服务。迁移完成后，您可以使用 CloudFormation 标记服务。

如果要使用 Terraform 标记简短 ARN 格式的服务，则必须使用 API、CLI 或控制台迁移该服务。迁移完成后，您可以使用 Terraform 标记服务。

完成迁移后，服务将具有以下更改：
+ 长 ARN 格式

  `arn:aws:ecs:region:aws_account_id:service/cluster-name/service-name`
+ 当您使用控制台进行迁移时，Amazon ECS 会向服务添加一个标签，其键设置为“ecs:serviceArnMigratedAt”，值设置为迁移时间戳（UTC 格式）。

  此标签计入您的标签配额。
+ 当 CloudFormation 堆栈中的 `PhysicalResourceId` 表示服务 ARN 时，该值不会更改，并且将继续作为短服务 ARN。

## 先决条件
<a name="migrate-service-arn-prerequisite"></a>

在迁移服务 ARN 之前执行以下操作。

1. 要查看您的服务 ARN 是否较短，请在 Amazon ECS 控制台中查看服务详细信息（当服务采用短 ARN 格式时，您会看到警告），或者查看来自 `describe-services` 的 `serviceARN` 返回参数。当 ARN 不包含集群名称时，您就有一个短 ARN。短 ARN 的格式如下所示：

    `arn:aws:ecs:region:aws_account_id:service/service-name`

1. 记下已创建日期。

1.  如果您的 IAM 策略使用的是短 ARN 格式，则请将其更新为长 ARN 格式。

   将每个*用户输入占位符*替换为您自己的信息。

    `arn:aws:ecs:region:aws_account_id:service/cluster-name/service-name`

   有关更多信息，请参阅《AWS Identity and Access Management 用户指南》**中的[编辑 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-edit.html)。

1.  如果您的工具使用的是短 ARN 格式，则请将其更新为长 ARN 格式。

   将每个*用户输入占位符*替换为您自己的信息。

    `arn:aws:ecs:region:aws_account_id:service/cluster-name/service-name`

1. 启用服务长 ARN 格式。在 `serviceLongArnFormat` 选项设置为 `enabled` 的情况下运行 `put-account-setting`。有关更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [put-account-setting](https://docs.aws.amazon.com/cli/latest/reference/ecs/put-account-setting.html)。

   当您的服务有未知 `createdAt` 日期时，以根用户身份运行该命令。

   ```
   aws ecs put-account-setting --name serviceLongArnFormat --value enabled
   ```

    输出示例

   ```
   {
       "setting": {
           "name": "serviceLongArnFormat",
           "value": "enabled",
           "principalArn": "arn:aws:iam::123456789012:role/your-role",
           "type": user
       }
   }
   ```

1. 启用任务长 ARN 格式。此账户设置会控制服务迁移完成后启动的新任务的 ARN 格式。在 `taskLongArnFormat` 选项设置为 `enabled` 的情况下运行 `put-account-setting`。有关更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [put-account-setting](https://docs.aws.amazon.com/cli/latest/reference/ecs/put-account-setting.html)。

   当您的服务有未知 `createdAt` 日期时，以根用户身份运行该命令。

   ```
   aws ecs put-account-setting --name taskLongArnFormat --value enabled
   ```

    输出示例

   ```
   {
       "setting": {
           "name": "taskLongArnFormat",
           "value": "enabled",
           "principalArn": "arn:aws:iam::123456789012:role/your-role",
           "type": user
       }
   }
   ```
**注意**  
`taskLongArnFormat` 设置不会直接迁移现有任务，仅会影响在启用该设置后创建的新任务的 ARN 格式。现有的正在运行的任务会保留当前的 ARN 格式，直到正常的服务操作（例如部署或扩展活动）将其替换。

## 过程
<a name="migrate-service-arn-procedure"></a>

使用以下内容迁移您的服务 ARN。

### 控制台
<a name="migrate-service-arn-procedure-console"></a>

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

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

1. 在**服务**部分中，选择 ARN 列中包含警告的服务。

   此时系统会显示服务详细信息页面。

1. 选择**迁移到长 ARN**。

   将显示“迁移服务”对话框。

1. 选择 **Migrate**。

### CLI
<a name="migrate-service-arn-procedure-cli"></a>

完成先决条件后，您可以标记服务。运行如下命令：

Amazon ECS 考虑在带有短 ARN 的服务的 `tag-resource` API 请求中传递长 ARN 格式，作为将服务迁移到使用长 ARN 格式的信号。

```
aws ecs tag-resource \
    --resource-arn arn:aws:ecs:region:aws_account_id:service/cluster-name/service-name
    --tags key=key1,value=value1
```

以下示例使用键设置为“TestService”、值设置为“WebServers”的标签来标记 MyService：

```
aws ecs tag-resource \
    --resource-arn arn:aws:ecs:us-east-1:123456789012:service/MyCluster/MyService
    --tags key=TestService1,value=WebServers
```

### Terraform
<a name="migrate-service-arn-procedure-terraform"></a>

完成先决条件后，您可以标记服务。创建 `aws_ecs_service` 资源并设置 `tags` 引用。有关更多信息，请参阅 Terraform 文档中的 [Resource: aws\$1ecs\$1service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service)。

```
resource "aws_ecs_service" "MyService" {
  name    = "example"
  cluster = aws_ecs_cluster.MyService.id

 tags = {
 "Name"  =  "MyService"
 "Environment"  =  "Production"
 "Department"  =  "QualityAssurance"
  }
}
```

### 后续步骤
<a name="tag-next-steps"></a>

您可以向服务添加标签。有关更多信息，请参阅 [向 Amazon ECS 资源添加标签](tag-resources-console.md)。

如果您希望 Amazon ECS 将标签从任务定义或服务传播到任务中，则请使用 `propagateTags` 参数运行 `update-service`。有关更多信息，请参阅《AWS Command Line Interface 参考》**中的 [update-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html)。

## 问题排查
<a name="troubleshooting-arn-migration"></a>

 一些用户在从短 ARN 格式迁移到长 ARN 格式时可能会遇到以下错误。

`There was an error while migrating the ARN of service service-name. The specified account does not have serviceLongArnFormat or taskLongArnFormat account settings enabled. Add account settings in order to enable tagging.` 

 如果您已经启用了 `serviceLongArnFormat` 账户设置，但仍然遇到此错误，则可能是因为最初创建服务的特定 IAM 主体尚未启用长 ARN 格式的账户设置。

1.  确定创建服务的主体。

   1. 在控制台中，可以在 Amazon ECS 控制台的“服务详细信息”页面的**配置和网络**选项卡中的**创建者**字段中找到该信息。

   1. 对于 AWS CLI，运行下面的命令：

      将 *user-input* 替换为您的值。

      ```
      aws ecs describe-services --cluster cluster-name --services service-name --query 'services[0].{createdBy: createdBy}'
      ```

1. 为该特定主体启用所需的账户设置。您可以通过下列方式之一来执行该操作：

   1.  代入该主体的 IAM 用户或角色。然后运行 `put-account-setting`。

   1.  使用根用户运行命令，同时使用 `principal-arn` 指定创建主体。

      示例。

      将 *principal-arn* 替换为步骤 1 中的值。

      ```
      aws ecs put-account-setting --name serviceLongArnFormat --value enabled --principal-arn arn:aws:iam::123456789012:role/jdoe
      ```

 这两种方法都会在创建服务的主体上启用所需的 `serviceLongArnFormat` 账户设置，从而允许 ARN 迁移继续进行。

# Amazon ECS 服务节流逻辑
<a name="service-throttle-logic"></a>

Amazon ECS 服务计划程序包含保护性逻辑，当任务反复启动失败后，会限制任务启动频率。这有助于防止不必要的资源消耗并降低成本。

如果服务中的任务未从 `PENDING` 状态转换为 `RUNNING` 状态，而是直接进入 `STOPPED` 状态，计划程序会执行以下操作：
+ 逐渐延长重启尝试间隔的时间
+ 持续增加延迟时间，直至最长尝试间隔延长至 27 分钟
+ 生成服务事件消息以通知您出现此问题

**注意**  
27 分钟的最长延迟间隔可能会在未来的更新中更改。

节流激活后，会收到以下服务事件消息：

```
(service service-name) is unable to consistently start tasks successfully.
```

节流逻辑的重要特征：
+ 服务会无限期地继续重试
+ 唯一的变化是延长了重启间隔的时间
+ 没有用户可配置的参数

## 解决节流问题
<a name="resolving-throttling"></a>

要解决节流问题，可以：
+ 更新服务以使用新的任务定义，这将使服务立即恢复为正常的无节流操作状态。有关更多信息，请参阅 [更新 Amazon ECS 服务](update-service-console-v2.md)。
+ 解决导致任务失败的根本原因。

触发节流的常见任务失败原因包括：
+ 集群资源（端口、内存或 CPU）不足
  + 由[资源服务不足的事件消息](service-event-messages-list.md#service-event-messages-1)表示
+ 容器映像拉取失败
  + 可能由无效的映像名称、标签或权限不足引起
  + 导致在 [查看 Amazon ECS 已停止任务错误](stopped-task-errors.md) 中出现 `CannotPullContainerError`
+ 磁盘空间不足
  + 导致在[已停止的任务错误](stopped-task-errors.md)中出现 `CannotCreateContainerError`
  + 有关解决步骤，请参阅[对 Amazon ECS 中的 Docker `API error (500): devmapper` 进行故障排除](CannotCreateContainerError.md)

**重要**  
以下场景不会触发节流逻辑：  
任务在进入 `RUNNING` 状态后停止
任务因 Elastic Load Balancing 运行状况检查失败而停止
任务中的容器命令在进入 `RUNNING` 状态后退出并返回非零代码

# Amazon ECS 服务定义参数
<a name="service_definition_parameters"></a>

服务定义用于定义如何运行您的 Amazon ECS 服务。可以在服务定义中指定以下参数。

## 启动类型
<a name="sd-launchtype"></a>

`launchType`  
类型：字符串  
有效值：`EC2` \$1`FARGATE` \$1`EXTERNAL`  
必需：否  
运行您的服务的启动类型。如果没有指定启动类型，将默认使用默认的 `capacityProviderStrategy`。  
更新服务时，此参数会触发新的服务部署。  
如果指定 `launchType`，必须省略 `capacityProviderStrategy` 参数。

## 容量提供程序策略
<a name="sd-capacityproviderstrategy"></a>

`capacityProviderStrategy`  
类型： 对象数组  
必需：否  
要用于服务的容量提供程序策略。  
更新服务时，此参数不会触发新的服务部署。  
容量提供程序策略由一个或多个容量提供程序以及要分配给它们的 `base` 和 `weight` 组成。容量提供程序必须与要在容量提供程序策略中使用的集群相关联。PutClusterCapacityProviders API 用于将容量提供程序与集群相关联。只能使用具有 `ACTIVE` 或 `UPDATING` 状态的容量提供程序。  
如果指定 `capacityProviderStrategy`，必须省略 `launchType` 参数。如果没有指定 `capacityProviderStrategy` 或 `launchType`，将使用集群的 `defaultCapacityProviderStrategy`。  
如果要指定使用自动扩缩组的容量提供程序，则必须先创建该容量提供程序。可以通过 CreateCapacityProvider API 操作创建新的容量提供程序。  
要使用 AWS Fargate 容量提供程序，请指定 `FARGATE` 或 `FARGATE_SPOT` 容量提供程序。AWS Fargate 容量提供程序对所有账户都可用，只需要与要使用的集群相关联。  
PutClusterCapacityProviders API 操作用于在创建集群后更新集群的可用容量提供程序列表。    
`capacityProvider`  <a name="capacityProvider"></a>
类型：字符串  
是否必需：是  
容量提供程序的短名称或完整的 Amazon 资源名称（ARN）。  
`weight`  <a name="weight"></a>
类型：整数  
有效范围：介于 0 到 1000 之间的整数。  
必需：否  
权重值指明使用指定容量提供程序的已启动任务总数的相对百分比。  
例如，假定您的策略包含两个容量提供程序，并且两个容量提供程序的权重均为 1。当满足基准时，任务会在两个容量提供程序之间均匀分配。按照相同的逻辑，假定您指定 *capacityProviderA* 的权重为 1，并指定 *capacityProviderB* 的权重为 4，那么，对于使用 *capacityProviderA* 运行的每个任务，都会有四个任务使用 *capacityProviderB*。  
`base`  <a name="base"></a>
类型：整数  
有效范围：介于 0 到 100000 万之间的整数。  
必需：否  
基准值指明在指定的容量提供程序上至少运行多少个任务。在一个容量提供程序策略中，只能有一个容量提供程序策略定义了基准。

## 任务定义
<a name="sd-taskdefinition"></a>

`taskDefinition`  
类型：字符串  
必需：否  
要在您的服务中运行的任务定义的 `family` 和 `revision`（`family:revision`）或完整 Amazon 资源名称（ARN）。如果未指定 `revision`，则会使用指定系列的最新 `ACTIVE` 版本。  
更新服务时，此参数会触发新的服务部署。  
使用滚动更新（`ECS`）部署控制器时，必须指定任务定义。

## 平台操作系统
<a name="platform-os"></a>

`platformFamily`  
类型：字符串  
必需：条件  
原定设置：Linux  
对于在 Fargate 上托管的 Amazon ECS 服务，此参数是必需的。  
对于在 Amazon EC2 上托管的 Amazon ECS 服务，可忽略此参数。  
运行服务的容器上的操作系统。有效值为 `LINUX`、`WINDOWS_SERVER_2019_FULL`、`WINDOWS_SERVER_2019_CORE`、`WINDOWS_SERVER_2022_FULL` 和 `WINDOWS_SERVER_2022_CORE`。  
为服务指定的每个任务的 `platformFamily` 值都必须与服务 `platformFamily` 值匹配。例如，如果您将 `platformFamily` 设置为 `WINDOWS_SERVER_2019_FULL`，则所有任务的 `platformFamily` 值必须是 `WINDOWS_SERVER_2019_FULL`。

## 平台版本
<a name="sd-platformversion"></a>

`platformVersion`  
类型：字符串  
必需：否  
正在运行服务中任务的平台版本。仅为使用 Fargate 启动类型的任务指定平台版本。如果没有指定任何版本，将默认使用最新版本（`LATEST`）。  
更新服务时，此参数会触发新的服务部署。  
AWS Fargate 平台版本用于指代 Fargate 任务基础设施的特定运行时环境。在运行任务或创建服务的过程中指定 `LATEST` 平台版本时，您将获得可用于任务的最新平台版本。当您纵向扩展服务时，这些任务将收到在服务的当前部署中指定的平台版本。有关更多信息，请参阅 [适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。  
不会使用 EC2 启动类型为任务指定平台版本。

## 集群
<a name="sd-cluster"></a>

`cluster`  
类型：字符串  
必需：否  
要在其上运行您的服务的集群的短名称或完整 Amazon 资源名称（ARN）。如果您未指定集群，则采用 `default` 集群。

## 服务名称
<a name="sd-servicename"></a>

`serviceName`  
类型：字符串  
是否必需：是  
您的服务的名称。最多能包含 255 个字母（大写和小写字母）、数字、连字符和下划线。一个集群中的服务名称必须唯一，但是您可以为一个区域或多个区域中多个集群中的服务提供相似的名称。

## 计划策略
<a name="sd-schedulingstrategy"></a>

`schedulingStrategy`  
类型：字符串  
有效值：`REPLICA` \$1 `DAEMON`  
必需：否  
要使用的计划策略。如果未指定计划策略，则使用 `REPLICA` 策略。有关更多信息，请参阅 [Amazon ECS 服务](ecs_services.md)。  
有两种服务计划程序策略可用：  
+ `REPLICA`：副本计划策略在集群中放置和维护所需数量的任务。默认情况下，服务计划程序可在多个可用区之间分布任务，但您可以使用任务放置策略和约束自定义任务放置决策。有关更多信息，请参阅 [副本计划策略](ecs_service-options.md#service_scheduler_replica)。
+ `DAEMON`：进程守护程序计划策略只在每个活动容器实例上部署一个任务，以满足您在集群中指定的所有任务放置约束。当使用此策略时，无需指定所需的任务数、任务放置策略，也无需使用服务自动扩缩策略。有关更多信息，请参阅 [进程守护程序计划策略](ecs_service-options.md#service_scheduler_daemon)。
**注意**  
Fargate 任务不支持 `DAEMON` 计划策略。

## 预期数量
<a name="sd-desiredcount"></a>

`desiredCount`  
类型：整数  
必需：否  
要在您的服务中放置并保持运行的指定任务定义的实例化数量。  
更新服务时，此参数不会触发新的服务部署。  
如果使用 `REPLICA` 计划策略，则需要此参数。如果服务使用 `DAEMON` 计划策略，则此参数是可选的。  
当您使用服务自动扩缩时，若您使用少于当前正在运行的任务数的 `desiredCount` 更新正在运行的服务时，该服务会缩减到指定的 `desiredCount`。

## 部署配置
<a name="sd-deploymentconfiguration"></a>

`deploymentConfiguration`  
类型：对象  
必需：否  
可选部署参数，用于控制部署期间运行的任务数以及停止和开始任务的顺序。  
更新服务时，此参数不会触发新的服务部署。    
`maximumPercent`  <a name="maximumPercent"></a>
类型：整数  
必需：否  
如果服务使用滚动更新（`ECS`）部署类型，`maximumPercent` 参数表示在部署期间允许处于 `RUNNING`、`STOPPING` 或 `PENDING` 状态的服务任务数上限。其表示为向下取整到最近整数的 `desiredCount` 的百分比。您可以使用此参数定义部署批次大小。例如，如果服务使用 `REPLICA` 服务调度器且任务的 `desiredCount` 为 4，`maximumPercent` 值为 200%，则调度器会在停止 4 个旧任务之前开始 4 个新任务。这样做的前提是具有执行此操作所需的集群资源。使用 `REPLICA` 服务计划程序的服务的默认 `maximumPercent` 值为 200%。  
只要有用于启动替换任务的集群资源可用，Amazon ECS 调度器就会使用此参数替换运行状况不佳的任务，方法是先启动替换任务，然后停止运行状况不佳的任务。有关调度器如何替换运行状况不佳的任务的更多信息，请参阅 [Amazon ECS 服务](ecs_services.md)。  
如果服务使用的是 `DAEMON` 服务调度器类型，则 `maximumPercent` 应保持在 100%。这是默认值。  
部署期间的最大任务数为 `desiredCount` 乘以 `maximumPercent`/100（向下取整到最近的整数值）。  
如果服务使用蓝绿（`CODE_DEPLOY`）或 `EXTERNAL` 部署类型，并且具有使用 EC2 启动类型的任务，则**最大百分比**值将设置为默认值。该值用于定义当容器实例处于 `DRAINING` 状态时该服务中仍保持在 `RUNNING` 状态的任务数上限。  
如果服务使用蓝绿（`CODE_DEPLOY`）或 `EXTERNAL` 部署类型并且具有使用 EC2 的任务，您无法为该服务指定自定义 `maximumPercent` 值。
如果服务使用蓝绿（`CODE_DEPLOY`）或 `EXTERNAL` 部署类型，并且服务中的任务使用 Fargate，则不会使用最大百分比值。在描述您的服务时仍会返回该值。  
`minimumHealthyPercent`  <a name="minimumHealthyPercent"></a>
类型：整数  
必需：否  
如果服务使用滚动更新（`ECS`）部署类型，`minimumHealthyPercent` 则表示在部署期间必须处于 `RUNNING` 状态的服务任务数下限。其表示为向上取整到最近整数的 `desiredCount` 的百分比。您可以使用此参数进行部署，而无需使用额外的集群容量。  
例如，如果您的服务的任务 `desiredCount` 为 4，`minimumHealthyPercent` 为 50% 且 `maximumPercent` 为 100%，则服务调度器可能先停止两个现有任务以释放集群容量，然后再启动两个新任务。  
 如果有任何任务运行状况不佳，并且 `maximumPercent` 不允许 Amazon ECS 调度器启动替换任务，则调度器将使用 `minimumHealthyPercent` 作为约束条件逐一停止运行状况不佳的任务，清理容量以便启动替换任务。有关调度器如何替换运行状况不佳的任务的更多信息，请参阅 [Amazon ECS 服务](ecs_services.md)。  
对于*不*使用负载均衡器的服务，请注意以下事项：  
+ 如果某个服务中任务内的所有基本容器都通过了运行状况检查，则该服务将被视为正常运行。
+ 如果任务没有已定义运行状况检查的基本容器，服务调度器会在任务达到 `RUNNING` 状态后等待 40 秒，然后将其计入最低正常运行百分比总计。
+ 如果任务具有一个或多个已定义运行状况检查的基本容器，服务计划程序会等待任务达到正常运行状态，然后将其计入最低正常运行百分比总计。当某个任务中的所有基本容器都通过了其运行状况检查时，该任务将被视为正常运行。服务计划程序可以等待的时间由容器运行状况检查设置决定。有关更多信息，请参阅 [运行状况检查](task_definition_parameters.md#container_definition_healthcheck)。
对于*确实*使用负载均衡器的服务，请注意以下事项：  
+ 如果任务不包含已定义运行状况检查的基本容器，服务计划程序会等待负载均衡器目标组运行状况检查返回正常运行状态，然后将任务计入最低正常运行百分比总计。
+ 如果任务具有一个已定义运行状况检查的基本容器，服务计划程序会等待任务达到正常运行状态且负载均衡器目标组运行状况检查返回正常运行状态，然后将任务计入最低正常运行百分比总计。
`minimumHealthyPercent` 的副本服务的默认值为 100%。使用 `DAEMON` 服务调度的原定设置 `minimumHealthyPercent` 值对于 AWS CLI、AWS 开发工具包和 API 为 0%，对于 AWS 管理控制台 为 50%。  
部署期间的最小正常任务数为 `desiredCount` 乘以 `minimumHealthyPercent`/100（向上取整到最近的整数值）。  
如果服务使用蓝绿（`CODE_DEPLOY`）或 `EXTERNAL` 部署类型，并且正在运行使用 EC2 的任务，则**最小正常运行百分比**值将设置为默认值。该值用于定义当容器实例处于 `DRAINING` 状态时该服务中仍保持在 `RUNNING` 状态的任务数下限。  
如果服务使用蓝绿（`CODE_DEPLOY`）或 `EXTERNAL` 部署类型并且具有使用 EC2 的任务，您无法为该服务指定自定义 `maximumPercent` 值。
如果服务使用蓝绿（`CODE_DEPLOY`）或 `EXTERNAL` 部署类型，并且正在运行使用 Fargate 的任务，则不会使用最小健康百分比值，尽管在描述服务时会返回该值。

## 部署控制器
<a name="sd-deploymentcontroller"></a>

`deploymentController`  
类型：对象  
必需：否  
要用于该服务的部署控制器。如果未指定部署控制器，则使用 `ECS` 控制器。有关更多信息，请参阅 [Amazon ECS 服务](ecs_services.md)。  
更新服务时，此参数不会触发新的服务部署。    
`type`  
类型：字符串  
有效值：`ECS` \$1`CODE_DEPLOY` \$1`EXTERNAL`  
是否必需：是  
要使用的部署控制器类型。部署控制器有三种类型：    
`ECS`  
Amazon ECS 部署控制器支持多种部署策略：滚动更新、蓝绿、线性和金丝雀。滚动更新部署类型涉及将当前运行版本的容器替换为最新版本。蓝绿部署会创建新环境并一次性转移所有流量。线性部署会以相等百分比增量逐渐转移流量。金丝雀部署首先转移一小部分流量，然后转移剩余流量。可以调整在服务部署期间允许的最小和最大正常任务数量，以控制滚动更新期间 Amazon ECS 在服务中添加或删除的容器数量，如 [deploymentConfiguration](#deploymentConfiguration) 中指定。  
`CODE_DEPLOY`  
蓝绿（`CODE_DEPLOY`）部署类型使用 CodeDeploy 支持的蓝绿部署模型，以允许您先验证新的服务部署，然后再向其发送生产流量。  
`EXTERNAL`  
当您需要使用任何第三方部署控制器来完全控制 Amazon ECS 服务的部署过程时，使用外部部署类型。

## 任务放置
<a name="sd-taskplacement"></a>

`placementConstraints`  
类型： 对象数组  
必需：否  
您的服务中的任务使用的一组放置约束对象。您可以为每个任务指定最多 10 个约束。此限制包括任务定义中的约束以及在运行时指定的约束。如果您使用的是 Fargate，则不支持任务放置约束。  
更新服务时，此参数不会触发新的服务部署。    
`type`  
类型：字符串  
必需：否  
约束类型。使用 `distinctInstance` 确保特定组中的每个任务在不同的容器实例上运行。使用 `memberOf` 将选择限制为一组有效的候选。任务定义不支持值 `distinctInstance`。  
`expression`  
类型：字符串  
必需：否  
应用于约束的集群查询语言表达式。如果约束类型为 `distinctInstance`，则不能指定表达式。有关更多信息，请参阅 [创建表达式，以为 Amazon ECS 任务定义容器实例](cluster-query-language.md)。

`placementStrategy`  
类型： 对象数组  
必需：否  
您的服务中的任务所用的放置策略对象。对于每项服务，您最多可以指定 4 种策略。  
更新服务时，此参数不会触发新的服务部署。    
`type`  
类型：字符串  
有效值：`random` \$1`spread` \$1`binpack`  
必需：否  
放置策略的类型。`random` 放置策略将任务随机放置在可用的候选上。`spread` 放置策略基于 `field` 参数将任务均匀地放置在可用候选上。`binpack` 策略将任务放置在可用资源数量最少（使用 `field` 参数指定）的可用候选上。例如，如果对内存使用装填，则会将任务放置到剩余内存最少但足以运行该任务的实例上。  
`field`  
类型：字符串  
必需：否  
应用放置策略的字段。对于 `spread` 放置策略，有效值为 `instanceId`（或具有相同效果的 `host`）或应用于容器实例的任何平台或自定义属性，例如 `attribute:ecs.availability-zone`。对于 `binpack` 放置策略，有效值为 `cpu` 和 `memory`。对于 `random` 放置策略，该字段未用。

## 标签
<a name="sd-tags"></a>

`tags`  
类型： 对象数组  
必需：否  
您应用于服务以帮助您对其进行分类和组织的元数据。每个标签都包含您定义的一个键和一个可选值。在服务被删除时，标签也会随之被删除。该服务最多可应用 50 个标签。有关更多信息，请参阅 [为 Amazon ECS 资源添加标签](ecs-using-tags.md)。  
更新服务时，此参数不会触发新的服务部署。    
`key`  
类型：字符串  
长度限制：最小长度为 1。最大长度为 128。  
必需：否  
构成标签的键-值对的一个部分。键是一种常见的标签，行为类似于更具体的标签值的类别。  
`value`  
类型：字符串  
长度限制：最小长度为 0。长度上限为 256。  
必需：否  
构成标签的键-值对的可选部分。值充当标签类别（键）中的描述符。

`enableECSManagedTags`  
类型：布尔值  
有效值：`true` \$1 `false`  
必需：否  
指定是否要为该服务内的任务使用 Amazon ECS 托管标签。如果未指定值，则默认值为 `false`。有关更多信息，请参阅 [使用标签记账](ecs-using-tags.md#tag-resources-for-billing)。  
更新服务时，此参数不会触发新的服务部署。

`propagateTags`  
类型：字符串  
有效值：`TASK_DEFINITION` \$1 `SERVICE`  
必需：否  
指定是否要将标签从任务定义或服务复制到服务中的任务。如果未指定值，则不会复制标签。只能在创建服务的过程中将标签复制到服务中的任务。要在创建服务或任务以后将标签添加到任务，请使用 `TagResource` API 操作。  
更新服务时，此参数不会触发新的服务部署。

## 网络配置
<a name="sd-networkconfiguration"></a>

`networkConfiguration`  
类型：对象  
必需：否  
服务的网络配置。对于使用 `awsvpc` 网络模式接收其自己的弹性网络接口的任务定义，此参数是必需的，但其他网络模式不支持该参数。如果使用 Fargate，则需要 `awsvpc` 网络模式。有关 EC2 联网的更多信息，请参阅 [EC2 的 Amazon ECS 任务联网选项](task-networking.md)。有关 Fargate 联网的更多信息，请参阅 [Fargate 的 Amazon ECS 任务联网选项](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-networking.html)。  
更新服务时，此参数会触发新的服务部署。    
`awsvpcConfiguration`  
类型：对象  
必需：否  
表示任务或服务的子网和安全组的对象。    
`subnets`  
类型：字符串数组  
是否必需：是  
与任务或服务相关联的子网。根据 `awsvpcConfiguration`，可指定的子网数量限制为 16 个。  
`securityGroups`  
类型：字符串数组  
必需：否  
与任务或服务相关联的安全组。如果您未指定安全组，将使用 VPC 的默认安全组。根据 `awsvpcConfiguration`，可指定的安全组数量限制为 5 个。  
`assignPublicIP`  
类型：字符串  
有效值：`ENABLED` \$1 `DISABLED`  
必需：否  
任务的弹性网络接口是否接收公有 IP 地址。如果未指定值，则使用默认值 `DISABLED`。

`healthCheckGracePeriodSeconds`  
类型：整数  
必需：否  
任务首次启动后的一段时间（以秒为单位），在此段时间内，Amazon ECS 服务计划程序将忽略未正常运行的 Elastic Load Balancing、VPC Lattice 和容器运行状况检查。如果没有指定运行状况检查宽限期值，则使用默认值 0。如果不使用任何运行状况检查，则未使用 `healthCheckGracePeriodSeconds`。  
如果服务的任务需要一段时间才能启动和响应，则您可以指定最长 2147483647 秒（大约 69 年）的运行状况检查宽限期。在此期间，Amazon ECS 服务计划程序将忽略运行状况检查状态。此宽限期可防止服务计划程序将由于时间不足尚未启动的任务标记为不正常并停止它们。  
更新服务时，此参数不会触发新的服务部署。

`loadBalancers`  
类型： 对象数组  
必需：否  
表示要用于您的服务的负载均衡器的负载均衡器对象。对于使用应用程序负载均衡器或网络负载均衡器的服务，最多可将 5 个目标组附加到服务。  
更新服务时，此参数会触发新的服务部署。  
创建服务后，无法从 AWS 管理控制台 更改负载均衡器配置。您只能使用 AWS Copilot、AWS CloudFormation、AWS CLI 或 SDK 来修改 `ECS` 滚动部署控制器的负载均衡器配置，而不是 AWS CodeDeploy 蓝/绿或外部控制器。当您添加、更新或删除负载均衡器配置时，Amazon ECS 会使用更新后的 Elastic Load Balancing 配置启动新部署。这将导致任务注册到负载均衡器或从负载均衡器取消注册。我们建议您在更新 Elastic Load Balancing 配置之前在测试环境中对此进行验证。有关如何修改配置的信息，请参阅 *Amazon Elastic Container Service API 参考*中的 [UpdateService](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html)。  
对于应用程序负载均衡器和网络负载均衡器，此对象必须包含负载均衡器目标组ARN、容器名称（如容器定义中所示）以及要从负载均衡器访问的容器端口。将此服务中的任务放置于容器实例之后，容器实例和端口组合会注册为指定目标组中的目标。    
`targetGroupArn`  
类型：字符串  
必需：否  
与服务关联的 Elastic Load Balancing 目标组的完整 Amazon 资源名称（ARN）。  
目标组 ARN 仅在使用应用程序负载均衡器或网络负载均衡器时指定。  
`loadBalancerName`  
类型：字符串  
必需：否  
要与该服务关联的负载均衡器的名称。  
如果您使用的是应用程序负载均衡器或网络负载均衡器，则会省略负载均衡器名称参数。  
`containerName`  
类型：字符串  
必需：否  
要与负载均衡器关联的容器的名称（与在容器定义中显示的相同）。  
`containerPort`  
类型：整数  
必需：否  
要与负载均衡器关联的容器上的端口。此端口必须对应于服务中的任务所使用任务定义中的 `containerPort`。对于使用 EC2 的任务，容器实例必须允许端口映射的 `hostPort` 上的入站流量。

`role`  
类型：字符串  
必需：否  
允许 Amazon ECS 代表您调用负载均衡器的 IAM 角色的名称或完整 ARN 。仅当为服务使用具有单个目标组的负载均衡器，并且任务定义不使用 `awsvpc` 网络模式时，才允许使用此参数。如果您指定 `role` 参数，则还必须指定具有 `loadBalancers` 参数的负载均衡器对象。  
更新服务时，此参数不会触发新的服务部署。  
如果您的指定角色的路径并非 `/`，则必须指定完整角色 ARN（推荐）或将此路径作为角色名称的前缀。例如，如果名称为 `bar` 的角色的路径为 `/foo/`，您应指定 `/foo/bar` 作为角色名称。有关更多信息，请参阅 *IAM 用户指南*中的[友好名称和路径](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-friendly-names)。  
如果您的账户已创建 Amazon ECS 服务相关角色，则默认情况下会为您的服务使用该角色，除非您在此处指定一个角色。如果您的任务定义使用 awsvpc 网络模式（在这种情况下，您不应在此处指定角色），则需要服务相关角色。有关更多信息，请参阅 [对 Amazon ECS 使用服务相关角色](using-service-linked-roles.md)。

`serviceConnectConfiguration`  
类型：对象  
必需：否  
此服务的配置用于发现和连接到服务，以及由命名空间内的其他服务发现和连接。  
更新服务时，此参数会触发新的服务部署。  
有关更多信息，请参阅 [使用 Service Connect 连接具有短名称的 Amazon ECS 服务](service-connect.md)。    
`enabled`  
类型：布尔值  
是否必需：是  
指定是否将 Service Connect 与此服务结合使用。  
`namespace`  
类型：字符串  
必需：否  
与 Service Connect 结合使用的 AWS Cloud Map 命名空间的 Amazon 资源名称（ARN）短名称或全称。命名空间必须与 Amazon ECS 服务和集群在同一个 AWS 区域 内。命名空间的类型不影响 Service Connect。有关 AWS Cloud Map 的更多信息，请参阅**《AWS Cloud Map 开发人员指南》中的[使用服务](https://docs.aws.amazon.com/cloud-map/latest/dg/working-with-services.html)。  
`services`  
类型： 对象数组  
必需：否  
一组 Service Connect 服务对象。这些是其他 Amazon ECS 服务用来连接到此服务的名称和别名（也称为端点）。  
对于作为命名空间成员的“客户端”Amazon ECS 服务，只有连接到命名空间内的其他服务时，才需要此字段。例如，接受来自附加到服务的负载均衡器或通过其他方式所传入请求的前端应用程序。  
对象从任务定义中选择一个端口，为 AWS Cloud Map 服务分配一个名称，并为客户端应用程序分配别名（也称为端点）数组和端口，以供客户端应用程序引用此服务。    
`portName`  
类型：字符串  
是否必需：是  
`portName` 必须与该 Amazon ECS 服务的任务定义中所有容器中的 `portMappings` 的其中一个的 `name` 相匹配。  
`discoveryName`  
类型：字符串  
必需：否  
`discoveryName` 是 Amazon ECS 为该 Amazon ECS 服务创建的新 AWS Cloud Map 服务的名称。此名称在 AWS Cloud Map 命名空间内必须是唯一的。  
如果未指定此字段，则使用 `portName`。  
`clientAliases`  
类型： 对象数组  
必需：否  
此 Service Connect 服务的客户端别名列表。您可以使用这些列表来分配供客户端应用程序使用的名称。您可以在此列表中包含的最大客户端别名数为 1。  
每个别名（“端点”）都是 DNS 名称和端口号，其他 Amazon ECS 服务（“客户端”）可以使用该 DNS 名称和端口号连接到此服务。  
每个名称和端口组合在命名空间内必须是唯一的。  
这些名称是在客户端服务的每项任务中配置的，而不是在 AWS Cloud Map 中配置的。解析这些名称的 DNS 请求不会离开任务，也不会计入每个弹性网络接口每秒的 DNS 请求的配额。    
`port`  
类型：整数  
是否必需：是  
Service Connect 代理的侦听端口号。此端口在同一个命名空间内的所有任务中都可用。  
为避免更改客户端 Amazon ECS 服务中的应用程序，请将其设置为客户端应用程序默认使用的同一个端口。  
`dnsName`  
类型：字符串  
必需：否  
`dnsName` 是您在客户端任务的应用程序中用来连接到此服务的名称。该名称必须是有效的 DNS 标签。  
如果未指定该字段，则值默认为 `discoveryName.namespace`。如果未指定 `discoveryName`，则使用任务定义中的 `portName`。  
为避免更改客户端 Amazon ECS 服务中的应用程序，请将其设置为客户端应用程序默认使用的同一个名称。例如，一些常用名称是 `database`、`db` 或数据库的小写名称，例如 `mysql` 或 `redis`。  
`ingressPortOverride`  
类型：整数  
必需：否  
（可选）Service Connect 代理侦听的端口号。  
使用此字段的值绕过此应用程序的任务定义中的已命名 `portMapping` 中指定的端口号上的流量代理，然后在 Amazon VPC 安全组中使用该代理，以允许流量进入该 Amazon ECS 服务的代理。  
在 `awsvpc` 模式下，默认值是容器端口号，该端口号在此应用程序的任务定义的已命名 `portMapping` 中指定。在 `bridge` 模式下，默认值是 Service Connect 代理的动态临时端口。  
`logConfiguration`  
类型：[LogConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html) 对象  
必需：否  
这定义了 Service Connect 代理日志的发布位置。在意外事件期间使用日志进行调试。此配置在此 Amazon ECS 服务的每个任务的 Service Connect 代理容器中设置 `logConfiguration` 参数。没有在任务定义中指定代理容器。  
我们建议您使用与该 Amazon ECS 服务任务定义的应用程序容器相同的日志配置。对于 FireLens，这是应用程序容器的日志配置。使用 `fluent-bit` 或 `fluentd ` 容器映像的不是 FireLens 日志路由器容器。  
`accessLogConfiguration`  
类型：[ServiceConnectAccessLogConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html) 对象  
必需：否  
Service Connect 访问日志记录的配置，包括日志格式以及日志是否应包含查询字符串。访问日志会捕获有关向服务发出的请求的详细信息，包括请求模式、响应代码和计时数据。要启用访问日志，您还必须在 `serviceConnectConfiguration` 中指定 `logConfiguration`。

`serviceRegistries`  
类型： 对象数组  
必需：否  
服务的服务发现配置的详细信息。有关更多信息，请参阅 [使用服务发现连接具有 DNS 名称的 Amazon ECS 服务](service-discovery.md)。  
更新服务时，此参数会触发新的服务部署。    
`registryArn`  
类型：字符串  
必需：否  
服务注册表的 Amazon 资源名称（ARN）。当前支持的服务注册表是 AWS Cloud Map。有关更多信息，请参阅 *AWS Cloud Map 开发人员指南*中的[使用服务](https://docs.aws.amazon.com/cloud-map/latest/dg/working-with-services.html)。  
`port`  
类型：整数  
必需：否  
在服务发现服务指定 SRV 记录时使用的端口值。如果使用 `awsvpc` 网络模式和 SRV 记录，则需要此字段。  
`containerName`  
类型：字符串  
必需：否  
用于服务发现服务的容器名称值。此值可在任务定义中指定。如果服务任务指定的任务定义使用 `bridge` 或 `host` 网络模式，则必须从任务定义中指定 `containerName` 和 `containerPort` 组合。如果服务任务指定的任务定义使用 `awsvpc` 网络模式，并且使用类型 SRV DNS 记录，则必须指定 `containerName` 和 `containerPort` 组合或 `port` 值，但不能同时指定二者。  
`containerPort`  
类型：整数  
必需：否  
用于服务发现服务的端口值。此值可在任务定义中指定。如果服务任务指定的任务定义使用 `bridge` 或 `host` 网络模式，则必须从任务定义中指定 `containerName` 和 `containerPort` 组合。如果服务任务指定的任务定义使用 `awsvpc` 网络模式，并且使用类型 SRV DNS 记录，则必须指定 `containerName` 和 `containerPort` 组合或 `port` 值，但不能同时指定二者。

## 客户端令牌
<a name="sd-clienttoken"></a>

`clientToken`  
类型：字符串  
必需：否  
用于确保请求的幂等性而提供的唯一、区分大小写的标识符。最长可为 32 个 ASCII 字符。

## 可用区再平衡
<a name="sd-availability-zone-rebalancing"></a>

`availabilityZoneRebalancing`  
类型：字符串  
必需：否  
指示服务是否使用可用区重新平衡。有效值为 `ENABLED` 和 `DISABLED`。  
更新服务时，此参数不会触发新的服务部署。  
默认行为：  
+ 对于新服务：如果未指定值，则默认值为 `DISABLED`。
+ 对于现有服务：如果未指定任何值，则 Amazon ECS 会将该值默认为现有值。如果之前未设置任何值，则 Amazon ECS 会将该值设置为 `DISABLED`。
有关可用区再平衡的更多信息，请参阅[在可用区之间平衡 Amazon ECS 服务](service-rebalancing.md)。

## 卷配置
<a name="sd-volumeConfigurations"></a>

`volumeConfigurations`  
类型：对象  
必需：否  
用于为服务管理的任务而创建卷的配置。只有在任务定义中标记为 `configuredAtLaunch` 的卷才能使用此对象进行配置。  
更新服务时，此参数会触发新的服务部署。  
此对象是将 Amazon EBS 卷附加到服务管理的任务所必需的。有关更多信息，请参阅 [将 Amazon EBS 卷与 Amazon ECS 结合使用](ebs-volumes.md)。    
`name`  
类型：字符串  
是否必需：是  
创建或更新服务时配置的卷的名称。最多可允许 255 个字母（大写和小写字母）、数字、下划线（`_`）和连字符（`-`）。此值必须与任务定义中指定的卷名称相匹配。  
`managedEBSVolume`  
类型：对象  
必需：否  
用于创建 Amazon EBS 卷的卷配置，这些卷附加到在创建或更新服务时由服务维护的任务。每个任务附加一个卷。    
`encrypted`  
类型：布尔值  
必需：否  
有效值：`true`\$1`false`  
指定是否加密每个创建的 Amazon EBS 卷。如果您已为 AWS 账户的特定 AWS 区域默认启用了 Amazon EBS 加密，但将此参数设置为 `false`，则此参数将被覆盖，并且卷将默认使用指定用于加密的 KMS 密钥进行加密。有关默认 Amazon EBS 加密的更多信息，请参阅《*Amazon EBS 用户指南*》中的 [Enable Amazon EBS encryption by default](https://docs.aws.amazon.com/ebs/latest/userguide/encryption-by-default.html)。有关加密附加到 Amazon ECS 任务的 Amazon EBS 卷的更多信息，请参阅[加密附加到 Amazon ECS 任务的 Amazon EBS 卷中存储的数据](ebs-kms-encryption.md)。  
`kmsKeyId`  
类型：字符串  
必需：否  
用于 Amazon EBS 加密的 AWS Key Management Service（AWS KMS）密钥的标识符。如果指定了 `kmsKeyId`，加密状态必须为 `true`。  
 使用此参数指定的密钥将覆盖 Amazon EBS 默认值或您可能已指定的 Amazon ECS 托管存储加密的任何集群级 KMS 密钥。有关更多信息，请参阅 [加密附加到 Amazon ECS 任务的 Amazon EBS 卷中存储的数据](ebs-kms-encryption.md)。  
您可以使用以下任一项指定 KMS 密钥：  
+ **密钥 ID** – 例如 `1234abcd-12ab-34cd-56ef-1234567890ab`。
+ **密钥别名** – 例如 `alias/ExampleAlias`。
+ **密钥 ARN** – 例如 `arn:aws:kms:us-east-1:012345678910:key/1234abcd-12ab-34cd-56ef-1234567890ab`。
+ **别名 ARN** – 例如 `arn:aws:kms:us-east-1:012345678910:alias/ExampleAlias`。
AWS 异步验证 KMS 密钥的身份。因此，如果您指定了无效的 ID、别名或 ARN，则操作可能会显示成功，但最终会失败。有关更多信息，请参阅[排查 Amazon EBS 卷附加问题](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/troubleshoot-ebs-volumes.html)。  
`volumeType`  
类型：字符串  
必需：否  
有效值：`gp2`\$1`gp3`\$1`io1`\$1`io2`\$1`sc1`\$1`st1`\$1`standard`  
Amazon EBS 卷类型。有关卷类型的更多信息，请参阅《Amazon EBS 用户指南》**中的 [Amazon EBS volume types](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html)。默认卷类型为 `gp3`。  
Fargate 任务不支持 `standard` 卷类型。  
`sizeInGiB`  
类型：整数  
必需：否  
有效范围：介于 1 到 16384 之间的整数   
EBS 卷的大小，以吉字节（GiB）为单位。如果您没有提供快照 ID 来配置要附加的卷，则必须提供大小值。如果使用快照配置卷以进行附加，则默认值为快照大小。然后，您可以指定大于或等于快照大小的大小。  
对于 `gp2` 和 `gp3` 卷类型，有效范围为 1-16384。  
对于 `io1` 和 `io2` 卷类型，有效范围为 4-16384。  
对于 `st1` 和 `sc1` 卷类型，有效范围为 125-16384。  
对于 `standard` 卷类型，有效范围为 1-1024。  
`snapshotId`  
类型：字符串  
必需：否  
Amazon ECS 用来创建要附加的新卷的现有 Amazon EBS 卷的快照的 ID。您必须指定 `snapshotId` 或 `sizeInGiB`。  
`volumeInitializationRate`  
类型：整数  
必需：否  
从现有 Amazon EBS 卷的快照中提取数据以创建要附加的新卷的速率（以 MiB/s 为单位）。仅当您指定了 `snapshotId` 时才可以指定此属性。有关此卷初始化速率的更多信息，包括支持的初始化速率范围，请参阅《*Amazon EBS 用户指南*》中的 [Initialize Amazon EBS volumes](https://docs.aws.amazon.com/ebs/latest/userguide/initalize-volume.html)。  
`iops`  
类型：整数  
必需：否  
每秒 I/O 操作数（IOPS）。对于 `gp3`、`io1` 和 `io2` 卷，这代表为卷预置的 IOPS 数。对于 `gp2` 卷，此值表示卷的基准性能和卷积累用于突增情况的 I/O 积分的速度。此参数是 `io1` 和 `io2` 卷的必需参数。`gp2`、`st1`、`sc1` 或 `standard` 卷不支持此参数。  
对于 `gp3` 卷，值的有效范围为 3000 到 16000。  
对于 `io1` 卷，值的有效范围为 100 到 64000。  
对于 `io2` 卷，值的有效范围为 100 到 64000。  
`throughput`  
类型：整数  
必需：否  
为附加到服务维护的任务的卷预调配的吞吐量。  
仅 `gp3` 卷支持此参数。  
`roleArn`  
类型：字符串  
是否必需：是  
基础设施 AWS Identity and Access Management（IAM）角色的 Amazon 资源 ARN（ARN），它为您的任务提供 Amazon ECS 管理 Amazon EBS 资源的权限。有关更多信息，请参阅 [Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。  
`tagSpecifications`  
类型：对象  
必需：否  
应用于每个 Amazon EBS 卷的标签的规范。    
`resourceType`  
类型：字符串  
是否必需：是  
有效值：`volume`  
要在创建时标记的资源类型。  
`tags`  
类型： 对象数组  
必需：否  
您应用于卷以帮助您对其进行分类和组织的元数据。每个标签都包含您定义的一个键和一个可选值。`AmazonECSCreated` 和 `AmazonECSManaged` 是 Amazon ECS 代表您添加的保留标签，因此您最多可以自己指定 48 个标签。在卷被删除时，标签也会随之被删除。有关更多信息，请参阅 [为 Amazon ECS 资源添加标签](ecs-using-tags.md)。    
`key`  
类型：字符串  
长度限制：最小长度为 1。最大长度为 128。  
必需：否  
构成标签的键-值对的一个部分。键是一种常见的标签，行为类似于更具体的标签值的类别。  
`value`  
类型：字符串  
长度限制：最小长度为 0。长度上限为 256。  
必需：否  
构成标签的键-值对的可选部分。值充当标签类别（键）中的描述符。  
`propagateTags`  
类型：字符串  
有效值：`TASK_DEFINITION` \$1`SERVICE` \$1`NONE`  
必需：否  
指定是否要将标签从任务定义或服务复制到卷中。如果指定 `NONE` 或未指定任何值，则不会复制标签。  
`fileSystemType`  
类型：字符串  
必需：否  
有效值：`xfs`\$1`ext3`\$1`ext4`\$1`NTFS`  
卷上的文件系统的类型。卷的文件系统类型会决定在卷中存储和检索数据的方式。对于从快照创建的卷，必须指定创建快照时卷使用的相同文件系统类型。如果文件系统类型不匹配，则任务将无法启动。  
Linux 的有效值为 `xfs`、ext3`, and ext4`。附加到 Linux 任务的卷的默认值为 `XFS`。  
Windows 的有效值为 `NTFS`。对于挂载到 Windows 任务的卷，默认值为 `NTFS`。

# 服务定义模板
<a name="sd-template"></a>

下面显示了 Amazon ECS 服务定义的 JSON 表示形式。

EC2

```
{
    "cluster": "", 
    "serviceName": "", 
    "taskDefinition": "", 
    "loadBalancers": [
        {
            "targetGroupArn": "", 
            "loadBalancerName": "", 
            "containerName": "", 
            "containerPort": 0
        }
    ], 
    "serviceRegistries": [
        {
            "registryArn": "", 
            "port": 0, 
            "containerName": "", 
            "containerPort": 0
        }
    ], 
    "desiredCount": 0, 
    "clientToken": "", 
    "launchType": "EC2", 
    "capacityProviderStrategy": [
        {
            "capacityProvider": "", 
            "weight": 0, 
            "base": 0
        }
    ], 
    "platformVersion": "", 
    "role": "", 
    "deploymentConfiguration": {
        "deploymentCircuitBreaker": {
            "enable": true, 
            "rollback": true
        }, 
        "maximumPercent": 0, 
        "minimumHealthyPercent": 0, 
        "alarms": {
            "alarmNames": [
                ""
            ], 
            "enable": true, 
            "rollback": true
        }
    }, 
    "placementConstraints": [
        {
            "type": "distinctInstance", 
            "expression": ""
        }
    ], 
    "placementStrategy": [
        {
            "type": "binpack", 
            "field": ""
        }
    ], 
    "networkConfiguration": {
        "awsvpcConfiguration": {
            "subnets": [
                ""
            ], 
            "securityGroups": [
                ""
            ], 
            "assignPublicIp": "DISABLED"
        }
    }, 
    "healthCheckGracePeriodSeconds": 0, 
    "schedulingStrategy": "REPLICA", 
    "deploymentController": {
        "type": "EXTERNAL"
    }, 
    "tags": [
        {
            "key": "", 
            "value": ""
        }
    ], 
    "enableECSManagedTags": true, 
    "propagateTags": "TASK_DEFINITION", 
    "enableExecuteCommand": true, 
    "availabilityZoneRebalancing": "ENABLED",
    "serviceConnectConfiguration": {
        "enabled": true, 
        "namespace": "", 
        "services": [
            {
                "portName": "", 
                "discoveryName": "", 
                "clientAliases": [
                    {
                        "port": 0, 
                        "dnsName": ""
                    }
                ], 
                "ingressPortOverride": 0
            }
        ], 
        "logConfiguration": {
            "logDriver": "journald", 
            "options": {
                "KeyName": ""
            }, 
            "secretOptions": [
                {
                    "name": "", 
                    "valueFrom": ""
                }
            ]
        }
    }, 
    "volumeConfigurations": [
        {
            "name": "", 
            "managedEBSVolume": {
                "encrypted": true, 
                "kmsKeyId": "", 
                "volumeType": "", 
                "sizeInGiB": 0, 
                "snapshotId": "", 
                "volumeInitializationRate": 0,
                "iops": 0, 
                "throughput": 0, 
                "tagSpecifications": [
                    {
                        "resourceType": "volume", 
                        "tags": [
                            {
                                "key": "", 
                                "value": ""
                            }
                        ], 
                        "propagateTags": "NONE"
                    }
                ], 
                "roleArn": "", 
                "filesystemType": ""
            }
        }
    ]
}
```

Fargate

```
{
    "cluster": "", 
    "serviceName": "", 
    "taskDefinition": "", 
    "loadBalancers": [
        {
            "targetGroupArn": "", 
            "loadBalancerName": "", 
            "containerName": "", 
            "containerPort": 0
        }
    ], 
    "serviceRegistries": [
        {
            "registryArn": "", 
            "port": 0, 
            "containerName": "", 
            "containerPort": 0
        }
    ], 
    "desiredCount": 0, 
    "clientToken": "", 
    "launchType": "FARGATE", 
    "capacityProviderStrategy": [
        {
            "capacityProvider": "", 
            "weight": 0, 
            "base": 0
        }
    ], 
    "platformVersion": "", 
    "platformFamily": "",
    "role": "", 
    "deploymentConfiguration": {
        "deploymentCircuitBreaker": {
            "enable": true, 
            "rollback": true
        }, 
        "maximumPercent": 0, 
        "minimumHealthyPercent": 0, 
        "alarms": {
            "alarmNames": [
                ""
            ], 
            "enable": true, 
            "rollback": true
        }
    }, 
    "placementStrategy": [
        {
            "type": "binpack", 
            "field": ""
        }
    ], 
    "networkConfiguration": {
        "awsvpcConfiguration": {
            "subnets": [
                ""
            ], 
            "securityGroups": [
                ""
            ], 
            "assignPublicIp": "DISABLED"
        }
    }, 
    "healthCheckGracePeriodSeconds": 0, 
    "schedulingStrategy": "REPLICA", 
    "deploymentController": {
        "type": "EXTERNAL"
    }, 
    "tags": [
        {
            "key": "", 
            "value": ""
        }
    ], 
    "enableECSManagedTags": true, 
    "propagateTags": "TASK_DEFINITION", 
    "enableExecuteCommand": true, 
    "availabilityZoneRebalancing": "ENABLED",
    "serviceConnectConfiguration": {
        "enabled": true, 
        "namespace": "", 
        "services": [
            {
                "portName": "", 
                "discoveryName": "", 
                "clientAliases": [
                    {
                        "port": 0, 
                        "dnsName": ""
                    }
                ], 
                "ingressPortOverride": 0   
            }
        ], 
        "logConfiguration": {
            "logDriver": "journald", 
            "options": {
                "KeyName": ""
            }, 
            "secretOptions": [
                {
                    "name": "", 
                    "valueFrom": ""
                }
            ]
        }
    }, 
    "volumeConfigurations": [
        {
            "name": "", 
            "managedEBSVolume": {
                "encrypted": true, 
                "kmsKeyId": "", 
                "volumeType": "", 
                "sizeInGiB": 0, 
                "snapshotId": "", 
                "volumeInitializationRate": 0, 
                "iops": 0, 
                "throughput": 0, 
                "tagSpecifications": [
                    {
                        "resourceType": "volume", 
                        "tags": [
                            {
                                "key": "", 
                                "value": ""
                            }
                        ], 
                        "propagateTags": "NONE"
                    }
                ], 
                "roleArn": "", 
                "filesystemType": ""
            }
        }
    ]
}
```

您可以使用以下 AWS CLI 命令创建此服务定义模板。

```
aws ecs create-service --generate-cli-skeleton
```