Docker作为长远最火的分量级容器技艺,有很多令人称道的功能,如Docker的镜像管理。然而,Docker异常有着很多没有圆满的地方,网络范畴就是Docker比较薄弱的整体。因此,我们有必要深入了解Docker的网络知识,以中意更高的网络需求。朱文首先介绍了Docker自身的4种网络使命方式,然后通过3个样例 将Docker容器配置到当地网络中、单主机Docker容器的VLAN辨别、多主机Docker容器的VLAN辨别,演示了如何使用pipework帮助我们中止容易的网络装置,以及pipework是如何使命的。
远近闻名,Docker使用了Linux的Namespaces技艺来中止资源隔离,如PID Namespace隔离进程,Mount Namespace隔离材料系统,Network Namespace隔离网络等。一个Network Namespace需求了一份的网络,包括网卡、由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器畸形会分配一个的Network Namespace。但如果启动容器的时候使用host方式,这样这个容器将没有会获得一个的Network Namespace,而是和宿主机共用一个Network Namespace。容器将没有会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
类似,我们正正在10.10.101.105/24的机器上用host方式启动一个含有web运用的Docker容器,tcp80端口。当我们正正在容器中执行任何类似ifconfig告诉审查网络时,看到的都是宿主机上的信息。而访问容器中的运用,则直接使用10.10.101.105:80即可,没有必任何NAT转换,就如直接跑正正在宿主机中一样。但是,容器的其他范畴,如材料系统、进程列表等还是和宿主机隔离的。
正正在理解了host方式后,这个方式也就好理解了。这个方式指定新缔造的容器和已经存正在的一个容器共享一个Network Namespace,而没有是和宿主机共享。新缔造的容器没有会缔造自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。异常,两个容器除了网络范畴,其他的如材料系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
这个方式和前两个没有同。正正在这种方式下,Docker容器拥有自己的Network Namespace,但是,并没无为Docker容器中止任何网络配置。也就是说,这个Docker容器没有网卡、IP、由等信息。需要我们自己为Docker容器平添网卡、配置IP等。
当Docker server启动时,会正正在主机上缔造一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的使命方式和道理交换机类似,这样主机上的所有容器就通过交换机连正正在了一个二层网络中。接下去就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机没有同的IP地方和子网分配给docker0,连接到docker0的容器就从这个子网当选择一个未占用的IP使用。如畸形Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(正正在主机上使用ifconfig告诉是可以看到docker0的,可以认为它是网桥的管理接口,正正在宿主机上作为一块虚拟网卡使用)。单机下的网络拓扑如下,主机地方为10.10.101.105/24。
Docker将veth pair设备的一端放正正在新缔造的容器中,并冠名儿为eth0。另一端放正正在主机中,以veth65f9这样类似的名字冠名儿,并将这个网络设备加入到docker0网桥中,可以通过brctl show告诉审查。
这条规则会将源地方为172.17.0.0/16的包(也就是从Docker容器发作的包),并且没有是从docker0网卡发出的,中止源地方转换,转换出息机网卡的地方。那样说可以没有太好理解,举一个案件说明一下。假设主机有一块网卡为eth0,IP地方为10.10.101.105/24,网关为10.10.101.254。从主机上一个IP为172.17.0.1/16的容器中ping百度(180.76.3.151)。IP包首先镇静器发往自己的默认网关docker0,包到达docker0后,也就到达了主机上。然后会查询主机的由表,发现包应该从主机的eth0发往主机的网关10.10.105.254/24。接着包会转发给eth0,并从eth0发出去(主机的ip_forward转发应该已经打开)。这时候,的Iptable规则就会起作用,关于包做SNAT转换,将源地方换为eth0的地方。这样,正正在看来,这个包就是从10.10.101.105上发出来的,Docker容器关于外是没有可见的。
这样,外面的机器是如何访问Docker容器的服务呢?我们首先用下面告诉缔造一个含有web运用的容器,将容器的80端口照射到主机的80端口。
docker run -d --name web -p 80:80 fmzhen/web
此条规则就是关于主机eth0收到的手腕端口为80的tcp流量中止DNAT转换,将流量发往172.17.0.5:80,也就是我们缔造的Docker容器。由于,只需访问10.10.101.105:80就可以访问到容器中得服务。
除此之外,我们还可以自定义Docker使用的IP地方、DNS等信息,甚至使用自己定义的网桥,但是其使命方式还是一样的。
Docker自身的网络功能比较简单,没有能中意很多容易的运用场景。因此,有很多开源项目用来恶化Docker的网络功能,如pipework、weave、flannel等。这里,就先介绍一下pipework的使用和使命原理。
pipework是由Docker的工程师Jrme Petazzoni开辟的一个Docker网络配置工具,由200多行shell实现,方便易用。下面用三个场景来演示pipework的使用和使命原理。
使用docker inspect找到容器正正在主机中的PID,然后通过PID将容器的网络冠名儿工夫链接到/var/run/netns/目录下。那样做的手腕是,方便正正在主机上使用ip netns告诉配置容器的网络。因为,正正在Docker容器中,我们没有权限配置网络。
然后就是配置新网卡的IP。若正正在IP地方的后面加上网关地方,这样pipework会重新配置默认由。这样容器通往外网的流量会经由新配置的eth1出去,而没有是通过eth0和docker0。(若想完全抛弃自带的网络装置,正正在启动容器的时候可以指定--net=none)
以上就是pipework配置Docker网络的历程,这和Docker的bridge方式有着相似的办法。事实上,Docker正正在实现上也采用了相同的底层机制。
通过源代码,可以看出,pipework通过封装Linux上的ip、brctl等告诉,简化了正正在容易场景下关于容器连接的操作告诉,为我们配置容易的网络拓扑需求了一个强有力的工具。当然,如果想了解底层的操作,我们也可以直接使用这些Linux告诉来完成使命,甚至可以根据自己的需求,平添额外的功能。
完成的办法后,主机A上的test1和主机B上的test3容器就辨别到了一个VLAN中,并且与主机A上的test2和主机B上的test4隔离(主机eth0网卡需要装置为混杂方式,连接主机的交换机端口应装置为trunk方式,即准许VLAN 100和VLAN 200的包通过)。拓扑图如下所示(省去了Docker默认的eth0网卡和主机上的docker0网桥):
通过的介绍,我相信本人关于Docker的网络已经有了一定的了解。对于于一个基本运用而言,Docker的网络模型已经很没有错了。然而,随着云计划和微服务的兴起,我们没有能永远中止正正在使用基本运用的级别上,我们需要性能更好且更锐敏的网络功能。pipework正好中意了我们这样的需求,从的样例中,我们可以看到pipework的方便之处。但是,同时也应注意到,pipework并没有是一套解决方案,它然而一个网络配置工具,我们可以使用它需求的强大功能,帮助我们构建自己的解决方案。
冯明振,浙江大学SEL实验室硕士研究生,长远正正在云院子团队从事科研和开辟使命。浙大团队关于PaaS,Docker,大数据和主流开源云计划技艺有深入的研究和二次开辟阅历,团队现将整体技艺文章贡献出来,希望能关于听众群有所帮助。