具有多归属的活动-活动 L3 网关¶
https://bugs.launchpad.net/neutron/+bug/2002687
目前 Neutron 路由器仅支持一个外部网关端口,并且只能手动将 ECMP 默认路由添加为额外的静态路由。同样,BFD 也无法为 ECMP 路由配置。本规范为现有的 Neutron API 提供扩展,用于配置多个外部网关,自动添加 ECMP 默认路由和这些路由的 BFD。它还讨论了在不同的 chassis 上为每个路由器调度多个网关端口的问题。OVN 被选为主要的后端。
问题描述¶
一些网络设计包括多个 L3 网关以
在不同的网关之间共享负载:在不同的 OVN chassis 托管不同的网关端口以及共享处理负载以及上游网关处理南北流量的一部分方面;
为南北方向提供独立的网络路径(例如,通过不同的 ISP),以在不依赖相同的 L2 的情况下实现弹性。
在实例级别实现多归属会给云的最终用户和客户操作系统带来额外的负担,而利用路由器侧的 ECMP 和 BFD 可以减轻实例侧对更复杂路由设置的感知需求。
添加多个网关端口意味着扩展现有的数据模型,该模型在 多个外部网关规范 中进行了描述。但是,它将添加额外的网关路由排除在范围之外,将其留给未来围绕动态路由的改进。此外,neutron-dynamic-routing 的重点到目前为止一直是通告路由,而不是接受来自外部对等体的路由 - 因此这种动态路由支持是一个非常不同的主题。但是,手动添加额外的路由并不能利用 Neutron 中子网可用的默认网关 IP 信息,而这可以通过在将多个网关端口添加到路由器时实现额外的条件行为来解决。
如果路由的下一跳不可达,ECMP 路由可能会导致流量黑洞。 BFD 是 IETF 采用的标准协议,用于检测下一跳故障,可用于路由驱逐。OVN 支持 BFD 自 v21.03.0 以来,具有一个数据模型,允许通过将 BFD 会话信息与路由关联,基于每个下一跳启用 BFD,但是,即使后端支持它,BFD 也没有在 Neutron 级别建模。
维护过多的 BFD 会话可能会对性能产生影响,因为周期性协议消息将消耗主机的 CPU 周期。该实现旨在最大限度地减少每个目标所需的 BFD 会话数量。一种方法是在路由器默认路由和额外的路由之间重用 BFD 会话信息,如果对等端点和会话配置的其余部分匹配。但是,运营商在他们希望配置 BFD 的路由器数量方面应小心。
从 Neutron 数据模型角度来看,ECMP 路由是一个受支持的概念,因为 ECMP 支持规范 在 Wallaby 中实现(尽管该规范侧重于基于 L3-agent 的实现)。
对于 OVN 和 BFD,OVN 数据库状态需要根据 Neutron 数据库中的数据填充。因此,需要对 Neutron DB 进行数据模型更改,以表示 BFD 会话参数。
提议的变更¶
数据库影响¶
核心模型¶
目前,在 Neutron 中表达路由器到网关端口关系有两种方式
gw_port_id外键在routers表中,设置为类型为network:router_gateway的路由器端口的 UUID;routerports表,该表 为了引用完整性而添加,并存储router_id到port_id映射以及冗余的port_type。
在 Neutron DB 中表示多个网关端口方面,该提案遵循 多个外部网关规范
保留
routers、routerports和ports表,保持原样,但在routerports表中开始存储每个路由器的多个network:router_gateway端口;为了保持向后兼容性,在
routers.gw_port_id中存储单个网关端口 ID。兼容的网关端口将与routerports表中的其他网关端口一起存储。使用新的属性
gw_ports扩展neutron.db.models.l3.Router类,该属性将映射到存储在routerports表中的所有相关的network:router_gateway端口。
BFD 和 ECMP 路由行为建模¶
路由器的每个外部网关信息字典应包含有关处理与网关端口关联的子网的默认路由的策略的其他信息。这是必要的,以便 Neutron 作为 CMS 具有指定 OVN 是否需要 ECMP 路由以及是否需要为它们启用 BFD 的所需状态,而不仅仅是在添加外部网关到路由器时传递这些选项。因此,需要沿路由器存储此信息。
建议在 router_extra_attributes 表中添加以下其他列
enable_default_route_ecmp 是路由器级别的策略,用于确定是否应使用 ECMP 默认路由(如果 L3 服务插件支持它们)。
enable_default_route_bfd 是路由器级别的策略,用于确定是否应使用 BFD 来检查默认路由的下一跳是否可达(如果 L3 服务插件支持 BFD)。
将使用 OVN 的 BFD 建模 来实现对默认路由的 BFD 会话的支持。
OVN 允许为特定的静态路由创建一个 BFD 会话,以使用与静态路由的下一跳不同的目标 IP 来检查可达性(通过在 BFD 表中的 dst_ip 字段中存储 BFD 对等 IP 地址)。这是一种有用的语义,用于分离控制平面和数据平面,也可以用于 Neutron 路由器的静态路由。但是,当涉及到从网关端口到子网关联推断的默认路由时,Neutron 的行为应该是将默认路由的下一跳用作 dst_ip。
OVN 将 BFD 表建模如下(有关更多信息,请参阅 ovn-nb 文档)
dst_ip- BFD 对等 IP 地址;min_tx- 一个整数,指定 OVN 在传输 BFD 控制包时将使用的最小间隔(毫秒,>=1)(减去抖动);min_rx- 一个整数,指定 OVN 能够支持的接收 BFD 控制包之间的最小间隔(毫秒)(减去发送者应用的抖动)。可以设置为 0,表示不希望从 BFD 对等体传输 BFD 控制包;detect_mult- 一个整数(>= 1),指定检测时间乘数。协商的传输间隔乘以此值,为异步模式下接收系统提供检测时间。OVN 包含
options字段,其中包含一个字符串-字符串对的映射,该映射保留供将来使用。可以稍后将类似的字段或额外的列添加到 Neutron 模型中,以考虑其他扩展。
本规范的提议方法仅限于可选地为推断的默认路由启用 BFD,将更高级的 BFD 模型与每个额外的静态路由 BFD 会话留给未来的迭代(例如,在实施 BFD 支持规范 规范期间)。
Rest API 变更¶
路由器 API¶
API 更改增加了 多个外部网关规范 中的更改,但也包括额外的行为更改,因此,本规范中使用不同的 API 扩展名称:external-gateway-multihoming,并且此处完整列出了 API 更改。
还添加了新的属性作为额外的路由器属性,并且 API 扩展到在 router API 资源中处理这些属性(每个属性添加一个单独的扩展)
enable_default_route_ecmp是路由器级别的策略,用于确定是否应使用 ECMP 默认路由(如果 L3 服务插件支持它们)。enable_default_route_bfd是路由器级别的策略,用于确定是否应使用 BFD 来检查默认路由的下一跳是否可达(如果 L3 服务插件支持 BFD)。
使用 external-gateway-multihoming 扩展,添加了一个新的路由器 API 资源属性,称为 external_gateways,它是一个 external_gateway_info 结构的列表。
出于兼容性目的,external_gateways 列表的第一个元素是特殊的,因为它包含与 external_gateway_info 相同的信息。当路由器上的 enable_default_route_ecmp 设置为 false 时,它还定义了放置在路由器路由表中的默认网关(虽然 OVN 驱动程序当前不支持多段网络的路由,但基于用于网络段的子网推断默认网关很重要)。
列表的其余部分的顺序被忽略。
列表中的重复项(即,具有相同 network_id 的多个外部网关)是允许的:在这种情况下,多个网关端口将附加到相同的网络(这可用于在同一网络上提供有源-有源设置)。但是,将多个网关端口附加到具有重叠子网范围的不同网络会导致路由问题,因此不允许这种重叠。
更新 external_gateway_info 也会更新 external_gateways 的第一个元素,并且保持 external_gateways 的其余部分不变。将 external_gateway_info 设置为空值会从路由器的网关端口集中删除单个(兼容)网关,并选择现有的额外网关作为兼容网关的替代品。
无法在 POST /v2.0/routers 或 PUT /v2.0/routers/{router_id} 请求中设置 external_gateways 属性,而是可以通过子方法进行管理
PUT /v2.0/routers/{router_id}/add_external_gateways接受
external_gateway_info结构的列表。将网关添加到同一网络是允许的,前提是尚未使用固定的 IP(如果指定)。如果路由器已经存在一个或多个网关,则列表中的第一个项目将成为额外的网关。如果没有,则第一个项目将被视为兼容网关。PUT /v2.0/routers/{router_id}/update_external_gateways接受
external_gateway_info结构的列表。要更新的外部网关由 PUT 请求中找到的network_id字段和external_fixed_ips标识。仅可以在路由器级别更新enable_snat。可以在不重新创建端口的情况下更新external_fixed_ips。PUT /v2.0/routers/{router_id}/remove_external_gateways接受潜在的部分
external_gateway_info结构的列表。external_gateway_info结构中的network_id和external_fixed_ips字段的组合用于标识要删除的特定网关。可以存在其他键,但其值将被忽略。
添加/更新/删除 PUT 子方法响应整个路由器对象,就像 POST/PUT/GET /v2.0/routers 一样。
额外的路由 API:ECMP¶
正如 ECMP 支持规范 所述,为了支持 ECMP 路由本身,无需对 API 进行任何更改:在添加额外路由时,已经可以指定到相同目的地的多个路由和不同的下一跳。然而,该规范侧重于基于代理的实现——这项工作的一部分是检查这对于基于 OVN 的 L3 实现是否也成立。
额外的路由 API:BFD¶
在没有完整的 BFD API 的情况下,用户将可以选择在路由器上指定一个策略 (enable_default_route_bfd)。
OVN 驱动程序变更¶
通常,我们将更新现有的 OVN 驱动程序,以处理在现有代码中当前处理网关端口的任何地方出现的多个网关端口。以下是一些感兴趣的领域。
路由器级别的 External IDs¶
现有实现中存在一些路由器级别的 External IDs,它们无法与多个网关端口一起工作
ovn_const.OVN_GW_PORT_EXT_ID_KEY
ovn_const.OVN_GW_NETWORK_EXT_ID_KEY
这些将被弃用,并替换为在运行时查找所需信息的方法。
L3 调度器变更¶
具有多个网关端口的路由器的主要用例之一是弹性。每当单个路由器存在多个网关端口时,我们希望确保这些端口跨底盘进行多样化部署,以最大限度地减少底盘故障的影响。
这将通过更新 leastloaded 调度器来实现,以便在为具有多个网关端口的路由器调度网关端口时应用软反亲和性。
不会对 chance 调度器进行任何更改。
超出范围¶
BFD 会话数据模型和 API;
BFD 身份验证,因为它没有在 OVN BFD 实现中实现,而是在协议 RFC 本身中存在。因此,数据模型应该可扩展,以便将来支持它;
为额外路由启用 BFD。目前,规范只会解决推断路由,将此留给未来的迭代;
解决分布式 SNAT 问题。一种方向是在网关端口之间使用 conntrack 状态同步。其他想法涉及在控制平面做出更明智的选择,关于 conntrack 状态应该存在的位置,而不是将其到处分发——可以通过确保流的处理在实例本地进行来实现,但这也存在一些缺点,需要更仔细地考虑
处理不对称路由
可以使用 conntrack 来避免实例生成的响应通过与请求到达的路由不同的路由,在存在 ECMP 路由的情况下。OVN 支持使回复流量走对称路径。这可以通过利用 OVN 中逻辑路由器静态路由表中的 options 列 来配置,该列允许配置 ECMP 对称回复 通过将
ecmp_symmetric_reply选项设置为true(它在 OVN 中也以路由级别建模)。Neutron 中的路由可以有一个
ecmp_symmetric_reply选项,以根据 L3 服务插件是否支持它来指定是否启用 ECMP 对称回复 的策略。然而,引入该功能的提交 在 OVN 中指出其使用的限制:它只能用于网关路由器,而不能用于由于逻辑路由器的入口流水线逻辑依赖于超visor-local CT 状态而具有网关端口的分布式路由器。
通过动态路由协议接受 ECMP 路由。当前的目标是利用 Neutron 子网中可用的默认网关信息来配置默认网关 ECMP 路由,或使用额外的路由扩展。该规范是未来支持动态路由的基础。
路由指标的建模。虽然在对于相同目的地,一个默认路由可能优于另一个默认路由的情况下,但 Neutron 和 OVN 今天都没有对此概念进行建模;
基于 Linux 命名空间的非 OVN L3 实现的 BFD 实现。
实现¶
负责人¶
Frode Nordahl <frode.nordahl@canonical.com> (~fnordahl)
Dmitrii Shcherbakov <dmitrii.shcherbakov@canonical.com> (~dmitriis)
工作项¶
通过对 neutron-lib 和 Neutron 更改 API、核心 Neutron 和 OVN 集成代码来添加新的 REST API;
更改数据库模式以添加新属性并创建相关的数据库迁移;
在 OVN 驱动程序中实现对 external-gateway-multihoming 扩展的支持。
更新 OVN L3 leastloaded 调度器,以便在为具有多个网关端口的路由器调度网关端口时应用软反亲和性。
更新 CLI,以便利用新添加的 rest API;
更新相关文档;
使用 Neutron 中现有的设施实现相关的单元和功能测试。