docker0和eth0有什么关系?
我知道默认情况下, docker0
创build一个虚拟网桥docker0
,所有的容器networking链接到docker0
。
如上图所示:
- 容器
eth0
与vethXXX
配对 -
vethXXX
链接到docker0
与链接到交换机的机器相同
但docker0
和host eth0
之间的关系是什么? 进一步来说:
- 当一个数据包从容器stream到docker0时,它怎么知道它会被转发到eth0,然后被转发到外部世界?
- 当外部数据包到达eth0时,为什么它被转发到docker0然后是容器? 而不是处理它或丢弃?
问题2可能有点混乱,我会保留在那里,再解释一下:
- 它是由容器(问题1)发起的返回包:由于外部不知道容器networking,所以将包发送到主机
eth0
。 它如何被转发到容器? 我的意思是,必须有一些地方来存储信息,我怎么检查它?
提前致谢!
在阅读答案和官方networking文章后,我发现下图更加准确, docker0
和eth0
没有直接链接,而是可以转发数据包:
http://dockerone.com/uploads/article/20150527/e84946a8e9df0ac6d109c35786ac4833.png
默认docker0
网桥和主机以太网设备之间没有直接的联系。 如果对容器使用--net=host
选项,则主机和容器networking堆栈将被链接。
当一个数据包从容器stream到docker0时,它怎么知道它会被转发到eth0,然后被转发到外部世界?
docker0
桥具有分配给它的.1
地址。
$ 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
默认networking上的容器接收.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处理连接跟踪并返回stream量。
当外部数据包到达eth0时,为什么它被转发到docker0然后是容器? 而不是处理它或丢弃?
如果您正在讨论返回出站stream量,请参阅上面的iptables。
如果您的意思是新的入站stream量,默认情况下,数据包不会转发到容器中。 达到此目的的标准方法是设置端口映射 。 Docker启动一个守护进程,监听端口X上的主机并转发到端口Y上的容器。
我不确定为什么NAT不用于入站stream量。 我遇到了一些问题,试图将大量的端口映射到容器中,导致将真实世界的接口完全映射到容器中。
您可以通过networking接口( iflink
从容器链接)和ifindex
上的iflink
来检测关系。
从容器获取iflink
:
$ docker exec ID cat /sys/class/net/eth0/iflink 17253
然后在主机的接口之间find这个ifindex
:
$ grep -l 17253 /sys/class/net/veth*/ifindex /sys/class/net/veth02455a1/ifindex