排查 AWS ECS 内容器服务 ALB 健康检查失败问题记录

Published: 2024-04-12

Tags: AWS

本文总阅读量

确认 Task 内容器服务已启动

通过跳板机登录到 Task 容器所在 EC2,而后通过 docker 命令进入到容器,确认资源、程序、配置、进程都已启动。

# 通过跳板机进入 ECS Node EC2 节点 
$ ssh -i ~/.ssh/your-jump-server-keys.pem ec2-user@10.0.11.22 -J jump-server

# 执行 docker 命令
$ docker ps

补充:EC2 IP 获取方法

在 ECS 集群上,找到需要排查问题的 Task 进入详情,详情中可以找到 “Launch type”,EC2 标签后的 i-XXXX 即节点 ID,点击跳转进入 EC2 详情,在 “Networking” 标签页可以看到 “Private IPv4 addresses”,可以看到两个 IP,选择跟 “Private IP DNS name (IPv4 only)” 一致的主 IP 使用

另外 jump-server 需要跟 ECS 的网络打通,建立 VPC 对等连接。

可能有些容器内部没有 curl 命令,同时也没有 apt 命令可供安装,可以在 Node EC2 上下载 curl-static 后复制进容器,命令参考:

$ docker cp curl-aarch64 container-name:/tmp/
$ docker exec -it container-name sh
$ chmod +x /tmp/curl-aarch64
$ /tmp/curl-aarch64 http://127.0.0.1:3000

备注:ECS Task 内的容器使用 Docker 进行运行,调试 ECS 容器的时候可以通过这种方式获知容器详情。

确认服务监听地址

Web 类型服务需要格外留意,因为 npm start 几乎都是默认绑定的 localhost,需要显式绑定为 0.0.0.0

以 Next 为例:

$ next start -H 0.0.0.0 -p 3001

端口访问确认

在第一步已经确认,在容器内部使用 curl 命令请求 localhost:3000(假定监听的是 3000 端口),可以请求通,说明服务正常启动并响应。

在容器内部通过 ifconfig 获取到 pod 的 IP 地址,如:10.0.16.170,退出容器(也可通过 TargetGroup 上注册的服务获取 IP)

在容器所在的 EC2 使用 curl 命令请求 10.0.16.170:3000,确认访问情况,访问不通说明 Task 对应的 Service 的安全组没有对端口放行

核对 TargetGroup 内注册端口

确认服务访问没问题后,到 TargetGroup 中查看 ECS 注册的容器 IP 和端口跟预期一致。

至此,可确认 ALB 到 Task 容器的访问链路没有问题。

验证结果总结

(1)在 TargetGroup 到 ECS Task 容器的访问链路中,Docker 镜像的 EXPOSE 和 Ansible 的 portMappings 没有实际作用,配置正确或错误都不影响访问结果。(此处提及 Ansible 是因为部署 ECS Task 使用的是 Ansible Playbook)

(2)实际验证下,能否正常请求只跟 ALB 能否通过容器IP + 容器端口访问到容器内服务有关,两个因素最为关键 —— 容器内服务正确监听了地址(0.0.0.0)、ECS Service 的安全组放行了要访问的端口