业界有很多容器网络实现,为什么选它们俩进行比较?我的标准是一容器一IP, 高效转发,隔离, 已有网络基础设施的兼容程度高,丰富的特性。所以,overlay,flannel之类的没考虑,linux bridge虽然简单,功能上无法应对复杂需求。筛选下来,只有它们比较值得去研究比较一下。当然,docker原生的mac vlan也不错,但我更倾向使用网络插件,因为可以独立升级。
接下来会简单介绍一下这两个网络插件,并从网络模型,实现机制,转发效率,软件成熟程度等方面进行比较。
Calico 是一个多主机路由软件,还包含一个分布式防火墙。 Calico 是专门为容器和虚拟机尤其是 docker 和 OpenStack 环境设计的。 Tigera 公司赞助,用 python 语言开发。看起来, calico 有望成为这样一种解决方案:用户能够在生产环境部署容器,同时保证严格的安全。
Calico 为每个容器或者虚拟机分配一个独立的 IP 地址,然后在每台物理主机上定义包含这些 IP 地址的 iptables 规则,实现了防火墙功能。 Calico 在每个物理节点上跑一个高效的vRouter, 由它对外广播本机各容器的路由信息。它基于BGP协议,不仅适用于小规模部署,在route reflector的帮助下,更能应用于大型DataCenter。包的转发用是的Linux内核的转发功能,高效而简单。只要编排框架支持为每个服务分配一个 IP 地址,就可以集成使用 calico 。借数人云老肖一个图:
从本质上讲,Calico巧妙地把容器们的访问信息,包装在路由信息里,把L3作为容器访问的隔离方式,并使用Liniux转发内核,很好地作出隔离与性能间的权衡。不象vxlan,weave,为了隔离损失了性能, 也不象host模式,为了性能而损失了隔离性。在大型IDC的部署中,Calico官方的部署模式建议为『AS Per Rack model』,即每个机架一个自治域,自治域间通过L2全连接或者L3树形连接。只要idc接受内部跑BGP,这种网络结构的扩展能力还是比较强的。
二层核心交换部署
三层核心交换部署
Contiv Netplugin是来自思科的解决方案。编程语言为Go。它基于openvswitch,以插件化的形式支持容器访问网络,支持vlan, vxlan, 多租户,主机访问控制策略等。作为思科整体支持容器基础设施contiv项目的网络部分,最大的亮点在于容器被赋予了SDN能力,实现对容器更细粒度,更丰富的访问控制功能。另外,对Docker CNM网络模型的支持,并内置了IPAM接口,不仅仅提供了一容器一IP,而且容器的网络信息被记录的容器配置中,伴随着容器的整个生命周期,减低因为状态不同步造成网络信息丢失的风险。有别于CNI, 这种内聚化的设计有利于减少对第三方模块的依赖。随着项目的发展,除了Docker, 还提供了对K8S以及Mesos的支持,即CNI接口。
我们逐个点来聊聊:
两者都支持CNI和CNM网络模型。Calico是先有CNI, 再有CNM。Netplugin先有CNM, 再支持CNI。因为MESOS的关系,Calico比较偏向CNI阵型。至于哪种网络模型更好,cni最简单,为了通用性而对功能与配置方式有所牺牲。CNM也不复杂,设计更优雅, 容器网络相关信息持久在容器内部,与docker的交互更紧密点。如果计划用docker作为 contianerizer的话,建议用CNM。计划支持docker外多种containerizer的话,用cni。Netplugin支持CNI的方式比较特别,有一个cniplugin binary脚本执行后并不是直接跑脚本配置网络,而是http去请求内部cniserver,这个跟兼容已有contiv model有关。
从实现机制来看,calico 的本质是基于BGP的三层交换,加上iptable的访问控制,从而支持各种profile rule。Netplugin 的话以openvswitch为基石,不仅支持VLAN bridge二层协议, 也支持三层的BGP协议(vrouter)。访问控制基于openflow table,属于SDN应用于容器网络的典范。Calico运用了传统linux已有的各种模块来搭建自己的产品,掌握起来起容易,而且文档方面比较丰富,前提是需要客户接受这种创新性的BGP协议使用方式。Netplugin更符合近传统的网络框架,引入 OVS的确会提高复杂度,然而它能提供更丰富的功能,特别有利于针对sdn的二次开发。况且业界已经有大规模使用OVS的样例,如JD,相信稳定性不是问题。另外,vxlan也为公有云的发展方向提供有力支持。VLAN技术已经被广泛使用的情况下, netplugin + vlan更能被IDC接受,跟已有基础设施兼容性会更好。也许更多的是考验OVS的稳定性以及性能吧。
包转效率一直是大家比较网络解决方案的重要指标。测试使用了iperf 工具,在千兆网卡上跑,tcp, 从测试结果来看。两者的包转发效率都在80%以上,Calico带宽更稳定,可以保持在95%以上。Calico随着宿主机容器增加(30个以上),转发效率会下降。
高级网络控制方面,Calico基于iptable可以做到对ip类型,协议,端口,方向,等控制,没有限流功能。基于OVS的netplugin更丰富,能支持各种可编程网络功能,不仅有多种访问控制,包分级,而且能让容器加入不同的enpoint group, 实现多级别的限速。另外,它还内置了面向服务的负载均衡功能。限速对于大型的应用集群来说,是一个必要的功能,能够帮助我们更好的规划使用网络资源,避免应用突发流量所造成的不必要资源竞争状态。只有netplugin能满足这个需求, 用Calico的话只有自己基于TC开发了。在Calico测试中发现,每个容器会对应四条iptable规则,两条flex-from/to, 两条容器的CHAIN, 随着容器数量的增加(30个),过多的规则对包转发的效率存在比较大的影响。
Calico没有多租户的概念,所有容器节点都要求可被路由,IP地址不能重复。 Netplugin基于VXLAN可创建互相隔离的网络空间,不需要担心IP网段overlap的问题,并具有为提供公有云服务的能力。
Calico使用Python编程语言相对GO来说,不需要编译,语法没有那么严格,开发门槛更低一些,调度也更容易。 然而GO语言已经是大部分云计算软件的选择,内置并发支持,拥有不错的性能。各有优势吧。
对于不同类型调度器的支持,calico 针对不同调度器创建相应project跟踪,如libnetwork-plugin, calico-kubernetes, calico-mesos, 或者cni接口统一用calico-cni。 而且这些插件都可以容器化的形式跑。针对三大调度系统,netplugin也有三类内部插件, 对应对不同调度系统。比如k8splugin,它会用一个cniserver来把cni的请求转成netplugin内部定义的一系列通用REST接口, 这样就可以用一套内部接口来满足多种调度类型。另外,可惜是这些服务都没有容器化,应该是考虑到跑systemd更稳定吧。
代码数量级方面比较相近,30K LOC以下, 改动不大的情况下一到两人的团队就能维护。软件成熟度方面明显calico更好,github 500 +星,v1.6版本已发布。相比netplugin 只有 170 +星, 开发版v0.1-11-30-2016.20-08-20.UTC, 正式版仍未出来。Calico有三大模块,包括felix(更新配置路由表,iptable), bird(BGP广播路由信息), conf(监听etcd,动态生成BIRD配置文件)。因为是容器化部署,软件升级很容易,只需要新起一个容器替换旧的就可以了。Netplugin也是三大模块netplugin(接管容器网络服务,转发IP资源请求), netmaster(管理全局IP资源池), ovsdb(OVS 操作go 库,被netplugin调用)。它也能独立升级,不需要重启docker。所以模块数量,维护难度,耦合程度来说,两者比较接近。
对于一定规模的idc来说,VLAN肯定是必备功能,BGP也不会陌生。网络基础部门接受VLAN一定没问题,而BGP话还是要看部门的技术熟悉程度和意愿。协议本身很简单,毕竟这是该协议的新玩法,如果跟公司已有的网络框架规划不符,推行起来有一定困难。扩展性方面VLAN应该算是驾轻就熟,但是要小心避免大二层网络规模过大出现的arp风暴与cam表爆仓的问题,要么用三层隔离,要么用arp proxy。BGP的扩展性比VLAN更好, 新AS可以横向自由扩展而流量无需要经过已有的子页交换机,而且该协议本来就是为了解决城域交换的问题,大规模支持不成问题。要考虑的地方是,旧有的子页交换机未必支持BGP, 有可能要换硬件。
在IP池管理方面,Calico无IP分配中心,资源信息保存在etcd, 由agent分别去etcd拿。使用过程为预先创建subnet pool, 起容器的时候分别为宿主机分配一个30个地址的段(/27),同一主机里的后继容器都在这个段拿。这是为了路由聚合,避免过多的路由信息,然而有可能造成地址资源的浪费。如果主机不超过30个容器,没被使用的IP并不能分给别的机器。如果主机超过30个容器,会新开一个段,地址浪费也许更严重。Netplugin用netmaster作为IP分配中心,资源信息也在etcd, agent找netmaster要IP,IP从subnet里拿按顺序分配。理论上这样资源使用更充分,却存在潜在瓶颈, 要限制处理好并发拿IP的数量。
- 网络拓扑直观易懂,平行式扩展,可扩展性强
- 容器间网络三层隔离,无需要担心arp风暴
- 基于iptable/linux kernel包转发效率高,损耗低
- 更容易的编程语言(python)
- 社区活跃,正式版本较成熟
- 较早支持CNM模型。与已有的网络基础设施兼容性较高,改造影响小。基于VLAN的平行扩展与现有网络结构地位对等
- SDN能力,能够对容器的网络访问做更精细的控制
- 多租户支持,具备未来向混合云/公有云迁移的潜力
- 代码规模不大,逻辑结构清晰,并发好,VLAN在公司内部有开发部署运维实践经验,稳定性经过生产环境验证
- 京东基于相同的技术栈(ovs + vlan)已支持10w+ 容器的运行。
从纯技术角度来说,两种都是非常优秀的方案,它们综合技术指标都非常接近,各有千秋。相信两种方案都具备支持大规模容器网络的能力。公司需要根据部署现状,团队开发运维能力,以及未来的技术发展路线,来选取合适的解决方案吧。