Neutron在OpenStack项目中负责提供网络相关的功能,我们知道OSI定义了一个七层网络模型,而Neutron在二层到七层都提供了一定程度的插件结构来支持各种不同的网络设备和网络服务。本文主要描述下我对Neutron在二层中的一些理解。

七层网络模型:

  • Layer1 物理层
  • Layer2 链路层 - Core-plugin
  • Layer3 网络层 - Service-plugin
  • Layer4 传输层 - Service-plugin
  • Layer5 会话层 - Service-plugin
  • Layer6 表示层 - Service-plugin
  • Layer7 应用层 - Service-plugin

1、二层网络

在二层网络中的API资源(network, subnet, port)被称为是neutron的核心资源,并且由Core-plugin负责管理。

这个Core-plugin插件即为ML2,它对二层网络进行了抽象。当需要使用新的技术对二层底层进行实现时,只需要实现其特殊部分的代码即可,这部分代码是用来驱动后端实现的,相当于把REST API请求转化为了底层技术的调用,称之为ML2中的MechanismDriver。ML2通过MechanismManager同时管理多个底层驱动,使得在同一个OpenStack环境中可以使用多种不同的二层网络技术,例如Linux bridge、openvswitch。不过对于同一个HOST来讲,只能使用同一种二层网络技术。

1.1、ML2代码框架

ML2代码框架.png
在ML2Plugin中实现了三个管理器,分别是TypeManager、ExtensionManager、MechanismManager,并通过initialize方法将Manager中所注册的driver进行初始化。

class Ml2Plugin(...略...):
    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()
        # ...略...
  • TypeManager

TypeManager管理TypeDriver。
TypeDriver定义了二层网络的类型,目前主要有local,flat,vlan,gre,vxlan这几种类型。TypeDriver中实现了跟具体网络技术无关的一些接口。插件使用这些接口来管理持久化类型的资源分配状态,这些状态与该网络类型的network segments有关。
在neutron代码的入口配置文件setup.cfg中,我们可以看到各个网络类型对应的TypeDriver:

neutron.ml2.type_drivers =
    flat = neutron.plugins.ml2.drivers.type_flat:FlatTypeDriver
    local = neutron.plugins.ml2.drivers.type_local:LocalTypeDriver
    vlan = neutron.plugins.ml2.drivers.type_vlan:VlanTypeDriver
    geneve = neutron.plugins.ml2.drivers.type_geneve:GeneveTypeDriver
    gre = neutron.plugins.ml2.drivers.type_gre:GreTypeDriver
    vxlan = neutron.plugins.ml2.drivers.type_vxlan:VxlanTypeDriver

TypeManager在初始化过程中会从配置文件ml2_conf.ini读取配置项[ml2]type_drivers,并将配置的TypeDriver注册到系统中。
[ml2]type_drivers指定了OpenStack环境支持的某一种或多种网络类型。

class TypeManager(...略...):
    def __init__(self):
        # Mapping from type name to DriverManager
        self.drivers = {}
        super(TypeManager, self).__init__('neutron.ml2.type_drivers',
                                          cfg.CONF.ml2.type_drivers,
                                          invoke_on_load=True)
        self._register_types()
        # ...略...

    def _register_types(self):
        for ext in self:
            network_type = ext.obj.get_type()
            if network_type in self.drivers:
                LOG.error(...略...)
            else:
                self.drivers[network_type] = ext

    def initialize(self):
        for network_type, driver in six.iteritems(self.drivers):
            LOG.info(_LI("Initializing driver for type '%s'"), network_type)
            driver.obj.initialize()

相关配置:

[ml2]
type_drivers = flat,vxlan,gre

然后在运行过程中由TypeManager根据实际的网络类型调用对应TypeDriver对象中的方法。

  • ExtensionManager

ExtensionManager管理ExtensionDriver。
ExtensionDriver通过附加属性扩展了由ML2插件实现的核心资源。通过API中对这些资源进行创建和更新的这两个操作来验证和保存扩展属性的值。这些扩展属性可以实现建立不同资源之间的联系(例如network和port之间的security group)等功能。
一样的,在neutron代码的入口配置文件setup.cfg中,我们可以看到各个支持的ExtensionDriver:

