无法从容器访问主机的服务



在主机上,有一个服务

@server# netstat -ln | grep 3308
tcp6       0      0 :::3308                 :::*                    LISTEN

可以从远程到达。容器位于用户定义的网桥网络中。服务器 IP 地址为 192.168.1.30

@localhost ~]# ifconfig
br-a54fd3b63acd: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        inet6 fe80::42:1eff:fecc:92e8  prefixlen 64  scopeid 0x20<link>
        ether 02:42:1e:cc:92:e8  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:37ff:fe9f:e4f1  prefixlen 64  scopeid 0x20<link>
        ether 02:42:37:9f:e4:f1  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 34  bytes 4018 (3.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.30  netmask 255.255.255.0  broadcast 192.168.1.255

容器中的ping也可以使用。

@33208c18aa61:~# ping -c 2 192.168.1.30
PING 192.168.1.30 (192.168.1.30) 56(84) bytes of data.
64 bytes from 192.168.1.30: icmp_seq=1 ttl=64 time=0.120 ms
64 bytes from 192.168.1.30: icmp_seq=2 ttl=64 time=0.105 ms

并且该服务可用。

@server# telnet 192.168.1.30 3308
Trying 192.168.1.30...
Connected to 192.168.1.30.
Escape character is '^]'.
N

但无法从容器访问该服务。

@33208c18aa61:~# telnet 192.168.1.30 3308
Trying 192.168.1.30...
telnet: Unable to connect to remote host: No route to host

我检查了使 docker 使用 IPv4 进行端口绑定确保我没有将 IPv6 设置为仅在 IPv6 上绑定

# sysctl net.ipv6.bindv6only
net.ipv6.bindv6only = 0

从 Docker 容器内部,如何连接到计算机的本地主机?发现我的路线有点不同。

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         router.asus.com 0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-a54fd3b63acd
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0

有关系吗?还是其他原因?

docker 容器位于不同的网络命名空间上,并连接到与主机不同的接口,这就是无法使用 IP 192.168.x.x访问它的原因

您需要做的是改用 docker 网络网关,在您的情况下172.17.0.1但请注意,此 IP 可能因主机而异,因此要在任何地方重现它并完全确定哪个是 IP,您可以创建一个用户定义的网络,指定子网和网关并在那里运行容器,例如:

docker network create -d bridge --subnet 172.16.0.0/24 --gateway 172.16.0.1 dockernet
docker run --net=dockernet ubuntu

此外,您尝试在此处连接的任何服务也必须侦听 docker 的桥接接口。

另一种选择是在与具有 --net=host 标志的主机相同的网络命名空间上运行容器,在这种情况下,您可以使用 localhost 访问容器外部的服务

灵感来自官方文档

Docker 桥驱动程序会自动在主机中安装规则 机器,以便不同桥接网络上的容器不能 直接相互沟通。

我检查了服务器上的iptables,对于一个实验,我暂时停止了iptables。然后,容器可以成功实现该服务。后来我被告知,服务器最近重新启动了。因此,在重新启动后猜测某些配置丢失了。不太熟悉iptables,当我尝试时

systemctl status iptables.service

它说该服务未安装。安装并运行服务后,

iptables -L -n

几乎是空的。现在不知道什么样的iptables规则会导致这种混乱。
但如果有人面临ping success telnet fail的情况,iptables可能是根本原因的地方。

最新更新