跳转至内容

KVM

来自 ArchWiki

KVM,即 基于内核的虚拟机 (Kernel-based Virtual Machine),是一个内置在 Linux 内核中的 虚拟机管理程序 (hypervisor)。它的目的与 Xen 类似,但运行起来要简单得多。与使用模拟的原生 QEMU 不同,KVM 是 QEMU 的一种特殊运行模式,它通过内核模块利用 CPU 扩展 (HVM) 来实现虚拟化。

使用 KVM,可以运行多个运行未经修改的 GNU/Linux、Windows 或任何其他操作系统的虚拟机。(更多信息请参阅 客户机支持状态。)每个虚拟机都拥有私有的虚拟化硬件:网卡、磁盘、显卡等。

KVM 与 XenVMware 或 QEMU 之间的区别可以在 KVM FAQ 中找到。

本文不涵盖多个使用 KVM 作为后端的模拟器的共同功能。此类信息请参阅相关文章。

检查 KVM 支持

硬件支持

KVM 要求虚拟机宿主机的处理器具有虚拟化支持(Intel 处理器称为 VT-x,AMD 处理器称为 AMD-V)。您可以使用以下命令检查处理器是否支持硬件虚拟化:

$ LC_ALL=C.UTF-8 lscpu | grep Virtualization

或者

$ grep -E --color=auto 'vmx|svm|0xc0f' /proc/cpuinfo

如果在运行任一命令后没有任何显示,那么您的处理器不支持硬件虚拟化,您将无法使用 KVM。

注意 您可能需要在 BIOS 中启用虚拟化支持。过去 10 年内由 AMD 和 Intel 制造的所有 x86_64 处理器都支持虚拟化。如果您的处理器看起来不支持虚拟化,那么几乎可以肯定是在 BIOS 中被关闭了。

内核支持

Arch Linux 内核提供了支持 KVM 所需的 内核模块

  • 可以使用以下命令检查内核中是否可用必要的模块 kvm 以及 kvm_amdkvm_intel
$ zgrep CONFIG_KVM= /proc/config.gz

仅当模块被设置为 ym 时,该模块才可用。

  • 然后,使用以下命令确保内核模块被自动加载:
$ lsmod | grep kvm
kvm_intel             245760  0
kvmgt                  28672  0
mdev                   20480  2 kvmgt,vfio_mdev
vfio                   32768  3 kvmgt,vfio_mdev,vfio_iommu_type1
kvm                   737280  2 kvmgt,kvm_intel
irqbypass              16384  1 kvm

如果命令没有返回任何内容,则需要手动加载模块;请参阅 内核模块#手动模块处理

提示 如果 modprobe kvm_intelkvm_amd 失败,但 modprobe kvm 成功,且 lscpu 声称支持硬件加速,请检查 BIOS 设置。某些厂商(尤其是笔记本电脑厂商)默认禁用这些处理器扩展。要确定是没有硬件支持还是在 BIOS 中被禁用,可以通过 modprobe 失败后的 dmesg 输出得出结论。

使用 Virtio 的半虚拟化

半虚拟化为客户机使用宿主机上的设备提供了一种快速且高效的通信手段。KVM 使用 Virtio API 作为管理程序和客户机之间的层,为虚拟机提供半虚拟化设备。

所有 Virtio 设备都由两部分组成:宿主机设备和客户机驱动程序。

内核支持

虚拟机内部使用以下命令检查内核中是否可用 VIRTIO 模块:

$ zgrep VIRTIO /proc/config.gz

然后,使用以下命令检查内核模块是否被自动加载:

$ lsmod | grep virtio

如果上述命令没有返回任何内容,您需要手动 加载内核模块

半虚拟化设备列表

  • 网络设备 (virtio-net)
  • 块设备 (virtio-blk)
  • 控制器设备 (virtio-scsi)
  • 串口设备 (virtio-serial)
  • 气球设备 (virtio-balloon)

如何使用 KVM

请参阅主文章:QEMU

技巧与提示

注意 请参阅 QEMU#技巧与诀窍QEMU/故障排除 以获取通用技巧。

嵌套虚拟化

嵌套虚拟化允许现有的虚拟机在第三方管理程序和其他云平台上运行,而无需对原始虚拟机及其网络进行任何修改。

在宿主机上,为 kvm_intel 启用嵌套功能:

注意 AMD 也可以执行相同的操作,只需在必要处将 intel 替换为 amd
# modprobe -r kvm_intel
# modprobe kvm_intel nested=1

