跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文档 / 虚拟化指南 / 使用 libvirt 管理虚拟机 / 使用 virsh 配置虚拟机
适用范围 SUSE Linux Enterprise Server 15 SP4

15 使用 virsh 配置虚拟机

您也可以在命令行上使用 virsh 来配置虚拟机 (VM),以此替代虚拟机管理器。使用 virsh 可以控制 VM 的状态、编辑 VM 的配置,甚至将 VM 迁移到另一台主机。下列章节介绍如何使用 virsh 来管理 VM。

15.1 编辑 VM 配置

VM 配置储存在 /etc/libvirt/qemu/ 中的某个 XML 文件内,其内容如下所示:

例 15.1︰ 示例 XML 配置文件
<domain type='kvm'>
  <name>sles15</name>
  <uuid>ab953e2f-9d16-4955-bb43-1178230ee625</uuid>
  <memory unit='KiB'>2097152</memory>
  <currentMemory unit='KiB'>2097152</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-2.0'>hvm</type>
  </os>
  <features>...</features>
  <cpu mode='custom' match='exact' check='partial'>
    <model fallback='allow'>Skylake-Client-IBRS</model>
  </cpu>
  <clock>...</clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>...</disk>
  </devices>
  ...
</domain>

如果您要编辑 VM Guest 的配置,请检查它是否处于脱机状态:

> sudo virsh list --inactive

如果您的 VM Guest 在此列表中,则表明您可以放心地编辑其配置:

> sudo virsh edit NAME_OF_VM_GUEST

在保存更改之前,virsh 会根据 RelaxNG 纲要验证您的输入。

15.2 更改计算机类型

使用 virt-install 工具安装时,VM Guest 的计算机类型默认为 pc-q35。计算机类型储存在 VM Guest 配置文件中的 type 元素内:

<type arch='x86_64' machine='pc-q35-2.3'>hvm</type>

下面的过程示范了如何将此值更改为 q35 计算机类型。值 q35 表示一种 Intel* 芯片组,其中包括 PCIe,最多支持 12 个 USB 端口,并支持 SATAIOMMU

过程 15.1︰ 更改计算机类型
  1. 检查您的 VM Guest 是否处于非活动状态:

    > sudo virsh list --inactive
    Id    Name                           State
    ----------------------------------------------------
    -     sles15                         shut off
  2. 编辑此 VM Guest 的配置:

    > sudo virsh edit sles15
  3. 请将 machine 属性的值替换为 pc-q35-2.0

    <type arch='x86_64' machine='pc-q35-2.0'>hvm</type>
  4. 重启动 VM Guest:

    > sudo virsh start sles15
  5. 检查计算机类型是否已更改。登录到 VM Guest 并运行以下命令:

    > sudo dmidecode | grep Product
    Product Name: Standard PC (Q35 + ICH9, 2009)
提示
提示:计算机类型更新建议

每当升级主机系统上的 QEMU 版本时(例如,将 VM 主机服务器升级到新服务包时),请将 VM Guest 的计算机类型升级到最新的可用版本。要进行检查,请在 VM 主机服务器上使用 qemu-system-x86_64 -M help 命令。

默认计算机类型(例如 pc-i440fx)会定期更新。如果您的 VM Guest 仍在 pc-i440fx-1.X 计算机类型上运行,我们强烈建议更新到 pc-i440fx-2.X。这样就可以利用计算机定义中最近的更新和更正,并确保将来可以更好地兼容。

15.3 配置超级管理程序功能

libvirt 可自动启用一组默认的超级管理程序功能(这些功能在大多数情况下已够用),同时还允许按需启用和禁用功能。例如,Xen 不支持默认启用 PCI 直通。必须使用直通设置来启用此功能。可以使用 virsh 来配置超级管理程序功能。查看 VM Guest 配置文件中的 <features> 元素,并根据需要调整各项功能。仍以 Xen 直通为例:

> sudo virsh edit sle15sp1
 <features>
    <xen>
      <passthrough/>
    </xen>
 </features>

保存更改并重启动 VM Guest。

有关详细信息,请参见 https://libvirt.org/formatdomain.html#elementsFeatures 上 libvirt 的《Domain XML format》(域 XML 格式)手册中的“Hypervisor features”(超级管理程序功能)一节。

15.4 配置 CPU

可以使用 virsh 来配置提供给 VM Guest 的虚拟 CPU 的许多属性。可以更改分配给 VM Guest 的当前和最大 CPU 数量,以及 CPU 型号及其功能集。以下小节介绍如何更改 VM Guest 的常用 CPU 设置。

15.4.1 配置 CPU 数量

分配的 CPU 数量储存在 /etc/libvirt/qemu/ 下 VM Guest XML 配置文件中的 vcpu 元素内:

<vcpu placement='static'>1</vcpu>

在此示例中,只为 VM Guest 分配了一个 CPU。下面的过程说明如何更改分配给 VM Guest 的 CPU 数量:

  1. 检查您的 VM Guest 是否处于非活动状态:

    > sudo virsh list --inactive
    Id    Name                           State
    ----------------------------------------------------
    -     sles15                         shut off
  2. 编辑现有 VM Guest 的配置:

    > sudo virsh edit sles15
  3. 更改分配的 CPU 数量:

    <vcpu placement='static'>2</vcpu>
  4. 重启动 VM Guest:

    > sudo virsh start sles15
  5. 检查 VM 中的 CPU 数量是否已更改。

    > sudo virsh vcpuinfo sled15
    VCPU:           0
    CPU:            N/A
    State:          N/A
    CPU time        N/A
    CPU Affinity:   yy
    
    VCPU:           1
    CPU:            N/A
    State:          N/A
    CPU time        N/A
    CPU Affinity:   yy

还可以在 VM Guest 正在运行时更改 CPU 数量。可以热插接 CPU,只要不超过 VM Guest 启动时配置的最大数量即可。同样,可以热拔除 CPU,只要不达到下限 1 即可。以下示例演示如何将活动 CPU 计数从 2 个更改为预定义的最大计数 4 个。

  1. 检查当前的在线 vcpu 计数:

    > sudo virsh vcpucount sles15 | grep live
    maximum      live           4
    current      live           2
  2. 将当前或活动的 CPU 数量更改为 4 个:

    > sudo virsh setvcpus sles15 --count 4 --live
  3. 检查当前的在线 vcpu 计数现在是否为 4 个:

    > sudo virsh vcpucount sles15 | grep live
    maximum      live           4
    current      live           4
