参考 IPAM 驱动

https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver

本文档提出将 Neutron 的 IPAM 代码(当前嵌入在数据库逻辑中)移动到一个合适的驱动程序中,Neutron 将通过 [1] 中定义的接口调用该驱动程序。

将 IPAM 逻辑从 Neutron 管理层解耦,长期以来一直是“偿还债务”任务列表中的一项。它也是朝着实现可插拔 IPAM 框架迈出的必要一步,该框架已被 Kilo 发布周期优先级之一所批准 [2]

以下规范既提供了所提出的参考 IPAM 驱动程序的长期演进蓝图,又提供了作为本蓝图一部分提出的更改的短期详细描述。关于长期演进的讨论在标题为“大局”的部分中;仅关心本规范将执行的更改的读者可以安全地跳过此部分。

问题描述

Neutron 的 IPAM 逻辑嵌入在“基础”DB 类中 [3]。这存在严重的可管理性缺陷,并且与 [1] 推广的活动不兼容。后一点使得将此 IPAM 逻辑转换为通过 IPAM 接口调用的驱动程序几乎是强制性的。

此外,此 IPAM 逻辑是 neutron DB 中“锁等待超时”问题的第一个来源,因为存在深度嵌套(且很长)的事务。

提议的变更

本文档的规范与其他为 Kilo 发布周期提出的规范相辅相成 [1][4]。由于这些努力,IPAM 将变得“可插拔”,这意味着部署者将能够选择最适合他们执行 IP 地址管理的解决方案。另一方面,当前逻辑,在许多生产部署中使用,也将成为一个 IPAM 驱动程序。更确切地说,这将是在上游 gate 测试中使用的 IPAM 驱动程序。因此,我们将把这个 IPAM 驱动程序称为“参考”驱动程序,希望不会滥用这个术语。

在 Kilo 发布周期结束时,Neutron 将拥有一个驱动程序,它以与 Neutron 今天完全相同的方式管理 IP 地址。作为本蓝图的一部分,我们还将尝试修复其一些众所周知的缺点,尽可能利用社区已经可供审查的贡献。

参考驱动程序将通过以下方式实现

  • 定义一个简单的数据模型,从当前“嵌入式”IPAM 数据模型中推断出来。

  • 将 IPAM 例程从“基础”DB 类 [3] 移动到新创建的 IPAM 驱动程序

  • 将 IPAM 驱动程序挂接到新开发的 IPAM 接口 [1]

驱动程序数据模型

参考 IPAM 驱动程序的数据模型将基于与当前 IPAM 逻辑相同的原则,即

  • 从子网的分配池开始创建可用性范围。

  • 从可用性范围分配 IP 地址。

  • 仅在必要时重新计算可用性范围。

  • 允许在分配池之外进行分配。

但是,参考 IPAM 驱动程序至少在其第一次迭代中,将不支持子网池 [8]。该驱动程序假定每个租户只有一个子网池,其地址范围是整个 IP 地址空间。为了确保向后兼容的行为,也允许从这个“默认”池进行重叠分配。

有关模式更改的详细信息,请参见相应的部分。

代码重构

代码重构活动主要涉及将现在是 neutron.db.db_base_plugin_v2.NeutronDbPluginV2 的一部分的代码移动过去。

更具体地说,以下方法将成为 IPAM 驱动程序的一部分
  • _allocate_ips_for_port

  • _update_ips_for_port 对于上述两种方法,语义和签名将略有不同,以反映新 IPAM 接口公开的操作。

  • _test_fixed_ips_for_port

  • _check_unique_ip

  • _allocate_fixed_ips

  • _allocate_specific_ip

  • _generate_ip

  • _try_generate_ip 上述两种方法中使用的锁定查询逻辑将被无锁算法取代。

  • _store_ip_allocation 对于此方法,一些逻辑将保留在 Neutron 的 DB 基础类中,因为它将用于向 API 消费者提供 IP 地址信息。

  • _allocate_pools_for_subnet

  • _rebuild_availability_ranges

  • _check_ip_in_allocation_pool

  • _delete_ip_allocation

连接到 IPAM 接口

本文档中提出的参考驱动程序将实现 [1] 中定义的接口。

get_subnet 操作将在此驱动程序中不执行任何操作。

  • allocate_subnet 将设置可用性范围;分配池应存储在基础 DB 类中,因为它们也通过 API 检索。

  • remove_subnet 将确保子网没有活动的分配,并清除可用性范围

  • allocate 将实现类似于 allocate_ips_for_port 的逻辑,唯一的例外是它将不为端口而为配置在端口上的每个 IP 调用。

  • deallocate 将简单地删除 IP 分配信息。对于参考驱动程序的首次实现,它很可能不执行任何操作。

大局

到目前为止,本文档讨论了驱动程序在 Kilo 中的外观。从架构的角度来看,它只是一个在启动时加载的类,IPAM 调用会分派到该类。

这仍然没有解决 Neutron 中 IPAM 的两个重要方面

  • 与核心插件的独立性

  • 多个服务器(或甚至工作进程)之间的协调

在 Kilo 中,对 IPAM 接口的调用仍然在基础 DB 类中,该类也是大多数 Neutron 插件的基础类。这意味着参考 IPAM 驱动程序实际上将由插件调用,而不是由 Neutron 管理层调用。这同样适用于任何其他 IPAM 驱动程序。这是一个架构流程,即使它不是主要的,这意味着

  • 运行特定 IPAM 驱动程序的能力取决于当前配置的 core_plugin。

  • IPAM 接口挂钩可能需要显式添加到插件模块。事实上,使用当前代码库,我们需要至少在基础 DB 类和 ML2 插件类 [5] 中插入对 IPAM 接口的调用。

  • 由于插件仍然可以自由选择如何使用 IPAM 接口,因此在 [1] 中定义的交互因此是插件特定的。这可能导致在运行特定插件和 IPAM 驱动程序组合时出现意外行为。例如,插件可能会重新定义核心方法,例如 create_port,并绕过对 IPAM 驱动程序的调用。作为另一个例子,插件可能会决定通过在 DB 事务中调用 IPAM 驱动程序来覆盖方法实现,从而创建数据库中死锁的条件。

