背景
在我之前 weave的运行原理 的文章中,介绍到weave在跨主机的容器通信过程中,会使用pcap截获容器发送和接收的 网络包,然后按照自定义的格式将这些包重新封装为UDP报文再次注入到bridge上的接口发送出去。实际上这不是weave独有的选择,CoreOS的 fannel网络项目也是一样的方法。最近被docker公司收购的初创项目socketplane,采用基于openvswitch的vxlan的隧道技术来实现相同的过程。那么,就有一个疑问:实际上只要使用主机port mapping或是将docker原生网桥docker0的上行链路连通网卡,容器的流量都可以从主机发送出去,为什么这么多的docker网络项目都不约而同地选择使用隧道技术将网络负载再次封装发送,接收的时候再解封装呢?
解析原因
隧道封装是目前最简单的穿透docker容器复杂网络环境安全设置的方法
实际上这个问题最重要的原因是与docker容器运行环境的多样复杂性是直接相关的。我们都知道docker容器可以运行在公有云、私有云、虚拟化以及裸机上。为了网络的安全,这些环境上都应该有严格的安全组和防火墙设置来保障只有合法流量能够通过端口。这些带来了网络安全的同时,也给 docker容器的部署和可移动性带来了麻烦。每次部署启动一个容器,就要将其相应使用的端口上的安全设置更新为开放。尤其是混合云场景下这个问题就更为麻烦了。我举一个具体的例子:当前很多的PaaS服务提供商都没有自己的数据中心,他们直接从公有云的IaaS提供商那里获得虚拟机,那么这个时候就需要 PaaS提供方调用公有云IaaS提供方的网络安全设置的API来打开端口。PaaS提供商是不会把自己绑定死的,会选择多家公有云的 IaaS(AWS,GCE,Azure等),这些IaaS提供商的API全都不一样,这得多麻烦啊。这还没有考虑私有云,自己数据中心的虚拟化和裸机环境的端口ACL设置的复杂。
网络安全的设置还不仅仅只有这些,比如最常见的ip与mac绑定,这是openstack的默认设置,要修改可以,同样也要调用 openstack neutron的API增加端口允许的ip-mac pair。这里额外提一下,docker主机的port mapping方式由于限制了容器移动后的可访问性,不被大多数跨主机docker网络项目采用,多数项目还是希望能给每个容器一个ip,容器间访问使用这个ip,而不是docker容器所在主机的ip。
结论
通过上面的解析,可以想象,如果是在混合云场景下,使用隧道封装技术后,从虚拟机流出的流量ip和mac都是唯一的,且只使用固定的端口,那docker容器运行环境的安全设置就可以固定下来,简便多了。
其实,docker网络中使用隧道封装技术还可以有利于一些其他问题的解决:
1. 容器相较于虚拟机在一台主机上的密度大大增加,至少多出一个量级,要说两个量级我也信。在这样的情况下机架上的接入交换机的port-mac表容量是否足够呢,这里使用了隧道封装了负载后,就不用担心这个问题了。
2. 此外,就如同虚拟机使用了vxlan后一样,有利于打破ip地址网段对二层网络规模的限制,打造出一个大二层的网络。