无法从主机访问 Docker 自定义桥接网络中发布的端口
Cannot access port published in a Docker custom bridge network from the host
所以,情况是这样的。我有两个容器,一个提供数据库服务,另一个提供前端。前端容器使用它的一个端口连接到 DB 容器,然后发布它自己的一个端口以提供一系列 RESTful 服务。
此配置运行在默认网桥中很好用。但是,我在 Docker 文档中读到不建议在生产环境的默认桥上 运行 容器,因为这些端口会暴露给任何机器,而不仅仅是在网络中.他们建议在这种情况下使用自定义桥。
我的想法是(如文档中描述的一个用例),我的前端可以通过发布相应的端口从主机访问,但数据库容器不能访问,它应该只能访问连接到同一个自定义桥的前端容器。
我已经设置了这样的配置,但是现在,即使前端的端口已经公开并发布,也无法从主机访问它。我想我做错了什么或者误解了一些概念,但我似乎无法弄清楚。
我采取的步骤如下:
创建自定义网络:
docker network create --subnet=172.19.0.0/16 -o com.docker.network.bridge.enable_ip_masquerade=true -o com.docker.network.bridge.host_binding_ipv4="172.19.0.1" -o com.docker.network.bridge.enable_icc=true -o com.docker.network.bridge.name="serversBridge" servers
运行 数据库容器:
docker run -d --name testDb --network servers --ip 172.19.0.2 couchdb
运行前端容器:
docker run --name myApp --network servers --ip 172.19.0.3 -p 12345:12345 myApp
如果我然后 运行 docker ps
,我得到下一行:
`CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b8e93e6e9e1 myApp "./myApp" 4 hours ago Up 4 hours 172.19.0.1:12345->12345/tcp myApp`
但是,如果我尝试从我的主机访问该 IP 地址和端口,我将收到 "connection refused" 消息。我已经检查了 IP 表,但是有一个规则:
target prot opt source destination
ACCEPT tcp -- anywhere 172.19.0.3 tcp dpt:12345
所以我目前的猜测是我的请求实际上被转发到容器并被它拒绝了。是不是我做错了什么,或者我误解了一些概念?
我最终通过 运行 本地广播 IP 地址 (0.0.0.0
) 容器内的应用程序解决了这个问题,而不是将其绑定到侦听本地主机 IP 地址 (127.0.0.1
).
据我所知,主机访问 IP 地址 172.19.0.1
以到达此容器,请求不会来自 127.0.0.1
接口,它们将被拒绝。
即使我尝试将端口转发到主机的 0.0.0.0:12345
并通过从主机向 localhost:12345
发送请求来访问网络,也是如此,因为我的默认网桥会创建NAT 伪装并使用相应的内部 IP 地址 (172.19.0.3
) 在本地转发请求。
我仍然不完全理解为什么同样的配置在默认网桥上起作用。我假设它的化装舞会不是以同样的方式完成的
所以,情况是这样的。我有两个容器,一个提供数据库服务,另一个提供前端。前端容器使用它的一个端口连接到 DB 容器,然后发布它自己的一个端口以提供一系列 RESTful 服务。
此配置运行在默认网桥中很好用。但是,我在 Docker 文档中读到不建议在生产环境的默认桥上 运行 容器,因为这些端口会暴露给任何机器,而不仅仅是在网络中.他们建议在这种情况下使用自定义桥。
我的想法是(如文档中描述的一个用例),我的前端可以通过发布相应的端口从主机访问,但数据库容器不能访问,它应该只能访问连接到同一个自定义桥的前端容器。
我已经设置了这样的配置,但是现在,即使前端的端口已经公开并发布,也无法从主机访问它。我想我做错了什么或者误解了一些概念,但我似乎无法弄清楚。
我采取的步骤如下:
创建自定义网络:
docker network create --subnet=172.19.0.0/16 -o com.docker.network.bridge.enable_ip_masquerade=true -o com.docker.network.bridge.host_binding_ipv4="172.19.0.1" -o com.docker.network.bridge.enable_icc=true -o com.docker.network.bridge.name="serversBridge" servers
运行 数据库容器:
docker run -d --name testDb --network servers --ip 172.19.0.2 couchdb
运行前端容器:
docker run --name myApp --network servers --ip 172.19.0.3 -p 12345:12345 myApp
如果我然后 运行 docker ps
,我得到下一行:
`CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b8e93e6e9e1 myApp "./myApp" 4 hours ago Up 4 hours 172.19.0.1:12345->12345/tcp myApp`
但是,如果我尝试从我的主机访问该 IP 地址和端口,我将收到 "connection refused" 消息。我已经检查了 IP 表,但是有一个规则:
target prot opt source destination
ACCEPT tcp -- anywhere 172.19.0.3 tcp dpt:12345
所以我目前的猜测是我的请求实际上被转发到容器并被它拒绝了。是不是我做错了什么,或者我误解了一些概念?
我最终通过 运行 本地广播 IP 地址 (0.0.0.0
) 容器内的应用程序解决了这个问题,而不是将其绑定到侦听本地主机 IP 地址 (127.0.0.1
).
据我所知,主机访问 IP 地址 172.19.0.1
以到达此容器,请求不会来自 127.0.0.1
接口,它们将被拒绝。
即使我尝试将端口转发到主机的 0.0.0.0:12345
并通过从主机向 localhost:12345
发送请求来访问网络,也是如此,因为我的默认网桥会创建NAT 伪装并使用相应的内部 IP 地址 (172.19.0.3
) 在本地转发请求。
我仍然不完全理解为什么同样的配置在默认网桥上起作用。我假设它的化装舞会不是以同样的方式完成的