返回 登录
0

OpenStack Neutron ML2

Neutron 系列文章 Neutron Topic Tree
图片描述

本文所有的内容都基于OpenStack Pike版本。

其实在2016年,我曾经在IBM Developerworks上写过一篇文章介绍Neutron ML2。现在,在经历了OVN和Dragonflow的ML2重构之后,现在再来回顾一下ML2。

首先,什么是ML2?ML2(Modular Layer 2)是Neutron Server中管理L2相关功能的模块。

**

Neutron Server

**
既然是Neutron Server中的模块,那就先看看ML2在Neutron Server架构中的位置。

OpenStack Neutron是OpenStack中的网络项目。Neutron由多个进程构成,这些进程分布在一个或者多个(通常是多个)主机上,协同工作,为OpenStack提供网络服务。所有这些进程的核心是Neutron Server,所有的API,DB,RPC请求,都是在这里汇总处理,主要的业务逻辑也是在Neutron Server中完成。可想而知,Neutron Server是所有Neutron进程中最复杂的。Neutron Server的架构粗略看来,如下所示:
图片描述

实际的架构要更加复杂,不过为了说明ML2,这个架构就够了。

Neutron Server北向提供REST API,Neutron的REST API/Resource都是在extension中定义,api router只是简单的将REST API定位到extension。extension与实际的plugin关联。

具体的REST API的处理都是在plugin中进行。Neutron Server的业务代码是由一个个plugin构成,这里分为core plugin和service plugin。Core plugin是实现了L2功能的plugin,service plugin是其他所有的plugin的统称,包括实现了Router的L3Plugin,实现了Trunk的Trunkplugin,实现了Segment的SegmentPlugin等等。可以看出,一个plugin就是一个小的网络功能。业务逻辑运算,DB和RPC的调用都是在plugin内部完成。

Neutron Server与其他Neutron进程(Neutron agents)的交互,通过Message Queue或者说是RPC(RabbitMQ)调用完成。Neutron中的service plugin都定义在这个目录:

neutron/neutron/services

既然plugin分为core plugin和service plugins,那么这里的core plugin和service plugin还有什么区别?

service plugin是可有可无的,大部分service plugin如果不配置,是不会运行在Neutron Server的进程中。而core plugin是必须存在的,如果不配置则无法启动Neutron Server。并且,不论从OSI 7层网络来看,还是TCP/IP协议族来看,二层网络是其他网络功能的基础,如果没有二层网络,其他所有网络都无法实现。所以从这个角度来看,实现L2功能的core plugin,是Neutron Server必须包含的plugin。本文介绍的ML2是Neutron core plugin的主流实现(没有之一)。

**

Core plugin发展历史

**
从诞生之初,OpenStack就支持多种SDN后端。比如Neutron自己,就有OpenVSwitch和LinuxBridge的实现。其他的如OVN,Dragonflow,ODL,OpenContrail,NSX等等,都是Neutron支持的SDN后端。不同的SDN对网络功能的实现方式不一样。在早期版本的Neutron中,存在各个SDN版本的core plugin。用户根据当前环境对应的SDN,选择相应的core plugin。这里有几个问题:
1.这些core plugin中,有大量的Neutron DB的操作。虽然SDN后端的实现不一样,但是Neutron DB中的数据模型基本是一样的。这样就有大量重复的代码在各个core plugin中。
2.一些业务逻辑的处理,例如segmentation的操作(分配VLAN ID),对于大多数SDN也是类似的,这些相似的业务代码,在各个core plugin中也重复着。
3.如果一个新的SDN,需要接入Neutron,那么需要新增一个core plugin,同样的也需要拷贝这些代码。
4.Bug fix需要在所有的core plugin中更新。
尽管有这些问题,早期的Neutron代码中,还是同时管理着所有的这些core plugin。随着Neutron的发展,一方面功能越来越多,相应的core plugin越来越庞大,另一方面,加入的SDN越来越多,core plugin的数量也越来越多。最多的时候有20+个core plugin存在于OpenStack Neutron的代码中,维护相当困难。

因此在OpenStack Havana版本,Neutron社区对core plugin进行重构,将重复的DB操作和业务逻辑代码剥离出来,成为ML2 plugin。而每个SDN独特的代码,作为ML2 mechanism driver,存在于新的ML2架构中。有关ML2的架构,下面会详细说明。

接下的几个版本,各个SDN逐渐将自己的core plugin转换成ML2 mechanism driver。而在Kilo版本,除了OpenVSwitch和LinuxBridge,所有其他SDN的mechanism driver和未完成转换的core plugin,都从Neutron代码中删除,这在Neutron Core and Vendor code decomposition有具体的介绍。被移除的SDN代码,有的成为了Neutron下面的子项目,像networking-ovn,networking-odl等,有些由SDN提供商自己维护。在这之后,每个SDN,只需要维护自己的ML2 mechanism driver(当然,还有一些service plugin),ML2 plugin由OpenStack Neutron社区维护。

