使用 KVM 的嵌套虚拟化:嵌套虚拟化中的 qemu 中的 -enable-kvm

nested virtualization with KVM: -enable-kvm in qemu in nested virtualization

在我已经虚拟化的主机中,尝试将选项传递给选项 -enable-kvm -m 1024,将会失败:

qemu-system-x86_64  -vga std -enable-kvm -m 1024   -monitor telnet:localhost:9313,server,nowait -drive file=my_img.img,cache=none
# Could not access KVM kernel module: No such file or directory
# failed to initialize KVM: No such file or directory

如果我删除该选项 -enable-kvm -m 1024,qemu 将加载(但它将永远加载,因为它使用的是软件仿真):

qemu-system-x86_64  -vga std  -monitor telnet:localhost:9313,server,nowait -drive file=my_img.img,cache=none
# qemu running, OK, but image taking forever to load.

当然,我的这台虚拟主机有嵌套自己虚拟化的能力。我到处都可以找到有关它的信息 [像这里: https://docs.openstack.org/developer/devstack/guides/devstack-with-nested-kvm.html ] 告诉我必须检查文件 /sys/module/kvm_intel/parameters/nested 根本不可用,因为 kvm-intel 不是也不能加载从图像内部:

sudo modprobe  kvm-intel
# modprobe: ERROR: could not insert 'kvm_intel': Operation not supported

可能这种调试嵌套虚拟化的方法只适用于裸机。 那么,如何从 kvm 内部启用(转发支持)kvm?

附加信息:

lscpu # from inside the virtualized host
# Architecture:          x86_64
# ...
# Vendor ID:             GenuineIntel
# CPU family:            6
# Model:                 13
# Model name:            QEMU Virtual CPU version (cpu64-rhel6)
# Stepping:              3 
# ...
# Hypervisor vendor:     KVM

ltrace 的 qemu:

# open64("/dev/kvm", 524290, 00)                   = -1
# __errno_location()                               = 0x7f958673c730
# __fprintf_chk(0x7f957fd81060, 1, 0x7f9586474ce0, 0Could not access KVM kernel module: No such file or directory

要测试 kvm 支持是否在当前主机中启用(即它在虚拟机中工作),请执行以下操作:

grep -E "(vmx|svm)" /proc/cpuinfo 
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 popcnt aes xsave avx f16c lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs xop skinit wdt lwp fma4 tce tbm topoext perfctr_core perfctr_nb arat cpb hw_pstate npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold vmmcall bmi1

问题中:

grep -E "(vmx|svm)" /proc/cpuinfo | wc -l 
0

表示支持被禁用,enable-kvm将无法使用。需要在裸机中执行操作。

默认情况下,Linux KVM 已禁用嵌套虚拟化支持。

您必须 enable it in the host 最外层的 VM(在您的问题中,您尝试在最外层的 VM 内执行此操作)。例如,对于英特尔 CPU:

# rmmod kvm_intel
# modprobe kvm_intel nested=1

验证(在最外层虚拟机的主机上):

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

(AMD 的 KVM 模块毫不奇怪地称为 kvm_amd。)

可以通过将配置文件拖放到 /etc/modprobe.d 中永久启用嵌套。

这是嵌套虚拟化的必要条件。除此之外,您需要通过提供正确的 CPU 参数在最外层的 VM 中 tell QEMU to enable virtualization support,例如:

-cpu host

或更具体的内容,例如:

-cpu Haswell-noTSX-IBRS,vmx=on

在最外层的 VM 中,您可以通过以下方式验证虚拟化支持:

$ grep -o 'vmx\|svm' /proc/cpuinfo
$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used