地址范围

https://blueprints.launchpad.net/neutron/+spec/address-scopes

让我们在 Neutron 中将地址范围作为一等公民来对待。由于 IPv4 和 IPv6 地址的重叠和任意使用,Neutron 无法知道哪些地址可以路由到哪里。地址范围将由 Neutron 用于解决此问题。

此提案与 RFC 4007 IPv6 地址范围无关 [1]

问题描述

Neutron 允许租户携带自己的地址,并允许在任何网络上使用重叠的 IP 地址。在子网池出现之前,可以创建具有用户想要提供的任何 CIDR 的子网。地址是否与其他项目或同一项目中的另一个子网重叠无关紧要。Neutron 在 L2 级别提供隔离,以确保这可以工作。

Kilo 中添加的子网池 [2] 是朝着正确的方向迈出的一步。它们增加了重叠保护,并允许管理员定义一个地址池,多个项目可以从中分配子网。现在我们可以协调地址了。这很好。

Neutron L3 提供有限的路由解决方案来隔离项目。只要路由器只连接一个项目的内部网络,浮动 IP 就可以在项目之间工作。但这只能走这么远。

对于 IPv6,我们希望忘记浮动 IP 并直接路由到租户网络。我们不能仅仅打开路由并假设一切都会正常工作。我们如何区分有效的、唯一的、可路由的子网和某人填写子网创建详细信息时随意创建的子网?即使对于 IPv4,小型到中型组织中的一些云也可能希望放弃浮动 IP 并直接使用一些私有寻址。

此外,将 MPLS/BGP VPN 完全集成到 Neutron 中,在未来可能会受益于此。在 L3 VPN 世界中,地址范围的类似物是路由区分器。通过添加地址范围,我们可以轻松映射到路由区分器。地址范围与路由区分器以及略有相关的路由目标的关联关系超出了此蓝图的范围。其他蓝图(如这个 [3])将更全面地解决这个问题。

提议的变更

添加一个新的对象,称为 AddressScope(地址范围)。一个 AddressScope 可以与多个 SubnetPool 对象关联,形成一对多的关系。这将允许将地址范围的各个部分委派给不同的租户。AddressScope 下的 SubnetPools 必须不重叠。它们还必须来自相同的地址族。只有管理员可以将来自不同租户的 AddressScope 和 SubnetPool 关联起来。一旦子网池关联后,只有地址范围所有者才能对其进行更新。如果此所有者不是子网池所有者,则必须是管理员。

未与 AddressScope 关联的 SubnetPool 将被视为与未从任何地址范围池创建的子网相同。这样做是为了保留 Kilo 中引入的行为,即地址范围不存在。

在 L3 插件的参考实现中,Neutron 路由器将意识到地址范围。它将使用多个路由表和策略路由——在 Linux 中找到并由 iproute2 管理的功能——来实现连接到具有不同地址范围的网络。传入设备 (iif) 将在每个规则中指定。

网络上的子网将限制在同一个子网池 [4]。即使在一个范围内有多个池,网络也将限制为每个地址族一个池。这项工作已经完成并回溯到 Kilo。

NAT 将自动包含在内部网络和路由器连接到的“外部”网络之间,作为网关,除非这两个网络具有来自相同地址范围中子网池的子网。它将为浮动 IP 提供 1-1 NAT,为默认 SNAT 提供多对一,就像今天一样。这将支持现有的用例。我们目前不打算实现比这更多的 NAT 用例。Liberty 之后的一个补充可能是更通用的 ipv4 NAT 功能,但我们想评估对它的需求并探索其他选项,例如将其作为 LBaaS 的一部分提供,或者类似的东西。

../../_images/address-scopes.png

路由器将在相同范围内的网络之间路由,而无需 NAT。例如,如果租户有一个子网池,并且管理员将该子网池包含在与外部网络相同的地址范围中,则该租户的子网将直接路由到外部网络。

您可能想知道,租户是否可以在管理员将其链接到范围后将任何地址添加到子网池。一旦子网池与地址池关联,只有地址范围的所有者才能更新池。

BGP 动态路由将使用地址范围的概念。它将附加元数据,以便知道如何将路由通告到地址范围。这将在 BGP 规范的后期工作中完成 [5]

数据模型影响

  1. 添加一个用于地址范围的新表。它将具有名称和 ID。

  2. 向 SubnetPool 添加一个新字段(默认值为 null),引用单个 AddressScope。这将是可更新的。在更新时,将检查子网池在范围内的其他子网池中是否存在地址唯一性。此外,必须通知路由器进行更改,以便调整路由。

