我在桥接网络中有一个容器。它可以毫无问题地到达主机,并连接到主机上的每个端口(除了其他容器发布的端口)。
我禁用了 userland 代理,所以我认为这可能与 docker 如何设置 iptable 规则有关。
有没有一种简单的方法可以允许容器到达其他容器(在不同的桥接网络中运行)发布的端口?
我想避免将两个容器放在同一网络中,或切换到主机网络。
答案1
我无法重现你的问题。
我定义了两个 Docker 桥接网络:
eecf335e7600 net1 bridge local
5c7ca74637b0 net2 bridge local
c1
我在网络中启动容器net1
,将容器端口发布8080
到主机端口8081
:
$ docker run -d --rm --net net1 -p 8081:8080 --name c1 \
--add-host host.docker.local:host-gateway alpinelinux/darkhttpd
c2
我在网络中启动容器net2
,将容器端口发布8080
到主机端口8082
:
$ docker run -d --rm --net net2 -p 8082:8080 --name c2 \
--add-host host.docker.local:host-gateway alpinelinux/darkhttpd
现在,在容器内,我可以通过访问主机端口来c1
访问容器中的 Web 服务:c2
8082
$ docker exec c1 wget -O- http://host.docker.local:8082
Connecting to host.docker.local:8082 (172.17.0.1:8082)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
...
从容器中,我可以通过访问主机端口来c2
访问容器中的 Web 服务:c1
8081
$ docker exec c2 wget -O- http://host.docker.local:8081
Connecting to host.docker.local:8081 (172.17.0.1:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
...
一切似乎都像广告上说的那样。如果重复同一组步骤得到不同的结果,我要检查的第一件事是查看主机上是否有可能干扰流量的防火墙规则。
更新
--add-host
正如预期的那样,如果我只选择主机地址而不是使用该选项,行为是相同的。例如,如果我有:
$ ip -o addr |grep -o '.*inet [^ ]*'
1: lo inet 127.0.0.1/8
2: eth0 inet 192.168.123.106/24
4: docker_gwbridge inet 172.23.0.1/16
8: br-70f125dc5b7d inet 192.168.208.1/20
15: br-a87cc1462629 inet 172.29.0.1/16
18: docker0 inet 172.17.0.1/16
35: br-eecf335e7600 inet 172.18.0.1/16
36: br-5c7ca74637b0 inet 172.19.0.1/16
然后这些都起作用:
$ docker exec c2 wget -O- 192.168.123.106:8081 | head -3
Connecting to 192.168.123.106:8081 (192.168.123.106:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
<title>/</title>
$ docker exec c2 wget -O- 172.29.0.1:8081 | head -3
Connecting to 172.29.0.1:8081 (172.29.0.1:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
<title>/</title>
$ docker exec c2 wget -O- 172.18.0.1:8081 | head -3
Connecting to 172.18.0.1:8081 (172.18.0.1:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
<title>/</title>
ETC。
我没有在问题中提到它,因为我很确定在禁用它之前我已经遇到了这个问题......
与默认设置相比,这是一个相当大的配置更改:)。
如果我禁用用户层代理,一切都会停止工作。
本文可能感兴趣:
在上一节中,我们确定了 Docker 无法使用 iptables NAT 规则将已发布端口映射到容器服务的两种场景:
- 当连接到另一个 Docker 网络的容器尝试访问该服务时(Docker 正在阻止 Docker 网络之间的直接通信);
- 当本地进程尝试通过环回接口访问服务时。
在这两种情况下,Docker 都使用用户层(Linux 进程)TCP 或 UDP 代理。在使用已发布端口启动容器后,您可以使用 netstat 命令轻松识别代理(我们将再次使用我们的标准 Flask 应用程序):