• Neutron中的二层网络服务架构


    转载:https://zpzhou.com/archives/neutron_layer2.html

    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进行初始化。

    Python
    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:

    Python
    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环境支持的某一种或多种网络类型。

    Python
    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:

    Python
    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的两个方法:

    Python
    <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:

    Python
    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的过程中才被调用到。

    ML2 的发展过程

    ML2 并非是随着 OpenStack Neutron 一同诞生的,直到 Havana 版本,OpenStack Neutron 才支持 ML2。OpenStack Neutron 最开始只支持 1-2 种 Layer 2 技术,随着发展,越来越多的 Layer 2 技术被支持。而在 ML2 之前,每支持一种 Layer 2 技术,都需要对 OpenStack Neutron 中的 L2 resource,例如 Network/Subnet/Port 的逻辑进行一次重写,这大大增加了相应的工作量。并且,在 ML2 之前,OpenStack Neutron 最多只支持一种 Layer 2 技术,也就是说如果配置使用了 Open vSwitch,那么整个 OpenStack 环境都只能使用 neutron-openvswitch-agent 作为 Layer 2 的管理服务与 Open vSwitch 交互。

    ML2 的提出解决了上面两个问题。ML2 之前的 Layer 2 plugin 代码相同的部分被提取到了 ML2 plugin 中。这样,当一个新的 Layer 2 需要被 Neutron 支持时,只需要实现其特殊部分的代码,需要的代码工作大大减少,开发人员甚至不需要详细了解 Neutron 的具体实现机制,只需要实现对应的接口。并且,ML2 通过其中的 mechanism drivers 可以同时管理多种 Layer 2 技术,如图 1 所示。这在后面会详细介绍。

    图 1. ML2 与 Neutron L2 agents

    ML2 的代码框架

    本部分将会介绍 ML2 的代码框架,以及其中各个组成部分的作用。ML2 框架可以用图 2 来表示。

    图 2. ML2 框架

    从图 2 可以看出,ML2 主要由 ML2 plugin,extensions drivers,types drivers,mechanism drivers 和 rpc 组成。下面分别介绍各个部分。

    ML2 plugin

    这是所有对 Neutron 中 L2 resource 操作的入口,实现文件是 neutron/plugins/ml2/plugin.py。仅当如清单 1 所示,在 neutron.conf 文件中配置才生效。用户如果希望创建一个 Neutron Network,那么对应执行的代码将是该文件中的 ML2Plugin.create_network。

    清单 1. 配置使用 ML2 plugin
    1
    2
    [DEFAULT]
    core_plugin = neutron.plugins.ml2.plugin.Ml2Plugin

    extensions drivers

    如前所述,网络都遵循着 OSI 7 层模型,但是并非每层之间就完全独立,例如 Neutron 中 DNS 服务与 Network 和 Port 关联。extensions drivers 就是建立 Neutron 中 L2 resource 与其他 resource 之间的联系。当创建、更新或删除 Neutron 中 L2 resource 时,对应的 extensions driver 会被执行,并更新对应的其他 resource。同时 extensions drivers 还会将其他 resource 与 Neutron L2 resource 的关联报告给 ML2 plugin,这样,用户在查看 Port 信息的时候,就能看到对应的 Security Group。extensions drivers 是一个可配置项,对应的配置信息在 ml2_conf.ini 中,如清单 2 中的 extension_drivers 所示。配置值默认为空,当需要打开某功能时,例如清单 2 中的 port_security,则需要在此处加上相应的信息,并重启 neutron-server。ML2 plugin 通过 neutron.plugins.ml2.managers.ExtensionManager 与配置了的 extension driver 交互。

    清单 2. ML2 的其他配置信息
    1
    2
    3
    4
    5
    [ml2]
    tenant_network_types = vxlan
    extension_drivers = port_security
    type_drivers = local,flat,vlan,gre,vxlan
    mechanism_drivers = openvswitch,linuxbridge

    types drivers

    物理环境中的 L2 网络类型有很多种,而在虚拟网络 OpenStack Neutron 中,也支持多种网络类型。这些网络类型的支持由 ML2 的 types drivers 来完成。当希望 OpenStack 的网络环境支持某一种或多种网络类型时,需要在清单 2 所示的 type_drivers 中进行配置。该配置项默认值是'local','flat','vlan','gre','vxlan','geneve'。实际上就是 ML2 内部所有支持的网络类型。清单 2 所示的配置项中没有 geneve,那么在 OpenStack Neutron 中创建 geneve 类型的网络时,Neutron 会报网络类型不支持的错误。

    清单 2 所示的配置项中,tenant_network_types 也属于 types drivers 的配置项。它表示,在创建 Network 时,如果没有指定网络类型,按照该配置项的内容自动给 Neutron Network 指定网络类型。可以理解成 Neutron Network 中网络类型的缺省值。当设定多个值时,第一个可用的值将被采用。

    ML2 plugin 通过 neutron.plugins.ml2.managers.TypeManager 来与配置了的 type driver 交互。

    mechanism drivers

    这部分是对各种 L2 技术的支持,例如 Open vSwitch,linux bridge 等等。最近流行的 OVN 也是作为一个 mechanism driver,通过 ML2 与 OpenStack Neutron 工作。有关 OVN 的更多信息,可以查看这里。mechanism drivers 也是 ML2 的一个可配置项,如清单 2 所示的 mechanism_drivers。该配置项默认值为空,当希望 Neutron 支持某个 L2 技术,例如 Open vSwitch 时,可以加上相应的配置。清单 2 中同时配置了 openvswitch 和 linuxbridge,这样 Neutron 就同时支持这两种 L2 技术。当希望支持 OVN 时,可以在这个配置项上加上 ovn。ML2 plugin 通过 neutron.plugins.ml2.managers.MechanismManager 与配置了的 mechanism driver 交互。

    rpc

    这是 ML2 与 L2 agents 通讯的部分,是基于 AMQP 的实现。例如,删除 Network,需要通过 rpc 通知 L2 agents 也删除相应的流表,虚拟端口等等。ML2 的 rpc 实现在 neutron.plugins.ml2.rpc。

    ML2 的工作方式

    本部分将介绍 ML2 内部各个部分如何工作。前面介绍过 ML2 plugin 是所有对 Neutron 中 L2 resource 操作的入口,实际上,对 ML2 中其他部分的调用,也是在 ML2 plugin 中完成的。下面通过两个常用的操作来说明一下 ML2 的工作方式。

    Create Network

    本部分介绍 OpenStack Neutron 中创建 Network 的流程。图 3 显示了创建 Network 的流程。

    图 3. ML2 创建 Network 流程

    如果在 Commit Network in DB 之前发生异常,那么 DB 不会做任何修改。从图 3 可以看出,extension drivers,type drivers 和 mechanism drivers,如果其中任何一个不能接受新创建的 Network,都会导致创建 Network 失败,并且清除在 Network 在 DB 中的记录。由于新创建的 Network 不含有任何 Port 或 Subnet,没有必要通知 L2 agents,所以在创建 Network 的过程中,没有调用 rpc 的过程。

    Create Port

    如果把 Neutron Network 理解成一个 Layer 2 Switch,那么 Port 就是接在这个 Switch 上的虚拟端口。图 4 显示了创建 Port 的流程。

    图 4. ML2 创建

    整个流程与创建 Network 类似。差别是少了调用 type drivers,因为 type drivers 针对的是 Network type 的支持,所以没有必要在 Port create 中调用。另一方面,创建 Port 会调用 rpc 通知 L2 agents,这是因为 Port 在 ML2 中还只是一个内存或者 DB 中的对象,真正在 SDN 中起作用的,是在各个 L2 agents 上的虚拟端口。ML2 通过 rpc 通知到 L2 agents,并创建相应的虚拟端口,这样,虚机,虚拟路由器,DHCP 服务等都能基于虚机端口提供网络服务。

    总结

    ML2 框架是一种极易扩展的框架。使用者和开发人员可以在不用改变现有 OpenStack Neutron 代码的前提下,对 ML2 进行扩展。

    • 当需要增加一种与 L2 resource 相关的 Neutron resource 时,不需要修改现有的 L2 resource 代码,只需要扩展 extension drivers。
    • 当需要支持一种新的网络类型时,只需要扩展 type drivers。
    • 当需要支持一种新的 L2 技术时,只需要扩展 mechanism drivers。

    同时,ML2 也是 OpenStack Neutron 中最复杂的模块之一,正确理解它的工作方式有助于了解 Neutron 的工作原理。

  • 相关阅读:
    c++字符串
    iOS调用相册
    cocos2d-x中有一个JniHelper类详细使用
    iOS 字符串应用
    c++调用java
    iOS调用相册、相机、上传等问题
    win32中GBK、UTF8的互转
    SQL Server海量数据查询代码优化建议
    JSON中的[]和{}
    数据库范式
  • 原文地址:https://www.cnblogs.com/dream397/p/13130595.html
Copyright © 2020-2023  润新知