支持 IPv6 前缀委派

https://blueprints.launchpad.net/neutron/+spec/ipv6-prefix-delegation

作者:

John Davidge

作者:

Dane LeBlanc

IPv6 前缀委派 (PD) 机制(如 RFC3769 [1] 和 RFC3633 [2] 中所述)提供了一种在路由器和主机上自动配置 IPv6 前缀和地址的方式。此机制可用于 Neutron,以自动化租户的 IPv6 前缀选择。

使用前缀委派,配置了前缀委派路由器(在本文档中称为前缀委派服务器,或 PD 服务器)的一组前缀。前缀委派过程始于充当前缀委派请求方(在本文档中称为前缀委派客户端,或 PD 客户端)的路由器通过 DHCP 消息请求配置信息。当 PD 服务器收到请求时,它会选择一个或多个可用的前缀进行委派给 PD 客户端。

应该注意的是,PD 服务器委派的前缀是可路由的,也就是说,PD 服务器为已委派的前缀提供下游路由。

此蓝图建议使用 IPv6 前缀委派来支持自动向租户/子网分配 IPv6 前缀,使用外部(在 OpenStack 云之外)路由器从预配置的可路由前缀池中委派前缀。

值得注意的是,可以有一个由 Neutron 管理并在 Neutron 路由器命名空间中运行的 PD 服务器应用程序,该应用程序使用 IPAM 子网分配 API [3] 进行配置。此支持超出此蓝图的范围,将在单独的蓝图中介绍。

问题描述

在当前的 Neutron 实现中,租户在创建子网时必须提供一个前缀。对于 IPv4 私有子网,这并不是什么大问题,因为私有子网上的 IP 地址可以重叠。对于使用全局单播地址 (GUA) 格式的 IPv6 子网,地址是全局可路由的(与 IPv6 唯一本地地址或 ULA 不同),因此需要小心确保一个租户选择的前缀不会与另一个租户选择的前缀重叠。

OpenStack 管理员可能希望通过从一个或多个大型预配置 IPv6 前缀池中自动为 IPv6 子网提供前缀,从而简化租户的子网前缀选择过程。这将消除前缀选择的任何潜在冲突。

IPv6 前缀委派机制提供了一种在路由器和主机上自动配置 IPv6 前缀和地址的方式,可用于 Neutron 以自动化租户的 IPv6 前缀选择。前缀委派还将为 OpenStack 云中的 IPv6 地址提供自动重新编号的途径,作为未来的增强功能。

此蓝图建议使用 IPv6 前缀委派来支持自动向租户/子网分配 IPv6 前缀,使用外部路由器从预配置的可路由前缀池中委派前缀。

提议的变更

前缀委派拓扑

蓝图中提出的前缀委派拓扑如图所示

                  +-------+-------+
                  |  PD Server    |
                  |  (Running on  |
                  |   external    |
                  |    router)    |
                  +-------+-------+
                          |
                          |
            +-------------+--------------+
            |                            |
     +------+-------+             +------+-------+
     |Neutron Router|             |Neutron Router|
     | (Running PD  |             | (Running PD  |
     | Client and   |             |  Client and  |
     |   RADVD)     |             |    RADVD)    |
     +------+-------+             +------+-------+
Router Port |                Router Port |
            | /64 Prefix #1              | /64 Prefix #2
            |                            |
     +------+------+               +-----+-------+
     |             |               |             |
+----+-----+ +-----+----+     +----+-----+ +-----+----+
| Tenant A | | Tenant A |     | Tenant B | | Tenant B |
|    VM    | |    VM    |     |    VM    | |    VM    |
+----------+ +----------+     +----------+ +----------+

请注意,在此拓扑中,由于 PD 服务器是 OpenStack 云外部的实体,因此 PD 客户端需要由 PD 服务器进行身份验证(以防止恶意请求者耗尽可用前缀),并且 PD 请求者需要对 PD 服务器的身份进行身份验证。这在 RFC3769 的 3.6 节中描述 [1]

PD 客户端功能可以由几个支持 PD 客户端的开源实用程序提供,例如

对于初始实现,我们选择使用 dibbler,因为它缺少其他客户端中的一些重要功能,这使其适用于此用例。将包含一个插件框架,以便将来添加其他客户端选项。

每当附加到该路由器的子网需要前缀委派时,一个新的 dibbler 客户端将在 Neutron 路由器命名空间中启动。