重要
重要:超过 255 个 CPU

在 KVM 中可以定义 CPU 数量超过 255 个的 VM Guest,但需要完成额外的配置才能启动和运行 VM Guest。需要微调 ioapic 功能,并且需要将 IOMMU 设备添加到 VM Guest。下面是适用于 288 个 CPU 的示例配置。

<domain>
 <vcpu placement='static'>288</vcpu>
 <features>
  <ioapic driver='qemu'/>
 </features>
 <devices>
  <iommu model='intel'>
   <driver intremap='on' eim='on'/>
  </iommu>
 </devices>
</domain>

15.4.2 配置 CPU 型号

向 VM Guest 公开的 CPU 型号往往会影响该 VM Guest 中运行的工作负载。默认 CPU 型号派生自一种名为 host-model 的 CPU 模式。

<cpu mode='host-model'/>

使用 CPU 模式 host-model 启动 VM Guest 时,libvirt 会将其主机 CPU 型号复制到 VM Guest 定义中。可以在 virsh capabilities 的输出中观察复制到 VM Guest 定义的主机 CPU 型号和功能。

另一种有趣的 CPU 模式是 host-passthrough

<cpu mode='host-passthrough'/>

使用 CPU 模式 host-passthrough 启动 VM Guest 时,将为该 VM Guest 提供与 VM 主机服务器 CPU 完全相同的 CPU。当 libvirt 的简化 host-model CPU 不能提供 VM Guest 工作负载所需的 CPU 功能时,该型号可能很有用。在某些情况下也需要 host-passthrough CPU 模式,例如,在运行内存超过 4TB 的 VM Guest 时。host-passthrough CPU 模式存在迁移能力下降的劣势。采用 host-passthrough CPU 模式的 VM Guest 只能迁移到具有相同硬件的 VM 主机服务器。

使用 host-passthrough CPU 模式时,仍可以禁用不需要的功能。以下配置将为 VM Guest 提供与主机 CPU 完全相同的 CPU,但会禁用 vmx 功能。

<cpu mode='host-passthrough'>
  <feature policy='disable' name='vmx'/>
  </cpu>

custom CPU 模式是另一种常用模式,用于定义可在群集中不同主机之间迁移的规范化 CPU。例如,在主机包含 Nehalem、IvyBridge 和 SandyBridge CPU 的群集中,可以使用包含 Nehalem CPU 型号的 custom CPU 模式来配置 VM Guest。

<cpu mode='custom' match='exact'>
  <model fallback='allow'>Nehalem</model>
  <feature policy='require' name='vme'/>
  <feature policy='require' name='ds'/>
  <feature policy='require' name='acpi'/>
  <feature policy='require' name='ss'/>
  <feature policy='require' name='ht'/>
  <feature policy='require' name='tm'/>
  <feature policy='require' name='pbe'/>
  <feature policy='require' name='dtes64'/>
  <feature policy='require' name='monitor'/>
  <feature policy='require' name='ds_cpl'/>
  <feature policy='require' name='vmx'/>
  <feature policy='require' name='est'/>
  <feature policy='require' name='tm2'/>
  <feature policy='require' name='xtpr'/>
  <feature policy='require' name='pdcm'/>
  <feature policy='require' name='dca'/>
  <feature policy='require' name='rdtscp'/>
  <feature policy='require' name='invtsc'/>
  </cpu>

有关 libvirt 的 CPU 型号和拓扑选项的详细信息,请参见 https://libvirt.org/formatdomain.html#cpu-model-and-topology 上的 CPU 型号和拓扑文档。

15.5 更改引导选项

可以在 os 元素中找到 VM Guest 的引导菜单,其外观通常如下所示:

<os>
  <type>hvm</type>
  <loader>readonly='yes' secure='no' type='rom'/>/usr/lib/xen/boot/hvmloader</loader>
  <nvram template='/usr/share/OVMF/OVMF_VARS.fd'/>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
  <boot dev='hd'/>
  <boot dev='cdrom'/>
  <bootmenu enable='yes' timeout='3000'/>
  <smbios mode='sysinfo'/>
  <bios useserial='yes' rebootTimeout='0'/>
  </os>

此示例中显示了两个设备:hdcdrom。配置还反映了实际引导顺序,在示例中,hdcdrom 之前引导。

15.5.1 更改引导顺序

VM Guest 的引导顺序通过 XML 配置文件中的设备顺序来表示。由于设备可以互换,因此可以更改 VM Guest 的引导顺序。

  1. 打开 VM Guest 的 XML 配置。

    > sudo virsh edit sles15
  2. 更改可引导设备的顺序。

    ...
    <boot dev='cdrom'/>
    <boot dev='hd'/>
    ...
  3. 通过查看 VM Guest 的 BIOS 中的引导菜单来检查引导顺序是否已更改。

15.5.2 使用直接内核引导

使用直接内核引导可以从主机上储存的内核和 initrd 引导。在 kernelinitrd 元素中设置这两个文件的路径:

<os>
    ...
  <kernel>/root/f8-i386-vmlinuz</kernel>
  <initrd>/root/f8-i386-initrd</initrd>
    ...
<os>

要启用直接内核引导,请执行以下操作:

  1. 打开 VM Guest 的 XML 配置:

    > sudo virsh edit sles15
  2. os 元素内部,添加一个 kernel 元素以及主机上内核文件的路径:

    ...
    <kernel>/root/f8-i386-vmlinuz</kernel>
    ...
  3. 添加 initrd 元素以及主机上 initrd 文件的路径:

    ...
    <initrd>/root/f8-i386-initrd</initrd>
    ...
  4. 启动 VM 以从新内核引导:

    > sudo virsh start sles15

15.6 配置内存分配

您还可以使用 virsh 来配置分配给 VM Guest 的内存量。该配置储存在 memory 元素中,它定义了引导时为 VM Guest 分配的最大内存。可选的 currentMemory 元素定义分配给 VM Guest 的实际内存。currentMemory 可以小于 memory,这样,就可以在 VM Guest 正在运行时增加(或扩大)内存。如果省略 currentMemory,则其默认值与 memory 元素的值相同。

可以通过编辑 VM Guest 配置来调整内存设置,但请注意,更改只会在下次引导后生效。以下步骤说明如何将 VM Guest 更改为使用 4G 内存引导,但随后可以扩展到 8G:

  1. 打开 VM Guest 的 XML 配置:

    > sudo virsh edit sles15
  2. 搜索 memory 元素并设置为 8G:

    ...
    <memory unit='KiB'>8388608</memory>
    ...
  3. 如果 currentMemory 元素不存在,请将其添加到 memory 元素下面,或将其值更改为 4G:

    [...]
    <memory unit='KiB'>8388608</memory>
    <currentMemory unit='KiB'>4194304</currentMemory>
    [...]

