Apprentissage de Qemu/LibVirt par l’exemple

La rédaction des billets de ce blog nécessite de travailler sur plusieurs systèmes d'exploitations différents. Plutôt que de monter une salle machine dans ma maison (pas sur que ma compagne soit d'accord), j'ai donc opté pour un virtualisation sur un serveur dédié OVH qui a le gros avantage de disposer d'une RAM conséquente de 16 Go (pour une machine en l'an 2012). Travaillant la plupart du temps du temps sous Linux, mon choix c'est donc porté sur la solution Qemu/KVM (Kernel-based Virtual Machine).

Installation de Qemu/KVM

Pour que Qemu/KVM ait des performances acceptables, il faut vérifier que votre processeur soit compatible avec les extensions de virtualisation. Sous Linux, il est facile de vérifier cela avec la ligne de commande suivante.

egrep '^flags.*(vmx|svm)' /proc/cpuinfo >/dev/null && echo OK || echo KO

Sur mon serveur de test (Kimsufi 16G chez OVH) pas de problème de ce coté là. J'obtiens un beau OK.

Le serveur peut donc supporter la virtualisation hardware. Chez OVH, le noyau par défaut est statique, il n'est donc pas possible d'ajouter dynamiquement des modules (comme le kvm_intel par exemple). Il faut donc suivre cette procédure. La dernière version des noyaux semble intégrer par défaut les modules KVM.

On peut ensuite passer à l'installation des briques logicielles (environ 257 Mo à télécharger):

  • qemu-kvm - Full virtualization on x86 hardware
  • virtinst - Programs to create and clone virtual machines
  • libvirt-bin - the programs for the libvirt library

On utilise les versions disponibles dans les dépôts Debian:

sudo apt-get install qemu-kvm virtinst libvirt-bin

Un petit reboot de la machine pour être sûr que tous les modules sont chargés avant de poursuivre.

Création de sa première machine virtuelle (VM)

Nous allons commencer par créer une machine virtuelle avec comme système hôte une Ubuntu Desktop 11.10. Une machine virtuelle a besoin d'un conteneur dans lequel elle va pourvoir s’exécuter: ce conteneur s'appelle une image disque. Ensuite, il faudra installer le système hôte à l'intérieur de cette image disque.

Il est possible d'utiliser la ligne de commande pour effectuer ces opérations (ce qui ouvre la voie à une automatisation par scripts). Nous aborderons cela un peu plus loin dans l'article. Pour commencer, nous allons utiliser le module libvirt-manager qui propose une interface graphique (GTK) permettant d'administrer à distance (via un tunnel SSH) son serveur d'hypervision Qemu/KVM.

On commence par vérifier que le daemon d'administration est bien lancé sur le serveur d'hypervision (ce qui devrait être le cas si vous avez suivi les étapes d'installations de ce billet):

sudo /etc/init.d/libvirt-bin status

Checking status of libvirt management daemon: libvirtd running.

Ensuite il faut ajouter votre utilisateur (nicolargo dans mon cas) dans les groupes 'libvirt' et 'kvm':

sudo usermod -a -G libvirt nicolargo

sudo usermod -a -G kvm nicolargo

Sur la machine GNU/Linux cliente (disposant d'une interface graphique), il faut installer les packages (par exemple sous Debian/Ubuntu):

sudo apt-get install virt-manager

Au lancement du client, il faut cliquer sur le menu File > Add connection...

Puis paramétrer la connexion vers votre serveur:

Notre serveur est alors disponible dans la liste, on peut alors configurer ses propriétés:

On configure le type de réseau que l'on va utiliser. Comme je ne dispose que d'une seule adresse publique sur mon serveur OVH Kimsufi, j'utilise la translation d'adresse (voir l'explication dans un chapitre suivant) qui est configurée par défaut:

Puis on configure les répertoires ou l'on pourra trouver les ISOs pour l'installation des machines hôtes:

 

 

Et voila le résultat après téléchargement de quelques images ISO depuis le répertoire ~/iso (le serveur disposant d'une accès 100 Mbs direct sur Internet, cela va assez vite !).

On peut passer à la création de la VM proprement dite en cliquant sur le bouton "Create a new virtual machine". On accède alors à un wizard:

On entre le nom de la VM (sans espace):

Puis l'image ISO qui va nous servir pour l'installation du système d'exploitation (le "Browse" sur le serveur peut prendre un certain temps):

On défini ensuite les ressources de la VM (CPU et mémoire). A noter que la limite à 2 Go de RAM sur ma configuration de test:

On donne ensuite la taille de l'image disque qui contiendra notre VM. Je conseille 16 Go pour les OS récents.

Enfin on finalise la configuration coté réseau (NAT) et hyperviseur (KVM):

Une fenêtre avec un déport d'affichage devrait alors s'afficher et l'installation du système guest (Ubuntu 11.10) commencer:

 Il ne vous reste plus qu'à finaliser l'installation !

Utilisation de sa VM

Une fois l'installation de la VM effectuée (voir le chapitre précédant). Celle-ci devrait apparaître dans la liste proposé par Virtual Machine Manager. Pour la lancer, il faut sélectionner la VM puis cliquer sur le bouton 'play' (Power On the virtual machine):

Et voilà le travail:

Niveau performance ?

Il ne faut pas s'attendre à des miracles. La virtualisation par Qem/KVM bien qu'aillant fait de gros progrès dans les dernières versions restent en dessous d'une solution comme VmWare ou Xen. Elles sont par contre suffisante dans mon cas ou je souhaite valider des procédures et des logiciels système et réseau.

Gestion en ligne de commande

Création de l'image disque

On commence par créer un répertoire ~/vm qui va contenir toutes mes images disques:

mkdir ~/vm

Puis on utilise la commande qemu-img pour générer l'image disque "vierge":

cd ~/vm

qemu-img create -f qcow2 debian6server.qcow2 16G

Cette dernière commande va donc générer une image disque nommée debian6server.qcow2 de type qcow2 (voir ci-dessous la liste des types disponibles sous Debian 6) avec une taille maximale de 16 Giga octets.

Sur mon système, la liste des "types" d'image disque est la suivante:

  • raw: pas de compression, l'image disque est directement "dumpée" dans un fichier
  • host_device
  • qcow2: format par défaut de Qemu (Qemu Image Format)
  • qcow: ancien format utilisé par Qemu (ne pas utiliser pour la création de nouvelle image disque)
  • vdi: format compatible avec VirtualBox
  • vmdk: format compatible avec VMWare
  • vpc: format compatible avec VirtualPC

Il est possible de convertir une image d'un format à un autre. Par exemple, si vous avez une image au format VMWare et que vous voulez la convertir vers un format Qcow2, il suffit de saisir la commande suivante:

qemu-img convert -f vmdk disk.vmdk -O qcow2 disk.qcow2

Création de la VM

Pour installer la VM, nous avons besoin de l'image ISO du système d'exploitation à installer (Debian 6 server dans mon exemple). On va donc télécharger cette image sur notre serveur (c'est dans ces moments là que l'on est heureux d'avoir un serveur avec une connexion à 100Mbps vers Internet...):

mkdir ~/iso

cd ~/iso

wget http://cdimage.debian.org/debian-cd/6.0.3/i386/iso-cd/debian-6.0.3-i386-CD-1.iso

Maintenant que nous disposons de l'image disque ~/vm/debian6server.qcow2 et du média d'installation ~/iso/debian-6.0.3-i386-CD-1.iso, nous allons créer la machine virtuelle en utilisant la couche d'abstraction libvirt.

Pourquoi utiliser libvirt plutôt que d'utiliser directement les commandes équivalentes Qemu ? Si demain vous décidez de changer votre système de virtualisation, vos procédures/scripts resteront les mêmes. En effet libvirt communique de manière transparente vers un grand nombre de systèmes de virtualisation en proposant en bonus une API de développement (notamment en Python).

On utilise donc la commande suivante pour créer la VM:

virt-install --ram=2047 --name=debian6server --file=/home/nicolargo/vm/debian6server.qcow2 --cdrom=/home/nicolargo/iso/debian-6.0.3-i386-CD-1.iso --hvm --vnc --noautoconsole

Note: la commande virt_install ne semble pas trop aimer les ~ dans les paths. Il faut donc donner le chemin absolu.

Note2: La taille maximale de RAM que je peux allouer est de 2047Mo.

Cette commande va donc créer une VM nommée debian6server qui disposera de 2 Go de RAM (d'ou l'avantage de faire tourner votre hyperviseur sur une machine disposant de pas mal de RAM / 16 Go dans mon cas sur une Kimsufi 16G).

Si tout est ok, le message suivant devrait s'afficher:

Domain installation still in progress.

You can reconnect to the console to complete the installation process.

Pour l'accès à la console (déport VNC via un tunnel SSH), je vous conseille d'utiliser l'interface d'administration de libvirt que vous pouvez lancer sur un PC client disposant d'une interface graphique.

Gestion du réseau par translation

Mon serveur dispose d'une seule adresse IP publique. Les VM auront donc des adresses IP privées et l'on utilisera la translation s'adresse (NAT) pour permettre au VM de sortir sur Internet (voir ce billet pour la création d'un réseau par NAT).

Certaines configurations sont à faire sur votre serveur:

sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
sudo vi /etc/sysctl.conf

# Uncomment the next line to enable packet forwarding for IPv4

net.ipv4.ip_forward=1

Si vous utilisez des règles Iptables alors il faut ajouter les lignes suivantes dans votre scripts (attention de bien vérifier que votre script ne repositionne pas la valeur net.ipv4.ip_forward à 0... je me suis fais avoir):

# Qemu rules (NAT VM and allow VM to DHCP)

/sbin/iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE

/sbin/iptables -A INPUT -i virbr0 -j ACCEPT

/sbin/iptables -A OUTPUT -o virbr0 -j ACCEPT

/sbin/iptables -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT

/sbin/iptables -A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT

/sbin/iptables -A INPUT -i virbr0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT

/sbin/iptables -A FORWARD -d 192.168.122.0/24 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT

/sbin/iptables -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT

/sbin/iptables -A FORWARD -i virbr0 -o virbr0 -j ACCEPT

echo 1 > /proc/sys/net/ipv4/ip_forward

Petite note pour les guests "BSD"

Pour un guest sous OpenBSD, il faut penser à effectuer les actions suivantes pour faire fonctionner correctement la carte réseau:

  • arrêter la VM
  • éditer le fichier /etc/libvirt/qemu/OpenBSD_5.0.xml
<interface type='network'>

...

<strong><model type='e1000'></strong>

</interface>
  • Relancer la VM

Sources utilisées lors de la rédaction de cet article:

13 commentaires/références

    On parle de ce billet (ping back):

    Commentaires (de mes chers lecteurs):


  1. src, le 13/02/2012 (#14925)

    Salut,

    Article intéressant.
    Au niveau des performances, c’est surtout mauvais quand tu as une interface graphique, et c’est du à VLC. Ou alors ton serveur dédié a un processeur de merde.

    Vérifie que ton périphérique réseau et ton périphérique de stockage sont bien en VirtIO. Virt-Manager le sélectionne automatiquement pour une machine de type Debian, mais en lignes de commandes je ne sais pas. Avec VirtIO tu auras de bien meilleures performances (valable pour les guest Linux, pour FreeBSD il faut laisser par défaut).

    Sur Linux-KVM.com il y a un blog sur lequel tu peux avoir des astuces dans ce domaine, ou des informations sur les nouvelles sorties.


    • src, le 13/02/2012 (#14926)

      J’ai oublié de dire qu’il faut aussi mettre le cache du périphérique de stockage en “none”, cela peut faire grimper les performances de manière spectaculaire…


  2. Jeyg, le 13/02/2012 (#14931)

    Article intéressant mais j’aimerais savoir pourquoi tu as utilisé cette solution plutôt qu’une autre ? Je pense à Xen en particulier.


  3. HacKurx, le 13/02/2012 (#14938)

    Tu as eu l’occasion de tester oVirt avec KVM?

    http://www.ovirt.org/

    Merci


    • NicoLargo, le 13/02/2012 (#14939)

      Non mais ke projet à l’air intéressant. Je testerai quand un package Debian sera publié.


  4. Greg, le 14/02/2012 (#14947)

    Salut, tu as oublié d’obfusquer une image…


  5. Gounick, le 14/02/2012 (#14949)

    Bonjour, j’utilise kvm à travers la solution web-based Proxmox-ve 1.9 / 2.0béta (sur Debian) http://pve.proxmox.com
    Cela fonctionne très bien.

    Pour les performances dont tu parlais, il est important d’activer les périphériques de type virtIO (supporté par les os guest en noyaux 2.6.25 et +). On obtient des perfs quasiment égales à l’hôte.


  6. HacKurx, le 14/02/2012 (#14953)

    Pour info avec virtIO, la machine invité utilise un périphérique genre /dev/vdZ


  7. Nebula, le 15/02/2012 (#14962)

    Le NAT, s’est bien, mais parfois on a besoin que les VMs accèdent directement au réseau. Dans ce cas, sur le parent (la machine hôte), il faut configurer un bridge. Dans l’exemple, on utilise un VLAN.

    aptitude install vlan
    modprobe 8011q
    vim /etc/modules #Ajouter cette ligne: 8021q

    vim /etc/network/interfaces
    auto eth0
    iface eth0 inet manual

    #L’interface VLAN qui sera bridger
    auto eth0.50
    iface eth0.50 inet manual
    vlan_raw_device eth0

    auto br0
    iface br0 inet static
    address 10.1.45.110
    netmask 255.255.0.0
    broadcast 10.1.255.255
    gateway 10.1.45.1
    bridge_ports eth0.50

    Et un /etc/init.d/networking restart

    Puis sur les VMs configurés:

    virsh edit

    Pour installer une VM de manière interactive en console: virt-install –prompt


  8. JaShuGan, le 16/02/2012 (#15011)

    Salut,

    Au niveau des perfs, je suis assez d’accord avec src : En configurant les entrées/sorties en virtio et le disque en mode “cache=none”, les perfs sont très correctes. Je n’ai pas d’éléments permettant d’ettayer cette afirmation mais j’ai pu lire ce constat ici et là.

    Ovirt, j’ai pu tester en montant une maquette (virtualisation imbriquée, paramètre nested du module kvm) et je ne suis pour le moment pas très convaincu. Je trouve la solution trop intrusive : installation d’un démon vdsm alors que je trouvais la solution qemu/kvm/libvirt très flexible.
    Y’a certainement moyen de créer une interface plus simple et qui se connecte simplement au démon libvirtd.
    L’interface est effectivement “sexy” mais solution lourde.
    Je n’arrete pas mon avis aux quelques tests rudimentaires effectués, je vais continuer.

    A priori, l’argument avancé serait le HA mais bon une solution telle que Corosync/Pacemaker est très bonne aussi.

    Bon j’arrete là, Sympa l’article. Merci Nico


  9. thier, le 22/02/2012 (#15067)

    Bonjour à tous …

    Pour ma part, j’ai presque tout testé en matière de virtualisation et la solution Qemu/KVM est de loin celle qui me donne le plus de satisfaction sur des configurations de serveurs moyenne gamme (fonctionnant sous Ubuntu server) et pour des connexions distantes (adsl).

    Effectivement, le moyen que vous utilisez pour vous connecter à la VM peut influer sur les performances graphiques … Pour ma part, j’ai installé un server NoMAchine (Nx server) sur les machines virtualisées et j’y accède par ce biais … C’est excellent en terme de rendu graphique et de rapidité.

    Et vis à vis de Proxmox, la gestion de la fenêtre est meilleure … l’accès ne passe pas par une session au serveur Proxmox (c’est direct) … on peut faire des copier/coller texte entre la VM et la machine “accueillante” … je n’y trouve que des qualités …

    Bon courage à tous …


Vous avez un compte Twitter ?

Cliquer sur le bouton ci-dessous pour vous enregistrer sur le blog en l'utilisant.

Laisser un message

Les informations saisies resteront privées