Docker的网络实现基本原理是利用了linux 的网络命令空间和虚拟网络设备,因为Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据包将直接复制到接收接口的接收缓存中,而无须通过外部物理设备进行交换,Docker 中的网络接口默认都是虚拟接口,虚拟接口的最大优势就是转发效率极高。对于本地系统和容器内系统,虚拟接口与一个正常的以太网卡相比并无区别,只是它的速度要快得多。Docker 的网络实现物理拓扑图如图1 所示。
图 1 Docker 的网络实现物理拓扑图
可以发现,不同容器之间的网络建立了连接并实现了各主机之间的通信,这是通过 Docker 网桥 docker 实现的。网桥是一个二层的虚拟网络设备,能把若干个网络接口连接起来,以使得接口之间的报文能够互相转发。
我们来具体看一下 Docker 创建一个容器的时候,会具体执行哪些操作
(1)创建一对虚拟接口,分别放到本地 Docker 宿主机和新容器的命名空间中。
(2)本地 Docker 宿主机一端的虚拟接口连接到默认的 docker网桥或指定网桥上,并具有一个以 “虚拟接口”开头的唯一名字,例如虚拟接口1。
(3)容器这边的虚拟接口将放到新创建的容器中,并修改名字为“虚拟接口2”,这个接口只在容器的命令空间中可见。
(4)Docker 宿主机从自身的网络可用地址中获取一个空闲地址分配给容器的“虚拟接口2”(例如 172.17.2.2/16)。
(5)完成这些操作以后,容器就可以使用它能看到的“虚拟接口2”虚拟网卡来访问外部网络(SNAT),或者外部网络访问新建容器(DNAT)。SNAT 和 DNAT 机制通过 Docker 宿主机本身的防火墙来实现。