Ce howto est principalement destiné aux membres d'Éfrei-Linux, mais peut cependant et je l'espère servir à beaucoup d'autres personnes qui souhaiteraient mettre en place des machines virtuelles sur un serveur grâce à KVM. Le but est de donner la possibilité à certains utilisateurs de créer des machines virtuelles sans avoir recours à des droits root (sudo par exemple).
Premièrement un serveur sur lequel il est possible de faire de la virtualisation, dans notre cas il s'agit d'Impalor. Sur ce dernier nous aurons besoin de certain paquets.
root$ aptitude install qemu kvm bridge-utils uml-utilities
Détaillons un peu le fonctionnement global du système de virtualisation utilisé ici.
Qemu est un emulateur d'architecture. Il peut simuler des architecture comme MIPS, SPARC, … ou encore X86 (architecture qui nous intéresse dans ce cas). Il peut faire appel à des modules pour exécuter les instructions de la machine virtuelle.
KVM (Kernel based Virtual Machine) est quand à lui un module de Linux qui permet d'utiliser les instructions de virtualisation des processeurs Intel et AMD. Le but étant d'augmenter fortement les performances comparé à une pure emulation. Cependant il est nécessaire de posséder un processeur supportant ces instructions (vmx pour Intel et svm pour AMD).
Ces paquets contiennent la commande tunctl et brctl très importantes dans le cas où vous souhaitez relier les VM au reste du réseau. Elles nous permettrons de créer un bridge et des interfaces virtuelles raccordées à ce bridge.
Voici maintenant les manipulations à effectuer.
Maintenant que les paquets nécessaires sont installé, il ne reste quelques petites choes à faire sur le système.
root$ modprobe kvm-intel
Ou bien si vous avez un processeur AMD:
root$ modprobe kvm-amd
Ici plusieurs possibilités se présentent à nous. Soit donner les droits à tout le monde d'utilisé ce device:
root$ chmod 666 /dev/net/tun
Soit on change le groupe propriétaire de ce device de sorte à ce que seul les utilisateurs de ce groupe est le droit d'utiliser les interfaces TUN/TAP:
root$ chgrp kvm /dev/net/tun
Nous avons choisi d'utiliser cette solution. Le groupe choisi est le groupe KVM car les utilisateurs de ce groupe sont sensés utiliser ces interfaces. pour faire en sorte que ces droits soit toujours bon au prochain démarrage de la machine il faut modifier les regles de UDEV. Nous créons donc le fichier ”/etc/udev/rules.d/80-persistent-tun.rules” dans lequel se trouve la ligne suivante:
KERNEL=="tun", NAME="net/%k", GROUP="kvm"
Cette étape nous permettra de connecter les VM au réseau sur lequel est connectée le serveur hôte. Plusieurs possibilités, le faire à la main ou l'automatiser. Nous éditons donc le fichier ”/etc/network/interfaces” dans lequel on trouve:
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback auto eth0 br0 iface eth0 inet manual iface br0 inet dhcp bridge_ports eth0 regex v_.* noregex bridge_maxwait 2 bridge_fd 4
Ainsi le bridge br0 sera monté automatiquement au démarrage et ajoutera eth0 et toutes les interfaces correspondantes à la regex au bridge.
Enfin la dernière chose à faire est de créer les interfaces virtuelles qui vont servir aux utilisateurs finaux. Cette fois encore plusieurs possibilités. Voici l'exemple pour que l'utilisateur john est une interface virtuelle à sa disposition sur le serveur.
Nous éditons donc le fichier ”/etc/network/interfaces” dans lequel on trouve:
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback # Interface virtuelle pour John auto v_john0 iface john0 inet manual pre-up tunctl -u john -t v_john0 pre-up ifconfig v_john0 up post-down tunctl -d v_john0 auto eth0 br0 iface eth0 inet manual iface br0 inet dhcp bridge_ports eth0 regex v_.* noregex bridge_maxwait 2 bridge_fd 4
On relance le réseaux:
root$ /etc/ini.d/network restart
Et le tour est joué !
Une autre possibilité est d'accorder certains droits à John grâce à la commande sudo. Pour cela on édite le fichier /etc/sudouers avec la commande visudo et on y rajoute deux lignes.
# /etc/sudoers # # This file MUST be edited with the 'visudo' command as root. # # See the man page for details on how to write a sudoers file. # Defaults env_reset # Uncomment to allow members of group sudo to not need a password # %sudo ALL=NOPASSWD: ALL # Host alias specification # User alias specification # Cmnd alias specification ## Commandes reversées ajoutées à l'alias KVM Cmnd_Alias KVM = /usr/sbin/tunctl -t v_* -u * , /usr/sbin/tunctl -d v_* , /sbin/ifconfig v_* up , /usr/sbin/brctl addif br0 v_*, /usr/sbin/brctl delif br0 v_* # User privilege specification root ALL=(ALL) ALL ## Le groupe kvm à le droit d'utiliser les commandes de l'alias KVM %kvm ALL=KVM
Maintenant les uilisateurs du groupe kvm ont le droit de créer, monter, ajouter au bridge br0, retirer du bridge br0 et détruire des interfaces virtuelles qui commence par v_ .
Maintenant pour faciliter la tâche de l'utilisateur nous allons faire en sorte que ces opérations soit réalisé par des scripts. Dans notre cas ces deux scripts seront ”/etc/kvm/kvm-ifup” et ”/etc/kvm/kvm-ifdown”.
Voici le contenu du premier ”/etc/kvm/kvm-ifup”:
#!/bin/sh switch=$(ip route ls | awk '/^default / { for(i=0;i<NF;i++) { if ($(i) == "dev") print $(i+1) }}') sudo /usr/sbin/tunctl -t $1 -u $USER sudo /sbin/ifconfig $1 up sudo /usr/sbin/brctl addif ${switch} $1 exit 0
Et le contenu du deuxième ”/etc/kvm/kvm-ifdown”:
#!/bin/sh switch=$(ip route ls | awk '/^default / { for(i=0;i<NF;i++) { if ($(i) == "dev") print $(i+1) }}') sudo /usr/sbin/brctl delif ${switch} $1 sudo /usr/sbin/tunctl -d $1 exit 0
Pour monter l'interface il faut lancer le script prévu à cet effet en tant qu'utilisateur:
john$ /etc/kvm/kvm-ifup v_john0
Ainsi l'interface est montée pour John.
Et pour démonter l'interface:
john$ /etc/kvm/kvm-ifdown v_john0
La première chose à faire est de donner les droits aux utilisateurs:
Maintenant, voyons comment utiliser tout cela. Notre utilisateur john souhaite lancer une VM, pour cela il dispose de tout les droits nécessaires et d'une interface v_john0.
John commence par créer une image disque qui sera le disque dur de sa VM:
john$ qemu-img create -f qcow2 test.img 5G
Il vient donc de créer une image au format qcow2 de 5 Go.
Il peut maintenant lancer la VM pour y installer une Debian Lenny dont il a l'iso du CD de net-install.
john$ kvm -hda test.img -cdrom Debian-Lenny.iso -boot d -vnc :0 -k fr -net nic -net tap,ifname=v_john0,script=no,downscript=no
Notez bien le script=“no” sans quoi qemu lancera un script de configuration de l'interface qui ne fonctionne pas dans notre cas.
Maintenant il souhaite avoir la possibilité d'accéder à la console de qemu. Il rajoute donc l'option -monitor de qemu:
john$ kvm -hda test.img -cdrom Debian-Lenny.iso -boot d -vnc :0 -k fr -net nic -net tap,ifname=v_john0,script=no,downscript=no -monitor stdio
Voici quelques petites astuces utiles sur Impalor.
Il est possible de lancer une VM en tant que démon de sorte qu'elle continue son exécution même si John se déconnecte du serveur. En ajoutant l'option –daemonize à la commande:
john$ kvm -hda test.img -cdrom Debian-Lenny.iso -boot d -vnc :0 -k fr -net nic -net tap,ifname=v_john0,script=no,downscript=no --daemonize
L'option -monitor de Qemu n'est pas compatible avec l'option –daemonize. Donc John à recours à une ruse qui consiste à lancer la VM dans un screen et ainsi obtenir le même comportement qu'avec un démon et en plus la possibilité de se rattacher au screen à fin de récupérer l'accès à la console Qemu.
john$ screen kvm -hda test.img -cdrom Debian-Lenny.iso -boot d -vnc :0 -k fr -net nic -net tap,ifname=v_john0,script=no,downscript=no -monitor stdio
La VM est maintenant lancée dans un screen. Pour s'y rattacher:
john$ screen -r