Routed Networks

https://blueprints.launchpad.net/neutron/+spec/routed-networks

问题描述

期望的使用场景

在许多情况下,物理数据中心网络架构会区分第二层和第三层。换句话说,存在只有一部分计算主机可用的不同 L2 网络段。路由允许流量跨越这些边界。这些拓扑用于管理网络资源容量(IP 地址、广播域大小、ARP 表等),以允许大规模网络。

来自 大型部署团队 (LDT) 和其他团队的运营商希望有一个由运营商配置的 Neutron 结构,该结构暴露给用户并映射到这种类型的物理网络。他们希望该结构代表一个 L3 域,通常比构成它的每个物理 L2 段具有更大的范围。用户必须能够指定虚拟机在该域中的任何位置启动 - 而不是在特定的物理 L2 段上。因此,在此结构/域上的虚拟机之间的唯一保证连接是在 L3 级别;因为任何两个虚拟机之间的数据路径可能涉及 IP 路由跳跃。幸运的是,许多工作负载只需要 L3 连接。

这些运营商希望租户继续思考和选择 Neutron 网络(例如,命名为“dev”和“prod”、“red”和“blue”等),同时确保仅保留 L3 语义。然后,Nova 和 Neutron 将协同工作,将实例调度到主机和 L2 段,该 L2 段既可以从该主机访问,又具有可路由的 IP 地址。

具体来说,运营商希望解决这个问题 无需使用覆盖网络。覆盖网络适用于许多较小到中等规模的 L2 网络(端口数量方面),并且可以覆盖在 L3 域之上。但是,将大规模 L2 覆盖网络覆盖在 L3 域之上会适得其反。他们不希望要求用户使用单个 L2 域。因此,从用户的角度来看,此用例看起来像是启动到具有直接外部连接的单个共享网络。它不涉及具有单个租户网络和虚拟路由器的自助服务拓扑。这些将来可能会出现,其中一些在 潜在的未来工作 中有所描述。

当前模型不足之处

在 Neutron 中,网络(无论是提供者网络还是逻辑租户网络)当前假定为 L2 广播域。这可能使其非常适合将 L2 段建模为单个提供者网络,或者当 l2 段确实是物理上通过覆盖(即隧道)实现的逻辑表示时。在前者的情况下,问题是用户将看到一个潜在的冗长网络列表,而没有任何明确的理由来区分它们。从用户体验的角度来看,这是一种糟糕的做法。实际上,这些段是无需暴露给用户的实现细节。

如果我们决定打破上述假设并使用网络来建模 L3 域,那么我们就会遇到其他问题。本规范详细介绍了这些问题的解决方案。问题和建议的解决方案在 建议的更改 部分中详细介绍。

提议的变更

概述

建议的解决方案从 Neutron 的 现有扩展机制 用于定义 多段网络 开始。简而言之,这些类型的网络是由具有潜在不同第二层技术(vxlan、vlan、flat、gre 等)的段的集合组成的管理员配置网络。它也可以是同构段的集合(即,所有 VLAN 的单一技术)。

许多插件尚未广泛实施这些多段网络。ML2 实现了它们,但其他许多插件没有。其他插件需要实施模型更改以支持此规范中描述的多个段。当前模型无法确定(更不用说控制)这些段是否桥接在一起以提供它们之间的 L2 可达性。

网络无法对子网与特定 L2 段的关联进行建模。所有子网都与网络(段的集合)相关联。

本规范建议将段作为 Neutron 中的一等对象,该对象具有 ID。这将允许子网与之关联。子网到网络的关联将保留,但一个可选的 segment_id 字段将被添加到子网以将其与特定段关联。

没有段 ID 的子网仍然假定跨越所有段。通常,在配置路由网络时,所有子网都将与一个段关联。

创建提供者网络时,如果插件支持“segments”扩展,则会自动创建一个段对象来反映该网络的实现方式 - 或者一组段对象,如果网络创建使用了多提供者扩展。

