为什么ping数据包无法到达docker中的自定义网关?

时间:2015-12-23 16:37:44

标签: linux networking docker icmp linux-containers

故事

我有以下虚拟Docker网络配置:

 ...10.2        ...10.3 ...100.3        ...100.2
+------+            +-------+            +------+
| so_A +--so_net_a--+ so_AB +--so_net_b--+ so_B |
+------+ ...10.0/24 +-------+ ..100.0/24 +------+

在问题的最后使用安装脚本进行构建。这里so_Aso_ABso_B是Debian容器; so_net_aso_net_b是Docker网络(最近添加的功能)。

我想从中间容器so_AB中创建一个路由器。为此,我将so_A中的默认网关替换为so_AB的IP:

docker exec --privileged so_A ip route del default
docker exec --privileged so_A ip route add default via $AB_A_IP dev eth0

然后我在tcpdump(在额外的终端窗口中)运行so_AB

docker attach so_AB
/# tcpdump -i eth0 -n

并从so_A ping一些地址。我不明白为什么当我从完全不相关的网络ping IP地址时,例如:

docker attach so_A
/# ping 192.168.200.2

so_AB接收ICMP数据包(虽然出于某种原因来自默认网关192.168.10.1,而我希望它们来自so_A ip 192.168.10.2),当时我ping so_net_b子网中的任何地址,例如:

/# ping 192.168.100.15

so_AB仅收到ARP请求,例如ARP, Request who-has 192.168.10.3 tell 192.168.10.2, length 28

ip route get表示so_A使用so_AB作为两个地址的第一跳。

问题

为什么相关IP地址的ping数据包到达自定义设置的默认网关,而不相关的地址呢?

设置

我在64位ubuntu 1.9.1, build a34a1d5上使用最新的Docker版本:14.04

以下是重现问题的设置脚本:

docker network create --driver=bridge --subnet=192.168.10.0/24 so_net_a
docker network create --driver=bridge --subnet=192.168.100.0/24 so_net_b

# Network topology:
# +------+            +-------+            +------+
# | so_A +--so_net_a--+ so_AB +--so_net_b--+ so_B |
# +------+            +-------+            +------+

docker run -itd --name=so_A --net=so_net_a debian /bin/bash
docker run -itd --name=so_B --net=so_net_b debian /bin/bash
docker run -itd --name=so_AB --net=so_net_a debian /bin/bash
docker network connect so_net_b so_AB

docker exec so_AB sh -c 'apt-get update && apt-get install -y tcpdump'

AB_A_IP=`docker inspect -f '{{.NetworkSettings.Networks.so_net_a.IPAddress}}' so_AB`
B_IP=`docker inspect -f '{{.NetworkSettings.Networks.so_net_b.IPAddress}}' so_B`

# Change the default gateway to so_AB
docker exec --privileged so_A ip route del default
docker exec --privileged so_A ip route add default via $AB_A_IP dev eth0

# Normally should be 192.168.100.2
echo $B_IP

0 个答案:

没有答案