当 VM Guest 正在运行时,可以使用 setmem 子命令更改内存分配。以下示例显示如何将内存分配增加到 8G:

  1. 检查 VM Guest 的现有内存设置:

    > sudo virsh dominfo sles15 | grep memory
    Max memory:     8388608 KiB
    Used memory:    4194608 KiB
  2. 将使用的内存更改为 8G:

    > sudo virsh setmem sles15 8388608
  3. 检查已更新的内存设置:

    > sudo virsh dominfo sles15 | grep memory
    Max memory:     8388608 KiB
    Used memory:    8388608 KiB
重要
重要:大内存 VM Guest

内存要求为 4TB 或更高的 VM Guest 目前必须使用 host-passthrough CPU 型号。

15.7 添加 PCI 设备

要使用 virsh 将 PCI 设备指派到 VM Guest,请执行以下步骤:

  1. 标识要指派到 VM Guest 的主机 PCI 设备。在下面的示例中,我们要将一块 DEC 网卡指派到 Guest:

    > sudo lspci -nn
    [...]
    03:07.0 Ethernet controller [0200]: Digital Equipment Corporation DECchip \
    21140 [FasterNet] [1011:0009] (rev 22)
    [...]

    请记下设备 ID(在本例中为 03:07.0)。

  2. 使用 virsh nodedev-dumpxml ID 收集有关设备的详细信息。要获取 ID,请将设备 ID (03:07.0) 中的冒号和句点替换为下划线。使用 pci_0000_ 作为结果的前缀:pci_0000_03_07_0.

    > sudo virsh nodedev-dumpxml pci_0000_03_07_0
    <device>
      <name>pci_0000_03_07_0</name>
      <path>/sys/devices/pci0000:00/0000:00:14.4/0000:03:07.0</path>
      <parent>pci_0000_00_14_4</parent>
      <driver>
        <name>tulip</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>3</bus>
        <slot>7</slot>
        <function>0</function>
        <product id='0x0009'>DECchip 21140 [FasterNet]</product>
        <vendor id='0x1011'>Digital Equipment Corporation</vendor>
        <numa node='0'/>
      </capability>
    </device>

    记下域、总线和功能的值(请查看上面以粗体列显的 XML 代码)。

  3. 从主机系统上分离设备,然后将其挂接到 VM Guest:

    > sudo virsh nodedev-detach pci_0000_03_07_0
      Device pci_0000_03_07_0 detached
    提示
    提示:多功能 PCI 设备

    使用不支持 FLR(功能级重设置)或 PM(电源管理)重设置的多功能 PCI 设备时,需要从 VM 主机服务器分离其所有功能。出于安全原因,整个设备都必须重设置。如果 VM 主机服务器或其他 VM Guest 仍在使用设备的某个功能,libvirt 将拒绝指派该设备。

  4. 将域、总线、插槽和功能值从十进制转换为十六进制。在本示例中,域 = 0,总线 = 3,插槽 = 7,功能 = 0。确保按正确顺序插入值:

    > printf "<address domain='0x%x' bus='0x%x' slot='0x%x' function='0x%x'/>\n" 0 3 7 0

    这会返回以下结果:

    <address domain='0x0' bus='0x3' slot='0x7' function='0x0'/>
  5. 在您的域上运行 virsh edit,并使用上一步的结果在 <devices> 部分添加以下设备项:

    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0' bus='0x03' slot='0x07' function='0x0'/>
      </source>
    </hostdev>
    提示
    提示:受管模式与不受管模式的比较

    libvirt 可识别 PCI 设备的两种处理模式:受管不受管。在受管模式下,libvirt 将处理从现有驱动程序取消绑定设备(如果需要)、重设置设备、在启动域之前将设备绑定到 vfio-pci 等事项的所有细节。对于受管设备,当终止域或者从域中去除设备时,libvirt 会将设备从 vfio-pci 取消绑定,然后将其重新绑定到原始驱动程序。如果设备不受管,则用户必须确保在将设备指派到域之前以及在设备不再由域使用之后,所有这些设备管理方面的操作都已完成。

    在上面的示例中,managed='yes' 选项表示设备是受管的。要将设备切换为不受管模式,请在上面的列表中设置 managed='no'。如果这样做,需使用 virsh nodedev-detachvirsh nodedev-reattach 命令处理相关的驱动程序。在启动 VM Guest 之前,需运行 virsh nodedev-detach pci_0000_03_07_0 以从主机分离设备。如果 VM Guest 未运行,您可以运行 virsh nodedev-reattach pci_0000_03_07_0,使设备可供主机使用。

  6. 关闭 VM Guest,并禁用 SELinux(如果它正在主机上运行)。

    > sudo setsebool -P virt_use_sysfs 1
  7. 启动 VM Guest 以使指派的 PCI 设备可用:

    > sudo virsh start sles15
重要
重要:SLES11 SP4 KVM Guest

在包含 SLES11 SP4 KVM Guest 的新型 QEMU 计算机(pc-i440fx-2.0 或更高版本)上,默认不会在 Guest 中装载 acpiphp 模块。必须装载此模块才能启用磁盘和网络设备热插拔功能。要手动装载该模块,请使用 modprobe acpiphp 命令。也可以通过在 /etc/modprobe.conf.local 文件中添加 install acpiphp /bin/true 来自动装载该模块。

重要
重要:使用 QEMU Q35 计算机类型的 KVM Guest

使用 QEMU Q35 计算机类型的 KVM Guest 采用 PCI 拓扑,其中包含一个 pcie-root 控制器和七个 pcie-root-port 控制器。pcie-root 控制器不支持热插拔。每个 pcie-root-port 控制器支持热插拔一个 PCIe 设备。PCI 控制器无法热插拔,因此,如果要热插拔的 PCIe 设备超过七个,请相应地做好规划并添加更多 pcie-root-port 控制器。可以添加一个 pcie-to-pci-bridge 控制器来支持热插拔旧式 PCI 设备。有关不同 QEMU 计算机类型的 PCI 拓扑的详细信息,请参见 https://libvirt.org/pci-hotplug.html

15.7.1 IBM Z 的 PCI 直通

