KVM
KVM, Kernel-based Virtual Machine,是 Linux 内核内置的虚拟机监视器。它的目的与 Xen 相似,但运行起来要简单得多。与使用模拟的原生 QEMU 不同,KVM 是 QEMU 的一种特殊操作系统模式,它利用 CPU 扩展(HVM)通过内核模块进行虚拟化。
使用 KVM,可以运行多个未修改的 GNU/Linux、Windows 或任何其他操作系统的虚拟机。(有关更多信息,请参阅 Guest Support Status)。每个虚拟机都有私有的虚拟化硬件:网卡、磁盘、显卡等。
KVM 与 Xen、VMware 或 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。
内核支持
Arch Linux 内核提供了支持 KVM 所需的 内核模块。
- 可以使用以下命令检查内核中是否可用必要的模块:
kvm和kvm_amd或kvm_intel:
$ zgrep CONFIG_KVM= /proc/config.gz
仅当模块设置为 y 或 m 时,才表示模块可用。
- 然后,使用以下命令确保内核模块已自动加载:
$ 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
如果命令返回空,则需要手动加载模块;请参阅 Kernel modules#Manual module handling。
kvm_intel 或 kvm_amd 模块加载失败但 kvm 模块加载成功,并且 lscpu 声称支持硬件加速,请检查 BIOS 设置。某些供应商,尤其是笔记本电脑供应商,默认禁用这些处理器扩展。为了确定是没有硬件支持还是 BIOS 中禁用了扩展,失败的模块加载后 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。
技巧与提示
嵌套虚拟化
嵌套虚拟化允许在第三方虚拟机监视器和云上运行现有的虚拟机,而无需对原始虚拟机或其网络进行任何修改。
在宿主机上,为 kvm_intel 启用嵌套功能:
intel 替换为 amd 即可。# modprobe -r kvm_intel # modprobe kvm_intel nested=1
使其永久生效(请参阅 Kernel modules#Setting module options):
/etc/modprobe.d/kvm_intel.conf
options kvm_intel nested=1
验证功能是否已激活:
$ cat /sys/module/kvm_intel/parameters/nested
Y
启用“宿主机直通”(host passthrough)模式,将所有 CPU 功能转发给虚拟机:
- 如果使用 QEMU,请使用以下命令运行虚拟机:
qemu-system-x86_64 -enable-kvm -cpu host。 - 如果使用 virt-manager,请将 CPU 模型更改为
host-passthrough。 - 如果使用 virsh,请使用
virsh edit vm-name并将 CPU 行更改为<cpu mode='host-passthrough' check='partial'/>。
启动虚拟机并检查 vmx 标志是否存在:
$ grep -E --color=auto 'vmx|svm' /proc/cpuinfo
启用巨型页面
您可能还想启用巨型页面以提高虚拟机的性能。对于最新的 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
如果数字较小,请关闭一些应用程序或使用较少的内存启动您的虚拟机(number_of_pages 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
参见
安全启动
KVM 安全启动在启用之前有一些要求:
- 您必须使用支持安全启动的 UEFI 进行编译。
- UEFI 必须已注册密钥。
要启用支持安全启动的 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 和 Red Hat 的安全启动密钥。安装 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 来进行双重检查。