Neutron/DVR
执行摘要
有无数的博客和教程解释了 Neutron 是什么以及它可以做什么。本文不打算作为 OpenStack Networking 的入门指南。本文的唯一目标是阐明 Neutron 社区为何将部分精力集中在改进开源框架提供的某些路由功能上,以及用户在获得其最新版本(即 Juno)时可以期待看到的内容。
Neutron 路由
Neutron 提供了一个 API 抽象,允许租户和云管理员管理逻辑路由器。这些逻辑工件可用于连接逻辑网络以及连接到外部世界(例如,互联网),从而提供安全性和 NAT 功能。此 API 的参考实现使用 Linux IP 堆栈和 iptables 来执行 L3 转发和 NAT。下图显示了支撑 Neutron 参考平台 L3 的软件架构。
上面的架构图显示了 Neutron 系统中的内部组件,这些组件需要相互交互才能通过 Neutron L2 网络为计算实例提供 L3 服务。DHCP 组件被故意省略。典型的部署架构如下所示。多个 Neutron 服务器的活动实例可以在负载均衡器后运行,而多个网络节点可以通过 RPC 总线与服务器实例交互,并且可以用于根据在 Neutron 服务器上运行的调度组件确定的可配置调度策略在逻辑路由器上分配负载。
使用这种部署模型,Neutron 服务器集群代表一个提供高可用性和容错能力 (HA 和 FT) 的单元:在单个服务器发生故障时,管理请求将由该组的其他成员提供服务;此外,如果该组无法应对负载,可以添加一个新成员以提高可扩展性。但是,在查看网络节点时,FT 和 HA 选项有限。在单个网络节点发生故障时,分配到该节点上的所有路由器都会丢失;此外,单个节点代表 L3 转发和 NAT 的瓶颈。那么对于这种架构的 FT/HA 有哪些选择?本质上,唯一可用的选项是为每个节点引入一个主动/被动副本(更多详细信息请参见 [3])。副本组的管理通过集群机制(例如,Pacemaker)在带外完成。由于增加了管理复杂性,此选项远非理想。或者,如果可以容忍一些停机时间,可以采用带外故障转移策略,以允许将属于失败节点的路由器重新配置到网络节点组的活动节点。此解决方案的缺点是,根据节点在发生故障时的负载,恢复可能需要相当长的时间。
通往 Juno 的道路
如前一节所述,Neutron 参考实现提供的路由解决方案存在单点故障和可扩展性问题。那么可以做些什么来解决这些问题?就冗余和高可用性而言,可以利用内置于路由器配置中的机制,例如 VRRP ([1])。在这种情况下,部署架构与上述描述的架构基本相同,但是使用 VRRP,每个逻辑路由器都必须转换为分配给多个网络节点的 VRRP 组。它们可以实现容错性和高可用性。但是,此解决方案仍然面临一些问题:a) 副本因子(通常为 3)将施加更高的系统要求(例如,需要更多的硬件);b) DNAT 的南北流量,更重要的是东西流量,仍然需要通过单个瓶颈(因为计算节点通常比网络节点具有更高的数量级)。或者,一种可以解决上述问题的架构是将 L3 转发和 NAT 功能分布到计算节点本身:这就是分布式虚拟路由 ([2]) 的含义,以及在下一节中更详细讨论的内容。
Juno 和分布式路由
使用 DVR,L3 转发和 NAT 分布到计算节点,这会对迄今为止描述的部署架构产生重大影响;这到底意味着什么?这意味着使用 DVR,每个计算节点都需要充当网络节点,提供 L3 和 NAT。这是否意味着我们可以摆脱一池集中式网络节点?并非完全如此!原因是,某些网络功能可能需要通过网络元素流动。此外,在计算结构上分配 SNAT 会导致消耗宝贵的 IPv4“外部”地址空间。就网络和计算节点而言,使用 DVR 的逻辑架构因此如下所示
这两个节点看起来完全相同,至少从系统要求方面来看:它们需要运行相同的软件,并且需要具有相同的网络资源访问权限。但是,网络节点将负责南北 SNAT,而每个计算节点将提供南北 DNAT 以及东西 L3 转发。这就是为什么图上方的两种操作模式(即 dvr_snat 与 dvr)不同的原因。这种逻辑架构假定 DHCP 功能由与网络节点和计算节点分开的网络元素处理(尽管在 dvr_snat 代理上运行 DHCP 代理同样有效)。现在,让我们看看部署架构是什么样子:这可能与之前显示的架构没有太大区别,但是现在,此架构提供了一些有趣的 FT 和 HA 特性:东西和南北 DNAT 流量不再流经中央节点,从而提供更好的负载分配。此外,不再存在单点故障,因为与网络相关的故障定位在计算主机上,这将使计算实例无法访问,就像计算主机崩溃并带走计算实例一样。这仍然不是理想的,但是计算主机仍然是 OpenStack 的一个故障单元,因此此架构并没有使其变得更糟。就南北 SNAT 而言,这仍然需要流经中央网络节点;话虽如此,仍然可以运行多个网络节点,但是网络节点的故障将导致与之关联的所有路由器崩溃,导致在多个计算节点上运行的实例同时失去外部连接。更强大的架构将包括每个网络节点通过 VRRP 复制,从而消除最后一个单点故障。不幸的是,就 Juno 而言,我们还没有完全实现这一点。
超越 Juno
本文描述了直到 Juno 版本 Neutron 架构在路由功能上的局限性。该架构依赖于单个网络元素来执行 L3 转发和 NAT 功能,从而代表整个云部署的单点故障。即使可以扩展该元素,也需要采用临时策略来提供容错性和高可用性。自 Juno 版本发布以来,基于 VRRP 的实现(本文未深入讨论)可用,并减轻了初始架构的一些限制。DVR 是更详细讨论的策略,该架构解决了某些 L3 函数的可扩展性和高可用性问题。该架构并非完全容错(例如,南北 SNAT 流量仍然容易受到单个节点故障的影响),但它确实提供了有趣的故障模式。可以结合这两种方法来代表 OpenStack Networking 路由中的“银弹”,这将是未来 Neutron 版本的开发重点。话虽如此,当我们更密切地查看每个替代方案时,仍然存在一些问题需要解决,就 DVR 而言,其中一些问题如下
- 路由器转换:允许将现有路由器转换为分布式路由器;
- 路由器迁移:允许将分布式路由器的“snat”部分从一个网络节点迁移到另一个网络节点。
- 高级服务支持:允许 VPN、防火墙和负载均衡器等服务与分布式路由器顺利配合工作;
- 外部网络:允许使用多个外部网络与分布式路由器;
- IPv6:允许 IPv6 网络与分布式路由器配合工作;
- VLAN 支持:允许分布式路由器与 VLAN 下层配合工作;
- 其他供应商插件中的分布式路由;
配置变量
- Neutron 服务器
- router_distributed = True ==> 它控制默认路由器类型:设置为 True 时,路由器将默认以分布式方式创建。
- L3 代理
- agent_mode = [dvr_snat | dvr | legacy ] ==> 要使 L3 代理分别在网络节点或计算节点上运行(legacy 是为了向后兼容的默认值)。dvr_snat L3 代理可以处理集中式路由器和分布式路由器。
- L2 代理
- enable_distributed_routing = True ==> 要使 L2 代理以 DVR 模式运行。DVR 模式下的 L2 代理可以无缝工作。
API 扩展
DVR 路由通过路由器资源上的 API 扩展属性公开。此属性仅对管理员用户可见。创建路由器时(无论用户角色如何),Neutron 都会依赖于系统范围内的配置(如上所述的 router_distributed),其默认设置目前允许创建“集中式”路由器,也称为 legacy 路由器。管理员可以根据需要覆盖默认路由器类型。