docker0和eth0之间有什么关系?

时间:2016-05-31 04:11:07

标签: networking docker

我知道默认情况下,docker会创建一个虚拟网桥docker0,并且所有容器网络都会链接到docker0

如上图所示:

  • 容器eth0vethXXX
  • 配对
  • vethXXXdocker0相关联,与链接到
  • 的机器相同

但是docker0和主持人eth0之间的关系是什么? 更具体地说:

  1. 当数据包从容器流向docker0时,它如何知道它将被转发到eth0,然后转发到外部世界?
  2. 当外部数据包到达eth0时,为什么它会转发到docker0然后转发到容器?而不是处理它或放弃它?
  3. 问题2可能有点令人困惑,我会将其保留在那里并再解释一下:

    • 这是一个由容器初始化的返回数据包(问题1):由于外部不知道容器网络,因此数据包将被发送到主机eth0。如何转发到容器?我的意思是,必须有一些地方存储信息,我该如何检查?

    提前致谢!

    在阅读完答案和官方网络文章后,我发现以下图表更准确,docker0eth0没有直接链接,而是可以转发数据包:

    http://dockerone.com/uploads/article/20150527/e84946a8e9df0ac6d109c35786ac4833.png

2 个答案:

答案 0 :(得分:20)

默认docker0网桥与主机以太网设备之间没有直接链接。如果对容器使用--net=host选项,则将链接主机和容器网络堆栈。

  

当数据包从容器流向docker0时,它如何知道它将被转发到eth0,然后转发到外部世界?

docker0网桥分配了Docker网络的.1地址,通常是172.17或172.18左右。

$ ip address show dev docker0
8: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:03:47:33:c1 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever

为容器分配一个veth接口,该接口连接到docker0网桥。

$ bridge link
10: vethcece7e5 state UP @(null): <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2

在默认Docker网络上创建的容器会将.1地址作为其默认路由。

$ docker run busybox ip route show
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  src 172.17.0.3 

Docker将NAT MASQUERADE用于来自那里的出站流量,它将遵循主机上的标准出站路由,可能会也可能不会默认为eth0

$ iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0  

iptables处理连接跟踪和返回流量。

  

当外部数据包到达eth0时,为什么它被转发到docker0然后容器?而不是处理它或丢弃它?

如果您询问返回出站流量,请参阅上面的iptables。

如果您的意思是新的入站流量,默认情况下不会将数据包转发到容器中。实现此目标的标准方法是设置a port mapping。 Docker启动一个守护程序,它在端口X上侦听主机并转发到端口Y上的容器。

我不确定为什么NA​​T也不用于入站流量。我遇到了一些问题,试图将大量端口映射到容器中,导致mapping real world interfaces完全进入容器。

答案 1 :(得分:0)

您可以通过网络接口iflink从容器和主机上的ifindex检测关系。

从容器中获取iflink

$ docker exec ID cat /sys/class/net/eth0/iflink

17253

然后在主机上的接口中找到此ifindex

$ grep -l 17253 /sys/class/net/veth*/ifindex

/sys/class/net/veth02455a1/ifindex