Open vSwitch 硬件卸载¶
本页的目的是描述如何在 OpenStack (使用 OpenStack Networking) 中启用 Open vSwitch 硬件卸载功能。此功能最早在 OpenStack Pike 版本中引入。本页旨在作为配置 OpenStack Networking 和 OpenStack Compute 以启用 Open vSwitch 硬件卸载的指南。
基础知识¶
Open vSwitch 是一个生产质量的多层虚拟交换机,采用开源 Apache 2.0 许可。它旨在通过程序化扩展实现大规模网络自动化,同时仍然支持标准的管理接口和协议。Open vSwitch (OVS) 允许虚拟机 (VM) 相互通信以及与外部世界通信。基于软件的 OVS 解决方案 CPU 密集型,会影响系统性能并阻止充分利用可用带宽。
术语 |
定义 |
|---|---|
PF |
物理功能。支持 SR-IOV 的物理以太网控制器。 |
VF |
虚拟功能。从物理以太网控制器创建的虚拟 PCIe 设备。 |
Representor Port |
类似于 SR-IOV 端口的虚拟网络接口,代表 Nova 实例。 |
第一个计算节点 |
可以托管计算实例 (虚拟机) 的 OpenStack 计算节点。 |
第二个计算节点 |
可以托管计算实例 (虚拟机) 的 OpenStack 计算节点。 |
支持的以太网控制器¶
已知以下制造商有效
Mellanox ConnectX-4 网卡 (VLAN 卸载)
Mellanox ConnectX-4 Lx/ConnectX-5 网卡 (VLAN/VXLAN 卸载)
Broadcom NetXtreme-S 系列网卡
Broadcom NetXtreme-E 系列网卡
有关 Mellanox 以太网卡的信息,请参阅 Mellanox: 以太网卡 - 概述。
先决条件¶
Linux Kernel >= 4.13
Open vSwitch >= 2.8
iproute >= 4.12
Mellanox 或 Broadcom 网卡
注意
支持 Open vSwitch 硬件卸载的 Mellanox 网卡固件
ConnectX-5 >= 16.21.0338
ConnectX-4 >= 12.18.2000
ConnectX-4 Lx >= 14.21.0338
使用 Open vSwitch 硬件卸载¶
为了启用 Open vSwitch 硬件卸载,需要执行以下步骤
启用 SR-IOV
将网卡配置为 switchdev 模式 (相关节点)
启用 Open vSwitch 硬件卸载
注意
在本指南中,enp3s0f0 用作 PF,eth3 用作 representor 端口。这些端口在不同的环境中可能会有所不同。
注意
在本指南中,我们使用 systemctl 重启 OpenStack 服务。这对于 systemd OS 是正确的。在其他环境中应使用其他方法来重启服务。
创建计算虚拟功能¶
为将用于 SR-IOV 的网络接口创建 VF。我们使用 enp3s0f0 作为 PF,它也用作 VLAN 提供商网络的接口,并且可以访问所有节点的私有网络。
注意
以下步骤详细介绍了如何使用 Mellanox ConnectX-4 和 SR-IOV 以太网卡在 Intel 系统上创建 VF。对于您选择的硬件,步骤可能会有所不同。
确保系统上已启用 SR-IOV 和 VT-d。通过将
intel_iommu=on添加到内核参数来启用 IOMMU,例如使用 GRUB。在每个计算节点上,创建 VF
# echo '4' > /sys/class/net/enp3s0f0/device/sriov_numvfs注意
网络接口可以同时用于 PCI 直通 (使用 PF) 和 SR-IOV (使用 VF)。如果使用 PF,则存储在
sriov_numvfs文件中的 VF 数量将丢失。如果 PF 再次附加到操作系统,分配给此接口的 VF 数量将为零。为了始终将 VF 数量分配给此接口,请根据您的操作系统更新相关文件。以下是一些示例在 Ubuntu 中,修改
/etc/network/interfaces文件auto enp3s0f0 iface enp3s0f0 inet dhcp pre-up echo '4' > /sys/class/net/enp3s0f0/device/sriov_numvfs
在 Red Hat 中,修改
/sbin/ifup-local文件#!/bin/sh if [[ "$1" == "enp3s0f0" ]] then echo '4' > /sys/class/net/enp3s0f0/device/sriov_numvfs fi
警告
或者,您可以将
max_vfs传递给网络接口的内核模块来创建 VF。但是,max_vfs参数已被弃用,因此 PCI /sys 接口是首选方法。您可以确定 PF 可以支持的最大 VF 数量
# cat /sys/class/net/enp3s0f0/device/sriov_totalvfs 8
验证是否已创建 VF 并且处于
up状态注意
PF 的 PCI 总线编号 (03:00.0) 和 VF (03:00.2 .. 03:00.5) 稍后将使用。
# lspci | grep Ethernet 03:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5] 03:00.1 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5] 03:00.2 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function] 03:00.3 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function] 03:00.4 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function] 03:00.5 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]
# ip link show enp3s0f0 8: enp3s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT qlen 1000 link/ether a0:36:9f:8f:3f:b8 brd ff:ff:ff:ff:ff:ff vf 0 MAC 00:00:00:00:00:00, spoof checking on, link-state auto vf 1 MAC 00:00:00:00:00:00, spoof checking on, link-state auto vf 2 MAC 00:00:00:00:00:00, spoof checking on, link-state auto vf 3 MAC 00:00:00:00:00:00, spoof checking on, link-state auto
如果接口处于关闭状态,请在启动来宾之前将其设置为
up,否则实例将无法启动# ip link set enp3s0f0 up
配置 Open vSwitch 硬件卸载¶
将 e-switch 模式从 legacy 更改为 switchdev,在 PF 设备上。这将还在主机 OS 中创建 VF representor 网络设备。
# echo 0000:03:00.2 > /sys/bus/pci/drivers/mlx5_core/unbind这会告诉驱动程序取消绑定 VF 03:00.2
注意
应为所有相关 VF (在本例中为 0000:03:00.2 .. 0000:03:00.5) 执行此操作
启用 Open vSwitch 硬件卸载,将 PF 设置为 switchdev 模式并重新绑定 VF。
# sudo devlink dev eswitch set pci/0000:03:00.0 mode switchdev # sudo ethtool -K enp3s0f0 hw-tc-offload on # echo 0000:03:00.2 > /sys/bus/pci/drivers/mlx5_core/bind
注意
应为所有相关 VF (在本例中为 0000:03:00.2 .. 0000:03:00.5) 执行此操作
重启 Open vSwitch
# sudo systemctl enable openvswitch.service # sudo ovs-vsctl set Open_vSwitch . other_config:hw-offload=true # sudo systemctl restart openvswitch.service
注意
给定的 OVS aging 以毫秒为单位给出,可以使用以下方式控制
# ovs-vsctl set Open_vSwitch . other_config:max-idle=30000
配置节点 (VLAN 配置)¶
更新 Controller 节点上的
/etc/neutron/plugins/ml2/ml2_conf.ini[ml2] tenant_network_types = vlan type_drivers = vlan mechanism_drivers = openvswitch
更新 Controller 节点上的
/etc/neutron/neutron.conf[DEFAULT] core_plugin = ml2
更新 Controller 节点上的
/etc/nova/nova.conf[filter_scheduler] enabled_filters = PciPassthroughFilter
更新 Compute 节点上的
/etc/nova/nova.conf[pci] #VLAN Configuration passthrough_whitelist example passthrough_whitelist ={"'"address"'":"'"*:'"03:00"'.*"'","'"physical_network"'":"'"physnet2"'"}
配置节点 (VXLAN 配置)¶
更新 Controller 节点上的
/etc/neutron/plugins/ml2/ml2_conf.ini[ml2] tenant_network_types = vxlan type_drivers = vxlan mechanism_drivers = openvswitch
更新 Controller 节点上的
/etc/neutron/neutron.conf[DEFAULT] core_plugin = ml2
更新 Controller 节点上的
/etc/nova/nova.conf[filter_scheduler] enabled_filters = PciPassthroughFilter
更新 Compute 节点上的
/etc/nova/nova.conf注意
VXLAN 配置需要 physical_network 为 null。
[pci] #VLAN Configuration passthrough_whitelist example passthrough_whitelist ={"'"address"'":"'"*:'"03:00"'.*"'","'"physical_network"'":null}
重启 nova 和 neutron 服务
# sudo systemctl restart openstack-nova-compute.service # sudo systemctl restart openstack-nova-scheduler.service # sudo systemctl restart neutron-server.service
验证 Open vSwitch 硬件卸载¶
注意
在本例中,我们将在不同的计算节点上启动两个实例,并在它们之间发送 ICMP Echo Request 数据包。然后,我们将检查 representor 端口上的 TCP 数据包,并看到只有第一个数据包会显示在那里。其余的都将被卸载。
在
private网络上创建一个direct端口# openstack port create --network private --vnic-type=direct direct_port1使用 direct 端口在“第一个计算节点”上创建一个实例
# openstack server create --flavor m1.small --image cloud_image --nic port-id=direct_port1 vm1重复上述步骤并在“第二个计算节点”上创建第二个实例
# openstack port create --network private --vnic-type=direct direct_port2 # openstack server create --flavor m1.small --image mellanox_fedora --nic port-id=direct_port2 vm2
注意
您可以使用 –availability-zone nova:compute_node_1 选项来设置所需的计算节点
连接到 instance1 并向 instance2 发送 ICMP Echo Request 数据包
# vncviewer localhost:5900 vm_1# ping vm2
连接到“第二个计算节点”并找到实例的 representor 端口
注意
首先找到 representor 端口,在本例中为 eth3
compute_node2# ip link show enp3s0f0 6: enp3s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master ovs-system state UP mode DEFAULT group default qlen 1000 link/ether ec:0d:9a:46:9e:84 brd ff:ff:ff:ff:ff:ff vf 0 MAC 00:00:00:00:00:00, spoof checking off, link-state enable, trust off, query_rss off vf 1 MAC 00:00:00:00:00:00, spoof checking off, link-state enable, trust off, query_rss off vf 2 MAC 00:00:00:00:00:00, spoof checking off, link-state enable, trust off, query_rss off vf 3 MAC fa:16:3e:b9:b8:ce, vlan 57, spoof checking on, link-state enable, trust off, query_rss off compute_node2# ls -l /sys/class/net/ lrwxrwxrwx 1 root root 0 Sep 11 10:54 eth0 -> ../../devices/virtual/net/eth0 lrwxrwxrwx 1 root root 0 Sep 11 10:54 eth1 -> ../../devices/virtual/net/eth1 lrwxrwxrwx 1 root root 0 Sep 11 10:54 eth2 -> ../../devices/virtual/net/eth2 lrwxrwxrwx 1 root root 0 Sep 11 10:54 eth3 -> ../../devices/virtual/net/eth3 compute_node2# sudo ovs-dpctl show system@ovs-system: lookups: hit:1684 missed:1465 lost:0 flows: 0 masks: hit:8420 total:1 hit/pkt:2.67 port 0: ovs-system (internal) port 1: br-enp3s0f0 (internal) port 2: br-int (internal) port 3: br-ex (internal) port 4: enp3s0f0 port 5: tapfdc744bb-61 (internal) port 6: qr-a7b1e843-4f (internal) port 7: qg-79a77e6d-8f (internal) port 8: qr-f55e4c5f-f3 (internal) port 9: eth3
检查 representor 端口上的流量。验证只有第一个 ICMP 数据包出现。
compute_node2# tcpdump -nnn -i eth3 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth3, link-type EN10MB (Ethernet), capture size 262144 bytes 17:12:41.220447 ARP, Request who-has 172.0.0.10 tell 172.0.0.13, length 46 17:12:41.220684 ARP, Reply 172.0.0.10 is-at fa:16:3e:f2:8b:23, length 42 17:12:41.260487 IP 172.0.0.13 > 172.0.0.10: ICMP echo request, id 1263, seq 1, length 64 17:12:41.260778 IP 172.0.0.10 > 172.0.0.13: ICMP echo reply, id 1263, seq 1, length 64 17:12:46.268951 ARP, Request who-has 172.0.0.13 tell 172.0.0.10, length 42 17:12:46.271771 ARP, Reply 172.0.0.13 is-at fa:16:3e:1a:10:05, length 46 17:12:55.354737 IP6 fe80::f816:3eff:fe29:8118 > ff02::1: ICMP6, router advertisement, length 64 17:12:56.106705 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 62:21:f0:89:40:73, length 300