

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

## 部署术语
<a name="deployment-terminology"></a>

整个 Amazon ECS 部署文档中使用了下面的术语：

蓝绿部署  
一种部署策略，它在现有环境（蓝色）旁边创建新环境（绿色），然后在验证后将流量从蓝色切换到绿色。

金丝雀部署  
一种部署策略，它将一小部分流量路由到新版本，同时将大部分流量保持在稳定版本上进行验证。

线性部署  
一种部署策略，随着时间推移以相等增量逐渐将流量从旧版本转移到新版本。

滚动部署  
一种部署策略，逐一将旧版本的实例替换为新版本的实例。

任务集  
部署期间在服务内运行相同任务定义的一组任务。

目标组  
部署期间从负载均衡器接收流量的目标的逻辑分组。

部署控制器  
用于部署新版本服务的方法，例如 Amazon ECS、CodeDeploy 或外部控制器。

回滚  
部署期间检测到问题时恢复到应用程序先前版本的过程。