随后,这些段对象可以由云管理员更新或销毁,并且可以为同一网络添加更多段对象,并且该网络的底层实现应相应地进行调整。在实践中,并非所有可能的“调整”都是可行的,因此我们可能需要一种描述给定插件实际可以支持的段对象更改的方式。

读取网络对象时,返回的“provider:”和“segments”属性应反映读取时存在的段对象。

L2 邻接性

一个名为 l2-adjacency 的属性将被添加到 Neutron 网络。这是一个布尔值,其中 true 表示您可以期望整个网络具有 L2 连接,而 false 表示不保证 L2 连接。此属性应可见给用户以设置期望。实现不会依赖此值,它仅仅面向用户。

此值将是只读的,并且源自网络内段的当前状态。如果网络上的子网直接连接到段,则该值将为 false。否则,它将为 true。

其他插件可以根据需要实施此功能。例如,Calico 可以将其硬编码为 false 并完成。实施路由网络的插件可以使用或模仿参考实施的行为。

DHCP 调度

DHCP 调度当前不知道子网到段的关联。

本规范建议在子网与段关联时更改 DHCP 调度程序。调度程序将注意确保所有此类段都具有 DHCP 服务器。如果需要多个 DHCP 服务器以实现冗余,它将为每个段调度所需的服务器数量。

对于未直接与段关联的子网,调度将像今天一样工作,假设网络中的任何段都足够了。在某些插件中,当 L2 邻接性为 False 时,可能会存在这样的子网。本规范目前不解决此问题。Calico,这样一个插件,通过在每个计算主机上运行 DHCP 和一些特殊的管道解决了这个问题。

运营商必须确保在每个段上都可用具有物理连接的 DHCP 代理。

每个服务器都将意识到分配给其分配段的子网。元数据代理服务将从每个服务器提供。

段主机映射

到目前为止,Neutron 网络通常假定可以访问部署中的所有计算主机。有了这个提议,这将继续通常为真。但是,对于此用例,网络内的给定段仅会访问一部分主机。这在使用 ML2 插件时已经可行。此外,目前正在进行工作以 利用映射使 DHCP 意识到段。但是,这需要在任何插件或机制驱动程序都可以提供的以某种方式形式化。

维护计算主机与段之间的映射将是 Neutron 插件的责任。可以使用后端特定的配置来处理它,或者可以提供 API 原语。

从高级别来看,我们需要能够有效地执行以下一些映射。这些操作将反映在新可选的插件 API 方法中,任何插件都可以实现这些方法。

  • 段 -> 具有与其 L2 可达性的主机。

  • 主机 -> 可以通过 L2 访问的段(s)

例如,对于基于代理的 ML2 部署,可以利用现有的桥接映射。在当前的 ML2 实现中,必要的数据被埋在列中的 JSON blob 中,使其对 DB 查询不透明。这将不得不改变。

确切地说,*agents* 表 中的 configurations 列保存一个 json blob。blob 如下所示(删除了冗余数据)

{...
 "bridge_mappings": {...}}

每个桥接映射是 (physnet, bridge)。桥接可以忽略,但 physnet 可以与 主机 配对以进行主机 / physnet 映射。我们可以将此与 网络段 / physnet 映射 结合起来,最终得到一个段 / 主机映射。

本规范引入了一个新表,segment_host_mapping,以使此最终映射显式化。该表将随着代理继续报告到 physnet 的可达性而填充和更新。在 ML2 中,这仅适用于 flat 和 vlan 类型的段。

对于无代理的 ML2 实现,可能需要提供另一种机制来填充此表。非 ML2 插件还需要提供此功能,可能利用已经完成的工作。目前,仅对使用 VLAN 或 flat 网络创建路由网络感兴趣。我们可能需要考虑如果有人尝试使用其他段类型会发生什么。

Nova 调度