REST API 影响

基本上,我们为新的地址范围对象添加 CRUD 语义。

我们需要 API 将地址范围与子网池关联。这将通过在地址范围上使用列表字段来完成。请注意,该列表将使用覆盖语义更新,而不是补丁语义。如果添加到地址池的子网池与不同的地址范围关联,则该操作将失败。

只有管理员才能将子网池与地址范围不同的所有者关联。一旦子网池关联,只有地址范围所有者才能更新子网池中的地址。

子网池将增强一个只读属性,以返回其所属的地址范围的 ID。

安全影响

查看性能影响。地址范围的更改可能会对控制平面产生重大影响。

通知影响

关于路由器通知…

  1. Address Scopes 的创建/更新/删除会向连接到受影响子网的路由器发送更新。任何属于子网池的子网的范围都可能发生变化。涉及多个项目的任何更改都将是仅限管理员的操作,这应该限制问题。无论如何,它不应该比部署软件升级(这将重新启动 L3 代理)产生更大的影响。

  2. 当 L3 代理请求有关路由器的信息时,必须查找路由器连接的每个子网的地址范围。这无需添加任何新查询即可完成。现有的查询需要通过子网池 ID 连接到地址范围表以检索地址范围 ID。

其他最终用户影响

  1. python-neutron 客户端将增强为操作地址范围

性能影响

AddressScopes 的添加、删除或更新可能会导致大量的 L3 代理活动。这是因为地址池的任何更改都可能更改子网的范围。涉及多个项目的任何更改都将是仅限管理员的操作,这应该限制问题。无论如何,它不应该比部署软件升级产生更大的影响。

当 L3 代理请求有关路由器的信息时,必须查找路由器连接的每个子网的地址范围。这无需添加任何新查询即可完成。现有的查询需要通过子网池 ID 连接到地址范围表以检索地址范围 ID。

IPv6 影响

这对于 IPv4 和 IPv6 同样有效。有些人可能会认为我们不需要 IPv6,因为每个人都将拥有唯一的地址。但他们没有抓住重点,因为这不仅仅是解决 IPv4 地址重叠的问题。它还认识到我们也有租户选择自己的 IPv6 地址。它们可能重叠或由于其他原因而无法路由。我们正在赋予 Neutron 了解如何处理它们的能力。

其他部署者影响

开发人员影响

社区影响

社区会喜欢它的。;)

说真的,这允许 Neutron L3 知道哪些东西可以路由到哪里。这尤其重要,对于 IPv6 而言,我们希望直接路由到项目的网络,而不是使用浮动 IP 跨越地址范围边界。

它也是将 MPLS/VPN 集成的关键部分,社区已经多次要求。这项工作将在 BGP 工作成熟后与 BGP 工作集成。BGP 和其他动态路由协议将了解地址范围,以便仅将来自正确范围的地址通告给给定的对等方或网络。

备选方案

使用多个路由表和策略路由的替代方案。例如,可以尝试 iptables 规则,但可能无法解决所有情况,尤其是在地址重叠时。地址范围非常适合多个路由表和路由策略。

还有一些工作要在 Linux 内核中直接引入 VRF 功能 [6]。这项工作可以提供更丰富的功能。但是,它非常新,还没有准备好用于此目的。

实现

负责人

主要负责人

carl-baldwin

其他贡献者

ryan-tidwell vikschw jbelamaric

工作项

  1. 将地址范围 ID 添加到发送给 L3 代理的 RPC 响应中。(最初只是子网池 ID)

  2. 增强 L3 代理以在路由表和策略路由中尊重地址范围。最初只是子网池 ID。它必须能够处理任何给定端口的范围 ID 更改。

  3. 添加地址范围的 DB 模型。

  4. 添加 AddressScope 的 CRUD,包括与 SubnetPool 的关联。更新 Neutron 服务器以发送适当的范围而不是池。

依赖项

测试

Tempest 测试

功能测试

对 L3 代理增强功能的实际测试路由表。

API 测试

对新 API 进行完整的 API 测试覆盖。

文档影响

用户文档

此功能值得一些新的用户文档,说明如何/为什么使用新的 API。

开发人员文档

需要记录的新 API。

参考资料

https://blueprints.launchpad.net/neutron/+spec/subnet-allocation