如何对已断开连接的 Amazon ECS 代理进行问题排查?

上次更新日期:2022 年 3 月 21 日

我的 Amazon Elastic Container Service (Amazon ECS) 容器实例已断开连接。

简短描述

在正常操作中,您的 Amazon ECS 容器代理可能会在一个小时内断开连接并重新连接数次。这些变更事件很正常,不需要担心。持续仅几分钟的连接事件可能并不表明容器代理或您的容器实例出现问题。但是,如果容器代理保持断开连接状态的时间更长,则容器实例无法作为 Amazon ECS 集群的成员运行。此问题可能由以下原因引起:

  • 联网问题阻止实例与 Amazon ECS 之间的通信。
  • 该容器代理不具有与 Amazon ECS 终端节点通信所需的 AWS Identity and Access Management (IAM) 权限。
  • 容器实例内的主机或 Docker 守护进程存在问题。
  • 底层主机中存在资源争用。

解决方法

注意:以下解决方案适用于经 Amazon ECS 优化的 Amazon Linux 2 AMI。有关适用于 Amazon ECS 优化型 Amazon Linux 1 AMI 的解决方法,请参阅为什么具有 Amazon Linux 1 AMI 的 Amazon ECS 容器实例已断开连接?

您可以使用 SSH 密钥连接到 Amazon EC2 实例。如果没有生成 SSH 密钥,您可以使用会话管理器连接到实例。默认情况下,AWS Systems Manager Agent 安装在 Amazon Linux 2 AMI 和 Amazon Linux 2 ECS 优化型基础 AMI 上。

验证容器代理在容器实例上运行

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

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

输出会指定 active (running),与以下内容类似:

ecs.service - Amazon Elastic Container Service - container agent
   Loaded: loaded (/usr/lib/systemd/system/ecs.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2022-02-15 15:51:09 UTC; 37min ago
     Docs: https://aws.amazon.com/documentation/ecs/
  Process: 30039 ExecStopPost=/usr/libexec/amazon-ecs-init post-stop (code=exited, status=0/SUCCESS)
  Process: 29987 ExecStop=/usr/libexec/amazon-ecs-init stop (code=exited, status=0/SUCCESS)
  Process: 30077 ExecStartPre=/usr/libexec/amazon-ecs-init pre-start (code=exited, status=0/SUCCESS)
 Main PID: 30123 (amazon-ecs-init)
    Tasks: 5
   Memory: 3.7M
   CGroup: /system.slice/ecs.service
           └─30123 /usr/libexec/amazon-ecs-init start
CONTAINER ID   IMAGE                                            COMMAND    CREATED      STATUS                PORTS     NAMES
eb1dc8d4ab3b   amazon/amazon-ecs-agent:latest   "/agent"        3 days ago   Up 3 days (healthy)                        ecs-agent

如果问题是由于代理断开连接导致的,请运行以下命令来重新启动 ECS 代理:

$ sudo systemctl restart ecs

注意:运行这些命令后,您看不到任何输出。

要验证代理正在运行,请运行以下命令:

sudo systemctl status ecs

验证 Docker 服务在容器实例上运行

要验证 Docker 服务在受影响的容器实例上运行,请运行以下命令:

sudo systemctl status docker

输出会指定 active (running),与以下内容类似:

docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-02-11 17:42:32 UTC; 3 days ago
     Docs: https://docs.docker.com
  Process: 4307 ExecStartPre=/usr/libexec/docker/docker-setup-runtimes.sh (code=exited, status=0/SUCCESS)
  Process: 4296 ExecStartPre=/bin/mkdir -p /run/docker (code=exited, status=0/SUCCESS)
 Main PID: 4315 (dockerd)
    Tasks: 24
   Memory: 360.5M
   CGroup: /system.slice/docker.service
           ├─4315 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=32768:65536
           ├─6010 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.17.0.2 -container-port 80
           └─6016 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 80 -container-ip 172.17.0.2 -container-port 80

如果 Docker 服务处于非活动状态,则运行以下命令以重新启动 Docker 服务:

sudo systemctl restart docker

注意:该命令不会返回任何输出。

要验证已重新启动 Docker 服务,请运行以下命令:

sudo systemctl status docker

查看容器代理和 Docker 的日志文件

如果您的容器实例仍然断开连接,则请查看容器代理和 Docker 的容器主机上的日志文件。

检查以下日志文件中的关键字,例如“error”、“warn”或“agent transition state”:

  • /var/log/ecs/ecs-agent.log 中查看 Amazon ECS 容器代理的最新日志。注意:您可以通过筛选 /var/log/ecs/ecs-agent-log.timestamp 来查看轮换的日志
  • /var/log/ecs/ecs-init.log 中查看 Amazon ECS init 日志。
  • /var/log/cloud-init.log 中查看用户数据执行日志
  • 使用 sudo journalctl -u docker 命令查看 Docker 守护进程日志

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

验证 IAM 实例配置文件拥有必要的权限

如果容器代理仍然断开连接,请验证与容器实例关联的 IAM 实例配置文件拥有必要的 IAM 权限。

1.    使用 SSH 或会话管理器连接到实例。

2.    要查看与实例关联的实例配置文件上的实例元数据,请运行以下命令:

curl http://169.254.169.254/latest/meta-data/iam/info

输出与以下内容类似:

{
  "Code" : "Success",
  "LastUpdated" : "2022-02-16T22:42:17Z",
  "InstanceProfileArn" : "arn:aws:iam::1122334455:instance-profile/ecsInstanceRole",
  "InstanceProfileId" : "AIPA4VIZXOFF55F72XIZN"
}

3.    验证 IAM 角色包含容器实例的正确权限

4.    要验证容器代理的特定凭证错误,请运行与以下内容类似的命令来检查容器代理日志中是否有 ECS 日志列表:

请务必将 YYYY-MM-DD-** 替换为相关的时间戳。

cat /var/log/ecs/ecs-agent.log.YYYY-MM-DD-**

注意:容器代理日志每小时轮换一次。后缀会自动更改以反映当前日期和时间。更新命令,以包含发生问题时的日期范围和日志 ID。

验证您的容器实例具有足够的资源来运行 ECS 代理

如果您的任务具有较高的内存/CPU 利用率,则您的容器实例可能没有足够的资源来运行 ECS 代理。

Amazon ECS 容器代理使用 Docker ReadMemInfo() 函数查询可用于操作系统的内存量。

在容器实例上运行以下命令,以查看操作系统识别的总内存量:

free -b

运行 Amazon ECS 优化型 Amazon Linux AMI 的 t2.large 实例的示例输出:

                          total        used         free                   shared     buff/cache    available
Mem:                    8361193472   298577920     7325388800              405504      737226752    7844274176
Swap:                     0              0           0

您可以选择为容器实例上的 Amazon ECS 容器代理和其他关键系统进程预留一些内存,这样任务的容器就不会争用相同的内存。有关更多信息,请参阅容器实例内存管理

验证环境变量 ECS_CLUSTER 具有正确的集群名称

如果 Amazon ECS 容器代理配置参数 ECS_CLUSTER 具有不正确的集群名称,则容器实例无法加入集群。检查 /etc/ecs/ecs.config 文件的内容以验证此参数。

cat /etc/ecs/ecs.config

验证 ECS 代理可以与 ECS 终端节点通信

请确保容器实例使用的网络访问控制列表和安全组允许端口 443 (HTTPS) 上的出站连接与 ECS 终端节点连接。

在容器实例上运行以下任一命令,检查与 ECS 终端节点 (ACS/TCS) 的出站连接:

sudo yum install telnet -y
$ telnet ecs.region.amazonaws.com 443

-或者-

$ curl https://ecs.region.amazonaws.com

以下是需要记住的一些最佳实践:


这篇文章对您有帮助吗?


您是否需要账单或技术支持?