检测已分配前缀

OpenStack/Neutron 需要了解前缀分配何时发生。例如,Neutron 需要使用分配给内部路由器端口的网关 IP 地址更新 IP 分配数据库,当 PD 客户端分配了前缀时。

Dibbler 支持配置一个自定义脚本,该脚本在进行前缀分配时执行。这样的自定义脚本可以提供必要的钩子。

工作流

  • 初始设置

    • 管理员配置 neutron.conf 配置文件中的 default_ipv6_subnet_pool 配置设置(如 IPAM 子网分配规范中所述 [3]),以指示应使用前缀委派来处理默认子网池。

  • 分配前缀

    • 用户/租户在创建 IPv6 子网时既不提供地址池也不提供前缀。通常,这表示子网池分配基础设施 [3] 应该从默认 IPv6 分配池自动分配前缀。但是,在这种情况下(由于初始设置部分中描述的配置),默认 IPv6 分配池的分配需要通过前缀委派来完成。此子网的子网池 ID 填充了一个特殊常量,以指示此子网需要前缀委派。

    • 用户/租户创建 Neutron 路由器(如果尚未存在)。

    • 用户/租户将 IPv6 子网附加到 Neutron 路由器。这会导致在 Neutron 路由器空间中生成 PD 客户端应用程序。

    • 对于 SLAAC/DHCP-stateless 子网,RADVD 配置会使用新路由器接口的“::/64”条目进行修改,并且会向 RADVD 发出信号以重新配置自身。此新配置指示 RADVD 应该监视新路由器接口上的 IPv6 地址分配,此时可以启动 RA 以通告新的前缀。

    • 一些 PD 委派客户端提供运行用户定义脚本的功能,每当收到前缀委派时都会运行该脚本。如果 PD 委派客户端不提供此功能,则将在此时间生成一个轮询脚本,以定期轮询以检测内部路由器接口上是否配置了新的 IPv6 地址。

    • PD 委派客户端的配置会修改为启动新路由器接口的 PD 请求,并向 PD 委派客户端发出信号以重新配置自身,或者在无法动态重新配置时初始化自身的新实例。

    • PD 委派服务器接收 PD 请求,从其前缀块中选择一个可用前缀,并将 PD 响应发送回 PD 委派客户端,指示要使用的前缀。

    • PD 委派客户端从委派的前缀中为路由器接口分配一个地址。

    • 如果 PD 委派客户端提供运行用户定义脚本的功能,每当委派前缀时,该脚本将运行以更新 OpenStack 数据库中的子网的新前缀。否则,轮询脚本最终会检测到将新的 IPv6 地址分配给路由器接口,并更新 OpenStack 数据库中的新前缀。

    • 对于 SLAAC 或 DHCP-stateless 子网,RADVD 将从委派的前缀为子网上创建的新端口分配 IPv6 地址。

限制和未来增强功能

  • 初始版本仅将委派 /64 前缀(不进行子委派)。可以将 Neutron 路由器将短前缀(大地址空间)委派到较长前缀作为未来的增强功能。

  • 在初始版本中,PD 服务器仅支持一个 /64 前缀池。可以在未来的版本中添加对多个前缀池的支持(例如,以添加对每个租户前缀池的支持)。

  • 将使用 OpenStack/Neutron 子网配额来维护每个租户允许使用的前缀数量的限制。

  • 对于此提案,前缀委派将仅限于 SLAAC 和 DHCPv6-stateless 子网。

数据模型影响

  • 如果 OpenStack 提供程序正在升级 OpenStack 实例,从不支持自动前缀委派的 Neutron 版本升级到支持自动前缀委派的 Neutron 版本,则不需要额外的迁移。

  • 如果 OpenStack 提供程序正在升级 OpenStack 实例,从支持自动前缀委派的 Neutron 版本升级到更新版本,则可能需要一个迁移脚本来重新触发所有现有自动前缀子网的委派请求,从而有效地导致重新编号。

REST API 影响

如子网池分配规范中所述 [3],子网创建 API 需要允许缺少子网前缀和子网池 ID。通常,这表示 Neutron(以及子网池分配基础设施)应该从为该 IP 家族配置的默认分配池自动分配前缀。但是,在这种情况下(由于初始设置部分中描述的配置),默认 IPv6 分配池的分配需要通过前缀委派来完成。在这种情况下,子网池 ID 填充了一个特殊常量,以标记需要前缀委派的子网。

