

# 使用第三方控制器部署 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` 以缩小规模。