docker0 和 eth0 有啥关系?

Posted

技术标签:

【中文标题】docker0 和 eth0 有啥关系?【英文标题】:What is the relation between docker0 and eth0?docker0 和 eth0 有什么关系? 【发布时间】:2016-09-28 22:25:12 【问题描述】:

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

如上图:

容器eth0vethXXX 配对 vethXXX 链接到docker0 与链接到交换机的机器相同

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

    当一个数据包从容器流到docker0时,它怎么知道它会被转发到eth0,然后再到外界? 当外部数据包到达eth0时,为什么它会被转发到docker0然后容器?而不是处理它或丢弃它?

问题 2 可能有点令人困惑,我将保留它并进一步解释:

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

提前致谢!


看了答案和官网文章,我发现下图更准确,docker0eth0没有直接链接,而是可以转发数据包:

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

【问题讨论】:

有人可以更新最后一个 png 链接吗? (破404)》下图 @HLL 我不记得它长什么样了,但这里是another that shows the concept of separation of the networks 【参考方案1】:

默认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

容器被分配了一个附加到docker0桥的veth接口。

$ 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,因为 MASQUERADE 将映射连接回来。

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

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

【讨论】:

感谢您的解释。我可以这样说:当一个数据包从容器到达docker0时,它不知道也不关心eth0。相反,内核接管并决定如何处理它。默认情况下内核会检查路由表,通常会发送到eth0,然后是SNAT,然后是out world? 是的,标准的 linux 路由和 NAT。【参考方案2】:

您可以通过容器中的网络接口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

【讨论】:

以上是关于docker0 和 eth0 有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章

Docker网络与Iptables浅析

Docker网络跨主机通讯vxlan和vlan

Docker网络

Docker网络

docker同宿主机容器和不同宿主机容器之间怎么通信?

linux本地回环lo有啥用