如“分配前缀”部分所述,当标记为需要前缀委派的子网(即子网池 ID 填充了特殊的委派常量)附加到路由器时,将触发前缀分配过程。

当子网正在等待通过前缀委派分配前缀时,子网列表和子网显示 API/CLI 的响应将使用临时 ::/64 前缀来列出子网的 cidr 和 allocation_pools。

安全影响

当 PD 服务器是 OpenStack 云外部的实体(例如,ISP 边缘路由器)时,PD 客户端需要由 PD 服务器进行身份验证(以防止恶意请求者耗尽可用前缀),并且 PD 请求者需要对 PD 服务器的身份进行身份验证。这在 RFC3769 的 3.6 节中描述 [1]

将使用 OpenStack/Neutron 子网配额来维护每个租户允许使用的前缀数量的限制。

通知影响

无。

其他最终用户影响

Horizon 需要更新以支持子网创建的此功能。Horizon 的这项工作可以作为对支持子网分配池所做的更改的一部分来完成。

性能影响

如果 PD 客户端不提供异步通知每个前缀分配或配置在分配前缀时调用的自定义脚本,则将在创建需要前缀委派的子网时生成一个轮询脚本。这些轮询脚本对性能的影响取决于任何给定时间创建的子网规模,但如果轮询间隔为几秒或更长,则不应太重要。

IPv6 影响

是,此更改将修改 Neutron IPv6 实现。

其他部署者影响

希望使用前缀委派的部署者需要配置外部路由器以充当 PD 服务器,并需要配置可用 IPv6 前缀的池。

开发人员影响

值得考虑向可插拔 IPAM 基础设施添加一种机制,该机制允许诸如前缀委派之类的功能报告已委派的前缀。这主要是为了提供信息,例如,用于显示通过前缀委派委派了哪些前缀。

社区影响

此功能与 IPAM 子网分配功能 [3] 互补。此实现可以在未来扩展,以支持内部(Neutron 管理)PD 服务器,从而用作 IPv6 部分 IPAM 子网分配的基础实现。

备选方案

与其使用 default_ipv6_subnet_pool Neutron 配置来指示在子网创建请求既没有子网前缀也没有子网池 ID 时应使用前缀委派,不如可以向子网创建 API 添加一个布尔属性来指示是否应为此子网使用前缀委派。这种 API 更改的优点是用户可以按子网选择前缀委派和默认分配池。但是,这种好处可能不值得为 API 添加另一个属性。

实现

负责人

主要负责人

Dane LeBlanc launchpad-id: leblancd

其他贡献者

John Davidge launchpad-id: john-davidge Robert (Bao) Li launchpad-id: baoli

工作项

  • 实施 PD 客户端配置。

  • 子网创建和路由器接口添加的编码/UT

  • 子网删除和路由器接口删除的编码/UT

  • 编写功能测试

  • 编写 Tempest 测试

依赖项

此提案中描述的子网创建 API 的行为变化需要基于为 IPAM 子网分配 [3] 将进行的 API 更改来构建。

测试

Tempest 测试

为了使用充当 PD 服务器的外部路由器测试功能,需要一个包含支持前缀委派的路由器的第三方 CI 系统。在此第三方 CI 系统上运行的 Tempest 测试将是

  • 配置外部路由器以进行前缀委派服务并配置 IPv6 前缀块。

  • 为 2 个单独的租户创建 Neutron 虚拟路由器

  • 为每个租户创建一个子网,确认每个子网都从 PD 服务器的前缀块分配。

功能测试

由于此功能依赖于在 OpenStack 外部运行的 PD 服务器,因此此功能需要一个功能测试,该测试在 neutron 命名空间中运行一个开源 PD 服务器应用程序,并配置一个 IPv6 前缀池。在 PD 服务器应用程序运行后,测试序列将类似于前一节中描述的序列。

可以考虑用于此测试的 PD 服务器应用程序包括

API 测试

此功能需要一个 API 测试,用于测试既未指定前缀也未指定分配池 ID 的子网创建 API。

文档影响

需要进行一些文档更改以反映前缀委派的默认 IPv6 子网池的配置。

用户文档

指定需要更改的任何用户文档。参考需要因此更改而更新的指南。

开发人员文档

需要更新 Neutron API 文档以反映子网创建的 API 行为变化。

参考资料