VPNaaS for OVN Networking

本文档规范涵盖了通过添加独立的 VPN agent 来支持 OVN 网络中的 VPNaaS。这个新的 agent 将在节点上创建一个命名空间,将其与 OVN 分布式逻辑路由器连接,并在命名空间中运行 Swan 进程。

问题描述

现有的 VPNaaS 服务插件仅支持参考 Neutron 软件路由器,例如使用 L3 agent 的 neutron L3 路由器。如果不存在 L3 agent,这种方法将不起作用。对于 OVN,需要不同的解决方案。

提议的变更

添加一个新的独立 VPN agent 来支持 OVN+VPN。添加 OVN 特定的服务和设备驱动程序,以支持这个新的 VPN agent。这将不会影响现有的 VPN 解决方案,现有的 L3 agent 及其 VPN 扩展仍然可以工作。

Neutron 服务器上的更改

VPN 服务驱动程序和 Agent 调度器

VPN 服务驱动程序针对不同的 VPNaaS 解决方案有不同的实现。现有的实现依赖于 Neutron L3 路由器调度器来决定 VPN 服务进程托管的位置,而 VPN 设备驱动程序是 L3 agent 的一部分。在 OVN 中,L3 路由器调度器和 L3 agent 已经不再使用,因此需要一个替代方案。

对于新引入的 agent 类型“VPN agent”,我们还添加了相应的 VPN agent 调度器。由于 VPN agent 调度器还应跟踪 VPN agent(s) 是否仍然存活,因此排除使用与 OVN 相关的路由器网关端口调度器。

新的 VPN agent 调度器将基于每个路由器的工作,以确保路由器上的所有 IPSec 站点连接都由同一个 agent 处理。

VPN 网关和传输网络

在 ML2/OVS 的现有实现中,VPNaaS 与路由器网关 IP 地址共享路由器 SNAT,但对于 OVN,网关公共 IP 地址 (SNAT) 不能与 VPN 共享,因为 SNAT 不在命名空间上下文中。因此,VPNaaS 命名空间需要一个新的公共 IP 地址,因此在路由器的外部网络中创建了一个 VPN 网关端口。此地址将显示为 VPN 服务的 external_v4_ip/external_v6_ip。

为了将路由器与命名空间连接,创建了一个“传输网络”(169.254.0.0/30)并将其附加到路由器。它用于在虚拟机网络和 VPN 进程命名空间之间路由流量。添加到路由器的相应路由是(每个对等 CIDR):

  • 目标 CIDR:对等 CIDR

  • 下一跳:传输网络中一个端口的 IP 地址 (169.254.0.2)

新的端口、传输网络和子网使用 Neutron 核心插件和 OVN L3 路由器服务插件的 API 进行管理,而不是“在底层”使用 OVN 函数,以避免 Neutron 数据库和 OVN 北向之间的不一致。这确保了同步 Neutron DB 和 OVN 北向(如 neutron-ovn-db-sync-util)的脚本不会删除为 VPNaaS 传输网络创建但没有相应的 Neutron DB 条目的 lswitches。

新添加的端口、传输网络和子网的 ID 存储在一个新的数据库表中“vpn_ext_gws”(用于 VPN 外部网关)。当路由器上的第一个 VPN 服务创建时,将自动创建网关端口和传输网络,并在路由器上的最后一个 VPN 服务删除后删除。

Neutron 对象的命名

  • VPN 的外部网关端口:“vpn-gw-{router_id}”(设备所有者“network:vpn_router_gateway”,设备 ID 是路由器 ID)

  • VPN 传输网络:“vpn-transit-network-{router_id}”

  • VPN 传输子网:“vpn-transit-subnet-{router_id}”

  • VPN 传输网络中的端口,由 VPN 命名空间中的 agent 插入:“vpn-ns-{router_id}”(设备所有者“network:vpn_namespace”,设备 ID 是传输子网 ID)

VPN agent 上的更改

对于 OVN,VPN 功能是在新的专用 VPN agent 中使用新的 OVN 特定设备驱动程序实现的。

配置同步

现有的 VPNaaS 实现使用 rabbitmq RPC 来同步数据库和 agent 控制的 IKE 守护程序(strongswan 等)之间的 VPN 配置。

理想情况下,用于 OVN 的 VPNaaS 解决方案应避免 rabbitmq。但目前 OVN 中不支持配置 VPN(通过北/南向数据库)。虽然可以为隧道端口配置 IPSec,但无法设置和配置到外部对等的 IPSec 站点连接。

