第 20 章 SR-IOV 对虚拟网络的支持
从 RHEL OpenStack Platform 6 开始,扩展了SR-IOV(single root I/O virtualization - 单引导 I/O 虚拟化)对虚拟机网络的支持。这意味着,OpenStack 可以不再需要虚拟网桥,而是把物理 NIC 的功能直接扩展到实例中。另外,通过对 IEEE 802.1br 的支持,虚拟 NIC 可以与物理交换机进行集成,并由它进行管理。
20.1. 在 RHEL OpenStack Platform 中配置 SR-IOV
本章包含配置 SR-IOV 以将物理 NIC 传递到虚拟实例的过程。这些步骤假设系统包括了一个 Controller 节点、一个 OpenStack Networking(neutron) 节点和多个 Compute(nova)节点。
请注意:当已存在了适当的 L2 配置(例如,flat 或 VLAN),使用 SR-IOV 端口的实例与使用普通端口(如连接到 Open vSwitch 网桥)的实例间就可以彼此进行通讯。当前,在相同 Compute 节点上的使用 SR-IOV 端口的实例与使用普通 vSwitch 端口的实例间的通讯有一个限制:如果它们在网卡上共享相同的 PF(Physical Function),则无法进行通讯。
20.2. 在 Compute 节点上创建虚拟功能
在带有支持硬件的所有 Compute 节点上执行这些步骤。
注意: 如需了解更多所支持硬件的信息,请参阅相关文档。
这个步骤会配置一个系统来传递一个 Intel 82576 网络设备。同时,虚拟功能(Virtual Functions)也会被创建,实例可以使用它们来进行 SR-IOV 到设备的访问。
1. 确认 Intel VT-d 或 AMD IOMMU 已在系统的 BIOS 中启用。请参阅机器的 BIOS 配置菜单,或其它相关信息。
2. 确保在操作系统中启用 Intel VT-d 或 AMD IOMMU:
3. 运行 lspci 命令确保网络设备可以被系统识别:
[root@compute ~]# lspci | grep 82576
网络设备包括在结果中:
03:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 03:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
4. 执行以下步骤来在 Compute 节点上激活 Virtual Functions:
4a.删除内核模块。在下一步中会对模块进行重新配置:
[root@compute ~]# modprobe -r igb
请注意:在第 4 步中,需要使用支持 SRIOV 的 NIC 所使用的模块,而不是使用其它 NIC 的 igb(如 ixgbe 或 mlx4_core)。运行 ethtool 命令来确认驱动。在这个例子中,em1 是我们需要使用的 PF(Physical Function):
[root@compute ~]# ethtool -i em1 | grep ^driver
4b. 启动模块时 max_vfs 的值为 7(或不多于被支持的最多数量)。
[root@compute ~]# modprobe igb max_vfs=7
4c. 使 Virtual Functions 有持久性:
[root@compute ~]# echo "options igb max_vfs=7" >>/etc/modprobe.d/igb.conf
请注意: 对于 Red Hat Enterprise Linux 7,为了使配置具有持久性,在进行完第 4 步后根据 rebuild the initial ramdisk image 中介绍的内容进行相关操作。
请注意:在 4c. 和 4d. 中进行的设置持久性如下:modprobe 命令在使用相同内核模块的所有 NIC 上启用 Virtual Function,并在系统重新引导后仍然可以保持这个设置。虽然可以只在特定 NIC 上启用 VF,但这可能会造成一些问题。例如,使用以下命令来在 enp4s0f1 接口上启用 VF:
# echo 7 > /sys/class/net/enp4s0f1/device/sriov_numvfs
当系统重启后,这个设备将不会被保留。解决这个问题的一个方法是,把这个设置添加到 rc.local 中,但这个方法仍然有以下限制:
# chmod +x /etc/rc.d/rc.local # echo "echo 7 > /sys/class/net/enp4s0f1/device/sriov_numvfs" >> /etc/rc.local
请注意:因为额外的 systemd,Red Hat Enterprise Linux 将会并行启动服务,而不是依次启动它们。这意味着,rc.local 在引导过程中被执行的位置是不固定的。因此,一些不可预见的情况可能会出现,我们不推荐使用这个方法。
4d. 把 intel_iommu=pt 和 igb.max_vfs=7 参数添加到内核命令行来在内核中激活 Intel VT-d。如果您希望一直使用这个方式引导内核,可以修改当前的设置;或者,您可以创建一个带有这些参数的自定义菜单,这样,您的系统就可以在默认情况下以这种方式启动,并且可以在需要时,不使用这些参数启动内核。
• 要修改当前内核命令行参数,运行以下命令:
[root@compute ~]# grubby --update-kernel=ALL --args="intel_iommu=pt igb.max_vfs=7"
如需了解更多使用 grubby 的信息,请参阅系统管理指南中的 Configuring GRUB 2 Using the grubby Tool。
请注意:如果使用 Dell Power Edge R630 节点,则需要使用 intel_iommu=on 而不是 intel_iommu=pt。您可以通过 grubby 启用它:
# grubby --update-kernel=ALL --args="intel_iommu=on"
• 创建一个自定义菜单项:
i. 在 grub 中找到默认的项:
[root@compute ~]# grub2-editenv list saved_entry=Red Hat Enterprise Linux Server (3.10.0-123.9.2.el7.x86_64) 7.0 (Maipo)
ii. a. 把所需的 menuentry 项的内容(以 "menuentry" 开始,以 "}" 结束。它在开始部分包括了前一步命令显示的 saved_entry 的值)从 /boot/grub2/grub.cfg 复制到 /etc/grub.d/40_custom。b. 在 menuentry 后修改标题 c. 在以 linux16 开始的行的最后添加 intel_iommu=on。
例如:
menuentry 'Red Hat Enterprise Linux Server, with Linux 3.10.0-123.el7.x86_64 - SRIOV' --class red --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-123.el7.x86_64-advanced-4718717c-73ad-4f5f-800f-f415adfccd01' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod ext2
set root='hd0,msdos2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos2 --hint-efi=hd0,msdos2 --hint-baremetal=ahci0,msdos2 --hint='hd0,msdos2' 5edd1db4-1ebc-465c-8212-552a9c97456e
else
search --no-floppy --fs-uuid --set=root 5edd1db4-1ebc-465c-8212-552a9c97456e
fi
linux16 /vmlinuz-3.10.0-123.el7.x86_64 root=UUID=4718717c-73ad-4f5f-800f-f415adfccd01 ro vconsole.font=latarcyrheb-sun16 biosdevname=0 crashkernel=auto vconsole.keymap=us nofb console=ttyS0,115200 LANG=en_US.UTF-8 intel_iommu=pt igb.max_vfs=7
initrd16 /initramfs-3.10.0-123.el7.x86_64.img
}iii. 更新 grub.cfg 以使配置文件中的修改生效:
[root@compute ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
iv. 修改默认的项:
[root@compute ~]# grub2-set-default 'Red Hat Enterprise Linux Server, with Linux 3.10.0-123.el7.x86_64 - SRIOV'
v. 创建 dist.conf 配置文件。
请注意:在执行这个步骤前,请重新查看描述 allow_unsafe_interrupts 的段落:检查 allow_unsafe_interrupts 的设置。
[root@compute ~]# echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/dist.conf
5. 重启服务器以使新内核参数生效:
[root@compute ~]# systemctl reboot
6. 查看 Compute 节点上的 SR-IOV 内核模块。运行 lsmod 以确认模块已被加载:
[root@compute ~]# lsmod |grep igb
这个经过过滤的结果应该包括所需的模块:
igb 87592 0 dca 6708 1 igb
7. 记录下您的网卡的 PCI 厂商 ID(格式是 vendor_id:product_id)。运行带有 -nn 选项的 lspci 命令可以得到这个值。例如:
[root@compute ~]# lspci -nn | grep -i 82576 05:00.0 Ethernet controller [0200]: Intel Corporation 82576 Gigabit Network Connection [8086:10c9] (rev 01) 05:00.1 Ethernet controller [0200]: Intel Corporation 82576 Gigabit Network Connection [8086:10c9] (rev 01) 05:10.0 Ethernet controller [0200]: Intel Corporation 82576 Virtual Function [8086:10ca] (rev 01)
请注意:根据您的网卡硬件的具体情况,这个参数可能会不同。
8. 使用 lspci 命令查看新创建的 VF:
[root@compute ~]# lspci | grep 82576
这个结果会包括设备和 Virtual Function:
0b:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 0b:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection(rev 01) 0b:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.3 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.4 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.5 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.6 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:10.7 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:11.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:11.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:11.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:11.3 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:11.4 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 0b:11.5 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
20.3. 在 Network 节点上配置 SR-IOV
OpenStack Networking(neutron)使用 ML2 机制驱动来支持 SR-IOV。在 Network 网络上执行这些步骤来配置 SR-IOV 驱动。
1. 在 /etc/neutron/plugins/ml2/openvswitch_agent.ini 文件中启用 sriovnicswitch。例如,这个配置启用了 SR-IOV 机制驱动和 Open vSwitch。
请注意:sriovnicswitch 不支持 DHCP Agent 的当前接口驱动,因此在使用 sriovnicswitch 时需要 openvswitch(或其它支持 VLAN 的机制驱动)。
[ml2] tenant_network_types = vlan type_drivers = vlan mechanism_drivers = openvswitch, sriovnicswitch [ml2_type_vlan] network_vlan_ranges = physnet1:15:20
- network_vlan_ranges - 在这个例子中,physnet1 被作为网络标签使用,VLAN 的范围是 15-20。
请注意:sriovnicswitch 当前只支持 flat 和 vlan 驱动。
2. 可选 - 如果您需要 VF 连接状态和 admin 状态管理,而且您的厂商支持这些功能,请在 /etc/neutron/plugins/ml2/sriov_agent.ini 文件中启用这个选项:
[root@network ~]# openstack-config --set /etc/neutron/plugins/ml2/sriov_agent.ini ml2_sriov agent_required True
3. 可选 - 支持的 vendor_id/product_id 组合是 15b3:1004, 8086:10ca。如果网卡厂商的产品 ID 和这个不同,则需要指定它们。例如:
[ml2_sriov] supported_pci_vendor_devs = 15b3:1004,8086:10ca
4. 配置 neutron-server.service 来使用 ml2_conf_sriov.ini 文件。例如:
[root@network ~]# vi /usr/lib/systemd/system/neutron-server.service [Service] Type=notify User=neutron ExecStart=/usr/bin/neutron-server --config-file /usr/share/neutron/neutron-dist.conf --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/openvswitch_agent.ini --config-file /etc/neutron/plugins/ml2/sriov_agent.ini --log-file /var/log/neutron/server.log
5. 重启 neutron-server 服务来使配置生效:
[root@network ~]# systemctl restart neutron-server.service
20.4. 在 Controller 节点上配置 SR-IOV
1. 为了正确调度 SR-IOV 设备,Compute 调度程序需要使用带有 PciPassthroughFilter 过滤的 FilterScheduler。在 Controller 节点上的 nova.conf 文件中应用这个配置。例如:
scheduler_available_filters=nova.scheduler.filters.all_filters scheduler_default_filters=RetryFilter,AvailabilityZoneFilter,RamFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,CoreFilter, PciPassthroughFilter
2. 重启 Compute 调度器以使修改生效:
[root@compute ~]# systemctl restart openstack-nova-scheduler.service
20.5. 在 Compute 节点上配置 SR-IOV
在所有 Compute 节点上,为每个物理网络关联有效的 VF:
1. 在 nova.conf 文件中定义这些项。在这个例子中,把设备名为 enp5s0f1 的 VF 网络与网络标签为 physnet1 的物理网络相关联。其中由 physical_network 所指定的网络标签是以前在 network_vlan_ranges 中配置的。
pci_passthrough_whitelist={"devname": "enp5s0f1", "physical_network":"physnet1"}下面的配置会把厂商 ID 为 8086 的 PF 网络与网络标签为 physnet1(由 physical_network 指定)的物理网络进行关联:~ pci_passthrough_whitelist = \{"vendor_id": "8086","product_id": "10ac", "physical_network":"physnet1"} ~
PCI passthrough whitelist 项的格式如下:
["device_id": "<id>",] ["product_id": "<id>",] ["address": "[[[[<domain>]:]<bus>]:][<slot>][.[<function>]]" | "devname": "Ethernet Interface Name",] "physical_network":"Network label string"
- id - id 的值可以是通配符(*),或一个有效的 device/product id。您可以使用 lspci 列出有效的设备名。
- address - address 的格式与使用带有 -s 选项的 lspci 命令输出中的格式相同。
- devname - devname 是一个有效的 PCI 设备名称。您可以使用 ifconfig -a 列出全部有效的名称。这个项需要和与一个 vNIC 相关联的 PF 或 VF 值相对应。如果设备由代表一个 SR-IOV PF 的地址或 devname 来定义,则 PF 下的所有 VF 必须和这个项匹配。另外,一个项可以关联0 个或多个标签。
- physical_network - 在使用 SR-IOV 网络时,"physical_network" 被用来指定设备附加到的物理网络。
您可以为每个主机配置多个 whitelist 项。device_id、product_id、以及 address 或 devname 的值将会和查询 libvirt 所返回的 PCI 设备进行匹配。
2. 重启 nova-compute 服务以使所做的改变生效:
[root@compute ~]# systemctl restart openstack-nova-compute
20.6. 启用 OpenStack Networking SR-IOV agent
可选的 OpenStack Networking SR-IOV agent 启用了对 admin_state 端口的管理。这个 agent 与网络适配器进行集成,允许管理员打开/关闭 VF 的管理状态。
另外,如果 agent_required=True 已在 OpenStack Networking(neutron)服务器上配置,则需要在每个 Compute 节点上都运行 OpenStack Networking SR-IOV Agent。
请注意:当前,不是所有网卡厂商都支持使用这个 agent 管理端口状态。
1. 安装 sriov-nic-agent 软件包以便进行以下步骤:
[root@compute ~]# yum install openstack-neutron-sriov-nic-agent
2. 在 /etc/neutron/plugins/ml2/openvswitch_agent.ini 文件中启用 NoopFirewallDriver:
[root@compute ~]# openstack-config --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
3. 在 /etc/neutron/plugins/ml2/sriov_agent.ini 文件中添加映射信息。在这个例子中,physnet1 是物理网络、enp4s0f1 是 physical function。把 exclude_devices 设为空来允许 agent 管理所有相关的 VF。
[sriov_nic] physical_device_mappings = physnet1:enp4s0f1 exclude_devices =
4. 可选操作 - 为了在 agent 配置中排除特定的 VF,在 sriov_nic 项中列出要排除的 VF。例如:
exclude_devices = eth1:0000:07:00.2; 0000:07:00.3, eth2:0000:05:00.1; 0000:05:00.2
5. 配置 neutron-sriov-nic-agent.service 来使用 ml2_conf_sriov.ini 文件。例如:
[root@compute ~]# vi /usr/lib/systemd/system/neutron-sriov-nic-agent.service [Service] Type=simple User=neutron ExecStart=/usr/bin/neutron-sriov-nic-agent --config-file /usr/share/neutron/neutron-dist.conf --config-file /etc/neutron/neutron.conf --log-file /var/log/neutron/sriov-nic-agent.log --config-file /etc/neutron/plugins/ml2/sriov_agent.ini
6. 启动 OpenStack Networking SR-IOV agent:
[root@compute ~]# systemctl enable neutron-sriov-nic-agent.service [root@compute ~]# systemctl start neutron-sriov-nic-agent.service
20.7. 配置一个实例来使用 SR-IOV 端口
在这个例子中,SR-IOV 端口被添加到 web 网络。
1. 获得有效的网络列表
[root@network ~]# neutron net-list +--------------------------------------+---------+------------------------------------------------------+ | id | name | subnets | +--------------------------------------+---------+------------------------------------------------------+ | 3c97eb09-957d-4ed7-b80e-6f052082b0f9 | corp | 78328449-796b-49cc-96a8-1daba7a910be 172.24.4.224/28 | | 721d555e-c2e8-4988-a66f-f7cbe493afdb | web | 140e936e-0081-4412-a5ef-d05bacf3d1d7 10.0.0.0/24 | +--------------------------------------+---------+------------------------------------------------------+
这个结果列出了已在 OpenStack Networking 中创建的网络,以及子网的详情。
2. 在 web 网络中创建端口
[root@network ~]# neutron port-create web --name sr-iov --binding:vnic-type direct
Created a new port:
+-----------------------+---------------------------------------------------------------------------------+
| Field | Value |
+-----------------------+---------------------------------------------------------------------------------+
| admin_state_up | True |
| allowed_address_pairs | |
| binding:host_id | |
| binding:profile | {} |
| binding:vif_details | {} |
| binding:vif_type | unbound |
| binding:vnic_type | normal |
| device_id | |
| device_owner | |
| fixed_ips | {"subnet_id": "140e936e-0081-4412-a5ef-d05bacf3d1d7", "ip_address": "10.0.0.2"} |
| id | a2122b4d-c9a9-4a40-9b67-ca514ea10a1b |
| mac_address | fa:16:3e:b1:53:b3 |
| name | sr-iov |
| network_id | 721d555e-c2e8-4988-a66f-f7cbe493afdb |
| security_groups | 3f06b19d-ec28-427b-8ec7-db2699c63e3d |
| status | DOWN |
| tenant_id | 7981849293f24ed48ed19f3f30e69690 |
+-----------------------+---------------------------------------------------------------------------------+3. 使用新端口创建一个实例。创建一个名为 webserver01 的新实例,配置它来使用新端口(端口 ID 是前一个输出中的 id 项中的值):
请注意:您可以使用 glance image-list 命令来获得有效镜像的列表,以及它们的 UUID。
[root@compute ~]# nova boot --flavor m1.tiny --image 59a66200-45d2-4b21-982b-d06bc26ff2d0 --nic port-id=a2122b4d-c9a9-4a40-9b67-ca514ea10a1b webserver01
新实例 webserver01 被创建,并配置为使用 SR-IOV 端口。
20.8. 检查 allow_unsafe_interrupts 设置
为了完全把带有分配设备的客户机与主机分离,需要平台对中断重映射功能的支持。如果不支持这个功能,主机可能会受到来自于恶意客户机上的中断注入攻击(interrupt injection attack)。而在一个客户端可以被完全信任的环境中,管理员可能会允许使用 allow_unsafe_interrupts 选项进行 PCI 设备的分配。您需要根据具体情况检查是否在主机上启用 allow_unsafe_interrupts。如果主机上的 IOMMU 支持中断重映射功能,则不需要启用这个选项。
1. 使用 dmesg 检查您的主机是否支持 IOMMU 中断重映射功能:
[root@compute ~]# dmesg |grep ecap
当 ecap (0xf020ff → …1111) 的第 3 位是 1 时,意味着 IOMMU 支持中断重映射。
2. 确认 IRQ 重映射是否已被启用:
[root@compute ~]# dmesg |grep "Enabled IRQ" [ 0.033413] Enabled IRQ remapping in x2apic mode
请注意:如需手工禁用 "IRQ remapping",把 intremap=off 添加到 grub.conf 文件中。
3. 如果主机的 IOMMU 不支持中断重映射,您需要在 kvm 模块中启用 allow_unsafe_assigned_interrupts=1。
20.9. 额外需要考虑的因素
- 在选择 vNIC 类型时请注意,当前还不支持 vnic_type=macvtap。
- 不支持带有附加了 SR-IOV 实例的 VM 迁移。
- 当前,安全组不能在启用了 SR-IOV 的端口中使用。

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.