为什么我的 Amazon ECS 任务停滞在“待处理”状态?

2 分钟阅读
0

我的 Amazon Elastic Container Service(Amazon ECS)任务停滞在“待处理”状态。

简短描述

以下情况通常会导致 Amazon ECS 任务停滞在“待处理”状态:

  • Docker 进程守护程序没有响应。
  • Docker 映像很大。
  • Amazon ECS 容器代理在任务启动过程中断开了与 Amazon ECS 服务的连接。
  • Amazon ECS 容器代理需要很长时间才能停止现有任务。
  • Amazon Virtual Private Cloud(Amazon VPC)路由配置不正确。
  • 主要容器依赖于无法处于“正常”状态的非主要容器。

解决方法

要了解您的任务为何停滞在“待处理”状态,请完成以下故障排除步骤。

**注意:**如果在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请确保您使用的是最新的 AWS CLI 版本

Docker 进程守护程序没有响应

对于 CPU 问题,请完成以下步骤:

1.    使用 Amazon CloudWatch 指标查看容器实例是否超过了最大 CPU。

2.    根据需要增加容器实例的大小

对于内存问题,请完成以下步骤:

1.    运行 free 命令,查看系统有多少可用内存。

2.    根据需要增加容器实例的大小

对于 I/O 问题,请完成以下步骤:

1.    运行 iotop 命令。

2.    查明哪些服务中哪些任务的 IOPS 利用率最高。然后,使用任务放置约束和策略将这些任务分发到不同的容器实例。

-或者-

使用 CloudWatch 为 Amazon Elastic Block Store(Amazon EBS)BurstBalance 指标创建警报。然后,使用 AWS Lambda 函数或您自己的自定义逻辑均衡任务。

Docker 映像很大

映像越大,下载时间越长,任务处于“待处理”状态的时间也会增加。

要缩短过渡时间,请调整 ECS_IMAGE_PULL_BEHAVIOR 参数以利用映像缓存。

**注意:**例如,在 /etc/ecs/ecs.config 中将 ECS_IMAGE_PULL_BEHAVIOR 参数设置为 prefer-cached。如果指定了 prefer-cached,则在没有缓存映像时会远程提取映像。否则,将使用实例上的缓存映像。

Amazon ECS 容器代理在启动过程中断开了与 Amazon ECS 服务的连接

1.    要验证 Amazon ECS 容器代理的状态和连接,请在容器实例上运行以下任一命令。

对 Amazon Linux 1 运行以下命令:

$ sudo status ecs
$ sudo docker ps -f name=ecs-agent

对 Amazon Linux 2 运行以下命令:

$ sudo systemctl status ecs
$ sudo docker ps -f name=ecs-agent

**注意:**您会在输出中看到 active/running

2.    要查看 ECS 容器实例中正在运行任务的元数据,请在容器实例上运行以下命令:

$ curl http://localhost:51678/v1/metadata

您会收到以下输出:

{
  "Cluster": "CLUSTER_ID",
  "ContainerInstanceArn": "arn:aws:ecs:REGION:ACCOUNT_ID:container-instance/TASK_ID",
  "Version": "Amazon ECS Agent - AGENT "
}

3.    要查看有关正在运行任务的信息,请在容器实例上运行以下命令:

$ curl http://localhost:51678/v1/tasks

您会收到以下输出:

{
  "Tasks": [
    {
      "Arn": "arn:aws:ecs:REGION:ACCOUNT_ID:task/TASK_ID",
      "DesiredStatus": "RUNNING",
      "KnownStatus": "RUNNING",
      ... ...
    }
  ]
}

4.    如果问题与代理断开连接有关,请使用以下任一命令重启容器代理。

对 Amazon Linux 1 运行以下命令:

$ sudo stop ecs
$ sudo start ecs

对 Amazon Linux 2 运行以下命令:

$ sudo systemctl stop ecs
$ sudo systemctl start ecs

您收到的输出类似于以下消息:

ecs start/running, process xxxx

5.    要确定代理连接,请在相关时间范围内查看以下日志,查找错误警告代理过渡状态等关键词:

查看 Amazon ECS 容器代理日志 /var/log/ecs/ecs-agent.log.yyyy-mm-dd-hh
查看 Amazon ECS 初始化日志 /var/log/ecs/ecs-init.log
查看 Docker 日志 /var/log/docker

**注意:**还可以使用 Amazon ECS 日志收集器收集 Amazon ECS 的常规操作系统日志、Docker 日志和容器代理日志。

Amazon ECS 容器代理需要很长时间才能停止现有任务

当容器代理收到要从 Amazon ECS 启动的新任务(从“待处理”变为“正在运行”)时,可能有旧任务需要停止。在这种情况下,代理会先停止旧任务,然后再启动这些新任务。

要在容器实例级别控制容器停止和启动超时,请设置以下两个参数

1.    在 /etc/ecs/ecs.config 中,调整 ECS_CONTAINER_STOP_TIMEOUT 参数的值。此参数设置了容器不能自行正常退出的情况下 Amazon ECS 强制结束容器之前经过的时间。

**注意:**Linux 和 Windows 的默认值为 30 秒

2.    在 /etc/ecs/ecs.config 中,调整 ECS_CONTAINER_START_TIMEOUT 参数的值。此参数设置了 Amazon ECS 容器代理停止尝试启动容器之前经过的时间。

**注意:**Linux 的默认值为 3 分钟,Windows 的默认值为 8 分钟

如果代理版本为 1.26.0 或更高版本,则可以为每个任务定义前面所述的停止和启动超时参数。这可能会使任务过渡到“已停止”状态。例如,假设容器 A 依赖于容器 B 达到“完成”、“成功”或“正常”状态。如果没有为容器 B 指定 startTimeout 值,且容器 B 在该时间内未达到所需状态,则容器 A 将不会启动。

有关容器依赖关系的示例,请参阅 AWS GitHub 上的示例: 容器依赖关系

Amazon VPC 路由配置不正确

检查运行 Amazon ECS 或 Fargate 任务的 VPC 子网的配置。如果子网配置不正确,则无法访问 Amazon ECS 或 Amazon ECR。要解决此问题,请确保子网的路由表具有互联网网关或 NAT 网关。如果在没有通往互联网的出口路由的子网中启动任务,请使用 AWS PrivateLink。这样,可以使用私有 IP 地址私密访问 Amazon ECS API。

主要容器依赖于无法处于“正常”状态的非主要容器

如果非主要容器无法处于“正常”状态,而主要容器依赖于这些非主要容器,则任务将停滞在“待处理”状态。在这种情况下,您会看到以下消息:

"stoppedReason":"Service ABCXYZ: task last status remained in PENDING too long."

要解决此问题,请确保依赖(非主要)容器按预期运行。如果无法解决基础问题,请将这些容器设置为主要容器,以避免任务停滞在“待处理”状态太长时间。

相关信息

容器依赖项

Amazon ECS 容器代理(AWS GitHub)

AWS 官方
AWS 官方已更新 10 个月前