为了仍然能够提供 VPNaaS,需要使用其他方法而不是通过 OVN 北/南向表进行配置。可能的解决方案包括:

  1. 像现有的 VPNaaS 插件一样使用 rabbitmq RPC。

  2. 代替 rabbitmq,在两端(Neutron 服务器和 VPN agent)实现 REST API。这包括允许 agent 了解配置更改(服务器 -> agent)的 API 端点,允许 agent 获取当前配置(agent -> 服务器),以及允许 agent 报告状态更改(agent -> 服务器)的 API 端点

最简单的实现方法是(1)依赖于现有的代码,即使它仍然在使用 rabbitmq,而不是使用新的 REST API 重写服务器/agent 通信。

VPN 命名空间管理

agent 创建一个 VPN 命名空间并插入两个端口

  • 外部网关端口

  • 绑定到 169.254.0.2 的传输网络中的一个端口

将每个路由器有一个 VPN 命名空间,并且它被安排在恰好一个 VPN agent 上。VPN agent 应该确保只有那些调度到那里的 VPN 命名空间才存在。例如,当 agent 启动时,它将与控制器同步并可能删除多余的 VPN 命名空间和/或创建缺少的命名空间。

VPN 命名空间由 VPN agent / 设备驱动程序在创建路由器上的第一个 IPSec 站点连接时创建,并在删除路由器上的所有 IPSec 站点连接时删除。

命名空间中配置路由以将传入流量路由到本地子网(目标:本地 CIDR,下一跳:传输网络的路由器端口,即 169.254.0.1)。每当 IPSec 站点连接配置发生更改时,这些路由都会更新。

agent 将

  1. 创建一个名为“qvpn-{router_id}”的命名空间

  2. 在命名空间中创建两个接口

    • vgxxxxxxxx-xxx,其中 xxxxxxxx-xxx 是 VPN 外部网关端口的端口 UUID 的前缀(外部网络中的 IP 地址)

    • vrxxxxxxxx-xxx,其中 xxxxxxxx-xxx 是 VPN 传输网络端口的端口 UUID 的前缀(169.254.0.2)

  3. 插入这两个接口

  4. 添加路由

VPN agent 的存活状态

有两种方法可以实现存活状态检查

  1. 传统方法使用 rabbitmq。VPN agent 定期报告其状态(“report_state” RPC)。服务器端插件利用 AgentSchedulerDbMixin 功能来跟踪存活的 agent,并可能在 agent 宕机时重新调度 VPN 服务。

  2. 使用 OVN 进行存活状态检查,类似于 OVN Metadata agent。服务器在 NB_Global 中设置“neutron:liveness_check_at”外部 ID 的新值,agent 监视 SB_Global 并在其 chassis 行中设置外部 ID(外部 ID “neutron:ovn-vpnagent-sb-cfg”)

第二种方法更符合 Neutron OVN 机制驱动程序中 agent 的管理方式。

OVN 的 VPN 插件配置

OVN VPN 插件是现有插件的扩展,以便添加 VPN agent 调度器和状态检查。

要添加到 neutron.conf 的服务插件是 neutron_vpnaas.services.vpn.ovn_plugin.VPNOVNDriverPlugin

对于 OVN,有一个新的专用服务驱动程序,因此 neutron_vpnaas.conf 中的 service_provider 设置将是:VPN:openswan:neutron_vpnaas.services.vpn.service_drivers.ovn_ipsec.IPsecOvnVPNDriver:default

有一个新的 agent 类型“VPN agent”

  • agent 二进制文件是 neutron-vpn-agent

  • agent 配置文件是 /etc/neutron/vpn_agent.ini

  • agent 使用在 vpnagent/vpn_device_driver 中配置的 VPN 设备驱动程序。一个示例设备驱动程序条目是 vpn_device_driver = neutron_vpnaas.services.vpn.device_drivers.ovn_ipsec.OvnStrongSwanDriver

数据库影响

向 neutron 数据库添加两个新表

  • vpn_ext_gws:保存路由器 VPN 服务所需的附加网络项目的 ID(网关端口、传输网络、子网、端口)

  • routervpnagentbindings:保存每个路由器的 VPN agent ID

REST API 和 CLI 影响

VPNaaS 或 Neutron 的 REST API 或 CLI 没有更改。

VPN 服务的外部 IP 地址在其 external_v4_ip/external_v6_ip 中可见,并且将与路由器的 IP 地址不同。

参考资料