使用 neutron 进行网络¶
虽然 nova 使用 OpenStack Networking 服务 (neutron) 为实例提供网络连接,但 nova 本身提供了一些 neutron 单独无法实现的其他功能。这些功能如下所述。
SR-IOV¶
版本 2014.2 中更改:以下描述的功能首次出现在 Juno 版本中。
SR-IOV 规范定义了一种标准化机制来虚拟化 PCIe 设备。该机制可以将单个 PCIe 以太网控制器虚拟化为多个 PCIe 设备。每个设备都可以直接分配给一个实例,绕过 hypervisor 和虚拟交换机层。因此,用户可以实现低延迟和接近线路速率的性能。
有关配置和使用 SR-IOV 的完整指南,请参阅 OpenStack Networking 服务文档
注意
nova 只支持字段限制在以下最大值内的 PCI 地址
域 - 0xFFFF
总线 - 0xFF
插槽 - 0x1F
功能 - 0x7
如果地址超出这些范围,nova 将忽略 hypervisor 报告的 PCI 设备。
版本 25.0.0 中添加:有关创建具有远程管理 SR-IOV 网络接口的 SmartNIC DPUs 服务器的信息,请参阅 Networking Guide 中的相关部分。
Limitations
仅支持 VF,并且必须在 Nova Compute 配置中的
pci.device_spec选项中标记为remote_managed: "true"。不会基于供应商和产品 ID 进行自动发现;VF 或其各自的 PF 必须暴露一个符合 PCI/PCIe 规范的 PCI VPD 功能,其中包含唯一的卡序列号(请参阅 Libvirt 文档,了解 VPD 数据如何表示以及预期内容)。如果不是这种情况,这些设备将不会出现在分配池中;
目前,只有 Libvirt 驱动程序能够支持此功能;
Libvirt 中 VPD 功能处理的支持是在 7.9.0 版本中添加的 - 旧版本不支持此功能;
为了成功调度具有
VNIC_TYPE_REMOTE_MANAGED端口的节点,所有计算节点必须升级到 Yoga 版本;与 传统 SR-IOV 端口一样,对实时迁移等操作也适用相同的限制;
通过编程 VLAN 0 清除 VLAN 不应导致计算主机上 VF 内核驱动程序中的错误。在 v8.1.0 之前,Libvirt 会在将 VF 传递给客户机之前通过编程 VLAN 0 清除 VLAN,这取决于您的驱动程序和内核版本,可能会导致错误(例如,请参阅 此错误,其中讨论了一个与一个驱动程序相关的情况)。从 Libvirt v8.1.0 开始,如果在设备 XML 中未显式请求 VLAN 清除(即未显式指定 VLAN 0),则会忽略在编程 VLAN 0 时遇到的 EPERM 错误。
NUMA 亲和性¶
版本 18.0.0 中添加:以下描述的功能首次出现在 Rocky 版本中。
重要提示
以下描述的功能当前仅受 libvirt/KVM 驱动程序支持。
如 CPU 拓扑 中所述,NUMA 是一种计算机架构,其中访问系统内存的某些区域可能比其他区域具有更高的延迟,具体取决于您的进程正在运行的 CPU。这种效应扩展到连接到 PCIe 总线的设备,这被称为 NUMA I/O。许多网络接口卡 (NIC) 使用 PCIe 接口连接,这意味着它们容易受到不良 NUMA 亲和性的不利影响。因此,在创建需要高性能数据平面性能的实例时,必须考虑 NUMA 定位。
幸运的是,nova 提供了确保使用 neutron 的实例具有 NUMA 亲和性的功能。这取决于您尝试使用的端口类型。
对于 SR-IOV 端口,虚拟函数(PCI 设备)将附加到实例。这意味着实例可以受益于 PCI 设备提供的 NUMA 亲和性保证。这是自动完成的,并在 PCI-NUMA 亲和性策略 中详细描述。
对于所有其他类型的端口,需要进行一些手动配置。
确定要为其提供 NUMA 亲和性的网络类型。
如果网络是 L2 类型网络(
provider:network_type为flat或vlan),则网络与给定 NUMA 节点(s) 的亲和性取决于网络的provider:physical_network属性的值,通常称为网络的 *physnet*。这是因为大多数 neutron 驱动程序将每个 *physnet* 映射到不同的桥接器,多个 NIC 附加到该桥接器,或不同的(逻辑)NIC。如果网络是 L3 类型网络(
provider:network_type为vxlan、gre或geneve),所有流量将使用分配给 *endpoint IP* 的设备。这意味着给定主机上的所有 L3 网络都将具有与相同的 NUMA 节点(s) 的亲和性。有关更多信息,请参阅 neutron 文档。
确定与给定网络(s) 关联的 NIC 的 NUMA 亲和性。
如何实现这一点取决于所使用的交换解决方案以及网络是 L2 类型网络还是 L3 类型网络。
考虑使用 Linux Bridge 机制驱动程序的 L2 类型网络。如 neutron 文档 中所述,*physnets* 使用
[linux_bridge] physical_interface_mappings配置选项映射到接口。例如[linux_bridge] physical_interface_mappings = provider:PROVIDER_INTERFACE
获得设备名称后,您可以查询 *sysfs* 以检索此设备的 NUMA 亲和性。例如
$ cat /sys/class/net/PROVIDER_INTERFACE/device/numa_node
对于使用 Linux Bridge 机制驱动程序的 L3 类型网络,将使用协议特定的 endpoint IP 配置选项配置设备。对于 VXLAN,这是
[vxlan] local_ip选项。例如[vxlan] local_ip = OVERLAY_INTERFACE_IP_ADDRESS
获得相关 IP 地址后,您可以使用 ip 识别分配此 IP 地址的设备,然后可以使用上述 *sysfs* 查询 NUMA 亲和性。
注意
以上示例仅仅是一个示例。如何识别此信息可能会因所使用的驱动程序、是否使用绑定、所使用的网络类型等而有很大差异。
在
nova.conf中配置 NUMA 亲和性。确定用于网络的设备的 NUMA 亲和性后,需要在
nova.conf中配置此信息。与网络类型一样,实现方式也各不相同。对于 L2 类型网络,NUMA 亲和性基于网络的
provider:physical_network属性定义。必须设置两个配置选项[neutron] physnets应将其设置为您希望提供 NUMA 亲和性的 physnet 列表。有关更多信息,请参阅
文档。[neutron_physnet_{physnet}] numa_nodes应将其设置为应将具有给定
{physnet}的网络亲和化的 NUMA 节点列表。
对于 L3 类型网络,NUMA 亲和性是全局定义的,适用于给定主机上的所有隧道网络。只有一个配置选项需要设置
[neutron_tunnel] numa_nodes应将其设置为实例使用隧道网络将要亲和化的一个或多个 NUMA 节点列表。
配置实例 flavor(s) 的 NUMA 拓扑
为了使网络 NUMA 亲和性产生任何影响,实例本身必须具有 NUMA 拓扑。这可以通过使用
hw:numa_nodes附加规格显式配置,或通过使用 CPU pinning (hw:cpu_policy=dedicated) 或 PCI 设备隐式配置。有关更多信息,请参阅 CPU 拓扑。
示例¶
首先以使用 L2 类型网络的部署为例。
[neutron]
physnets = foo,bar
[neutron_physnet_foo]
numa_nodes = 0
[neutron_physnet_bar]
numa_nodes = 2, 3
此配置将确保使用一个或多个具有 provider:physical_network=foo 的 L2 类型网络的实例必须在 NUMA 节点 0 的主机核心上调度,而使用一个或多个具有 provider:physical_network=bar 的网络的实例必须在 NUMA 节点 2 和 3 的主机核心上调度。对于后一种情况,将需要使用 hw:numa_nodes 附加规格(如 此处 所述)将客户机拆分到两个或多个主机 NUMA 节点上。
现在,以使用 L3 网络部署的示例。
[neutron_tunnel]
numa_nodes = 0
这要简单得多,因为所有隧道流量都使用相同的逻辑接口。与 L2 类型网络一样,此配置将确保使用一个或多个 L3 类型网络的实例必须在 NUMA 节点 0 的主机核心上调度。也可以定义多个 NUMA 节点,在这种情况下,实例必须拆分到这些节点上。
virtio-net 多队列¶
版本 12.0.0 中添加: (Liberty)
版本 25.0.0 中更改: (Yoga)
从 Yoga (25.0.0) 版本开始,通过 hw:vif_multiqueue_enabled flavor 附加规格配置多队列的支持。
重要提示
以下描述的功能当前仅受 libvirt/KVM 驱动程序支持。
使用 virtio-net 驱动程序的虚拟 NIC 支持多队列功能。默认情况下,这些 vNIC 将仅使用单个 virtio-net TX/RX 队列对,这意味着客户机将不会并行传输或接收数据包。因此,客户机中的协议堆栈的规模可能会受到限制,因为网络性能不会随着 vCPU 数量的增加而扩展,并且会遇到底层 vSwitch 中的每队列数据处理限制。解决此问题的方法是启用 virtio-net 多队列,这允许客户机实例通过根据 CPU 数量扩展接收和传输队列对的数量来提高总网络吞吐量。
virtio-net 多队列并非总是必需的,但当
流量数据包相对较大时。
客户机在许多连接上处于活动状态,流量在客户机之间、客户机与主机之间或客户机与外部系统之间运行时。
队列数等于 vCPU 的数量。这是因为多队列支持优化了 RX 中断亲和性和 TX 队列选择,以便使特定队列私有于特定的 vCPU。
但是,虽然 virtio-net 多队列功能通常会提供可喜的性能提升,但它有一些限制,因此不应无条件启用
启用 virtio-net 多队列会提高总网络吞吐量,但同时也会增加 CPU 消耗。
在主机 QEMU 配置中启用 virtio-net 多队列不会在客户机操作系统中启用该功能。客户机操作系统管理员需要手动为每个需要此功能的客户机 NIC 启用它,使用 ethtool。
如果客户机实例中的 vNIC 数量与 vCPU 数量成比例,则启用多队列功能不太重要。
考虑到这些点,可以使用 hw:vif_multiqueue_enabled flavor 附加规格或等效的 hw_vif_multiqueue_enabled 镜像元数据属性来启用或显式禁用多队列。例如,要为选定的 flavor 启用 virtio-net 多队列
$ openstack flavor set --property hw:vif_multiqueue_enabled=true $FLAVOR
或者,要显式禁用选定镜像的多队列
$ openstack image set --property hw_vif_multiqueue_enabled=false $IMAGE
注意
如果同时提供了 flavor 附加规格和镜像元数据属性,则它们的值必须匹配,否则将引发错误。
一旦客户机启动,您必须使用 ethtool 启用多队列。例如
$ ethtool -L $devname combined $N
其中 $devname 是网络设备的名称,$N 是要配置的 TX/RX 队列对的数量,对应于实例 vCPU 的数量。或者,您可以使用 udev 以持久的方式配置此设置。例如,要为网络设备 eth0 配置四个 TX/RX 队列对
# cat /etc/udev/rules.d/50-ethtool.rules
ACTION=="add", SUBSYSTEM=="net", NAME=="eth0", RUN+="/sbin/ethtool -L eth0 combined 4"
有关此功能的更多信息,请参阅 原始规范。