跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文档 / 虚拟化指南 / 使用 QEMU 管理虚拟机 / 设置 KVM VM 主机服务器
适用范围 SUSE Linux Enterprise Server 15 SP6

33 设置 KVM VM 主机服务器

本节介绍如何设置并使用 SUSE Linux Enterprise Server 15 SP6 作为基于 QEMU-KVM 的虚拟机主机。

提示
提示:资源

虚拟 Guest 系统所需的硬件资源与将其安装在物理机上时所需的资源相同。您打算在主机系统上运行的 Guest 越多,需要添加到 VM 主机服务器的硬件资源(CPU、磁盘、内存和网络)就越多。

33.1 CPU 的虚拟化支持

要运行 KVM,您的 CPU 必须支持虚拟化,并且需要在 BIOS 中启用虚拟化。/proc/cpuinfo 文件包含有关 CPU 功能的信息。

要确定您的系统是否支持虚拟化,请参见第 7.1.1 节 “KVM 硬件要求”

33.2 所需的软件

需在 KVM 主机上安装多个软件包。要安装所有必要的软件包,请执行以下操作:

  1. 校验是否已安装 yast2-vm 软件包。此软件包是 YaST 的配置工具,可以简化虚拟化超级管理程序的安装过程。

  2. 运行 YaST › 虚拟化 › 安装超级管理程序和工具

    安装 KVM 超级管理程序和工具
    图 33.1︰ 安装 KVM 超级管理程序和工具
  3. 选择 KVM 服务器,最好也选择 KVM 工具,然后单击接受确认。

  4. 在安装过程中,您可以选择性地让 YaST 自动为您创建网桥。如果您不打算另外为虚拟 Guest 使用一块物理网卡,那么将 Guest 计算机连接到网络的标准方式就是使用网桥。

    网桥
    图 33.2︰ 网桥
  5. 安装所有所需的软件包(并激活新网络设置)后,尝试加载适用于 CPU 类型的 KVM 内核模块 — kvm_intelkvm_amd

    # modprobe kvm_intel

    检查该模块是否已加载到内存中:

    > lsmod | grep kvm
    kvm_intel              64835  6
    kvm                   411041  1 kvm_intel

    现在,KVM 主机即可为 KVM VM Guest 提供服务。有关更多信息,请参见第 35 章 “使用 qemu-system-ARCH 运行虚拟机

33.3 特定于 KVM 主机的功能

您可以让基于 KVM 的 VM Guest 充分使用 VM 主机服务器硬件的特定功能(半虚拟化),以此提高这些 Guest 的性能。本节将介绍可以通过哪些方法来使 Guest 直接访问物理主机的硬件(无需模拟层),以充分利用这些硬件。

提示
提示

本节中的示例假设读者基本了解 qemu-system-ARCH 命令行选项。有关详细信息,请参见第 35 章 “使用 qemu-system-ARCH 运行虚拟机

33.3.1 使用具有 virtio-scsi 的主机存储设备

virtio-scsi 是 KVM 的高级存储堆栈。它取代了以前用于 SCSI 设备直通的 virtio-blk 堆栈。与 virtio-blk 相比,它具有多项优势:

提高了可缩放性

KVM Guest 的 PCI 控制器数量有限,导致挂接的设备数量也受到限制。virtio-scsi 解决了这个限制,因为它可以将多个存储设备组合到单个控制器上。virtio-scsi 控制器上的每个设备以逻辑单元 (LUN) 表示。

标准命令集

virtio-blk 会使用 virtio-blk 驱动程序和虚拟机监控器均需识别的一小部分命令,因此引入新命令需要同时更新该驱动程序和监控器。

相比之下,virtio-scsi 并不定义命令,而是遵循行业标准 SCSI 规范为这些命令定义一个传输协议。此方法与光纤通道、ATAPI 和 USB 设备等其他技术共享。

设备命名

virtio-blk 设备在 Guest 中显示为 /dev/vdX,这与物理系统中的设备名称不同,可能导致迁移时出现问题。

virtio-scsi 会确保设备名称与物理系统上的名称相同,这样便可轻松重新定位虚拟机。

SCSI 设备直通

对于由主机上整个 LUN 提供支持的虚拟磁盘,最好让 Guest 直接向 LUN 发送 SCSI 命令(直通)。此功能在 virtio-blk 中受到限制,因为 Guest 需使用 virtio-blk 协议而不是 SCSI 命令直通,此外,此功能并不适用于 Windows Guest。virtio-scsi 原生消除了这些限制。

33.3.1.1 virtio-scsi 的用法

KVM 支持对 virtio-scsi-pci 设备使用 SCSI 直通功能:

# qemu-system-x86_64 [...] \
-device virtio-scsi-pci,id=scsi

33.3.2 使用 vhost-net 实现加速网络

vhost-net 模块用于加速 KVM 的半虚拟化网络驱动程序。它可提供更低的延迟和更高的网络吞吐量。通过以下示例命令行启动 Guest 即可使用 vhost-net 驱动程序:

