一 引言
当 Docker 启动时,会自动在主机上创建一个名为 docker0 虚拟网桥,这实际上就是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
系统会为这个 docker0 分配一个私有网段的ip。如ip地址为172.17.0.1子网掩码为255.255.0.0。
当我们创建一个新的容器时,同时会创建了一对veth pair接口(即对等接口,当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。
![](https://i-blog.csdnimg.cn/blog_migrate/6ca64ebe087f869ae5dca91ec5ac0e15.png)
二 验证过程
先创建两个容器:
docker run -itd -P --name tomcat1 tomcat
docker run -itd -P --name tomcat2 tomcat
ifconfig
![](https://i-blog.csdnimg.cn/blog_migrate/75ae7ef81d7e52654481d7d36c572500.png)
可以看到随机生成了两个名称为veth9454074和vethe9b7cb1的interfaces。
查看主机网桥配置。
brctl show
两个容器的网络端口都挂载到了 docker0 上。
docker ps
查看运行的docker容器。
![](https://i-blog.csdnimg.cn/blog_migrate/770f71d9bbdabf532190adcc24fa2a85.png)
查看容器的网络信息
docker inspect tomcat1
![](https://i-blog.csdnimg.cn/blog_migrate/7fe16e003f64aed005ed4bf2eff08d4d.png)
docker inspect tomcat2
![](https://i-blog.csdnimg.cn/blog_migrate/87c63ef1b72b979d3d795fa95f774420.png)
可以看出,这里两个容器的网关都是172.17.0.1,即 docker 在物理主机上创建的 docker0 虚拟网桥。
ip地址分别为172.17.0.2和172.17.0.3。
进入到容器tomcat1中。
在容器中执行下面的命令,可以查看容器的网络信息。
ip addr show
![](https://i-blog.csdnimg.cn/blog_migrate/de24edb80b301287625f530da1c565ed.png)
可以看到,容器内有一个名为eth0的网络接口,ip为172.17.0.2。
查看容器转发信息
ip route show
![](https://i-blog.csdnimg.cn/blog_migrate/7a466d61bec042c3f3fedc83f2f4c189.png)
可以看出来,在容器中输出的路由信息,由172.17.0.0/16可知子网掩码是255.255.0.0。由此可知,docker的docker0 虚拟网桥和容器里的eth0都是属于同一个子网的。
这些网络配置和使用docker inspect查询出来的也是一致的。
同时可以验证,容器(tomcat1)与容器(tomcat2)之间,主机与容器之间,容器与主机之间的网络都是联通的。
![](https://i-blog.csdnimg.cn/blog_migrate/f86895b59bc8665a39cd3b58d067961b.png)
通过分析,上面的网络拓扑如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6d89b323ecf75bbb852e24598963c4ee.png)
三 网络配置的过程
所以,Docker完成以上网络配置的过程大致是这样的
1 在主机上创建一对虚拟网卡veth pair设备。
2 Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth*这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
3 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。