为了支持 IBM Z,QEMU 扩展了 PCI 表示形式,现在它允许配置额外的属性。<zpci/> libvirt 规范中添加了两个额外的属性:uidfiduid 表示用户定义的标识符,fid 表示 PCI 功能标识符。这些属性是可选的,如果不指定,系统将使用不冲突的值自动生成这些属性。

要在域规范中包含 zPCI 属性,请使用以下示例定义:

<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='1' model='pci-bridge'>
  <model name='pci-bridge'/>
  <target chassisNr='1'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'>
    <zpci uid='0x0001' fid='0x00000000'/>
  </address>
</controller>
<interface type='bridge'>
  <source bridge='virbr0'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x01' slot='0x01' function='0x0'>
    <zpci uid='0x0007' fid='0x00000003'/>
  </address>
</interface>

15.8 添加 USB 设备

要使用 virsh 将 USB 设备指派到 VM Guest,请执行以下步骤:

  1. 标识要指派到 VM Guest 的主机 USB 设备:

    > sudo lsusb
    [...]
    Bus 001 Device 003: ID 0557:2221 ATEN International Co., Ltd Winbond Hermon
    [...]

    记下供应商 ID 和产品 ID。在本示例中,供应商 ID 为 0557,产品 ID 为 2221

  2. 在您的域上运行 virsh edit,并使用上一步获得的值在 <devices> 部分添加以下设备项:

    <hostdev mode='subsystem' type='usb'>
      <source startupPolicy='optional'>
       <vendor id='0557'/>
       <product id='2221'/>
      </source>
    </hostdev>
    提示
    提示:供应商/产品或设备地址

    如果不使用 <vendor/><product/> ID 定义主机设备,您可以根据第 15.7 节 “添加 PCI 设备”中所述的适用于主机 PCI 设备的操作使用 <address/> 元素。

  3. 关闭 VM Guest,并禁用 SELinux(如果它正在主机上运行):

    > sudo setsebool -P virt_use_sysfs 1
  4. 启动 VM Guest 以使指派的 PCI 设备可用:

    > sudo virsh start sles15

15.9 添加 SR-IOV 设备

支持单根 I/O 虚拟化 (SR-IOV) 的 PCIe 设备能够复制其资源,因此它们看上去像是多个设备。可将其中的每个伪设备指派到 VM Guest。

SR-IOV 是外围部件互连专业组 (PCI-SIG) 联盟制定的行业规范。其中介绍了物理功能 (PF) 和虚拟功能 (VF)。PF 是用于管理和配置设备的完整 PCIe 功能。PF 还可以移动数据。VF 在配置和管理方面的作用有所欠缺 — 它们只能移动数据,提供的配置功能有限。由于 VF 不包括所有的 PCIe 功能,主机操作系统或超级管理程序必须支持 SR-IOV 才能访问和初始化 VF。理论上 VF 的最大数量为每台设备 256 个(因此,对于双端口以太网卡,最大数量为 512 个)。在实际环境中,此最大数量要少得多,因为每个 VF 都会消耗资源。

15.9.1 要求

要使用 SR-IOV,必须符合以下要求:

  • 支持 SR-IOV 的网卡(从 SUSE Linux Enterprise Server 15 开始,只有网卡支持 SR-IOV

  • 支持硬件虚拟化的 AMD64/Intel 64 主机(AMD-V 或 Intel VT-x),有关详细信息,请参见第 7.1.1 节 “KVM 硬件要求”

  • 支持设备指派的芯片组(AMD-Vi 或 Intel VT-d

  • libvirt 0.9.10 或更高版本

  • 主机系统上必须装载并配置 SR-IOV 驱动程序

  • 符合重要:VFIO 和 SR-IOV 的要求中所列要求的主机配置

  • 要指派到 VM Guest 的 VF 的 PCI 地址列表

提示
提示:检查设备是否支持 SR-IOV

可以通过运行 lspci 从设备的 PCI 描述符中获取有关该设备是否支持 SR-IOV 的信息。支持 SR-IOV 的设备会报告类似如下的功能:

Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV)
注意
注意:在创建 VM Guest 时添加 SR-IOV 设备

您必须已按照第 15.9.2 节 “装载和配置 SR-IOV 主机驱动程序”中所述配置 VM 主机服务器,才可在最初设置 VM Guest 时向其添加 SR-IOV 设备。

15.9.2 装载和配置 SR-IOV 主机驱动程序

要访问和初始化 VF,需在主机系统上装载一个支持 SR-IOV 的驱动程序。

  1. 在装载驱动程序之前,请运行 lspci 来确保可正常检测到网卡。下面的示例显示了双端口 Intel 82576NS 网卡的 lspci 输出:

    > sudo /sbin/lspci | grep 82576
    01:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)

    如果未检测到网卡,可能是因为未在 BIOS/EFI 中启用硬件虚拟化支持。要检查是否已启用硬件虚拟化支持,请查看主机 BIOS 中的设置。

  2. 运行 lsmod 来检查是否已装载 SR-IOV 驱动程序。在下面的示例中,用于检查是否装载了 Intel 82576NS 网卡的 igb 驱动程序的命令返回了一条结果。这表示已装载该驱动程序。如果该命令未返回任何结果,则表示未装载该驱动程序。

    > sudo /sbin/lsmod | egrep "^igb "
    igb                   185649  0
  3. 如果已装载驱动程序,请跳过以下步骤。如果尚未装载 SR-IOV 驱动程序,需要先去除非 SR-IOV 驱动程序,然后再装载新驱动程序。使用 rmmod 卸载驱动程序。下面的示例会卸载 Intel 82576NS 网卡的非 SR-IOV 驱动程序:

    > sudo /sbin/rmmod igbvf
  4. 随后使用 modprobe 命令装载 SR-IOV 驱动程序 — 必须指定 VF 参数 (max_vfs):

    > sudo /sbin/modprobe igb max_vfs=8