# qemu-system-x86_64 [...] \
-netdev tap,id=guest0,vhost=on,script=no \
-net nic,model=virtio,netdev=guest0,macaddr=00:16:35:AF:94:4B

guest0 是 vhost 驱动的设备的标识字符串。

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

QEMU 提供了使用多队列提升网络性能的方式,来应对 VM Guest 中的虚拟 CPU 数量增加的情况。多队列 virtio-net 允许 VM Guest 的虚拟 CPU 并行传输包,因此可以提升网络性能。VM 主机服务器和 VM Guest 端都需要提供多队列支持。

提示
提示:性能优势

多队列 virtio-net 解决方案在以下情况下最有利:

  • 网络流量包较大。

  • VM Guest 上存在许多同时保持活动状态的连接,这些连接主要是在 Guest 系统之间、Guest 与主机之间,或者 Guest 与外部系统之间建立的。

  • 活动队列数量等于 VM Guest 中虚拟 CPU 的数量。

注意
注意

尽管多队列 virtio-net 可以增加总网络吞吐量,但由于使用了虚拟 CPU 的计算资源,因此也会增加 CPU 消耗量。

过程 33.1︰ 如何启用多队列 virtio-net

以下过程列出了使用 qemu-system-ARCH 启用多队列功能的重要步骤。假设在 VM 主机服务器上设置了一个具有多队列功能(自内核版本 3.8 开始支持此功能)的 tap 网络设备。

  1. qemu-system-ARCH 中,为该 tap 设备启用多队列:

    -netdev tap,vhost=on,queues=2*N

    其中 N 表示队列对的数量。

  2. qemu-system-ARCH 中,为 virtio-net-pci 设备启用多队列并指定 MSI-X(消息信号式中断)矢量:

    -device virtio-net-pci,mq=on,vectors=2*N+2

    在用于计算 MSI-X 矢量数量的公式中:N 个矢量用于 TX(传输)队列,N 个矢量用于 RX(接收)队列,一个矢量用于配置目的,一个矢量用于可能的 VQ(矢量量化)控制。

  3. 在 VM Guest 中的相关网络接口(在本示例中为 eth0)上启用多队列:

    > sudo ethtool -L eth0 combined 2*N

最终的 qemu-system-ARCH 命令行类似于以下示例:

qemu-system-x86_64 [...] -netdev tap,id=guest0,queues=8,vhost=on \
-device virtio-net-pci,netdev=guest0,mq=on,vectors=10

对于命令行中的两个选项,需指定相同的网络设备 id (guest0)。

在运行中的 VM Guest 内部,以 root 特权指定以下命令:

> sudo ethtool -L eth0 combined 8

现在,Guest 系统网络将使用 qemu-system-ARCH 超级管理程序的多队列支持。

33.3.4 VFIO:对设备进行安全的直接访问

将 PCI 设备直接分配到 VM Guest(PCI 直通)可以避免在性能关键型路径中进行任何模拟,从而避免性能问题。VFIO 取代了传统的 KVM PCI 直通设备分配。要使用此功能,VM 主机服务器配置必须符合重要:VFIO 和 SR-IOV 的要求中所述的要求。

要通过 VFIO 将 PCI 设备分配到 VM Guest,需要确定该设备属于哪个 IOMMU 组。IOMMU(用于将支持直接内存访问的 I/O 总线连接到主内存的输入/输出内存管理单元)API 支持组表示法。组是可与系统中的所有其他设备相互隔离的一组设备。因此,组是 VFIO 使用的所有权单元。

过程 33.2︰ 通过 VFIO 将 PCI 设备分配到 VM Guest
  1. 标识要分配到 Guest 的主机 PCI 设备。

    > sudo lspci -nn
    [...]
    00:10.0 Ethernet controller [0200]: Intel Corporation 82576 \
    Virtual Function [8086:10ca] (rev 01)
    [...]

    记下设备 ID(在本例中为 00:10.0)和供应商 ID (8086:10ca)。

  2. 确定此设备的 IOMMU 组:

    > sudo readlink /sys/bus/pci/devices/0000\:00\:10.0/iommu_group
    ../../../kernel/iommu_groups/20

    此设备的 IOMMU 组为 20。现在,您可以检查该设备是否属于同一个 IOMMU 组:

    > sudo ls -l /sys/bus/pci/devices/0000\:01\:10.0/iommu_group/devices/
    [...] 0000:00:1e.0 -> ../../../../devices/pci0000:00/0000:00:1e.0
    [...] 0000:01:10.0 -> ../../../../devices/pci0000:00/0000:00:1e.0/0000:01:10.0
    [...] 0000:01:10.1 -> ../../../../devices/pci0000:00/0000:00:1e.0/0000:01:10.1
  3. 从设备驱动程序取消绑定设备:

    > sudo echo "0000:01:10.0" > /sys/bus/pci/devices/0000\:01\:10.0/driver/unbind
  4. 使用步骤 1 中记下的供应商 ID 将设备绑定到 vfio-pci 驱动程序:

    > sudo echo "8086 153a" > /sys/bus/pci/drivers/vfio-pci/new_id

    随即会创建一个新设备 /dev/vfio/IOMMU_GROUP,在本例中为 /dev/vfio/20

  5. 更改新建设备的所有权:

    > sudo chown qemu.qemu /dev/vfio/DEVICE
  6. 现在,运行为其分配了 PCI 设备的 VM Guest。

    > sudo qemu-system-ARCH [...] -device
         vfio-pci,host=00:10.0,id=ID
