容器网络插件 Calico 与 Contiv Netplugin深入比较


前言

业界有很多容器网络实现,为什么选它们俩进行比较?我的标准是一容器一 IP,高效转发,隔离, 已有网络基础设施的兼容程度高,丰富的特性。所以,Overlay,Flannel 之类的没考虑,Linux Bridge 虽然简单,功能上无法应对复杂需求。筛选下来,只有它们比较值得去研究比较一下。当然,Docker 原生的 MAC VLAN 也不错,但我更倾向使用网络插件,因为可以独立升级。

接下来会简单介绍一下这两个网络插件,并从网络模型,实现机制,转发效率,软件成熟程度等方面进行比较。

Calico简介

Calico 是一个多主机路由软件,还包含一个分布式防火墙。 Calico 是专门为容器和虚拟机尤其是 Docker 和 OpenStack 环境设计的。 Tigera 公司赞助,用 Python 语言开发。看起来, Calico 有望成为这样一种解决方案:用户能够在生产环境部署容器,同时保证严格的安全。

Calico 为每个容器或者虚拟机分配一个独立的 IP 地址,然后在每台物理主机上定义包含这些 IP 地址的 iptables 规则,实现了防火墙功能。 Calico 在每个物理节点上跑一个高效的vRouter, 由它对外广播本机各容器的路由信息。它基于BGP协议,不仅适用于小规模部署,在route reflector的帮助下,更能应用于大型DataCenter。包的转发用是的Linux内核的转发功能,高效而简单。只要编排框架支持为每个服务分配一个 IP 地址,就可以集成使用 Calico 。借数人云老肖一个图:
B79FB9E4-8AB0-42FD-B36E-AB36CFE33710.png

从本质上讲,Calico巧妙地把容器们的访问信息,包装在路由信息里,把L3作为容器访问的隔离方式,并使用 Linux 转发内核,很好地作出隔离与性能间的权衡。不象 Vxlan,Weave,为了隔离损失了性能, 也不象 host 模式,为了性能而损失了隔离性。在大型 IDC 的部署中,Calico 官方的部署模式建议为『AS Per Rack model』,即每个机架一个自治域,自治域间通过L2全连接或者L3树形连接。只要 IDC 接受内部跑 BGP,这种网络结构的扩展能力还是比较强的。
4F8739CA-9702-4EA5-B706-A24A2F3F44B5.png

二层核心交换部署

7B576B07-0D48-466F-B6A0-3421D8FA1E0A.png

三层核心交换部署

Contiv Netplugin 简介

Contiv Netplugin 是来自思科的解决方案。编程语言为 Go。它基于 OpenvSwitch,以插件化的形式支持容器访问网络,支持 VLAN,Vxlan,多租户,主机访问控制策略等。作为思科整体支持容器基础设施contiv项目的网络部分,最大的亮点在于容器被赋予了 SDN 能力,实现对容器更细粒度,更丰富的访问控制功能。另外,对 Docker CNM 网络模型的支持,并内置了 IPAM 接口,不仅仅提供了一容器一 IP,而且容器的网络信息被记录的容器配置中,伴随着容器的整个生命周期,减低因为状态不同步造成网络信息丢失的风险。有别于 CNI,这种内聚化的设计有利于减少对第三方模块的依赖。随着项目的发展,除了 Docker,还提供了对 Kubernetes 以及 Mesos 的支持,即 CNI 接口。
9260E9B7-43C0-48B8-B5C7-CF8B952959D2.png

  • Netmaster 后台进程负责记录所有节点状态,保存网络信息,分配 IP 地址
  • Netplugin 后台进程作为每个宿主机上的 Agent 与 Docker 及 OVS 通信,处理来自 Docker 的请求,管理 OVS。Docker 方面接口为 remote driver,包括一系列 Docker 定义的 JSON-RPC(POST) 消息。OVS 方面接口为 remote ovsdb,也是 JSON-RPC 消息。以上消息都在 localhost 上处理。
  • 集群管理依赖 etcd/serf


580469BC-468C-49C8-B29E-8B88143AFE0A.png

分析比较

chart1.png

chart2.png

我们逐个点来聊聊:

两者都支持 CNI 和 CNM 网络模型。Calico是先有CNI,再有CNM。Netplugin先有CNM,再支持CNI。因为Mesos的关系,Calico比较偏向CNI阵型。至于哪种网络模型更好,CNI最简单,为了通用性而对功能与配置方式有所牺牲。CNM也不复杂,设计更优雅, 容器网络相关信息持久在容器内部,与Docker的交互更紧密点。如果计划用Docker作为 Containerizer的话,建议用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个以上),转发效率会下降。
071238CA-1542-4FCE-BDE3-FA674F176A03.png

高级网络控制方面,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的数量。

总结:各有优势

Calico的优势

  • 网络拓扑直观易懂,平行式扩展,可扩展性强
  • 容器间网络三层隔离,无需要担心arp风暴
  • 基于iptable/linux kernel包转发效率高,损耗低
  • 更容易的编程语言(Python)
  • 社区活跃,正式版本较成熟


Netplugin的优势

  • 较早支持CNM模型。与已有的网络基础设施兼容性较高,改造影响小。基于VLAN的平行扩展与现有网络结构地位对等
  • SDN能力,能够对容器的网络访问做更精细的控制
  • 多租户支持,具备未来向混合云/公有云迁移的潜力
  • 代码规模不大,逻辑结构清晰,并发好,VLAN在公司内部有开发部署运维实践经验,稳定性经过生产环境验证
  • 京东基于相同的技术栈(OVS + VLAN)已支持10w+ 容器的运行。


从纯技术角度来说,两种都是非常优秀的方案,它们综合技术指标都非常接近,各有千秋。相信两种方案都具备支持大规模容器网络的能力。公司需要根据部署现状,团队开发运维能力,以及未来的技术发展路线,来选取合适的解决方案吧。

5 个评论

calico现在还是不够成熟,如果内部没专门的开发团队支持用起来还是会有不少困难的。
举个遇到的case,直接把宿主机器reboot,然后calico-node容器起不来,只能把整个集群干了重搭。。。
calico从1.4.x版本开始就用go语言重写了,并发性能上并无质的差距
contiv netplugin在测试过程中发现边边角角的小bug挺多的,比较烦人。举个例子:使用contiv网络的docker容器,在主机重启后,就无法重启重启了,会endpoint exists的异常。(/ □ \)
halbart

halbart 回复 gnuer

calico-node起不来是因为docker-daemon起不来吗?应该是宿主机上依赖calico网络的容器的restart策略问题,将restart设置为no,宿主机reboot后calico-node可以正常启动
Axe

Axe 回复 gnuer

我把集群内的部分机器设置为定时重启,并没有发现这个问题~~~可以具体描述下复现方法么?

要回复文章请先登录注册