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 localhostcurl 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 端口未正确绑定的主要内容,如果未能解决你的问题,请参考以下文章

在 Amazon ECS 上运行 X-Ray 守护程序

使用 docker compose 在 Amazon ECS 上部署应用程序

AWS 使用 Fargate 对 ECS 服务的多个端口进行负载平衡

AWS ECS Fargate - 任务未运行

Amazon ECS - 在 Docker 入口点上使用 IAM 角色时权限被拒绝

我们可以在 AWS ECS docker 容器上挂载 EFS 吗?