在主机上,有一个服务
@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
可能是根本原因的地方。