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 主机上安装多个软件包。要安装所有必要的软件包,请执行以下操作:
校验是否已安装 yast2-vm 软件包。此软件包是 YaST 的配置工具,可以简化虚拟化超级管理程序的安装过程。
运行
› › 。图 33.1︰ 安装 KVM 超级管理程序和工具 #选择
,最好也选择 ,然后单击 确认。在安装过程中,您可以选择性地让 YaST 自动为您创建
。如果您不打算另外为虚拟 Guest 使用一块物理网卡,那么将 Guest 计算机连接到网络的标准方式就是使用网桥。图 33.2︰ 网桥 #安装所有所需的软件包(并激活新网络设置)后,尝试加载适用于 CPU 类型的 KVM 内核模块 —
kvm_intel
或kvm_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 消耗量。
以下过程列出了使用 qemu-system-ARCH
启用多队列功能的重要步骤。假设在 VM 主机服务器上设置了一个具有多队列功能(自内核版本 3.8 开始支持此功能)的 tap 网络设备。
在
qemu-system-ARCH
中,为该 tap 设备启用多队列:-netdev tap,vhost=on,queues=2*N
其中
N
表示队列对的数量。在
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(矢量量化)控制。
在 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 使用的所有权单元。
标识要分配到 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
)。确定此设备的 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从设备驱动程序取消绑定设备:
>
sudo
echo "0000:01:10.0" > /sys/bus/pci/devices/0000\:01\:10.0/driver/unbind使用步骤 1 中记下的供应商 ID 将设备绑定到 vfio-pci 驱动程序:
>
sudo
echo "8086 153a" > /sys/bus/pci/drivers/vfio-pci/new_id随即会创建一个新设备
/dev/vfio/IOMMU_GROUP
,在本例中为/dev/vfio/20
。更改新建设备的所有权:
>
sudo
chown qemu.qemu /dev/vfio/DEVICE现在,运行为其分配了 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
设备。
>
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
要导出的文件系统的标识。 | |
要导出的主机上的文件系统路径。 | |
要使用的安全模型 — | |
前面使用 | |
稍后要用来在 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,请执行以下操作。
尽管 SLES 在内核中包含了 KSM 支持,但其默认处于禁用状态。要启用该支持,请运行以下命令:
#
echo 1 > /sys/kernel/mm/ksm/run现在,请在 KVM 中运行多个 VM Guest,并检查
pages_sharing
和pages_shared
文件的内容,例如:>
while [ 1 ]; do cat /sys/kernel/mm/ksm/pages_shared; sleep 1; done 13522 13523 13519 13518 13520 13520 13528