

# 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"
    }
]
```