或者,您也可以通过 SYSFS 装载驱动程序:

  1. 通过列出以太网设备确定物理 NIC 的 PCI ID:

    > sudo lspci | grep Eth
    06:00.0 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
    06:00.1 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
  2. 要启用 VF,请向 sriov_numvfs 参数回送需要装载的 VF 数量:

    > sudo echo 1 > /sys/bus/pci/devices/0000:06:00.1/sriov_numvfs
  3. 校验是否已装载 VF NIC:

    > sudo lspci | grep Eth
    06:00.0 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
    06:00.1 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
    06:08.0 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
  4. 获取可用 VF 的最大数量:

    > sudo lspci -vvv -s 06:00.1 | grep 'Initial VFs'
                           Initial VFs: 32, Total VFs: 32, Number of VFs: 0,
    Function Dependency Link: 01
  5. 创建 /etc/systemd/system/before.service 文件,用于在引导时通过 SYSFS 装载 VF:

    [Unit]
    Before=
    [Service]
    Type=oneshot
    RemainAfterExit=true
    ExecStart=/bin/bash -c "echo 1 > /sys/bus/pci/devices/0000:06:00.1/sriov_numvfs"
    # beware, executable is run directly, not through a shell, check the man pages
    # systemd.service and systemd.unit for full syntax
    [Install]
    # target in which to start the service
    WantedBy=multi-user.target
    #WantedBy=graphical.target
  6. 在启动 VM 之前,需要创建指向 /etc/init.d/after.local 脚本(用于分离 NIC)的另一个服务文件 (after-local.service)。否则 VM 将无法启动:

    [Unit]
    Description=/etc/init.d/after.local Compatibility
    After=libvirtd.service
    Requires=libvirtd.service
    [Service]
    Type=oneshot
    ExecStart=/etc/init.d/after.local
    RemainAfterExit=true
    
    [Install]
    WantedBy=multi-user.target
  7. 将此文件复制到 /etc/systemd/system

    #! /bin/sh
    # ...
    virsh nodedev-detach pci_0000_06_08_0

    将它另存为 /etc/init.d/after.local

  8. 重引导计算机,然后根据本过程的第一步所述,重新运行 lspci 命令检查是否已装载 SR-IOV 驱动程序。如果已成功装载 SR-IOV 驱动程序,您应该会看到额外的 VF 行:

    01:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    01:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    01:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    01:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    [...]
    04:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    04:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    04:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    [...]

15.9.3 将 VF 网络设备添加到 VM Guest

在 VM 主机服务器上正确设置 SR-IOV 硬件后,便可将 VF 添加到 VM Guest。为此,您需要先收集一些数据。

过程 15.2︰ 将 VF 网络设备添加到现有 VM Guest

下面的过程使用的是示例数据。请务必将其替换为您设置中的相应数据。

  1. 使用 virsh nodedev-list 命令获取您要指派的 VF 的 PCI 地址及其对应的 PF。第 15.9.2 节 “装载和配置 SR-IOV 主机驱动程序”中所示的 lspci 输出中的数字值(例如 01:00.004:00.1)已经过转换:添加了前缀“pci_0000_”并将冒号和句点替换为下划线。因此,lspci 列出的 PCI ID“04:00.0”会被 virsh 列为“pci_0000_04_00_0”。下面的示例列出了 Intel 82576NS 网卡的第二个端口的 PCI ID:

    > sudo virsh nodedev-list | grep 0000_04_
    pci_0000_04_00_0
    pci_0000_04_00_1
    pci_0000_04_10_0
    pci_0000_04_10_1
    pci_0000_04_10_2
    pci_0000_04_10_3
    pci_0000_04_10_4
    pci_0000_04_10_5
    pci_0000_04_10_6
    pci_0000_04_10_7
    pci_0000_04_11_0
    pci_0000_04_11_1
    pci_0000_04_11_2
    pci_0000_04_11_3
    pci_0000_04_11_4
    pci_0000_04_11_5

    前两个项表示 PF,其他项表示 VF。

  2. 对您要添加的 VF 的 PCI ID 运行以下 virsh nodedev-dumpxml 命令:

    > sudo virsh nodedev-dumpxml pci_0000_04_10_0
    <device>
      <name>pci_0000_04_10_0</name>
      <parent>pci_0000_00_02_0</parent>
      <capability type='pci'>
        <domain>0</domain>
        <bus>4</bus>
        <slot>16</slot>
        <function>0</function>
        <product id='0x10ca'>82576 Virtual Function</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <capability type='phys_function'>
          <address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
        </capability>
      </capability>
    </device>

    下一步需要以下数据:

    • <domain>0</domain>

    • <bus>4</bus>

    • <slot>16</slot>

    • <function>0</function>

  3. 创建一个临时 XML 文件(例如 /tmp/vf-interface.xml),其中包含将 VF 网络设备添加到现有 VM Guest 所需的数据。该文件至少需包含如下所示的内容:

    <interface type='hostdev'>1
     <source>
      <address type='pci' domain='0' bus='11' slot='16' function='0'2/>2
     </source>
    </interface>

    1

    VF 的 MAC 地址不固定;每次重引导主机后,MAC 地址都会改变。使用 hostdev传统方式添加网络设备时,每次重引导主机后都需要重新配置 VM Guest 的网络设备,因为 MAC 地址会改变。为避免出现这种问题,libvirt 引入了 hostdev 值用于在指派设备之前设置网络特定的数据。

    2

    请在此处指定上一步中获取的数据。

  4. 如果设备已挂接到主机,则无法将它挂接到 VM Guest。要使该设备可供 Guest 使用,请先将它从主机分离:

    > sudo virsh nodedev-detach pci_0000_04_10_0
  5. 将 VF 接口添加到现有 VM Guest:

    > sudo virsh attach-device GUEST /tmp/vf-interface.xml --OPTION

    需将 GUEST 替换为 VM Guest 的域名、ID 或 UUID。--OPTION 可为下列其中一项:

    --persistent

    此选项始终将设备添加到域的永久性 XML 中。此外,如果域正在运行,则会热插入设备。

    --config

    此选项只影响永久性 XML,即使域正在运行也是如此。设备在下次引导后才会显示在 VM Guest 中。

    --live

    此选项只影响运行中的域。如果域处于非活动状态,则操作将会失败。设备不会永久保留在 XML 中,因此其下次引导后在 VM Guest 中将不可用。

    --current

    此选项影响域的当前状态。如果域处于非活动状态,设备将添加到永久性 XML 中,因此其下次引导后仍可用。如果域处于活动状态,则会热插入设备,但不会将其添加到永久性 XML 中。

  6. 要分离 VF 接口,请使用 virsh detach-device 命令,该命令也接受上面所列的选项。

15.9.4 动态分配池中的 VF

如果您按照第 15.9.3 节 “将 VF 网络设备添加到 VM Guest”中所述以静态方式在 VM Guest 的配置中定义了 VF 的 PCI 地址,此类 Guest 将很难迁移到另一台主机。该主机必须在 PCI 总线上的相同位置具有相同的硬件,否则每次启动之前都必须修改 VM Guest 配置。