重要
重要:不支持热插拔

SUSE Linux Enterprise Server 15 SP6 开始,不支持热插拔通过 VFIO 传递给 VM Guest 的 PCI 设备。

/usr/src/linux/Documentation/vfio.txt 文件中提供了有关 VFIO 驱动程序的更详细信息(需要安装软件包 kernel-source)。

33.3.5 VirtFS:在主机与 Guest 之间共享目录

VM Guest 通常在单独的计算空间中运行 — 它们各自都有自己的内存范围、专用的 CPU 和文件系统空间。能够共享 VM 主机服务器文件系统的某些部分,就能通过简化相互数据交换来提高虚拟化环境的灵活性。网络文件系统(例如 CIFS 和 NFS)是传统的共享目录方式,但由于它们不是专为虚拟化目的而设计,因此会有重大的性能和功能问题。

KVM 引入了一种经过优化的新方法,称为 VirtFS(有时称为文件系统直通)。VirtFS 使用半虚拟文件系统驱动程序,可以避免将 Guest 应用程序文件系统操作转换为块设备操作,然后又将块设备操作转换为主机文件系统操作。

VirtFS 通常可用于以下情况:

  • 要从多个 Guest 访问共享目录,或者提供 Guest 到 Guest 的文件系统访问。

  • 在 Guest 引导过程中,要将虚拟磁盘替换为 Guest 的 RAM 磁盘所要连接到的根文件系统。

  • 要从云环境中的单个主机文件系统为不同的客户提供存储服务。

33.3.5.1 实施

在 QEMU 中,可以通过定义两种类型的服务来简化 VirtFS 的实现:

  • 用于在主机与 Guest 之间传输协议消息和数据的 virtio-9p-pci 设备。

  • 用于定义导出文件系统属性(例如文件系统类型和安全模型)的 fsdev 设备。

例 33.1︰ 使用 VirtFS 导出主机的文件系统
> sudo qemu-system-x86_64 [...] \
-fsdev local,id=exp11,path=/tmp/2,security_model=mapped3 \
-device virtio-9p-pci,fsdev=exp14,mount_tag=v_tmp5

1

要导出的文件系统的标识。

2

要导出的主机上的文件系统路径。

3

要使用的安全模型 — mapped 可使 Guest 文件系统模式和权限与主机相互隔离,而 none 会调用直通安全模型,其中,对 Guest 文件进行的权限更改也会反映在主机上。

4

前面使用 -fsdev id= 定义的已导出文件系统 ID。

5

稍后要用来在 Guest 上挂载所导出文件系统的挂载标记。

可按如下所示在 Guest 上挂载此类导出的文件系统:

> sudo mount -t 9p -o trans=virtio v_tmp /mnt

其中,v_tmp 是前面使用 -device mount_tag= 定义的挂载标记,/mnt 是要将导出的文件系统挂载到的挂载点。

33.3.6 KSM:在 Guest 之间共享内存页

内核同页合并 (KSM) 是 Linux 内核的一项功能,可将多个运行中进程的相同内存页合并到一个内存区域中。由于 KVM Guest 在 Linux 中以进程的形式运行,KSM 为超级管理程序提供了内存过量使用功能,以提高内存的使用效率。因此,如果您需要在内存有限的主机上运行多个虚拟机,KSM 可能有所帮助。

KSM 将其状态信息存储在 /sys/kernel/mm/ksm 目录下的文件中:

> ls -1 /sys/kernel/mm/ksm
full_scans
merge_across_nodes
pages_shared
pages_sharing
pages_to_scan
pages_unshared
pages_volatile
run
sleep_millisecs

有关 /sys/kernel/mm/ksm/* 文件含义的详细信息,请参见 /usr/src/linux/Documentation/vm/ksm.txt(软件包 kernel-source)。

要使用 KSM,请执行以下操作。

  1. 尽管 SLES 在内核中包含了 KSM 支持,但其默认处于禁用状态。要启用该支持,请运行以下命令:

    # echo 1 > /sys/kernel/mm/ksm/run
  2. 现在,请在 KVM 中运行多个 VM Guest,并检查 pages_sharingpages_shared 文件的内容,例如:

    > while [ 1 ]; do cat /sys/kernel/mm/ksm/pages_shared; sleep 1; done
    13522
    13523
    13519
    13518
    13520
    13520
    13528