如何从外部IP访问使用network_mode: "host"运行的Docker服务

5
我的情况:
我有一台IP地址为x.x.x.x的服务器,在此服务器上运行了一个MongoDB实例。同时,我也使用下面的docker-compose.yml文件构建了我的服务。
version: "3" 
services:  
   myApp:
    image: myApplication
    ports:
      - "8080:8080"
    environment:
      SPRING_DATA_MONGODB_URI: mongodb://localhost:27017/myAppDb

当我运行docker-compose up来启动容器时,我可以通过x.x.x.x:8080从我的计算机访问我的服务。但问题是,我的服务无法连接到位于localhost:27017的mongoDB,因为它们不在同一个网络中。因此,我在我的docker-compose文件中添加了选项network_mode: "host",它解决了问题,我的服务可以连接到在服务器上运行的mongoDB。但是,我不能再通过x.x.x.x:8080访问我的服务了。
我的问题是:如何在选项network_mode:"host"的情况下仍然可以通过x.x.x.x: 80连接到我的服务?或者有没有一种方法,我不需要使用那个选项,但我的服务仍然可以连接到mongoDB实例?
注意:MongoDB实例是以传统方式安装(yum install mongodb-org),并设置为只能通过localhost:27017(或127.0.0.1:27107)访问。我不知道为什么或如何,但就是这样,所以我不能将连接字符串更改为mongodb://x.x.x.x:27017。它只是行不通的。
我还知道可以将mongodb作为docker-compose文件中的服务添加以实现我的目标,但我不想这样做,因为在我的情况下,最好单独管理数据库。
2个回答

0

看起来唯一的出路是以 host 模式运行 myApp 容器。在此模式下,服务应该可以通过主机的 IP 地址和端口 8080 访问。 如果不能访问,那很可能是由于防火墙问题。

相同的服务也可以在 bridge 网络模式下访问,因为在这种模式下,Docker 操作 iptables 规则以提供对容器的访问。更多信息请参见 这里

在您的特定情况下,Docker 添加了一个 NAT 规则,将主机上端口 8080 的传入流量转发到容器上的端口 8080。执行 iptables 命令即可。

iptables -t nat -L

应该输出规则:
Chain POSTROUTING (policy ACCEPT)
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:http-alt
...
Chain DOCKER (2 references)
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http-alt to:172.17.0.2:8080 

其中172.17.0.2是容器的IP

问题出在host模式,发布端口被丢弃,Docker不会添加任何规则来允许端口8080的传入流量。您需要自己添加规则。

希望能有所帮助。


谢谢。我想我的情况正如你所说的那样。现在我对Docker网络有了一些了解,感觉很傻,曾经问过这样一个愚蠢的问题:D - Hien Le
没有所谓的愚蠢问题。一旦你理解了某件事情,你会觉得它很显然。 - b0gusb
请帮帮我,我正在使用macOS,但是没有“iptables”命令,你知道其他等效的命令吗? - jonathasborges1

0

我曾经遇到过类似的问题,但我没有使用docker-compose,不过我认为你可以尝试应用相同的方法。

你可以创建自己的桥接网络(https://docs.docker.com/network/bridge/)来代替使用主机,然后我认为你的服务应该能够访问mongodb,而你也应该能够访问mongodb :)


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