要使其永久生效(请参阅 内核模块#设置模块选项):

/etc/modprobe.d/kvm_intel.conf
options kvm_intel nested=1

验证功能是否已激活:

$ cat /sys/module/kvm_intel/parameters/nested
Y

启用“主机透传 (host passthrough)”模式,将所有 CPU 功能转发给客户机系统。

  1. 如果使用 QEMU,请使用以下命令运行客户虚拟机:qemu-system-x86_64 -enable-kvm -cpu host
  2. 如果使用 virt-manager,将 CPU 型号更改为 host-passthrough
  3. 如果使用 virsh,请使用 virsh edit vm-name 并将 CPU 行更改为 <cpu mode='host-passthrough' check='partial'/>

启动虚拟机并检查是否存在 vmx 标志。

$ grep -E --color=auto 'vmx|svm' /proc/cpuinfo

启用大页 (Huge pages)

本文或本节可能是合并到 QEMU 的候选。

注:qemu-kvm 已不再存在。在上述问题解决后,我建议将此节合并到 QEMU 中。(在 Talk:KVM 中讨论)

您可能还希望启用大页以提高虚拟机的性能。在更新的 Arch Linux 和运行中的 KVM 中,您可能已经拥有了所需的一切。检查是否有 /dev/hugepages 目录。如果没有,请创建它。现在我们需要正确的权限来使用此目录。默认权限是 root 的 uid 和 gid 且为 0755,但我们希望 kvm 组中的任何人都能访问大页。

添加到您的 /etc/fstab

/etc/fstab
hugetlbfs       /dev/hugepages  hugetlbfs       mode=01770,gid=kvm        0 0

除了直接使用 gid=kvm 指定组名外,您当然也可以将 gid 指定为数字,但它必须与 kvm 组匹配。1770 模式允许组内的任何人创建文件,但不能删除或重命名彼此的文件。确保 /dev/hugepages 已正确挂载。

# umount /dev/hugepages
# mount /dev/hugepages
$ mount | grep huge
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,mode=1770,gid=78)

现在您可以计算需要多少个大页。检查大页的大小:

$ grep Hugepagesize /proc/meminfo

通常应该是 2048 kB ≙ 2 MB。假设您想以 1024 MB 运行虚拟机。1024 / 2 = 512。多加几个,我们可以将其四舍五入到 550。现在告诉您的机器您想要多少个大页:

# sysctl -w vm.nr_hugepages=550

如果您有足够的空闲内存,您应该会看到:

$ grep HugePages_Total /proc/meminfo
HugesPages_Total:  550

如果数字较小,请关闭一些应用程序或以较少的内存(页数 x 2)启动虚拟机。

$ qemu-system-x86_64 -enable-kvm -m 1024 -mem-path /dev/hugepages -hda <disk_image> [...]

请注意 -mem-path 参数。这将利用大页。

现在您可以在虚拟机运行时检查使用了多少页:

$ grep HugePages /proc/meminfo
HugePages_Total:     550
HugePages_Free:       48
HugePages_Rsvd:        6
HugePages_Surp:        0

既然一切运行正常,如果您愿意,可以默认启用大页。添加到您的 /etc/sysctl.d/40-hugepage.conf

/etc/sysctl.d/40-hugepage.conf
vm.nr_hugepages = 550

参见

安全启动

本文或此章节是与 QEMU#启用安全启动 合并的候选对象。

注:这并非 KVM 特有,将是对那里已描述内容的极佳补充。(在 Talk:KVM 中讨论)

KVM 安全启动在启用前有几个要求:

  1. 您必须使用编译了安全启动支持的 UEFI。
  2. UEFI 必须已注册密钥。
注意 与 Fedora 等发行版不同,Arch Linux 目前没有安全启动密钥。如果您打算对 Arch Linux 进行安全启动,必须在执行以下步骤后创建自己的签名密钥并为内核签名。更多信息请参阅 统一可扩展固件接口/安全启动

要启用支持安全启动的 UEFI,请安装 edk2-ovmf 并将您的虚拟机设置为使用启用了安全启动的 UEFI。如果您使用 libvirt,可以通过在虚拟机的 XML 配置中添加以下内容来实现。

<os firmware="efi">
  <loader readonly="yes" secure="yes" type="pflash">/usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd</loader>
</os>

接下来您需要注册一些密钥。在本例中,我们将注册 Microsoft 和 Redhat 的安全启动密钥。安装 virt-firmware 并运行以下命令。将 vm_name 替换为您的虚拟机名称。

$ virt-fw-vars --input /usr/share/edk2/x64/OVMF_VARS.4m.fd --output /var/lib/libvirt/qemu/nvram/vm_name_SECURE_VARS.fd --secure-boot --enroll-redhat

然后编辑虚拟机的 libvirt XML 配置,使其指向新的 VARS 文件。

<os firmware="efi">
  <loader readonly="yes" secure="yes" type="pflash">/usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd</loader>
  <nvram template="/usr/share/edk2/x64/OVMF_VARS.4m.fd">/var/lib/libvirt/qemu/nvram/{vm-name}_SECURE_VARS.fd</nvram>
</os>

在此之后,安全启动应该会自动启用。您可以通过在看到 UEFI 启动标志时按下 F2 进入虚拟机的 BIOS 来双重确认。

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.