

# 将故障注入功能用于 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
```