另一种方法是使用一个包含 SR-IOV 设备所有 VF 的设备池创建 libvirt 网络。之后,VM Guest 将引用此网络,每次 VM Guest 启动时,系统都会向它动态分配单个 VF。当 VM Guest 停止时,该 VF 将返回到池中,可供其他 Guest 使用。

15.9.4.1 在 VM 主机服务器上使用 VF 池定义网络

下面的网络定义示例为 SR-IOV 设备创建了一个包含所有 VF 的池,该设备的物理功能 (PF) 位于主机中的网络接口 eth0 上:

<network>
  <name>passthrough</name>
    <forward mode='hostdev' managed='yes'>
      <pf dev='eth0'/>
    </forward>
  </network>

要在主机上使用此网络,请将上述代码保存到文件(例如 /tmp/passthrough.xml)中,然后执行以下命令。请记得将 eth0 替换为 SR-IOV 设备的 PF 的实际网络接口名称:

> sudo virsh net-define /tmp/passthrough.xml
> sudo virsh net-autostart passthrough
> sudo virsh net-start passthrough

15.9.4.2 将 VM Guest 配置为使用池中的 VF

下面的 VM Guest 设备接口定义示例使用第 15.9.4.1 节 “在 VM 主机服务器上使用 VF 池定义网络”中为 SR-IOV 设备创建的池中的某个 VF。Guest 首次启动时,libvirt 会自动派生与该 PF 关联的所有 VF 的列表。

<interface type='network'>
  <source network='passthrough'>
</interface>

在第一个使用以 VF 池定义的网络的 VM Guest 启动后,校验关联的 VF 列表。为此,请在主机上运行 virsh net-dumpxml passthrough

<network connections='1'>
  <name>passthrough</name>
  <uuid>a6a26429-d483-d4ed-3465-4436ac786437</uuid>
  <forward mode='hostdev' managed='yes'>
    <pf dev='eth0'/>
    <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>

15.10 列出挂接的设备

尽管 virsh 中没有任何机制可列出 VM 主机服务器中已挂接到其 VM Guest 的所有设备,但您可以通过运行以下命令列出已挂接到特定 VM Guest 的所有设备:

virsh dumpxml VMGUEST_NAME | xpath -e /domain/devices/hostdev

例如:

> sudo virsh dumpxml sles12 | -e xpath /domain/devices/hostdev
Found 2 nodes:
-- NODE --
<hostdev mode="subsystem" type="pci" managed="yes">
  <driver name="xen" />
  <source>
    <address domain="0x0000" bus="0x0a" slot="0x10" function="0x1" />
  </source>
  <address type="pci" domain="0x0000" bus="0x00" slot="0x0a" function="0x0" />
  </hostdev>
-- NODE --
<hostdev mode="subsystem" type="pci" managed="yes">
  <driver name="xen" />
  <source>
    <address domain="0x0000" bus="0x0a" slot="0x10" function="0x2" />
  </source>
  <address type="pci" domain="0x0000" bus="0x00" slot="0x0b" function="0x0" />
</hostdev>
提示
提示:列出通过 <interface type='hostdev'> 挂接的 SR-IOV 设备

对于通过 <interface type='hostdev'> 挂接到 VM 主机服务器的 SR-IOV 设备,需要使用不同的 XPath 查询:

virsh dumpxml VMGUEST_NAME | xpath -e /domain/devices/interface/@type

15.11 配置储存设备

储存设备在 disk 元素中定义。一般的 disk 元素支持多个属性。下面是两个最重要的属性:

  • type 属性描述虚拟磁盘设备的来源。有效值为 fileblockdirnetworkvolume

  • device 属性指示如何向 VM Guest 操作系统公开磁盘。例如,可能的值可能包括 floppydiskcdrom 等。

下面是最重要的子元素:

  • driver包含驱动程序和总线。VM Guest 使用驱动程序和总线来操作新磁盘设备。

  • target 元素包含新磁盘显示在 VM Guest 中时所用的设备名称。它还包含可选的总线属性,该属性定义用于操作新磁盘的总线的类型。

下面的过程说明如何将储存设备添加到 VM Guest:

  1. 编辑现有 VM Guest 的配置:

    > sudo virsh edit sles15
  2. disk 元素内部,连同属性 typedevice 一起添加 disk 元素:

    <disk type='file' device='disk'>
  3. 指定 driver 元素并使用默认值:

    <driver name='qemu' type='qcow2'/>
  4. 创建一个磁盘映像,用作新虚拟磁盘设备的来源:

    > sudo qemu-img create -f qcow2 /var/lib/libvirt/images/sles15.qcow2 32G
  5. 添加磁盘来源的路径:

    <source file='/var/lib/libvirt/images/sles15.qcow2'/>
  6. 定义 VM Guest 中的目标设备名以及用于操作磁盘的总线:

    <target dev='vda' bus='virtio'/>
  7. 重启动您的 VM:

    > sudo virsh start sles15

现在,新储存设备在 VM Guest 操作系统中应该可供使用。

15.12 配置控制器设备

一般情况下,libvirt 会根据 VM Guest 使用的虚拟设备类型自动管理控制器。如果 VM Guest 包含 PCI 和 SCSI 设备,libvirt 将自动创建并管理 PCI 和 SCSI 控制器。libvirt 还可为特定于超级管理程序的控制器(例如 KVM VM Guest 的 virtio-serial 控制器,或 Xen VM Guest 的 xenbus 控制器)建模。尽管默认控制器及其配置在一般情况下都可满足需求,但在某些用例中,需要手动调整控制器或其属性。例如,virtio-serial 控制器可能需要更多端口,或者 xenbus 控制器可能需要更多内存或更多虚拟中断。

Xenbus 控制器的独特之处在于,它充当着所有 Xen 半虚拟设备的控制器。如果 VM Guest 包含许多磁盘和/或网络设备,则控制器可能需要更多内存。Xen 的 max_grant_frames 属性设置要将多少授权帧或共享内存块分配给每个 VM Guest 的 xenbus 控制器。

默认值 32 在大多数情况下已够用,但包含大量 I/O 设备的 VM Guest 以及 I/O 密集型工作负载可能会由于授权帧耗尽而发生性能问题。可以使用 xen-diag 来检查 dom0 与 VM Guest 的当前和最大 max_grant_frames 值。VM Guest 必须正在运行:

> sudo virsh list
 Id   Name             State
--------------------------------
 0    Domain-0         running
 3    sle15sp1         running

 > sudo xen-diag gnttab_query_size 0