需要说明的是,并非所有的SDN的core plugin都重构到了ML2架构下,有些仍然是core plugin的形式存在,例如OpenContrailVMware NSX

所以,现在说的Neutron ML2 plugin,是一个通用的,新的架构。而其他的Neutron core plugin,是一些私有的,遗留的代码。

**

ML2 Architecture

**
虽然ML2是Neutron Server的一个可插拔的(core)plugin,但是ML2本身也是由多个可插拔的组件组成。简单的画了一下:
图片描述

网络上其他有关Neutron ML2架构介绍,一般都不包括Extension Driver,这是因为这是一个后加的组件,定义在:Support for Extensions in ML2。接下来,看看这三类Driver分别起什么作用。

1.Type Drivers:对于Tenant network type,例如VLAN,VXLAN,FLAT的支持。它包括了segmentation ID的分配,MTU计算等。对于Tunnel network type,例如VXLAN,还涉及VTEP的管理。这里ML2将VTEP需要更新的信息,通过RPC,发送到计算/网络节点,通过节点上的OpenVSwitch Agent更新VTEP信息。
2.Mechanism Drivers:配置SDN,完成port binding等。原来这些代码是在各个core plugin,ML2重构之后,core plugin将自己特殊的代码剥离出来,放在Mechanism Driver。前面说过OpenStack Neutron只管理OVS Mechanism driver和Linuxbridge Mechanism Driver,其他的Driver由SDN自己的项目管理。
3.Extension Drivers:Neutron L2附加功能的支持。例如与Port和Network关联的DNS,Securitygroup和QOS。
既然有了这些可插拔的组件,Neutron ML2是如何使用它们?可以看出,这里有三类driver,Neutron ML2通过三个manager对象来管理这些Drivers,每一类Drivers对应一个manager对象,代码在:neutron.plugins.ml2.managers。通过这些manager,Neutron ML2完成Driver的初始化,方法调用等。

在Neutron ML2 plugin初始化的时候,会调用manager的初始化方法:

neutron/plugins/ml2/plugin.py
   def __init__(self):
       # First load drivers, then initialize DB, then initialize drivers
       self.type_manager = managers.TypeManager()
       self.extension_manager = managers.ExtensionManager()
       self.mechanism_manager = managers.MechanismManager()
       super(Ml2Plugin, self).__init__()
       self.type_manager.initialize()
       self.extension_manager.initialize()
       self.mechanism_manager.initialize()

前面说过Neutron ML2是Neutron L2相关功能的代码。虽然OpenStack Neutron提供非常多的数据对象,但是Neutron定义的L2相关的数据对象只有网络(Network),子网(Subnet)和端口(Port)。所以,Neutron ML2 plugin都是关于网络,子网,端口的创建,更新,删除。对应的ML2的各个组件,都是围绕着这这些操作进行。这里举个比较典型的例子,就是创建网络,其对应的流程图如下所示:
图片描述

从这个流程来看,ML2的架构还是比较简单的。在处理请求的时候只是依次的调用自身的各个模块。其中与SDN相关的部分就是mechanism driver中的create_network_precommit和create_network_postcommit两个方法。SDN只需要实现相应的方法,并且注册到ML2中,就可以完成与Neutron的对接。

**

最后

**
ML2的历史背景和大概架构介绍完了。ML2还有很多细节的地方,例如Hierarchical port binding,Overlay Network Tunnel管理,OVS和LinuxBridge的实现,L2 Population等。从架构上来看,ML2是简单的,从功能上看,ML2又是庞大复杂的。这种设计实现思想在整个OpenStack Neutron项目都有体现。总结一下ML2的特点:

1.提供统一的API。不同的SDN只要实现相同的API即可接入OpenStack。
2.核心架构较小。主要就是三类Driver(type,extension,mechanism),对应三个manager。
3.可插拔的开放架构。任何功能,网络类型,都可以通过是实现上面三种Driver的一个或者多个来完成。
4.方便扩展。新功能的扩展不需要修改现有架构。

==========================================================
本文转载自“肖宏辉-软件定义网络”专栏,链接:
https://zhuanlan.zhihu.com/p/30119950

如果你想要更深入,更系统的了解Neutron,也许这篇文章也会对你有多帮助:
https://zhuanlan.zhihu.com/p/33540411

该文章版权为作者-肖宏辉所有,侵权必究。
如需转载请联系作者获得授权并注明出处。

评论