Docker一直以来的理念都是“以简单为美”,从Docker对Linux网络协议栈的操作可以看到,Docker一开始并没有考虑到多主机互联的网络解决方案。之后Docker收购了一家网络解决方案公司Socketplane,将原有的网络部分抽离,独立成Docker的网络库,即libnetwork。libnetwork实现了5种驱动,通过插件的形式允许用户根据自己的需求来实现网络驱动,但libnetwork组件只是将Docker平台中的网络子系统模块化为一个独立库的简单尝试,离成熟和完善还有一段距离。
随着容器技术在企业生产系统的逐步落地,用户对于容器云的网络特性要求也越来越高,跨主机容器间的网络互通已经成为最基本的要求。跨主机的容器网络解决方案不外乎三大类。
1、隧道方案
比如Flannel的VXLAN,特点是对底层的网络没有过高的要求,一般来说只要是三层可达即可——只要是在一个三层可达网络里,就能构建出一个基于隧道的容器网络。不过问题也很明显,一个得到大家共识的是随着节点规模的增长,复杂度会提升,而且出现网络问题后跟踪起来也比较麻烦。在大规模集群情况下,这是需要考虑的。
2、路由方案
路由技术从三层实现跨主机容器互通,没有NAT,效率比较高,与目前的网络能够融合在一起,每一个容器都可以像虚拟机一样分配一个业务的IP。但路由网络也有问题,路由网络对现有网络设备影响比较大,路由器的路由表应该有空间限制,一般是两三万条,而容器的大部分应用场景是运行微服务,数量集很大。如果几万个新的容器IP冲击到路由表中,会导致下层的物理设备无法承受;而且每一个容器都分配一个业务IP,业务IP会很快消耗完。
3、VLAN方案
所有容器和物理机在同一个VLAN中。基于主机的端口冲突和网络资源竞争比较麻烦,相对来说Calico的是纯三层的SDN实现,它基于BPG协议和Linux自己的路由转发机制,不依赖特殊硬件,没有使用NAT或Tunnel等技术。
它能够方便地部署在物理服务器、虚拟机(如OpenStack)或者容器环境下,同时它自带的基于Iptables的ACL管理组件非常灵活,能够满足比较复杂的企业安全隔离需求。关于容器应用的网络隔离还有多种解决方案,基本上就是把不同的应用容器放置在不同的VLAN/VXLAN中,通过让不同的VLAN/VXLAN不能互访而实现隔离。
可以尝试用Docker自带的Overlay来简单地解决,首先创建不同的网络,然后在启动不同应用的容器时,使用--net参数指定容器所在的对应的VXLAN即可。结果是同一个网络中的容器是互通的,不同网络中的容器是隔离的。目前应用OVS/Linux-bridge+VLAN方案的企业比较多,但长远看来Calico方案前景不错。