domid=0: nr_frames=1, max_nr_frames=256

> sudo xen-diag gnttab_query_size 3
domid=3: nr_frames=3, max_nr_frames=32

sle15sp1 Guest 仅使用了 32 个帧中的 3 个。如果您发现了性能问题并且有日志项指出帧数不足,请使用 virsh 增大该值。查看 Guest 配置文件中的 <controller type='xenbus'> 行,并添加 maxGrantFrames 控制元素:

> sudo virsh edit sle15sp1
 <controller type='xenbus' index='0' maxGrantFrames='40'/>

保存更改并重启动 Guest。现在,xen-diag 命令应该会显示您的更改:

> sudo xen-diag gnttab_query_size 3
domid=3: nr_frames=3, max_nr_frames=40

与 maxGrantFrames 类似,xenbus 控制器也支持 maxEventChannels。事件通道类似于半虚拟中断,它们与授权帧共同构成半虚拟驱动程序的数据传输机制。它们还用于处理器间的中断。包含大量 vCPU 和/或许多半虚拟设备的 VM Guest 可能需要增大最大默认值 1023。可以像更改 maxGrantFrames 那样更改 maxEventChannels:

> sudo virsh edit sle15sp1
 <controller type='xenbus' index='0' maxGrantFrames='128' maxEventChannels='2047'/>

有关详细信息,请参见 https://libvirt.org/formatdomain.html#elementsControllers 上 libvirt 的《Domain XML format》(域 XML 格式)手册中的“Controllers”(控制器)一节。

15.13 配置视频设备

使用虚拟机管理器时,只能定义视频设备型号。只能在 XML 配置中更改分配的 VRAM 量或 2D/3D 加速。

15.13.1 更改分配的 VRAM 量

  1. 编辑现有 VM Guest 的配置:

    > sudo virsh edit sles15
  2. 更改分配的 VRAM 大小:

    <video>
    <model type='vga' vram='65535' heads='1'>
    ...
    </model>
    </video>
  3. 通过查看虚拟机管理器中的数量来检查 VM 中的 VRAM 量是否已更改。

15.13.2 更改 2D/3D 加速状态

  1. 编辑现有 VM Guest 的配置:

    > sudo virsh edit sles15
  2. 要启用/禁用 2D/3D 加速,请相应地更改 accel3daccel2d 的值:

    <video>
     <model>
      <acceleration accel3d='yes' accel2d='no'>
     </model>
    </video>
提示
提示:启用 2D/3D 加速

只有 virtiovbox 视频设备支持 2D/3D 加速。无法在其他视频设备上启用此功能。

15.14 配置网络设备

本节介绍如何使用 virsh 配置虚拟网络设备的特定方面。

https://libvirt.org/formatdomain.html#elementsDriverBackendOptions 中提供了有关 libvirt 网络接口规范的更多细节。

15.14.1 使用多队列 virtio-net 提升网络性能

多队列 virtio-net 功能允许 VM Guest 的虚拟 CPU 并行传输包,因此可以提升网络性能。有关更多一般信息,请参见第 33.3.3 节 “使用多队列 virtio-net 提升网络性能”

要为特定的 VM Guest 启用多队列 virtio-net,请遵照第 15.1 节 “编辑 VM 配置”中所述编辑其 XML 配置,并按如下所示修改其网络接口:

<interface type='network'>
 [...]
 <model type='virtio'/>
 <driver name='vhost' queues='NUMBER_OF_QUEUES'/>
</interface>

15.15 使用 macvtap 共享 VM 主机服务器网络接口

使用 Macvtap 可将 VM Guest 虚拟接口直接挂接到主机网络接口。基于 macvtap 的接口扩展了 VM 主机服务器网络接口,它在相同以太网段上有自己的 MAC 地址。通常,使用此功能是为了使 VM Guest 和 VM 主机服务器都直接显示在 VM 主机服务器连接的交换机上。

注意
注意:Macvtap 不能与 Linux 网桥搭配使用

Macvtap 不能与已连接到 Linux 网桥的网络接口搭配使用。在尝试创建 macvtap 接口之前,请去除网桥中的接口。

注意
注意:使用 macvtap 在 VM Guest 与 VM 主机服务器之间通讯

使用 macvtap 时,一个 VM Guest 可与其他多个 VM Guest 通讯,并可与网络上的其他外部主机通讯。但是,该 VM Guest 无法与用于运行它的 VM 主机服务器通讯。这是规定的 macvtap 行为,原因与 VM 主机服务器物理以太网挂接到 macvtap 网桥的方式有关。从 VM Guest 进入该网桥并转发到物理接口的流量无法回弹到 VM 主机服务器的 IP 堆栈。同样,来自 VM 主机服务器 IP 堆栈并发送到物理接口的流量无法回弹到 macvtap 网桥以转发到 VM Guest。

libvirt 通过指定接口类型 direct 支持基于 macvtap 的虚拟网络接口。例如:

<interface type='direct'>
   <mac address='aa:bb:cc:dd:ee:ff'/>
   <source dev='eth0' mode='bridge'/>
   <model type='virtio'/>
   </interface>

可以使用 mode 属性控制 macvtap 设备的操作模式。下面的列表显示了该属性的可能的值以及每个值的说明:

  • vepa:将所有 VM Guest 包都发送到外部网桥。如果包的目标是某个 VM Guest,而该 VM Guest 所在的 VM 主机服务器与包的来源服务器相同,那么这些包将由支持 VEPA 的网桥(现今的网桥通常都不支持 VEPA)发回到该 VM 主机服务器。

  • bridge:将其目标与来源为同一 VM 主机服务器的包直接递送到目标 macvtap 设备。来源和目标设备需处于 bridge 模式才能直接递送。如果其中一个设备处于 vepa 模式,则需要使用支持 VEPA 的网桥。

  • private:将所有包都发送到外部网桥;仅当通过外部路由器或网关发送所有包,并且设备会将其发回到 VM 主机服务器时,才将所有包递送到同一 VM 主机服务器上的目标 VM Guest。如果来源或目标设备处于 private 模式,将遵循此过程。

  • passthrough:可为网络接口提供更强大的能力的一种特殊模式。将所有包转发到接口,并允许 virtio VM Guest 更改 MAC 地址或设置混杂模式,以桥接该接口或在该接口上创建 VLAN 接口。请注意,在 passthrough 模式下,网络接口不可共享。将某个接口指派到 VM Guest 会使其与 VM 主机服务器断开连接。出于此原因,在 passthrough 模式下常常会将 SR-IOV 虚拟功能指派到 VM Guest。

