Docker容器(IP 172.17.0.2)无法访问同网段外部IP的技术咨询
当你的Docker容器使用默认bridge网络(IP 172.17.0.2),要访问外部同网段(172.17.xxx.xx)的服务时,默认路由会把整个172.17.0.0/16网段的流量都导向Docker内部的docker0网桥,根本不会走宿主机路由去访问外部服务,这就是连接失败的核心原因。
下面是几种可行的解决办法:
修改容器内路由表(临时生效)
先进入目标容器:docker exec -it <你的容器名/ID> bash
删除默认的全局172.17网段路由:ip route del 172.17.0.0/16
然后添加针对外部服务所在具体子网的路由(假设外部服务子网是172.17.100.0/24,下一跳填宿主机的docker0地址,一般是172.17.0.1):ip route add 172.17.100.0/24 via 172.17.0.1
这样只有指定子网的流量会走宿主机转发到外部,容器间的正常通信不受影响。使用自定义Bridge网络(推荐长期方案)
默认bridge网络的路由规则比较死板,自定义网络会自动适配路由:
先创建自定义bridge:docker network create --driver bridge --subnet 172.18.0.0/16 custom-bridge
启动容器时指定这个网络:docker run -d --network custom-bridge --ip 172.18.0.2 <你的镜像名>
自定义网络只会为容器实际存在的IP生成路由,访问外部172.17网段服务时会自动走宿主机默认路由,彻底避免冲突。临时调整宿主机iptables(仅测试用)
如果不想改动容器,可以在宿主机上添加iptables规则,让目标为外部服务IP的流量绕过Docker的DNAT规则:iptables -t nat -I PREROUTING -d 172.17.xxx.xx/32 -j RETURN
注意:Docker重启后这个规则会丢失,不适合长期使用。
内容的提问来源于stack exchange,提问作者Ahmad Mohamed

