第 9 章 客户机虚拟机设备配置
- 模拟设备是 纯粹的虚拟设备,可模拟实际硬件,允许未经修改的虚拟机操作系统使用其标准驱动程序来配合它们。Red Hat Enterprise Linux 6 支持 216 virtio 设备。
- VirtIO 设备 纯粹的虚拟设备,设计为在虚拟机中最佳工作。VirtIO 设备与模拟设备类似,但非 Linux 虚拟机不包括它们默认需要的驱动程序。虚拟机管理器(virt-manager)和 Red Hat Virtualization Hypervisor(RHV-H)等虚拟化管理软件自动为支持的非 Linux 客户机操作系统安装这些驱动程序。Red Hat Enterprise Linux 6 支持多达 700 个 scsi 磁盘。
- 分配的设备 是公开给虚拟机的物理设备。此方法也称为"passthrough"。设备分配允许虚拟机为一系列任务对 PCI 设备进行独占访问,并允许 PCI 设备出现,就像它们物理附加到客户端操作系统一样。Red Hat Enterprise Linux 6 支持每个虚拟机最多 32 个分配的设备。
/etc/security/limits.conf
中配置,该文件可以被 /etc/libvirt/qemu.conf
覆盖)。其他限制因素包括虚拟总线上可用的插槽数,以及 sysctl 设置的打开文件的系统范围限制。
vfio_iommu_type1
模块使用 allow_unsafe_interrupts
选项进行 PCI 设备分配。这可以通过在 /etc/modprobe.d
中添加 .conf 文件(如 local.conf
)来永久完成,包含以下内容:
options vfio_iommu_type1 allow_unsafe_interrupts=1或者动态使用 sysfs 条目进行相同的操作:
# echo 1 > /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts
9.1. PCI 设备
过程 9.1. 为 PCI 设备分配准备 Intel 系统
启用 Intel VT-d 规格
Intel VT-d 规格为直接为虚拟机分配物理设备提供了硬件支持。这些规格需要使用 Red Hat Enterprise Linux 的 PCI 设备分配。在 BIOS 中必须启用 Intel VT-d 规格。有些系统制造商默认禁用这些规格。用于参考这些规格的条款在制造商之间有所不同;请参考您的系统厂商文档来获取适当的条款。在内核中激活 Intel VT-d
在/etc/sysconfig/grub
文件中,在 GRUB_CMDLINX_LINUX 行的末尾添加intel_iommu=on
参数来激活 Intel VT-d。以下示例是已激活 Intel VT-d 的修改 GRUB 文件。GRUB_CMDLINE_LINUX="rd.lvm.lv=vg_VolGroup00/LogVol01 vconsole.font=latarcyrheb-sun16 rd.lvm.lv=vg_VolGroup_1/root vconsole.keymap=us $([ -x /usr/sbin/rhcrashkernel-param ] && /usr/sbin/ rhcrashkernel-param || :) rhgb quiet intel_iommu=on"
重新生成配置文件
运行以下命令重新生成 /etc/grub2.cfg:grub2-mkconfig -o /etc/grub2.cfg
请注意,如果您使用基于 UEFI 的主机,则目标文件应为/etc/grub2-efi.cfg
。准备好使用
重启系统以启用更改。您的系统现在可以进行 PCI 设备分配。
过程 9.2. 为 PCI 设备分配准备 AMD 系统
启用 AMD IOMMU 规格
在 Red Hat Enterprise Linux 中使用 PCI 设备分配需要 AMD IOMMU 规格。这些规格必须在 BIOS 中启用。有些系统制造商默认禁用这些规格。启用 IOMMU 内核支持
将amd_iommu=on
附加到 GRUB_CMDLINX_LINUX 行的末尾,在引号中附加,以便在启动时启用 AMD IOMMU 规格。重新生成配置文件
运行以下命令重新生成 /etc/grub2.cfg:grub2-mkconfig -o /etc/grub2.cfg
请注意,如果您使用基于 UEFI 的主机,则目标文件应为/etc/grub2-efi.cfg
。准备好使用
重启系统以启用更改。您的系统现在可以进行 PCI 设备分配。
9.1.1. 使用 virsh 分配 PCI 设备
pci_0000_01_00_0
,以及一个名为 guest1-rhel6-64 的完整虚拟化客户机计算机。
过程 9.3. 使用 virsh 将 PCI 设备分配给客户端虚拟机
识别该设备
首先,识别为虚拟机分配设备指定的 PCI 设备。使用 lspci 命令列出可用的 PCI 设备。您可以使用 grep 重新定义 lspci 的输出。本例使用以下输出中突出显示的以太网控制器:# lspci | grep Ethernet 00:19.0 Ethernet controller: Intel Corporation 82567LM-2 Gigabit Network Connection 01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
此以太网控制器显示短标识符00:19.0
。我们需要找出 virsh 使用的完整标识符,以便将此 PCI 设备分配给虚拟机。为此,请使用 virsh nodedev-list 命令列出附加到主机机器的特定类型(pci
)的所有设备。然后查看映射到您要使用的设备的简短标识符的字符串输出。本例突出显示映射到以太网控制器的字符串,其 ID 为00:19.0
。在本例中,:
和.
字符在完整标识符中被替换为下划线。# virsh nodedev-list --cap pci pci_0000_00_00_0 pci_0000_00_01_0 pci_0000_00_03_0 pci_0000_00_07_0 pci_0000_00_10_0 pci_0000_00_10_1 pci_0000_00_14_0 pci_0000_00_14_1 pci_0000_00_14_2 pci_0000_00_14_3 pci_0000_00_19_0 pci_0000_00_1a_0 pci_0000_00_1a_1 pci_0000_00_1a_2 pci_0000_00_1a_7 pci_0000_00_1b_0 pci_0000_00_1c_0 pci_0000_00_1c_1 pci_0000_00_1c_4 pci_0000_00_1d_0 pci_0000_00_1d_1 pci_0000_00_1d_2 pci_0000_00_1d_7 pci_0000_00_1e_0 pci_0000_00_1f_0 pci_0000_00_1f_2 pci_0000_00_1f_3 pci_0000_01_00_0 pci_0000_01_00_1 pci_0000_02_00_0 pci_0000_02_00_1 pci_0000_06_00_0 pci_0000_07_02_0 pci_0000_07_03_0
记录映射到您要使用的设备的 PCI 设备编号;在其他步骤中,这是必需的。查看设备信息
有关域、总线和功能的信息可在 virsh nodedev-dumpxml 命令的输出中获取:virsh nodedev-dumpxml pci_0000_00_19_0 <device> <name>pci_0000_00_19_0</name> <parent>computer</parent> <driver> <name>e1000e</name> </driver> <capability type='pci'> <domain>0</domain> <bus>0</bus> <slot>25</slot> <function>0</function> <product id='0x1502'>82579LM Gigabit Network Connection</product> <vendor id='0x8086'>Intel Corporation</vendor> <iommuGroup number='7'> <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/> </iommuGroup> </capability> </device>
注意IOMMU 组根据 IOMMU 从 IOMMU 的角度看设备的可见性和隔离决定。每个 IOMMU 组可以包含一个或多个设备。当存在多个设备时,必须声明 IOMMU 组内的所有端点才能分配给一个客户端。这可通过向客户机分配额外端点或使用 virsh nodedev-detach 从主机驱动程序分离来实现。单个组中包含的设备不能在多个虚拟机之间分割或分割在主机和客户机之间。非端点设备(如 PCIe 根端口、交换机端口和网桥)不应与主机驱动程序分离,且不会干扰端点的分配。可以使用 virsh nodedev-dumpxml 输出的 iommuGroup 部分来确定 IOMMU 组中的设备。组的每个成员都通过单独的 "address" 字段提供。这些信息也可以在 sysfs 中使用:$ ls /sys/bus/pci/devices/0000:01:00.0/iommu_group/devices/
输出的示例如下:0000:01:00.0 0000:01:00.1
要只为客户机分配 0000.01.00.0,未使用的端点应当在启动客户机前从主机分离:$ virsh nodedev-detach pci_0000_01_00_1
确定所需的配置详情
如需配置文件所需的值,请参阅 virsh nodedev-dumpxml pci_0000_00_19_0 命令的输出。示例设备具有以下值: bus = 0, slot = 25 和 function = 0。十进制配置使用以下三个值:bus='0' slot='25' function='0'
添加配置详情
运行 virsh edit,指定虚拟机名称,并在 <source>
部分中添加一个设备条目,以将 PCI 设备分配到客户端虚拟机。# virsh edit guest1-rhel6-64 <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0' bus='0' slot='25' function='0'/> </source> </hostdev>
或者,运行 virsh attach-device,指定虚拟机名称和客户机 XML 文件:virsh attach-device guest1-rhel6-64
file.xml
启动虚拟机
# virsh start guest1-rhel6-64
9.1.2. 使用 virt-manager 分配 PCI 设备
过程 9.4. 使用 virt-manager 将 PCI 设备分配给客户端虚拟机
打开硬件设置
打开 guest 虚拟机,按钮,向虚拟机添加新设备。图 9.1. 虚拟机硬件信息窗口
选择 PCI 设备
从左侧的 Hardware 列表中选择 PCI 主机设备。选择一个未使用的 PCI 设备。如果您选择了一个被另一个客户端使用的 PCI 设备,则可能会导致错误。在这个示例中使用备用 82576 网络设备。点 Finish 完成设置。图 9.2. Add new virtual hardware 向导
添加新设备
设置已完成,客户端虚拟机现在可以直接访问 PCI 设备。图 9.3. 虚拟机硬件信息窗口
9.1.3. 使用 virt-install 的 PCI 设备分配
--host-device
参数。
过程 9.5. 使用 virt-install 为虚拟机分配 PCI 设备
识别该设备
识别为客户端虚拟机分配设备指定的 PCI 设备。# lspci | grep Ethernet 00:19.0 Ethernet controller: Intel Corporation 82567LM-2 Gigabit Network Connection 01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
virsh nodedev-list 命令列出系统中附加的所有设备,并使用字符串识别每个 PCI 设备。要只将输出限制为 PCI 设备,请运行以下命令:# virsh nodedev-list --cap pci pci_0000_00_00_0 pci_0000_00_01_0 pci_0000_00_03_0 pci_0000_00_07_0 pci_0000_00_10_0 pci_0000_00_10_1 pci_0000_00_14_0 pci_0000_00_14_1 pci_0000_00_14_2 pci_0000_00_14_3 pci_0000_00_19_0 pci_0000_00_1a_0 pci_0000_00_1a_1 pci_0000_00_1a_2 pci_0000_00_1a_7 pci_0000_00_1b_0 pci_0000_00_1c_0 pci_0000_00_1c_1 pci_0000_00_1c_4 pci_0000_00_1d_0 pci_0000_00_1d_1 pci_0000_00_1d_2 pci_0000_00_1d_7 pci_0000_00_1e_0 pci_0000_00_1f_0 pci_0000_00_1f_2 pci_0000_00_1f_3 pci_0000_01_00_0 pci_0000_01_00_1 pci_0000_02_00_0 pci_0000_02_00_1 pci_0000_06_00_0 pci_0000_07_02_0 pci_0000_07_03_0
记录 PCI 设备编号;其他步骤中需要该数字。有关域、总线和功能的信息可在 virsh nodedev-dumpxml 命令的输出中获取:# virsh nodedev-dumpxml pci_0000_01_00_0 <device> <name>pci_0000_01_00_0</name> <parent>pci_0000_00_01_0</parent> <driver> <name>igb</name> </driver> <capability type='pci'> <domain>0</domain> <bus>1</bus> <slot>0</slot> <function>0</function> <product id='0x10c9'>82576 Gigabit Network Connection</product> <vendor id='0x8086'>Intel Corporation</vendor> <iommuGroup number='7'> <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/> </iommuGroup> </capability> </device>
注意如果 IOMMU 组中有多个端点,而不是分配给客户机,则需要在启动客户端前手动从主机中手动分离其他端点:$ virsh nodedev-detach pci_0000_00_19_1
有关 IOMMU 组的更多信息,请参阅 注意 中的 第 9.1.1 节 “使用 virsh 分配 PCI 设备”。添加设备
使用 virsh nodedev 命令的 PCI 标识符输出作为--host-device
参数的值。virt-install \ --name=guest1-rhel6-64 \ --disk path=/var/lib/libvirt/images/guest1-rhel6-64.img,size=8 \ --nonsparse --graphics spice \ --vcpus=2 --ram=2048 \ --location=http://example1.com/installation_tree/RHEL6.0-Server-x86_64/os \ --nonetworks \ --os-type=linux \ --os-variant=rhel6 --host-device=pci_0000_01_00_0
完成安装
完成客户机安装。PCI 设备应当连接到客户端。
9.1.4. 分离分配的 PCI 设备
过程 9.6. 使用 virsh 从客户机中分离 PCI 设备
分离该设备
使用以下命令,通过从客户机的 XML 文件中删除 PCI 设备来从客户机中分离它:# virsh detach-device name_of_guest file.xml
将设备重新关联到主机(可选)
如果设备处于managed
模式,请跳过这一步。设备将自动返回到主机。如果该设备没有使用managed
模式,使用以下命令将 PCI 设备重新附加到主机机器中:# virsh nodedev-reattach device
例如,要将pci_0000_01_00_0
设备重新连接到主机:virsh nodedev-reattach pci_0000_01_00_0
现在,该设备可用于主机使用。
过程 9.7. 使用 virt-manager 从客户机分离 PCI 设备
打开虚拟硬件详情屏幕
在 virt-manager 中,双击包含该设备的虚拟机。选择 Show virtual hardware details 按钮,以显示虚拟硬件的列表。图 9.4. 虚拟硬件详细信息按钮
选择并删除该设备
选择要从左侧面板中虚拟设备列表分离的 PCI 设备。图 9.5. 选择要分离的 PCI 设备
9.1.5. 创建 PCI 网桥
9.1.6. PCI Passthrough
<源>
元素指定)直接分配给使用通用设备 透传 的 guest,在第一个选择将设备的 MAC 地址设置为配置后,并使用可选的指定 <虚拟端口>
元素将设备与 802.1Qbh 相关联(请参阅上述为 type='direct' 网络设备的 virtualport 示例)。由于标准单端口 PCI 以太网卡驱动程序设计的限制 - 仅限 SR-IOV(Single Root I/O 虚拟化)虚拟功能(VF)设备,以此方式分配标准单端口 PCI 或 PCIe 以太网卡,请使用传统的 <hostdev>
设备定义。
<type='hostdev'>
接口可以有一个可选的驱动程序子元素,并将 name 属性设置为 "vfio"。要使用旧的 KVM 设备分配,您可以将 name 设置为 "kvm"(或只省略 <驱动程序>
元素,因为 <driver='kvm'>
目前是默认值)。
<hostdev>
设备的功能相似,这种方法为通过设备指定 MAC 地址 <和虚拟端口>
。如果不需要这些功能,或者您使用的是支持 SR-IOV 的标准单端口 PCI、PCIe 或 USB 网卡(因此,在分配到客户端域后,任何时候都会丢失配置的 MAC 地址),或者如果您使用比 0.9.11 旧的 libvirt 版本,您应该使用标准 <hostdev>
将设备分配给 guest,而不是 <接口 type=host/dev'>
。
图 9.6. PCI 设备分配的 XML 示例
<devices> <interface type='hostdev'> <driver name='vfio'/> <source> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </source> <mac address='52:54:00:6d:90:02'> <virtualport type='802.1Qbh'> <parameters profileid='finance'/> </virtualport> </interface> </devices>
9.1.7. 使用 SR-IOV 设备配置 PCI 分配(Passthrough)
<hostdev>
为虚拟客户机分配,但因为 SR-IOV VF 网络设备没有永久唯一的 MAC 地址,从而导致客户端虚拟机的网络设置在每次重新引导主机物理机器时都必须重新配置问题。要补救这一点,您需要在将 VF 分配给主机物理机器前设置 MAC 地址,每次客户端虚拟机引导时都需要设置它。要分配这个 MAC 地址以及其他选项,请参阅 过程 9.8, “配置 MAC 地址、vLAN 和虚拟端口,以便在 SR-IOV 中分配 PCI 设备” 中描述的步骤。
过程 9.8. 配置 MAC 地址、vLAN 和虚拟端口,以便在 SR-IOV 中分配 PCI 设备
<hostdev>
元素不能用于特定于功能的项目,如 MAC 地址分配、vLAN 标签 ID 分配或虚拟端口分配,因为 <mac>
、<vlan>
和 <virtualport>
元素不是 <hostdev>
的有效子项。当它们对 <接口>
有效时,增加了对新接口类型的支持(<interface type='hostdev'>
)。这个新接口设备类型作为接口和 <hostdev>
的混合运行。<>
因此,在为客户机虚拟机分配 PCI 设备前,libvirt 在虚拟机 XML 配置文件中初始化特定于网络的硬件/交换机(例如设置 MAC 地址、设置 vLAN 标签或与 802.1Qbh 交换机关联)。有关设置 vLAN 标签的详情,请参考 第 18.14 节 “设置 vLAN Tags”。
关闭客户机虚拟机
使用 virsh shutdown 命令(请参考 第 14.9.1 节 “关闭客户机虚拟机”),关闭名为 guestVM 的客户机虚拟机。# virsh shutdown guestVM
收集信息
要使用<接口 type='hostdev'>
,您必须有一个支持 SR-IOV 功能的网卡,主机物理机器硬件支持 Intel VT-d 或 AMD IOMMU 扩展,您必须知道您要分配的 VF 的 PCI 地址。打开 XML 文件进行编辑
运行 # virsh save-image-edit 命令以打开 XML 文件进行编辑(详情请参阅 第 14.8.10 节 “编辑域 XML 配置文件” )。由于您要将 guest 虚拟机恢复到以前的运行状态,在这种情况下,--running
将用在内。本例中的配置文件的名称是 guestVM.xml,因为客户端虚拟机的名称是 guestVM。# virsh save-image-edit guestVM.xml
--running
在默认编辑器中打开 guestVM.xml。编辑 XML 文件
更新配置文件(guestVM.xml)使其具有类似如下的<设备>
条目:图 9.7. hostdev 接口类型的域 XML 示例
<devices> ... <interface type='hostdev' managed='yes'> <source> <address type='pci' domain='0x0' bus='0x00' slot='0x07' function='0x0'/> <!--these values can be decimal as well--> </source> <mac address='52:54:00:6d:90:02'/> <!--sets the mac address--> <virtualport type='802.1Qbh'> <!--sets the virtual port for the 802.1Qbh switch--> <parameters profileid='finance'/> </virtualport> <vlan> <!--sets the vlan tag--> <tag id='42'/> </vlan> </interface> ... </devices>
请注意,如果您不提供 MAC 地址,系统将自动生成,就像其他类型的接口设备一样。另外,只有在您要连接到 802.11Qgh 硬件开关(802.11Qbg)(a.k.a)时,才会使用<virtualport>
元素。"VEPA")交换机当前不受支持。重新启动客户机虚拟机
运行 virsh start 命令,以重新启动您在第一步中关闭的 guest 虚拟机(例如,使用 guestVM 作为客户机虚拟机的域名)。如需更多信息,请参阅 第 14.8.1 节 “启动定义的域”。# virsh start guestVM
当客户机虚拟机启动时,它会看到由物理主机的适配器(带有配置的 MAC 地址)提供的网络设备。此 MAC 地址在客户机虚拟机之间保持不变,主机物理机器重新引导。
9.1.8. 从 SR-IOV 虚拟功能池设置 PCI 设备分配
- 指定的 VF 必须在每次启动客户机虚拟机时可用,这意味着管理员必须将每个 VF 永久分配给单个客户端虚拟机(或者修改每个 guest 虚拟机的配置文件,以指定目前未使用的 VF 的 PCI 地址)。
- 如果 guest 虚拟机被移动到另一台主机物理计算机,则该主机物理计算机必须在 PCI 总线上同一位置上有相同的硬件(或者,启动之前必须修改客户机虚拟机配置)。
过程 9.9. 创建设备池
关闭客户机虚拟机
使用 virsh shutdown 命令(请参考 第 14.9 节 “关闭客户机虚拟机的关闭、重新启动和关闭”),关闭名为 guestVM 的客户机虚拟机。# virsh shutdown guestVM
创建配置文件
使用您选择的编辑器在/tmp
目录中创建 XML 文件(例如:throughthrough .xml )。确保将pf dev='eth3'
替换为您自己的 SR-IOV 设备的 PF 的 netdev 名称以下是一个网络定义示例,它会在主机 物理机器上使用其物理功能(PF) 为 SR-IOV 适配器提供所有 VF 池:图 9.8. 网络定义域 XML 示例
<network> <name>passthrough</name> <!--This is the name of the file you created--> <forward mode='hostdev' managed='yes'> <pf dev='myNetDevName'/> <!--Use the netdev name of your SR-IOV devices PF here--> </forward> </network>
加载新的 XML 文件
运行以下命令,将 /tmp/passthrough.xml 替换为您在上一步中创建的 XML 文件的名称和位置:# virsh net-define /tmp/passthrough.xml
重启客户端
运行以下命令将 passthrough.xml 替换为您在上一步中创建的 XML 文件的名称:# virsh net-autostart passthrough # virsh net-start passthrough
重新启动客户机虚拟机
运行 virsh start 命令,以重新启动您在第一步中关闭的 guest 虚拟机(例如,使用 guestVM 作为客户机虚拟机的域名)。如需更多信息,请参阅 第 14.8.1 节 “启动定义的域”。# virsh start guestVM
为设备启动 passthrough
虽然只显示单个设备,但 libvirt 会在其域 XML 中使用接口定义(如下所示)在 PF 首次启动时,自动获得与 PF 相关联的所有 VF 列表:图 9.9. 接口网络定义的域 XML 示例
<interface type='network'> <source network='passthrough'> </interface>
验证
启动使用网络的第一个客户机后,您可以运行 virsh net-dumpxml passthrough 命令进行验证;您可以获得类似如下的输出:图 9.10. XML 转储文件 透传 内容
<network connections='1'> <name>passthrough</name> <uuid>a6b49429-d353-d7ad-3185-4451cc786437</uuid> <forward mode='hostdev' managed='yes'> <pf dev='eth3'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x1'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x3'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x5'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x7'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x1'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x3'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x5'/> </forward> </network>