Amazon AWS ECS Docker 端口未正确绑定
Posted
技术标签:
【中文标题】Amazon AWS ECS Docker 端口未正确绑定【英文标题】:Amazon AWS ECS Docker Port not binding correctly 【发布时间】:2016-12-17 05:51:52 【问题描述】:我正在使用 ECS 优化的 ECS 映像并使用 ECS 进行部署。
因此,如果我 bash 进入容器并 curl localhost
我得到预期的输出(预期在端口 80 上),这可以正常工作。
如果我运行docker ps
我得到以下输出
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1234 orgname/imagename:release-v0.3.1 "npm start" 53 minutes ago Up 53 minutes 0.0.0.0:80->80/tcp ecs-myname-1234`
这表明端口80
正在按预期映射。 (我也看到了 Amazon ECS 代理,但在上面发布了它并不重要)
然后我可以运行netstat -tulpn | grep :80
并得到以下输出
(No info could be read for "-p": geteuid()=500 but you should be root.)
tcp 0 0 :::80 :::* LISTEN -
然后以 root 身份运行 sudo netstat -tulpn | grep :80
并得到以下输出
tcp 0 0 :::80 :::* LISTEN 21299/docker-proxy
这让我觉得它只是在侦听 IPv6 接口?我作为 localhost 的主机记录是 127.0.0.1 这就是为什么当我在主机上运行 curl localhost
或 curl 127.0.0.1
时我得到 curl: (56) Recv failure: Connection reset by peer
我还检查了安全组和网络 ACLS(不是说它们应该对 localhost 有影响)...
任何想法将不胜感激!
编辑:
为了更好地衡量(有些人建议当 ipv6 可用时 netstat 只显示 ipv6 而不是 ipv4。我也运行了这个命令 lsof -OnP | grep LISTEN
给出以下输出
sshd 2360 root 3u IPv4 10256 0t0 TCP *:22 (LISTEN)
sshd 2360 root 4u IPv6 10258 0t0 TCP *:22 (LISTEN)
sendmail 2409 root 4u IPv4 10356 0t0 TCP 127.0.0.1:25 (LISTEN)
exe 2909 root 4u IPv4 13802 0t0 TCP 127.0.0.1:51678 (LISTEN)
exe 21299 root 4u IPv6 68069 0t0 TCP *:80 (LISTEN)
exe 26395 root 4u IPv6 89357 0t0 TCP *:8080 (LISTEN)
【问题讨论】:
这似乎也适用于 Docker for AWS(完全相同)。你有什么发现吗? 有没有可能,容器内的应用没有绑定到80端口?您是否尝试从容器内部检查它?像 docker exec -it 1234 curl localhost 【参考方案1】:我在使用bridge
网络模式时遇到了这个确切的问题。我还没有找到解决办法。但是,我使用了两种解决方法。
解决方法
对我来说最简单的方法是在我的 ECS 任务定义中将 NetworkMode
更改为 host
。
或者,您可以通过使用Application Load Balancer
来消除了解或关心端口映射方式的需要。
网络模式
bridge
通过 docker-proxy 将容器端口映射到主机上的另一个端口(可能不同)。这是我在 ECS 中遇到问题的模式。
host
允许容器直接在主机上打开一个端口,不需要代理。缺点是同一个容器的实例不能在同一个主机上运行而不引起端口冲突。
awsvpc
类似于host
,只是它映射到您的 VPC 中的 ENI,而不是主机 IP 上的端口。
none
听起来就是这样。
应用负载均衡器
自从发布此答案后,我的项目要求发生了变化。我没有机会直接返回并在桥接模式下测试端口映射。但是,我现在使用 Application Load Balancer 来提供对我的容器的访问。
使用 ALB 时,您根本不必担心主机端口。相反,您的 ECS 服务会自动将您的容器作为目标添加到给定的 ALB 目标组。本文档详细介绍了如何执行此操作:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html
这里不再详细说明,因为它不是对端口绑定问题的直接回答。
有趣的是,在您提出问题 5 天后,ECS 的网络模式就宣布了:
公告:https://aws.amazon.com/about-aws/whats-new/2016/08/amazon-ec2-container-service-now-supports-networking-modes-and-memory-reservation/
网络模式文档:https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RegisterTaskDefinition.html#ECS-RegisterTaskDefinition-request-networkMode
希望这个答案对其他一些 Google 员工有所帮助。 注意:如果我知道如何让bridge
模式在 ECS 中正常工作,我会更新这个答案。
【讨论】:
如果桥接模式正常工作,期待您的更新!【参考方案2】:我遇到了类似的问题,但我在 docker 中运行 Java,它仅绑定在 IPv6 端口上。原来是Java相关的。更多关于这个here
【讨论】:
以上是关于Amazon AWS ECS Docker 端口未正确绑定的主要内容,如果未能解决你的问题,请参考以下文章
使用 docker compose 在 Amazon ECS 上部署应用程序
AWS 使用 Fargate 对 ECS 服务的多个端口进行负载平衡