用户感知的启动工作流程不会改变,无论他/她选择从端口还是从网络启动。但是,用户应该意识到,在端口创建时指定 IP 地址会将它限制为与匹配子网的段,从而限制了它们可以着陆的计算主机集合。在大多数情况下,拥有特定的 IP 地址不会是用户希望限制其 VM 放置的第一件事。这应该在文档中明确说明这种权衡是存在的。

路由网络中的所有子网都将与一个段关联。因此,如果未指定地址,Neutron 将延迟此端口的 IP 地址分配。换句话说,Neutron 在端口绑定到主机之前,不会考虑与段关联的任何子网进行自动 IP 分配。在那之前,端口没有 IP 地址是可以的。

这项工作在 Nova backlog 规范 中进行了更详细的讨论。这包括对实时迁移的调度以及调度程序将如何将 IP 子网视为资源池的讨论。

绑定

完成调度后,端口将绑定到所选主机。此时,Neutron 可以为端口选择合适的子网并进行 IP 分配。

潜在的未来工作

本节描述了一些超出本规范范围的潜在后续工作。

  • 将 Neutron 路由器连接到路由网络作为它们的外部网关。这与 DVR 路由器一起变得非常有趣。它还可以启用 FIP 命名空间,因为每个 L2 网络的规模将很小(使用 L3 域是拥有 FIP 命名空间的主要动机之一)

  • 段 api 可以有一个 DHCP 启用标志,以允许禁用特定段的 DHCP。

  • DHCP 中继可以作为在每个段中运行 DHCP 代理的替代方案来实现。

数据模型影响

  1. 多提供者网络扩展是建模分段 L3 网络的基础

  2. 段是一等对象,子网与之关联

    • 将为 ML2 静态段提供迁移(可能不需要迁移,ML2 段 已经拥有所有数据)

  1. 明确表示同一网络内段的 l2 邻接性

    • 只读属性源自段的当前状态

    • 对于单段网络为 true,否则为 false

  2. 实施更改以使 DHCP 在非相邻的多段网络中工作

    • 可能不需要进一步的建模更改。

  3. 正式建模主机到段的映射

    • 新表从 agents/configurations json blob 迁移

  4. 延迟多段网络的端口 IP 分配

    • 可能不需要任何新的模型更改

REST API 影响

常规 CRUD

  • 对于管理员,能够列出可到达段的主机

  • 列出与段关联的子网

网络

子网

  • segment_id 属性在 Segments 中描述

端口

  • segment_id(即使没有绑定的端口具有 IP,仍然可以与 Segment 具有关联性)

安全影响

预计此更改不会带来任何新的安全问题。

通知影响

我认为我们可以根据情况处理这些问题。

其他最终用户影响

客户端将被增强以支持 API 中的更改。Horizon 至少需要在网络上暴露 l2-adjacency 属性。

性能影响

我不认为这会对性能产生显著影响。它支持一种以 L3 为中心的物理网络拓扑,这种拓扑已被证明在扩展方面表现更好。

IPv6 影响

此更改将平等地考虑 IPv4 和 IPv6。

其他部署者影响

部署者在升级代码之前不需要执行任何操作,直到他们希望使用此规范提供的新的功能。在这种情况下,他们需要从他们的网络架构开始。

此规范主要针对绿色部署,在这种部署中,操作员具有完全的灵活性来以 L3 为中心的方式定义物理网络拓扑。

话虽如此,现有部署在升级代码后,可以通过部署新的 Neutron 网络来使用此新功能。他们可以创建新的 VLAN,在他们的机架顶端交换机上启用路由功能,添加路由器,以及创建 L3 网络所需的一切。在某些情况下,只需配置现有的物理设备即可完成。

无论哪种方式,我认为从网络的角度来看,这都是一个绿色部署。

将会有一些操作员拥有一个大型扁平网络,或者已经路由在一起的 Neutron 网络集合,他们希望转换为使用单个多段 Neutron 网络,并将 l2-adjacency 设置为 false。我希望与这些操作员讨论一个迁移计划。目前,我还没有对此有一个完整的了解。

