TripleO 路由网络部署 (Spine-and-Leaf Clos)¶
https://blueprints.launchpad.net/tripleo/+spec/tripleo-routed-networks-templates
此蓝图是 tripleo-routed-networks-deployment 系列的一部分 [0]。
TripleO 今天对所有网络使用共享的 L2 网络,除了配置网络。 (在 Queens 中添加了 L3 配置网络的支持。)
配置网络上的 L3 支持使用网络段,这是 Neutron 路由网络中的一个概念,我们可以表示每个 VLAN 多个子网。如果没有网络段,我们将限制为每个 VLAN 一个子网。
对于非配置网络,我们今天在 TripleO 中无法模拟真正的 L3 路由网络。在部署这种架构时,我们当前为每个隔离网络创建自定义(neutron)网络,用于所有不同的 l2 段。虽然这种方法有效,但有一些注意事项。
此规范涵盖了重构 TripleO Heat 模板,以支持部署到多个 L2 域隔离的网络,并通过路由器在 L2 域之间转发流量。
问题描述¶
路由网络部署的总体蓝图将问题集分解为多个部分 [0]。 此蓝图介绍了适用于此蓝图的问题如下。
问题描述¶
问题 #1:将系统部署到路由配置网络。
虽然我们今天可以模拟路由配置网络并在该网络之上部署系统。 但这样做需要额外的复杂配置,例如
设置所需的静态路由,以确保 L3 控制平面内的流量在整个网络中走所需的路径。
L2 段使用不同的路由器地址。
L2 段可以使用不同的子网掩码。
其他 L2 段属性差异。
这种配置基本上是将信息手动传递到模板中以部署超云。 这些信息已经在部署内云时提供了。 虽然这可行,但会增加复杂性以及用户提供不正确配置数据的可能性。
我们应该能够根据在部署内云时提供的信息获取这些信息中的大部分。
为了支持这种模型,Heat 和 Neutron 必须满足一些要求。
问题 #1 的替代方法
方法 1
注意
这是我们目前所做的。
由于我们使用 Heat 模板和 os-net-config 的组合来控制主机节点上的地址和路由,因此可能使用静态路由到超网来提供 L2 邻接关系,而不是依赖 Neutron 生成需要更新所有主机的动态路由列表。
最终结果是,每个主机都有一组通过功能隔离的 IP 地址和路由。 为了使回程流量也通过功能隔离,必须在两个主机上存在类似的路由,指向本地子网上本地网关,用于包含所有内部 API 子网的更大的超网。
缺点是,我们必须要求正确的超网划分,这可能会导致使用更大的 IP 地址块来提供充足的扩展增长空间。 例如,在上面的示例中,为最多 255 个内部 API 网络的本地子网预留了整个 /16 网络。 如果本地子网的数量不会超过 64 个,则可以将其更改为更合理的空间,例如 /18 等。 对于 IPv6 来说,这个问题不太严重,因为 IPv4 的稀缺性更高。
方法 2
不要传递 ControlPlaneCidr、ControlPlaneDefaultRoute 等参数,而是实现 Neutron RFE [5] 和 Heat RFE [6]。 在 tripleo-heat-templates 中,我们可以使用 get_attr 来获取数据。 我们将 L3 网络的路由计算和提供留给 neutron。
这需要 [3],我相信在活动策略放弃之前,它处于相当好的状态。 (另一种选择是更改 os-net-config 以使其具有仅更改和应用路由配置的选项。 类似于运行 ifdown-routes / ifup-routes,但是 [3] 可能是更好的解决方案。)
问题 #2:静态 IP 分配:从正确的子网选择静态 IP
某些角色,例如 Compute,可能可以放置在任何子网中,但我们需要将某些角色放置在相同的 L2 域内。 例如,提供 Neutron 服务的任何角色都需要所有控制器位于相同的 L2 域,以便 VRRP 正常工作。
网络接口将使用创建 os-net-config 配置文件的模板进行配置。写入每个节点配置的 IP 地址需要位于每个主机的正确子网中。 为了使 Heat 从正确的子网分配端口,我们需要一个主机到子网的映射。
可能的解决方案、想法或方法
注意
我们目前使用 #2,通过为每个角色指定参数。
这将最简单的实现方式可能是角色/索引到一组子网的映射,以便 Heat 知道 Controller-1 在子网集 X 中,Compute-3 在子网集 Y 中。 然后,该节点将从适当的子网集中选择每个网络的 IP 和子网信息。 对于其他节点,我们需要以编程方式确定哪些子网对于给定的节点是正确的。
我们可以将特定的子网与角色关联起来,然后使用每个 L2 域(例如,每个机架)一个角色。 这可以通过角色到子网的映射来实现,或者通过为每个角色指定参数来实现,例如:超网、子网(ID 和/或 ip/netmask)和子网路由器。
初始实现可能遵循 environments/ips-from-pool-all.yaml 中演示的隔离网络的模型。 首先开发 ips-from-pool 模型将允许在开发使用指定子网内动态分配 IP 的模板的同时测试各种组件。
角色和模板应该被重构以允许在与角色关联的子网内动态 IP 分配。 我们可能希望评估将路由的子网存储在 Neutron 中,使用仍在开发中的路由网络扩展。 但是,在这种情况下,这可能不需要实现每个机架中的单独子网。
一个可扩展的长期解决方案是在内省期间映射主机所在的子网。 如果我们可以识别每个接口的正确子网,那么我们可以将其与来自正确分配池的 IP 地址相关联。 这将具有不需要静态角色到节点到子网映射的优点。 为了做到这一点,需要在 Ironic 和 Neutron 之间进行额外的集成(使 Ironic 意识到每个网络上的多个子网,并在内省期间添加能够进行关联的能力。
我们还需要考虑同一 L2 广播域(例如,在机架内)中存在异构硬件节点的情况。
注意
这可以通过在 NetConfigDataLookup 中使用节点组来实现,如审核 [4] 中所示,或者通过使用额外的自定义角色来实现。
问题 #3:隔离网络需要静态路由以确保使用正确的 VLAN
为了继续使用隔离网络模型,需要在每个节点上放置路由,以将流量引导到正确的 VLAN 接口。 路由在 os-net-config 首次运行时写入,但可能会更改。 我们不能仅仅依赖指向其他子网的特定路由,因为子网的数量会随着机架的添加或移除而增加或减少。
可能的解决方案、想法或方法
要求使用各种网络组的超网。 例如,所有内部 API 子网都将是超网的一部分,例如 172.17.0.0/16 可以使用,并分解为许多较小的子网,例如 /24。 这将简化路由,因为只需要一个指向 172.17.0.0/16 的路由,指向每个子网上的本地网关(例如,172.19.1.1 和 172.19.2.1)。
示例:假设为内部 API 网络提供了 2 个子网:172.19.1.0/24 和 172.19.2.0/24。 我们希望所有内部 API 流量都通过控制器和远程计算节点上的内部 API VLAN。 内部 API 网络为两个节点使用不同的 VLAN,因此我们需要主机上的路由指向内部 API 网关,而不是默认网关。 这可以通过指向每个子网上的本地网关(例如,172.19.1.1 和 172.19.2.1)的 172.19.x.x 的超网路由来提供。 这可以在 os-net-config 中表示如下
- type: interface name: nic3 addresses: - ip_netmask: {get_param: InternalApiXIpSubnet} routes: - ip_netmask: {get_param: InternalApiSupernet} next_hop: {get_param: InternalApiXDefaultRoute}
其中 InternalApiIpSubnet 是本地子网上的 IP 地址,InternalApiSupernet 是“172.19.0.0/16”,而 InternalApiRouter 是 172.19.1.1 或 172.19.2.1,具体取决于主机所属的本地子网。
修改 os-net-config,以便在不使接口中断的情况下更新路由,然后在缩放发生时在所有节点上运行 os-net-config。 正在进行对此功能的审核 [3]。
不要将有关路由(或超网路由)的参数传递给 THT,而是实现 Neutron RFE [5] 和 Heat RFE [6]。 在 tripleo-heat-templates 中,我们可以使用 get_attr 来获取我们当前从用户提供的参数(例如上面的示例中的 InternalApiSupernet 和 InternalApiXDefaultRoute)读取的数据。 (我们还可以考虑用扩展
network/ports/port.j2在 tripleo-heat-templates 中来替换 [6]。)
os-net-config 配置每个接口的静态路由。 如果我们可以保持路由简单(每个功能网络一个路由),那么我们将能够像今天一样将流量隔离到功能 VLAN 上。
在部署以及更新时运行 os-net-config 将是对现有工作流程的更改,但如果这是一个非影响事件(接口不必中断),那可能没问题。 (另一种选择是在 os-net-config 中添加一个选项,该选项仅添加新路由。 类似于 os-net-config –no-activate + ifdown-routes/ifup-routes。)
稍后,应考虑使用动态路由的可能性,因为它减少了用户错误的风险,并且更适合集中管理。 超云节点可以参与内部路由协议。 SDN 解决方案是另一种提供此功能的方法,可以考虑其他方法,例如设置 OVS 隧道。
问题 #4:TripleO Heat 模板中的隔离网络需要重构
当前的隔离网络模板使用嵌套堆栈中的参数来定义每个网络的 IP 信息。 当前模式中没有空间来定义每个网络的多个子网,也没有配置每个网络的路由器的空间。 这些值由单个参数提供。
可能的解决方案、想法或方法
我们需要重构这些资源以提供每个网络的不同的路由器。
我们将扩展 TripleO 中的自定义和隔离网络,以添加对 Neutron 路由网络(段)和多个子网的支持。 每个子网将映射到不同的 L2 段。 我们应该使扩展向后兼容,并且仅在使用的模板定义网络上的多个子网时才启用 Neutron 路由网络(即,将子网与段关联)。 为了实现这一点,我们需要在 Neutron 和 Heat 中进行一些更改,这些是正在进行中的审核
提议的变更¶
以下讨论了拟议的更改。
概述¶
为了为部署提供 spine-and-leaf 网络,必须对 TripleO 进行一些更改
Neutron DHCP 服务器(正在进行中)和 Ironic DHCP 服务器中的 DHCP 中继支持(这在同一系列中的单独蓝图中解决)。
重构控制平面 IP 分配以支持路由网络(由单独的蓝图解决:tripleo-predictable-ctlplane-ips [2]。
对 TripleO Heat 模板的网络隔离进行重构,以支持每个隔离网络上的多个子网,以及每个子网和超网路由。
修改 Infra CI 以支持测试。
文档更新。
替代方案¶
此处概述的方法非常严格,即必须提前知道网络,并且 IP 地址必须从合适的池中选择。这是由于依赖于 Heat 提供的静态 IP 地址。Heat 将需要对子网进行建模,并将其与角色(节点组)关联。
一种替代方法是在所有主机的所有接口上使用 DHCP 服务器分配 IP 地址。这将简化 Heat 模板和环境文件中的配置。不幸的是,这是 TripleO 的原始方法,并且被最终用户认为不足,他们希望 IP 地址稳定,并且不想对 DHCP 有外部依赖性。
另一种方法是在网络交换机基础设施中使用 DHCP 服务器功能来 PXE 启动系统,然后在 PXE 启动完成后通过 DHCP 分配静态 IP 地址。这种方法仅解决了需求的一部分:网络启动。它没有解决在每个网络上拥有静态 IP 地址的愿望。可以通过在某种节点映射中拥有静态 IP 地址来实现。但是,这种方法不如以编程方式确定 IP 地址可扩展,因为它仅适用于固定数量的主机。我们希望保留使用 Neutron 作为 IP 地址管理 (IPAM) 后端的能力,理想情况下。
另一个考虑的方法是简单地将所有网络回传到 Undercloud,以便 dnsmasq 可以直接响应 DHCP 请求,而不是需要 DHCP 中继。不幸的是,这已被一些大型运营商确定为不可接受,他们拥有大量使用路由器进行 L2 分离的网络架构。这也不适用于地理位置 VLAN 之间的分离,例如在拆分站点部署中。
安全影响¶
脊柱-叶片网络与标准隔离网络的主要区别在于,各个子网通过路由器连接,而不是完全隔离。这意味着如果没有路由器上适当的 ACL,应该私有的网络可能会对外开放流量。
应在文档中解决此问题,并强调应实施 ACL 以防止不必要的网络流量。例如,内部 API 网络非常敏感,因为数据库和消息队列服务在该网络上运行。它应该与外部连接隔离。如果使用超网,则可以相对容易地实现这一点,这样如果所有内部 API 子网都是 172.19.0.0/16 超网的一部分,则简单的 ACL 规则将只允许内部 API IP 之间的流量(这是一个简化的示例,通常适用于所有内部 API 路由器 VLAN 接口或全局 ACL)
allow traffic from 172.19.0.0/16 to 172.19.0.0/16
deny traffic from * to 172.19.0.0/16
隔离网络设计将控制平面流量与数据平面流量分离,并将管理流量与租户流量分离。为了保持这种流量分离,我们将使用指向超网的静态路由。这确保了任何进入网络内任何子网的流量都将通过连接到该网络中本地子网的接口退出。对于最终用户来说,在路由网络中实施 ACL 以防止远程访问在共享 L2 部署中完全隔离的网络非常重要。
其他最终用户影响¶
使用 spine-and-leaf 部署将需要额外的参数来提供路由信息和所需的多个子网。这将需要记录。此外,验证脚本可能需要更新,以确保配置已验证,并且 overcloud 节点之间具有适当的连接。
性能影响¶
许多今天通过层 2 进行的流量将在此设计中跨越层 3 路由边界。这会增加一些最小的延迟和开销,尽管在实践中,差异可能并不明显。一个重要的考虑因素是,路由器在其上行链路上的提交不能过多,并且必须监视路由器以确保它们不会成为瓶颈,尤其是在使用复杂的访问控制列表时。
其他部署者影响¶
spine-and-leaf 部署比仅使用一组 VLAN 的部署更难进行故障排除。部署者可能需要更多的网络专业知识,或者在某些情况下可能需要专门的网络工程师来进行故障排除。
开发人员影响¶
脊柱-叶片网络在虚拟环境中不容易测试。这应该是可行的,但由于设置 libvirt 桥接和路由的复杂性,我们可能希望提供一个预配置的快速入门环境来进行测试。这可能涉及在 Undercloud 上构建多个 libvirt 桥接并在它们之间进行路由,或者可能涉及在 virt-host 上使用 DHCP 中继以及 virt-host 上的路由来模拟完整的路由交换机。需要制定开发和测试计划,因为不能期望每个开发人员都拥有一个路由环境来工作。开发路由虚拟环境可能需要一些时间,因此最初的工作将在裸机上完成。
一个单独的蓝图将涵盖将路由网络支持添加到 tripleo-quickstart。
实现¶
负责人¶
- 主要负责人
Dan Sneddon <dsneddon@redhat.com>
- 其他指派人
Bob Fournier <bfournie@redhat.com>
Harald Jensas <hjensas@redhat.com>
Steven Hardy <shardy@redhat.com>
Dan Prince <dprince@redhat.com>
Approver(s)¶
- 主要审批人
Alex Schultz <aschultz@redhat.com>
工作项¶
实现对路由网络上 DHCP 的支持,使用 DHCP 中继,如上述问题 #1 中所述。
向 Heat 中的隔离网络模型添加参数,以支持单个子网的超网路由,如问题 #3 中所述。
修改 Heat 中的隔离网络模型以支持多个子网,如问题 #4 中所述。
在 Controller 上实现对 iptables 的支持,以减轻 API 潜在地可以通过远程路由访问,如安全影响部分所述。或者,记录使用路由器上 ACL 的缓解程序。
记录测试程序。
修改 tripleo-docs 中的文档以涵盖脊柱-叶片案例。
修改 Ironic-Inspector 服务以记录主机到子网的映射,也许在内省期间,以解决问题 #2(长期)。
Implementation Details¶
工作流程
操作员配置 DHCP 网络和 IP 地址范围
操作员导入裸机 instackenv.json
当进行内省或部署时,DHCP 服务器通过 DHCP 中继从裸机主机接收 DHCP 请求
如果节点尚未进行内省,则使用内省池*和 inspector PXE 启动镜像回复 IP 地址
如果节点已经过内省,则服务器假定这是一个部署尝试,并回复 Neutron 端口 IP 地址和 overcloud-full 部署镜像
Heat 模板将被处理,生成 os-net-config 模板,并运行 os-net-config 以从正确的子网分配静态 IP,以及通过路由器网关地址到其他子网的路由。
在使用 spine-and-leaf 架构时,DHCP 服务器需要根据通过段路由器转发的 DHCP 中继数据包中包含的信息,在适当的子网上提供内省 IP 地址。dnsmasq 会自动将转发请求的路由器的网关地址 (GIADDR) 与接收到 DHCP 请求的子网匹配,并使用适合该子网的 IP 和网关进行回复。
上述 DHCP 服务器工作流程应允许在多个子网上配置 IP。
依赖项¶
可能存在对 Neutron 路由网络的依赖。在完全评估是否仅使用每个网络的多个子网来表示脊柱-叶片网络之前,这一点尚不清楚。
对于生产脊柱-叶片部署,将需要对执行 DHCP 中继服务的路由交换机进行依赖。
测试¶
为了正确测试此框架,我们需要建立至少一个部署脊柱-叶片的 CI 测试。如本规范中所讨论的,为了测试此功能,不必拥有完整的路由裸机环境,尽管在虚拟环境(如 OVB)中使其工作需要一些工作。
对于裸机测试,将所有 VLAN 中继回 Undercloud 就足够了,然后在 Undercloud 上运行 DHCP 代理以接收所有请求并将其转发到 br-ctlplane,dnsmasq 在其中侦听。这将提供 DHCP 中继路由器的替代方案。对于 Neutron DHCP,可能需要对 iptables 规则进行一些修改,以确保来自 overcloud 节点的 DHCP 请求都由 DHCP 代理和/或在 dhcp-agent 命名空间中运行的 Neutron dnsmasq 进程接收。
文档影响¶
需要记录设置开发环境的程序,并且有一项工作项目提到了此要求。
TripleO 文档需要更新,以包含在 spine-and-leaf 环境中部署的详细说明,包括环境设置。涵盖交换机配置的具体厂商实现超出本范围,但应包含所需配置选项的特定概述,例如启用 DHCP 中继(也称为“helper-address”)并将 Undercloud 设置为接收 DHCP 请求的服务器。
TripleO 文档的更新还必须包含关于在部署之前要做的 IP 寻址选择的详细讨论。如果使用超网进行网络隔离,则需要一个良好的 IP 寻址计划,以确保未来的可扩展性。