跳至内容

如何对断开连接的 Amazon ECS 代理进行故障排除?

3 分钟阅读
0

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

简短描述

作为正常操作的一部分,您的 Amazon ECS 容器代理在一小时内多次断开连接并重新连接是正常的。这些变更事件并不令人担忧。仅持续几分钟的连接事件可能并不表示容器代理或您的容器实例存在问题。

但是,如果容器代理处于断开连接状态的时间更长,则容器实例将无法作为 Amazon ECS 集群的一部分运行。此问题可能是由以下原因之一引起的:

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

**注意:**最佳做法是使用最新版本的 Amazon ECS 容器代理。

解决方法

**注意:**以下解决方案适用于 Amazon ECS 优化的 Amazon Linux 2 AMI。

您可以使用 SSH 密钥连接到您的 Amazon EC2 实例。如果您没有生成 SSH 密钥,则可以使用会话管理器(AWS Systems Manager 的一项功能)连接到您的实例。默认情况下,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

输出指定处于活动状态(正在运行),如下所示:

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

输出指定处于活动状态(正在运行),如下所示:

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 来查看轮换的日志
  • 查看 Amazon ECS 初始化日志 /var/log/ecs/ecs-init.log
  • /var/log/cloud-init.log 中查看用户数据执行日志
  • 使用 sudo journalctl -u docker 命令查看 Docker 进程守护程序日志

如果您使用的是 Linux,还可以查看退出代码以获取有关已停止的代理容器的详细信息。有关详细信息,请参阅 GitHub 网站上的 exitcodes

要获取退出代码,请运行以下命令:

docker inspect your container ID

您的容器 ID 替换为已停止的容器的 ID。

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

验证 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 日志列表:

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

    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 容器代理和其他关键系统进程预留一些内存。预留此内存有助于确保任务的容器不会争用相同的内存。有关详细信息,请参阅预留 Amazon ECS Linux 容器实例内存

验证环境变量 ECS_CLUSTER 的集群名称是否正确

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

cat /etc/ecs/ecs.config

验证 ECS 代理是否可以与 ECS 端点通信

要连接 ECS 端点,网络访问控制列表和容器实例安全组必须允许端口 443 (HTTPS) 上的出站连接。

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

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

-或-

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

查看以下最佳实践:

相关信息

Amazon ECS 故障排除

创建容器实例角色

查看 Amazon ECS 容器代理日志

AWS 官方已更新 1 年前