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

上次更新时间:2019 年 8 月 20 日

为什么我的 Amazon Elastic Container Service (Amazon ECS) 任务卡在“待处理”状态?

简短描述

可能会导致您的 ECS 任务卡在“待处理”状态的一些常见情况包括:

  • Docker 守护程序无响应
  • Docker 映像很大
  • ECS 容器代理在任务启动中丢失了与 Amazon ECS 服务的连接
  • ECS 容器代理需要很长时间才能停止现有任务

要了解您的任务卡在“待处理”状态的原因,请根据您的问题完成以下故障排除步骤。

解决方法

Docker 守护程序无响应

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

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

2.    根据需要提高您的容器实例大小

注意:要更改实例类型,您可能需要移除代理状态文件 (/var/lib/ecs/data/ecs_agent_data.json),从而使代理能够重新注册到 ECS 集群。

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

1.    运行免费命令以查看您的系统有多少可用内存。

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,则会在没有缓存映像时远程拉取映像。否则,将使用实例上的缓存映像。

ECS 容器代理在启动中丢失了与 Amazon ECS 服务的连接

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

对于 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

注意:预期输出应为活动状态/正在运行

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.    要确定代理连接,请在相关时间范围内检查以下日志中是否有“error”、“warn”或“agent transition state”等关键词:

/var/log/ecs/ecs-agent.log.yyyy-mm-dd-hh 中查看 ECS 容器代理日志。
/var/log/ecs/ecs-init.log 中查看 ECS init 日志。
/var/log/docker 中查看 Docker 日志。

注意:您还可以使用 Amazon ECS 日志收集器收集一般操作系统日志、Docker 日志和 Amazon ECS 容器代理日志。

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

如果 ECS 容器代理在接收到要从 ECS 后端开始的新任务时具有要停止的较旧任务(从“待处理”到“运行中”),该代理在停止旧任务之前不能开始这些新任务。

您可以将下面两个参数设置为在容器实例级别控制容器停止和开始超时:

1.    在 /etc/ecs/ecs.config 中,将 ECS_CONTAINER_STOP_TIMEOUT 参数的值设置为您希望在容器(在未自行正常退出的情况下)强制终止之前经过的时间。

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

2.    在 /etc/ecs/ecs.config 中,将 ECS_CONTAINER_START_TIMEOUT 参数的值设置为您希望在 ECS 容器代理停止尝试启动容器之前经过的时间。

注意:Linux 和 Windows 的默认值分别为 3m 和 8m。

如果您的代理版本为 1.26.0 或更高版本,您可以按任务定义前述停止和启动超时参数。这可能会导致任务转换到“已停止”状态。例如,containerA 对达到“完成”、“成功”或“运行正常”状态的 containerB 存在依赖关系。如果为 containerB 指定了 startTimeout 值且 containerB 未在此时间内达到所需状态,则 containerA 会放弃且不会启动。

有关容器依赖项的示例,请参阅示例:容器依赖项


这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助吗?