

# 将 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 所使用的同一负载均衡器侦听器和目标组。如果您正在使用 Amazon CloudFormation，请参阅 [将 Amazon CloudFormation CodeDeploy 蓝绿部署模板迁移到 Amazon ECS 蓝绿部署 Amazon 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 部署。
+ 考虑对新的部署流程实施自动测试，以确保其按预期运行。