因此,IPAM 驱动程序调用应由管理层执行,IPAM 操作的结果应发送到插件层。但是,这将需要对插件接口进行广泛的更改,并且超出了本发布周期的范围。理想情况下,这非常适合定义了允许对不同资源进行操作的不同接口的“v3”插件接口的世界。

当部署多个服务器或工作进程(或两者兼而有之)时,参考 IPAM 驱动程序也会有多个实例。使用当前实现,这会导致众所周知的竞争条件,例如 [7]。IPAM 参考驱动程序的第一次迭代很可能遭受相同的困扰。在后续迭代中,社区可能会评估可扩展且可靠的解决方案,这些解决方案可能包括驱动程序实例之间的分布式协调或“conductor 风格”的实现,其中驱动程序将操作转发到集中的 IPAM 服务。

数据模型影响

理想情况下,不应更改模式。但是,IPAM 驱动程序将负责管理 IPAvailabilityRanges 表。

对于 IPAllocation 和 IPAllocationPools,理想情况下应将这些表拆分,因为它们都在 REST 层和 IPAM 系统中发挥作用。

虽然拆分这些表提供了插件和 IPAM 驱动程序之间最佳的关注点分离,但它也有一些缺点。最值得注意的是信息重复(例如,IP 地址将同时位于插件和 IPAM 端)以及分配地址所需的数据库操作数量增加。

因此,至少对于首次实现,我们将假设 Neutron DB 层和 IPAM 驱动程序可以共享数据库表。在这种情况下,不需要数据库模式更改。

REST API 影响

拟议的更改不会以任何方式改变 Neutron API 的语法和语义。从这个实现中产生的任何 API 更改行为都将是一个无意的副作用,因此应将其视为高优先级错误。

安全影响

我们预计参考 IPAM 驱动程序不会比当前的逻辑更不安全,因为大部分代码将在驱动程序中保持不变。

通知影响

无。

其他最终用户影响

无。

性能影响

参考驱动程序将包含防止锁超时和减少锁定查询范围的逻辑。这可能会在重负载下提高性能,但我们预计这种改进并不相关。从“嵌入式 IPAM”的逻辑变化主要针对可靠性。

IPv6 影响

预计与 IPv6 相关的 IPAM 功能(例如 SLAAC)不会发生变化。从本规范的实施中产生的任何变化都是无意的副作用,应被视为高优先级错误。

其他部署者影响

参考 IPAM 驱动程序将是 IPAM 驱动程序的默认值。为了避免部署者在运行多个服务器时可能出现的混乱,应在每台服务器上使用相同的 IPAM 驱动程序。

开发人员影响

社区影响

这将对社区有利,因为它将在 neutron 代码树中提供一个单一的位置,IPAM SME 可以做出贡献。

注意:到目前为止,这项工作针对 neutron 代码树,但将来参考 IPAM 驱动程序可能会根据插件/驱动程序拆分蓝图 [6] 移动到外部。

备选方案

在假设存在可插拔 IPAM 接口的情况下,实际上没有替代方案。除非考虑使用以下逻辑包装每个 IPAM 接口调用可能是一种替代方案

::
if cfg.CONF.use_pluggable_ipam

self.ipam_driver.do_this(subnet_id, …)

else

<db 基础类中的先前逻辑>

本文档的作者希望没有人会认为上面的代码片段是可行的替代方案。即使它可以作为允许独立开发可插拔接口的短期措施,也应尽可能避免使用它。

实现

Kilo 的最低目标是拥有一个以与“嵌入式”逻辑今天相同的方式管理 IP 的驱动程序。

负责人

主要负责人

salv-orlando

工作项

  • 实现驱动程序

  • 为其编写单元测试和功能测试

  • 与可插拔接口结合,通过 gate 测试

  • 根据与 [1] 的努力同步的策略,可能会有残留代码需要删除

依赖项

  • 可插拔 IPAM 接口 [1]

  • 引入子网池概念。这是 [4] 的一部分

测试

测试将很棘手,因为在可插拔接口到位之前,无法完全测试驱动程序。另一方面,为了引入可插拔接口,需要一个驱动程序。为了打破这种僵局,一种可能性是引入驱动程序,但仅限于单元和功能测试,直到 IPAM 接口到位为止。

以下部分将定义在驱动程序与可插拔 IPAM 接口一起合并以及驱动程序在没有可插拔 IPAM 接口的情况下合并两种情况下的策略。

Tempest 测试

当前定义的场景测试为参考驱动程序提供了足够的覆盖范围,因为它在功能上等同于当前的“嵌入式”代码。

显然,只有当可插拔 IPAM 接口到位并分派调用到参考 IPAM 驱动程序时,才能进行 tempest 场景测试的覆盖。

功能测试

在经典的 neutron 意义上,在可插拔 IPAM 接口合并之前,无法进行功能测试。但是,始终可以进行通过其接口行使驱动程序的功能测试。

另一方面,如果 IPAM 可插拔接口已经到位,这将允许我们通过行使 neutron API 来执行功能测试,从而利用当前的框架。

API 测试

由于不会进行 API 更改,因此不需要对 API 测试进行任何更改。

文档影响

用户文档

没有变化。

开发人员文档

参考 IPAM 驱动程序应附带适当的开发人员文档

参考资料