OpenStack网络新项目Dragonflow研究
https://www.ustack.com/blog/openstack-dragonflow/
本文由2015年5月30日举行的OpenStack Meetup北京上的演讲整理而成,演讲者为UnitedStack网络工程师王为。
在温哥华OpenStack Summit上,Neutron最新的子项目Dragonflow并未被特别提及。事实上,在网络领域,这个由华为以色列技术团队提出的项目在开发者中还是很受关注的。Dragonflow项目提出的时间是在2014年,2015年开始提交代码,目前已经成为OpenStack的孵化项目。
Dragonflow可以理解为Neutron的3层的控制器扩展组件。它实现了Neutron的L3 Service API,还为Neutron提供了分布式虚拟路由器功能。从设计理念上讲,Dragonflow使用的是可插入式无状态化轻量级SDN控制器,实现了租户子网间(东-西)流量的完全分布化,避开了网络节点,减小了故障域,避免单点故障。
按照Dragonflow的设计理念,它可以提升OpenStack Neutron L3的可扩展性、弹性、性能和可靠性。它可以支持数千个计算节点,为实现动态增长而保持控制器的无状态化,没有中央瓶颈,通过避免使用iptables和命名空间减少计算节点开销。
DVR分布式虚拟路由模式
Dragonflow到底进行了哪些改进?要了解Dragonflow的设计思路,我们先来看看目前OpenStack网络所采用的DVR(分布式虚拟路由)模式。
上图显示,DVR的服务架构上,L3作为Service Plugin集成在Neutron Server里,计算节点启动L3 Agent,网络节点启动L3 NAT Agent。
上图是DVR模式的网络I/O路径图,我们可以看到,针对东西流量,计算节点的L3 Agent会启一个NameSpace,然后做ARP的抢答、MAC地址修改,最后把流量直接打到对面的计算节点上去。如果对面的流量想返回,路径也是相同的。
这样的设计目的是什么呢?首先就是要截住本身的ARP,把ARP回应回去;第二,是要把Mac地址通过OVS修改成虚拟的Mac地址,然后发送过去。
这样的模式的问题在于,不仅需要走Namespace(网络设备多),同时逻辑也会非常复杂。NameSpace里面一些需要配置ARP的规则需要在整个集群中同租户的计算节点进行配置,无论这个计算节点是不是真的有相关网络的虚拟机,都需要进行下发的。
再来看看南北流量。做法同样是基于Namespace把公网IP附着上去,然后再送到公网上。特别是SNAT的话整个路径会比较复杂。走完计算节点然后再出去,送到网络节点,然后通过SNAT的Namespace来做。
DVR模式的优点1. 确实解决了流量的分布问题。
实际把东西流量Offload到交换机上,而不是说跨子网还需要走网络节点、走路由器,然后再返回;
2. 减少单点故障,减小故障域。
如果网络节点挂掉,也只会影响一个SNAT的流量。如果是东西流量,或者是有了公网IP的南北流量,是不会受到影响的。这个优势非常重要,因为网络节点HA的社区实现不是非常健壮,因此不要把所有的希望都寄放在社区的HA上。另外,目前的HA也没有实现Contrack的同步,因此用户体验不佳。
DVR模式明显的缺点1.资源和性能损耗的问题。
每一个计算节点都要起namespace,这样就会占用资源,而流量都需要走namespace的TCP/IP协议栈,走一遍内核,这是比较浪费性能的。
2. 管理的复杂性问题。
DVR能够分布式东西流量了,部署之后感觉挺好。但是一旦出了问题,如果想去debug,想去tcpdump的话,你会看到全部都是假的ARP,全部都是假的Mac地址,流量的路径也都非常奇怪,很难去做运维操作。也就是说,不出问题还好,一出问题就很难解决。这个问题在生产环境是比较敏感的。对于云服务商来说,不可能保障永远不出故障,最近比较火的今日头条、携程的事故就是例子。既然无法保证100%不出故障,那么出了故障就需要快速地进行解决或者恢复生产。
3. 代码的复杂性。
(1)计算节点管理了这么多的设备,需要Driver去管理这些东西,这些都是需要代码的;
(2)它和二层的耦合性比较强,也就是说部署了DVR L3,就需要同步更新DVR L2,它和L2是紧耦合的。我们看到,以前我们只能支持Overlay,不能支持VLAN网络。
Dragonflow进行了哪些改进?
Dragonflow是由华为的以色列技术团队在2014年提出,2015年开始提交代码,目前已经成为OpenStack的孵化项目。
Dragonflow的设计比较符合一个标准的Neutron扩展,通过Plugin来实现API,通过两个Agent分别实现功能。
在上图中我们可以看到,在Dragonflow模式中,Service的实现方式是一样的(service plugin)。它把Network节点由单纯的网络节点(走SNAT流量)改成了Neutron Controller Agent。Neutron Controller Agent相当于传统SDN方案的网络控制器,更准确的说是三层的SDN控制器。计算节点上跑的还是L2 Agent。在原来DVR的模式下,网络节点要跑L3 Agent,现在就不需要了。也就是说,Dragonflow改成了纯粹用OpenFLow去控制三层流量的方式。
Dragonflow是如何完成这样的改变的呢?首先,它将metadata dispatch出来,也就是分清哪些是DHCP的,哪些是VLAN的。VLAN的部分需要标记TAG,送到Packet classifier里面。Classifier做的也很简单,主要是分辨ARP、广播和三层流量。关键在于,它会把三层流量(default)区分出来,送到另外一个表里,也就是L3的Forwarding表。
Forwarding表中包含了协议的流表规则(controller规则),也就是说流量如果命中不了任何一个Flow的话,就会被送到Controller里去,做Reactive的反应。流表会被下发到这里,实现OpenFlow对三层流量的控制。
个人观点个人认为,Dragonflow的做法在SDN领域实际上没有特别大的新意,基本上就是命中流量,然后把包发送到Controller上,Controller会重新下发流表。它的好处体现在,我们不需要预配置流表了,管理的复杂度能够显著降低。
从DVR和Dragonflow我想到了一个问题:我们到底需要一个什么样的SDN?
Dragonflow确实好像完成了一些事情,比方说,计算节点上不需要部署L3 Agent了,网络节点上无需起很多的namespace,去穿过这些这些额外的TCP/IP协议栈,貌似是实现了性能的提升。但是Dragonflow的性能提升是很有限的,因为按照我们一般的理解,网络性能提升的关键重要体现在内核、网卡方面。因此,希望从Controller入手实现性能的提升目光似乎有些短浅。
关于主动和被动式,SDN的解决方案有两种,主动下发流表,或者根据流量的情况被动地下发流表。被动的方式看上去很美,但是也有它自己的问题。比方说,规模很大的时候,控制器的性能就会成为瓶颈,这种情况下如何提升控制器的性能?可能我们会想到,可以把控制器分布到不同的计算节点上,可这样就又几乎走回到DVR的网络上了。
融合式SDN(Hybrid)是另一种思路,但是问题也很多,首先就是代码的复杂性会非常高。其次采用反应式的SNAT也会存在问题,SNAT包含状态信息,单纯地通过二层控制会比较麻烦。也正是出于这个原因,Dragonflow的SNAT走的是L3的模式,也就是直接送到网络节点,然后再送出去。
UnitedStack目前在公有云服务上的做法是采用纯Neutron,自己想办法提升性能,效果也不错,扩展性表现也可以。目前我们的想法是,希望只利用DVR二层东西流量的部分,而不让它插手南北流量。这样也实现了非常不错的性能和效果。