开发人员影响

此更改将对开发人员产生影响。此蓝图包含插件提供程序需要查看并实施的 API 和模型更改。具体来说,他们将希望实施 L2 AdjacencySegmentsSegment Host Mapping

社区影响

是的。此更改已经是一个高度可见的更改,已经在 ML 上讨论过,在 Neutron 会议(尤其是 L3)以及在各种设计峰会上讨论过。最值得注意的是,在温哥华的一个大型部署团队会议和在东京的一个设计会议上。

备选方案

社区对一个替代方案进行了长时间的讨论。它通过使用网络的实例来表示 L3 域,从而避免向模型添加新对象。将创建一个 Neutron 路由器,以将“前端”仅 L3 网络与任何数量的“后端”网络相关联,这些网络代表 L2 段。该替代方案承认 L2 和 L3 混合在同一个对象中。

提供商网络允许描述在此规范中的大部分内容。事实上,此处描述的网络在很大程度上类似于提供商网络。此规范需要增强提供商网络概念,以支持描述的 L3 架构。

另一个经过长时间讨论的替代方案是添加一个新的 IpNetwork 结构来表示 L3 网络。如果我要重新建模 Neutron,我会这样做,但现在没有平滑的路径来实现。当前的提案是一种妥协方案,似乎具有更好的迁移路径。

实现

负责人

主要负责人

其他贡献者

请在此处添加您的姓名并参加 Routed Networks 会议,如果您想做出贡献。如果您的姓名在此处但您没有时间做出贡献,请告诉我。本节实际上只是我记录贡献者,他们可以在这项工作中发挥作用的便签。

工作项

  1. 仅管理员 Segments 扩展

    • 对于 ML2,使用多提供商扩展数据模型。

    • API测试

    • 客户端支持

    • 将 segment_id 添加到 Subnet

      • 客户端支持

    • 将 segment_id 添加到 Port

      • 这代表了分配 IP 的 segment_id,并不完全等同于通过端口绑定关联的 Segment。

      • 这应与通过 IPAllocation 关联的任何 segment_id 保持一致。

  1. 延迟多段网络的端口 IP 分配

    • 如果没有 segment,Port 只有在存在没有 segment 关联的子网时才能获得 IP 地址。

    • Nova 验证端口是否具有 IP。这必须删除(首选)或延迟到主机绑定之后。

  2. 主机/Segment 映射

    • 在从代理接收到桥接映射时更新映射

    • 通过 API 暴露

      • 可通过新的 segment API 获取可用于 Segment 的主机列表。

  3. 维护主机聚合并在 Nova 中创建调度器资源池。

    • 这些应与主机/Segment 映射保持同步

  4. 在 Nova 启动/实时迁移中,将现有 Port 的 segment_id 绑定到资源池。

    • 在调度器表中,资源池中有一个“外部 ID”,需要与现有 Port 中的 segment_id 匹配。我不确定 Nova 如何注意到 Port 上的现有 segment_id 并将其匹配。有关更多详细信息,请参阅 Nova 规范

  1. DHCP 调度器和代理

    • 将与子网关联的段调度到具有可达性的代理

    • 理想情况下,代理应仅配置为服务与其连接的段上的子网(以及与任何段没有关联的子网)。

  2. 将 L2 邻接性添加到 Network

    • 只读属性源自段的当前状态

    • 对于单段网络为 true,否则为 false

依赖项

Nova 规范。这将需要与 Nova,尤其是调度器团队的协调。

测试

Tempest 测试

将对 tempest 测试进行更改。

功能测试

未知

API 测试

  • Segment 资源(CRUD)- 它与 Subnets 和 Networks 的关系

  • Network l2-adjacency 标志(通过 API 以只读方式)

  • 主机/Segment 映射(通过 API 以只读方式)

文档影响

用户文档

记录 Network 上的 l2-adjacency 标志

开发人员文档

参考资料