如何从外部容器Ping通Docker-in-Docker内部的容器?
解决Docker DinD环境下con1访问internal_container的问题
要实现con1(172.28.5.1)ping通con2内部的internal_container(172.28.6.1),需要完成路由配置和SNAT地址转换两个核心步骤,具体操作如下:
1. 给con1添加静态路由
con1默认不知道172.28.6.0/24网段的位置,需要指定该网段的流量全部转发到con2(172.28.5.2):
docker exec con1 ip route add 172.28.6.0/24 via 172.28.5.2
2. 在con2上配置SNAT规则
当con1的流量通过con2转发到internal_container时,需要将源IP转换为con2在dind_net网段的网关IP(172.28.6.254),这样internal_container的回包才能正确返回给con2,再转发回con1:
docker exec con2 iptables -t nat -A POSTROUTING -s 172.28.5.0/24 -d 172.28.6.0/24 -j SNAT --to-source 172.28.6.254
3. (可选)确保转发规则放行流量
如果con2的iptables默认过滤了转发流量,添加以下规则允许双向转发:
docker exec con2 iptables -A FORWARD -s 172.28.5.0/24 -d 172.28.6.0/24 -j ACCEPT docker exec con2 iptables -A FORWARD -s 172.28.6.0/24 -d 172.28.5.0/24 -j ACCEPT
完整修改后的脚本
将上述步骤插入到原脚本的ping命令前,最终脚本如下:
#!/bin/bash docker rm -f con1 docker rm -f con2 docker network rm net1 docker network create \ --driver=bridge \ --subnet=172.28.0.0/16 \ --ip-range=172.28.5.0/24 \ --gateway=172.28.5.254 \ net1 docker run -itd --network=net1 --ip=172.28.5.1 --privileged --name con1 ubuntu docker exec con1 apt-get update docker exec con1 apt-get install -y iptables iputils-ping docker exec con1 sysctl -w net.ipv4.conf.all.forwarding=1 docker run -itd --network=net1 --ip=172.28.5.2 --privileged --name con2 docker:dind sleep 2 # Wait until docker deamon is up # Create a network within "docker in docker" docker exec con2 \ docker network create \ --driver=bridge \ --subnet=172.28.6.0/24 \ --ip-range=172.28.6.0/24 \ --gateway=172.28.6.254 \ dind_net # In this "docker in docker" container create a container and join it to the dind_net network docker exec con2 \ docker run -itd --network=dind_net --ip=172.28.6.1 --name internal_container busybox docker exec con2 sysctl -w net.ipv4.conf.all.forwarding=1 # 添加路由和iptables规则 docker exec con1 ip route add 172.28.6.0/24 via 172.28.5.2 docker exec con2 iptables -t nat -A POSTROUTING -s 172.28.5.0/24 -d 172.28.6.0/24 -j SNAT --to-source 172.28.6.254 docker exec con2 iptables -A FORWARD -s 172.28.5.0/24 -d 172.28.6.0/24 -j ACCEPT docker exec con2 iptables -A FORWARD -s 172.28.6.0/24 -d 172.28.5.0/24 -j ACCEPT # Ping the internal_container(within the "docker in docker" container) docker exec con1 ping 172.28.6.1
原理说明
- 静态路由:让con1明确知道访问172.28.6.0/24网段的流量要走con2这个网关
- SNAT转换:由于internal_container的默认网关是con2内部的dind_net网关(172.28.6.254),如果直接用con1的IP访问,internal_container的回包会找不到路由;通过SNAT把源IP换成con2内部的网关IP,回包就能正确回到con2,再由con2转发回con1
内容的提问来源于stack exchange,提问作者Jayser
相关产品推荐
相关产品推荐

