KVM in KVM
Objectif
Il s'agit de pouvoir exécuter une machine virtuelle de type KVM, à l'intérieur d'une première machine virtuelle (KVM, elle aussi).
Un des avantages de cette idée est de pouvoir développer et tester des hyperviseurs comme des machines virtuelles classiques.
Problème
Pas vraiment de difficulté, il suffit d'avoir du matériel et un noyau relativement récent.
Environnement de départ
- une machine physique alpha (avec processeur Intel) - noyau 4.6 (jessie-backports) - libvirt (jessie-backports)
Environnement cible
- une VM hostkvm (créée depuis l'hyperviseur), avec un environnement libvirt / qemu
- une VM guestkvm (créée depuis hostkvm)
Étapes
Afin de pouvoir créer une VM KVM depuis une première VM, il suffit simplement de s'assurer que la bonne configuration du paramètre:
- /sys/module/kvm_intel/parameters/nested
- /sys/module/kvm_amd/parameters/nested
Donc première chose à faire (à adapter au type de processeur utilisé):
$ cat /sys/modules/kvm_intel/parameters/nested Y
Si la réponse est N (ou 0), il faudra recharger le module en définissant cette option à 1 (ou Y). Cela peut être fait:
-
soit en paramètre de démarrage du noyau: kvm-intel.nested=1 (suivit d'un redémarrage de la machine)
-
soit en option pour modprobe:
# rmmod kvm-intel # echo "options kvm-intel nested=y" > /etc/modprobe.d/kvm.conf # modprobe kvm-intel
Si la réponse au test est toujours négative c'est que votre noyau / distribution / plateforme matérielle est trop ancien(ne).
Lorsque l'option est activée, il suffit de créer sa première VM (hostkvm) avec l'option:
<cpu mode="host-passthrough"></cpu>
Ainsi, en employant l'outil de création de VM virt-install et le paramètre --cpu host-passthrough, cela donne:
# hostname alpha # virt-install --name hostkvm --cpu host-passthrough --ram 4096 --location http://ftp.fr.debian.org/debian/dists/jessie/main/installer-amd64/ --disk size=5 --os-variant debianwheezy --console "pty,target_type=serial" --extra-args="console=ttyS0,115200n8 serial" --network bridge=virbr0
L'option existe de manière similaire au travers de l'interface graphique virt-manager.
On se connecte à la VM par ssh ou directement sur la console, on configure rapidement un environnement libvirt, et on crée la VM guestkvm:
# hostname hostkvm # apt-get install ebtables libvirt-bin virtinst # virsh net-start default # virt-install --name guestkvm --ram 512 --location http://ftp.fr.debian.org/debian/dists/jessie/main/installer-amd64/ --disk size=1 --os-variant debianwheezy --console "pty,target_type=serial" --extra-args="console=ttyS0,115200n8 serial" --network bridge=virbr0
La seconde installation se réalise, et l'on peut vérifier à partir des diverses machines qui est contenue par qui:
# hostname alpha # virsh list Id Name State ---------------------------------------------------- 4 hostkvm running # ps aux | grep kvm libvirt+ 20564 9.7 1.7 3209864 569788 ? Sl 22:39 1:29 qemu-system-x86_64 -enable-kvm -name hostkvm -S -machine pc-i440fx-2.1,accel=kvm,usb=off -cpu host -m 4096 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 43642e0a-1022-4136-b8cd-d3b33747ded8 -nographic -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/hostkvm.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=discard -no-hpet -no-shutdown -boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x3.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x3 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x3.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x3.0x2 -drive file=/var/lib/libvirt/images/hostkvm-1.qcow2,if=none,id=drive-virtio-disk0,format=qcow2 -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -netdev tap,fd=24,id=hostnet0,vhost=on,vhostfd=25 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:d2:62:90,bus=pci.0,addr=0x2 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -msg timestamp=on
Sur la machine alpha, libvirt contrôle une VM d'identifiant 4 et nommée hostkvm. Une recherche parmi les processus d'alpha ne montre la présence que d'un seul processus 20564, nommé hostkvm (avec kvm et 4096Mo de RAM).
# hostname hostkvm # virsh list Id Name State ---------------------------------------------------- 3 guestkvm running # ps aux | grep kvm libvirt+ 8693 59.0 15.0 951028 76064 ? Sl 23:08 3:08 qemu-system-x86_64 -enable-kvm -name guestkvm -S -machine pc-i440fx-2.1,accel=kvm,usb=off -cpu Broadwell -m 512 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 7e5df8a8-7764-4dbb-a854-536fe4d6cce6 -nographic -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/guestkvm.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=discard -no-hpet -no-shutdown -boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x3.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x3 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x3.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x3.0x2 -drive file=/var/lib/libvirt/images/guestkvm.qcow2,if=none,id=drive-virtio-disk0,format=qcow2 -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -netdev tap,fd=24,id=hostnet0,vhost=on,vhostfd=25 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:ed:c3:19,bus=pci.0,addr=0x2 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -msg timestamp=on
Sur la machine hostkvm, libvirt contrôle une VM d'identifiant 3 et nommée guestkvm. Une recherche parmi les processus d'hostkvm ne montre la présence que d'un seul processus 8693, nommé guestkvm (avec kvm et 512Mo de RAM).