Docker无法连接到容器暴露的端口

33

场景:

嗨,我正在使用docker compose运行容器。 这个compose文件在我的本地windows 10 docker桌面上完美运行。 我使用driver bridge配置了自己的网络。 现在我想在带有ubuntu虚拟机的外部服务器上运行docker compose。 我远程连接到服务器的putty。当我运行docker-compose up时,所有服务都成功启动了。 我还运行了portainer以进行GUI控制。

问题: 就像我说的,我所有的服务都在运行。与我的本地设置唯一不同的是,我将portainer作为单独的容器启动。我可以用浏览器连接到portainer并检查整个设置。但是,当我想调用我的暴露容器时,我无法建立连接并出现连接失败错误。当我查看portainer中容器规格中的IP地址列时,我发现portainer的IP与我的docker-compose容器不同。因此,portainer具有172.17.xxx,而所有其他容器都以172.20.xxx启动。显然,我的私有网络中的暴露端口未暴露给主机桥接网络。

期望结果: 我希望我的暴露端口能够通过我的虚拟机的IP像我的portainer实例一样可用。

想法: 我对docker还不太熟悉,因此我查看了文档,我认为由于描述:

在用户定义的桥接网络中,不支持链接。您可以在此网络中的容器上公开和发布容器端口。 如果您要将桥接网络的一部分提供给外部网络,则此功能非常有用。

..作为网络驱动程序的bridge会将我的网络连接到本地主机Internet连接。

问题: 当我从我的compose中单独运行portainer时,是否存在问题? 在外部服务器上运行我的compose而不是在localhost上运行时,是否还有其他事项需要注意?

compose network cfg:

networks:
  my_net:
    driver: bridge

我的版本是2.1

更新: Docker ps显示所有容器都在运行。 我想通过互联网访问的容器的docker inspect:

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "9e1e335ab30f1f4d3f690e8902e06523fa095e7d8bshddkdksis7d66s7sjdjd",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "7778/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "7778"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/9e1e386ttf56",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "my_net": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "3cb72e02c43b",
                        "usermanagement-service"
                    ],

                    "Gateway": "172.20.xx.x",
                    "IPAddress": "172.20.xx.xx",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null
                }
            }
        }
    }

1
你想要暴露的容器的 docker psdocker inspect 结果是什么? - Mostafa Hussein
更新了我的回答。 - FishingIsLife
你开放了端口7778,任何人都可以访问。当你尝试使用公共IP和端口连接时会发生什么? - Mostafa Hussein
超时。看起来是服务器端的防火墙问题。我只是在想9000是否有效。 - FishingIsLife
1
我已经添加了答案和解释,这样以后可能会帮助其他人 :D - Mostafa Hussein
显示剩余5条评论
5个回答

81

所以,这个问题可以分解为以下几个步骤:

  1. 检查 docker inspect 或者 docker ps 的结果,确保端口正确暴露。
  2. 尝试使用公共 IP 进行连接。如果出现错误信息,例如:

    • 连接被拒绝:原因可能是容器内部的应用程序没有按预期运行。例如,您需要确保应用程序绑定到 0.0.0.0 而不是 127.0.0.1

    • 连接超时:原因可能是服务器外部的防火墙(如 AWS 中的 SecurityGroups 或类似的防火墙)或者 Docker 没有管理服务器防火墙(这不是默认设置)。


2
对于未来的读者,在我的情况下,一个名为 openvpn 的进程导致了超时问题。 - Rodrigo Chaves
31
有些细节我忽略了:“你需要确保应用程序绑定到 0.0.0.0 而不是 127.0.0.1”。这就是我的问题所在。应用程序(Apache Tika 服务器)的默认端口是本地主机,所以我必须在 Docker 中使用 --host=0.0.0.0 来解决它。谢谢! - fbicknel
1
在我的情况下,我试图将应用程序绑定到与服务相同名称的主机(这是Docker文档中描述的内容),实际上只有当我将其绑定到0.0.0.0时才起作用。我的问题是:如果文档本身告诉我们使用服务名称作为主机,为什么它不起作用?可能是任何配置错误吗? - Sidney de Moraes
2
谢谢大家,--host=0.0.0.0 也是我的问题! - André Pacheco
在我的情况下,我只是停止了 Docker 服务并重新启动它,然后它就可以工作了。 - Gabriel Rockson
显示剩余2条评论

19
在我的情况下,这是由于参数顺序不正确引起的:
docker run myrazorapp -p 8080:80

应该是这样:

docker run -p 8080:80 myrazorapp 

端口参数被简单地忽略了。

3

最近我们遇到了与容器到容器连接类似的问题,问题出在默认Ubuntu防火墙ufw配置不当。

因此,在我们的情况下,解决方案是:

 sudo ufw disable

谢谢,这很有帮助! - Богдан Соловьев
谢谢,这很有帮助! - undefined

0
我在MacOS上运行Colima时遇到了这个问题。其他应用程序都正常工作,这让我感到困惑。结果发现重新启动Colima就解决了问题。
colima stop
colima start

-1

我遇到了一个问题,我指定了 RUN npm start 而不是 CMD npm start

你的容器将会启动但无法暴露出来,以下方法适用于我


你用了什么方法? - Waqar Afridi
我认为piecepaper的意思是他更改了Dockerfile,使用CMD而不是RUN来执行应用程序,并且这对他解决了问题。 - Ricardo Souza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接