15.16 禁用内存气球设备

内存气球已成为 KVM 的默认选项。设备将显式添加到 VM Guest,因此您无需在 VM Guest 的 XML 配置中添加此元素。但是,如果您出于任何原因想要在 VM Guest 中禁用内存气球,需按如下所示设置 model='none'

<devices>
   <memballoon model='none'/>
</device>

15.17 配置多个监视器(双头)

libvirt 支持使用双头配置在多个监视器上显示 VM Guest 的视频输出。

重要
重要:不受 Xen 支持

Xen 超级管理程序不支持双头配置。

过程 15.3︰ 配置双头
  1. 当虚拟机正在运行时,校验 xf86-video-qxl 软件包是否已安装在 VM Guest 中:

    > rpm -q xf86-video-qxl
  2. 关闭 VM Guest,并按照第 15.1 节 “编辑 VM 配置”中所述开始编辑其 XML 配置。

  3. 校验虚拟显卡的型号是否为“qxl”:

    <video>
     <model type='qxl' ... />
  4. 将显卡型号规格中的 heads 参数从默认值 1 增大为 2,例如:

    <video>
     <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='2' primary='yes'/>
     <alias name='video0'/>
     <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </video>
  5. 将虚拟机配置为使用 Spice 显示器而不是 VNC:

    <graphics type='spice' port='5916' autoport='yes' listen='0.0.0.0'>
     <listen type='address' address='0.0.0.0'/>
    </graphics>
  6. 启动虚拟机并使用 virt-viewer 连接到其显示器,例如:

    > virt-viewer --connect qemu+ssh://USER@VM_HOST/system
  7. 在 VM 列表中,选择您已修改了其配置的 VM,并单击连接确认。

  8. 在 VM Guest 中装载图形子系统 (Xorg) 后,选择视图 › 显示器 › 显示器 2 打开一个新窗口,其中会显示第二个监视器的输出。

15.18 将 IBM Z 上的加密适配器直通到 KVM Guest

15.18.1 简介

IBM Z 计算机附带加密硬件以及一些实用的功能,例如生成随机数、生成数字签名或加密。KVM 允许将这些加密适配器作为直通设备专门用于 Guest。这意味着,超级管理程序无法观察 Guest 与设备之间的通讯。

15.18.2 本章内容

本章介绍如何将 IBM Z 主机上的加密适配器和域专用于 KVM Guest。该过程包括以下基本步骤:

  • 对主机上的默认驱动程序屏蔽加密适配器和域。

  • 装载 vfio-ap 驱动程序。

  • 将加密适配器和域指派到 vfio-ap 驱动程序。

  • 将 Guest 配置为使用加密适配器。

15.18.3 要求

  • QEMU/libvirt 虚拟化环境需已正确安装且正常运行。

  • 用于运行内核的 vfio_apvfio_mdev 模块需在主机操作系统上可用。

15.18.4 将加密适配器专用于 KVM 主机

  1. 校验 vfio_apvfio_mdev 内核模块是否已装载到主机上:

    > lsmod | grep vfio_

    如有任何一个模块未列出,请手动装载,例如:

    > sudo modprobe vfio_mdev
  2. 在主机上创建一个新的 MDEV 设备,并校验是否已添加该设备:

    uuid=$(uuidgen)
    $ echo ${uuid} | sudo tee /sys/devices/vfio_ap/matrix/mdev_supported_types/vfio_ap-passthrough/create
    dmesg | tail
    [...]
    [272197.818811] iommu: Adding device 24f952b3-03d1-4df2-9967-0d5f7d63d5f2 to group 0
    [272197.818815] vfio_mdev 24f952b3-03d1-4df2-9967-0d5f7d63d5f2: MDEV: group_id = 0
  3. 识别主机逻辑分区中您要专用于 KVM Guest 的设备:

    > ls -l /sys/bus/ap/devices/
    [...]
    lrwxrwxrwx 1 root root 0 Nov 23 03:29 00.0016 -> ../../../devices/ap/card00/00.0016/
    lrwxrwxrwx 1 root root 0 Nov 23 03:29 card00 -> ../../../devices/ap/card00/

    在此示例中,该设备是卡 0 队列 16。为了与硬件管理控制台 (HMC) 配置相匹配,需要将十六进制数 16 转换为十进制数 22

  4. 使用以下命令对 zcrypt 屏蔽适配器:

    > lszcrypt
    CARD.DOMAIN TYPE MODE STATUS REQUEST_CNT
    -------------------------------------------------
    00 CEX5C CCA-Coproc online 5
    00.0016 CEX5C CCA-Coproc online 5

    屏蔽适配器:

    > cat /sys/bus/ap/apmask
    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    echo -0x0 | sudo tee /sys/bus/ap/apmask
    0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

    屏蔽域:

    > cat /sys/bus/ap/aqmask
    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    echo -0x0 | sudo tee /sys/bus/ap/aqmask
    0xfffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  5. 将适配器 0 和域 16(十进制数 22)指派到 vfio-ap

    > sudo echo +0x0 > /sys/devices/vfio_ap/matrix/${uuid}/assign_adapter
    > echo +0x16 | sudo tee /sys/devices/vfio_ap/matrix/${uuid}/assign_domain
    > echo +0x16 | sudo tee /sys/devices/vfio_ap/matrix/${uuid}/assign_control_domain
  6. 校验配置的矩阵:

    > cat /sys/devices/vfio_ap/matrix/${uuid}/matrix
    00.0016
  7. 创建一个新 VM(参见第 10 章 “Guest 安装)并等待它初始化,或使用现有的 VM。对于这两种情况,请确保 VM 已关闭。

  8. 将 VM 的配置更改为使用 MDEV 设备:

    > sudo virsh edit VM_NAME
    [...]
    <hostdev mode='subsystem' type='mdev' model='vfio-ap'>
     <source>
      <address uuid='24f952b3-03d1-4df2-9967-0d5f7d63d5f2'/>
     </source>
    </hostdev>
    [...]
  9. 重启动 VM:

    > sudo virsh reboot VM_NAME
  10. 登录到 Guest 并校验该适配器是否存在:

    > lszcrypt
    CARD.DOMAIN TYPE MODE STATUS REQUEST_CNT
    -------------------------------------------------
    00 CEX5C CCA-Coproc online 1
    00.0016 CEX5C CCA-Coproc online 1

15.18.5 更多资料