docker0桥接是如何在主机内部工作的



我想了解桥接的docker0接口是如何工作的。

    当docker守护进程启动时,它创建一个桥接设备docker0;
  • 当容器启动时,它创建一个接口vthn并绑定到docker0

假设我们从容器内部向外部主机发出ping命令

[root@f505f022eb5b app]# ping 130.49.40.130
PING 130.49.40.130 (130.49.40.130) 56(84) bytes of data.
64 bytes from 130.49.40.130: icmp_seq=1 ttl=52 time=11.9 ms

所以很明显我的主机eth0收到了这个ping,但是这个包是如何转发到容器的呢?有几个问题要问

  • eth0和docker0没有桥接,docker0如何从eth0获得数据包?
  • 即使docker0得到了数据包,它是如何在内部向vth0发送数据包的?它内部是否维护一些映射,以便它可以在不同的mac地址之间转换数据包?
  • iptables在这里是如何关联的?

欢呼。

Docker在这里并没有做任何特别神奇的事情,你的问题也不是真正依赖于Docker。

docker0只是一个网桥。一旦这个桥接被创建(在启动docker服务时),您就可以假设一台新机器(在这种情况下是VM/docker形式)已经加入了您的网络。

当从主机ping docker容器时,或者反之亦然,你基本上是在ping网络中的另一台机器。

关于docker,除非你创建了一个新的网络接口(我怀疑没有,因为你正在ping eth0),你基本上是在ping你自己。

如果您运行容器为:

docker run -i -t --rm -p 10.0.0.99:80:8080 ubuntu:16.04

你告诉docker在iptables中创建一个NAT规则,将任何到10.0.0.99:80的数据包转发到端口8080上的docker容器。

当你运行容器时:

docker run -i -t --rm -p --net=host ubuntu:16.04

那么你是说docker容器应该有与主机相同的网络堆栈,所以所有要到主机的数据包也将通过docker0桥到达你的docker容器

回答您的问题,容器如何ping外部主机,这也是通过NAT实现的。

使用sudo iptables -t nat -L

列出Iptables/NAT规则

您可能会看到类似于下面的内容(docker子网可能不同)

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        anywhere

这基本上是说NAT任何来自docker子网的传出数据包。因此,传出的数据包将看起来来自docker主机。当ping包返回时,NAT表将被用来确定是一个docker主机实际发出了请求,并且数据包被转发到docker服务器。

最新更新