neutron.ml2.extension_drivers =
    test = neutron.tests.unit.plugins.ml2.drivers.ext_test:TestExtensionDriver
    testdb = neutron.tests.unit.plugins.ml2.drivers.ext_test:TestDBExtensionDriver
    port_security = neutron.plugins.ml2.extensions.port_security:PortSecurityExtensionDriver
    qos = neutron.plugins.ml2.extensions.qos:QosExtensionDriver
    dns = neutron.plugins.ml2.extensions.dns_integration:DNSExtensionDriverML2
    data_plane_status = neutron.plugins.ml2.extensions.data_plane_status:DataPlaneStatusExtensionDriver
    dns_domain_ports = neutron.plugins.ml2.extensions.dns_integration:DNSDomainPortsExtensionDriver

ExtensionManager的初始化过程和TypeManager相同,不再描述。只不过读取的配置为[ml2]extension_drivers

[ml2]
extension_drivers = port_security
  • MechanismManager

MechanismManager管理MechanismDriver。
MechanismDriver在创建、更新、删除网络或端口的时候被调用,负责二层网络技术底层的具体实现,和不同的网络设备进行交互。在每次事件中会调用到MechanismDriver的两个方法:

<event>_precommit:在提交数据到DB之前调用
<event>_postcommit:在提交数据到DB之后调用

例如:create_network_precommit、create_network_postcommit

MechanismManager的初始化过程和TypeManager也相同,不再描述。读取的配置为[ml2]mechanism_drivers

[ml2]
mechanism_drivers = openvswitch,l2population

在neutron代码的入口配置文件setup.cfg中,我们可以看到各个支持的MechanismManager:

neutron.ml2.mechanism_drivers =
    logger = neutron.tests.unit.plugins.ml2.drivers.mechanism_logger:LoggerMechanismDriver
    test = neutron.tests.unit.plugins.ml2.drivers.mechanism_test:TestMechanismDriver
    linuxbridge = neutron.plugins.ml2.drivers.linuxbridge.mech_driver.mech_linuxbridge:LinuxbridgeMechanismDriver
    macvtap = neutron.plugins.ml2.drivers.macvtap.mech_driver.mech_macvtap:MacvtapMechanismDriver
    openvswitch = neutron.plugins.ml2.drivers.openvswitch.mech_driver.mech_openvswitch:OpenvswitchMechanismDriver
    l2population = neutron.plugins.ml2.drivers.l2pop.mech_driver:L2populationMechanismDriver
    sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver.mech_driver:SriovNicSwitchMechanismDriver
    fake_agent = neutron.tests.unit.plugins.ml2.drivers.mech_fake_agent:FakeAgentMechanismDriver
    faulty_agent = neutron.tests.unit.plugins.ml2.drivers.mech_faulty_agent:FaultyAgentMechanismDriver

1.2、ML2调用流程

  • create_network

    • create_network_in_db
    • extension_manager.process_create_network
    • type_manager.create_network_segments
    • mechanism_manager.create_network_precommit
    • db commit
    • mechanism_manager.create_network_postcommit
graph TD
    A[CREATE NETWORK] --> B(create_network_in_db)
    B --> C(extension_manager.process_create_network)
    C --> D(type_manager.create_network_segments)
    D --> E(mechanism_manager.create_network_precommit)
    E --> F(commit_network_to_db)
    F --> G(mechanism_manager.create_network_postcommit)
  • create_subnet

    • create_subnet_in_db
    • extension_manager.process_create_subnet
    • mechanism_manager.create_subnet_precommit
    • db commit
    • mechanism_manager.create_subnet_postcommit
graph TD
    A[CREATE SUBNET] --> B(create_subnet_in_db)
    B --> C(extension_manager.process_create_subnet)
    C --> D(mechanism_manager.create_subnet_precommit)
    D --> E(commit_subnet_to_db)
    E --> F(mechanism_manager.create_subnet_postcommit)
  • create_port

    • create_port_in_db
    • extension_manager.process_create_port
    • port biding
    • mechanism_manager.create_port_precommit
    • db commit
    • mechanism_manager.create_port_postcommit
graph TD
    A[CREATE PORT] --> B(create_port_in_db)
    B --> C(extension_manager.process_create_port)
    C --> D(port_biding)
    D --> E(mechanism_manager.create_port_precommit)
    E --> F(commit_port_to_db)
    F --> G(mechanism_manager.create_port_postcommit)

其中type_manager只有在create network的过程中才被调用到。