La virtualisation KVM avec libvirt

closeCet article a été publié il y a 10 ans 5 mois 11 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Aujourd’hui, je continue dans la reprise d’article que j’ai publié ailleurs. J’ai eu l’occasion de manipuler plusieurs plateformes de virtualisation, et la dernière facile d’accès (Proxmox) avait des problèmes de performances sur le serveur de mon équipe. Après réflexion, on a choisi avec mon compère Arowan de se tourner vers une Debian brute, et il nous fallait un outil pour manipuler des machines virtuelles. La réponse à la question a été vite trouvée : libvirt.

Utiliser des machines virtuelles sur un serveur a plusieurs avantages : isolation complète des services, utilisation de plusieurs systèmes d’exploitation en parallèle (typiquement Windows et une ou plusieurs distributions Linux), sauvegardes et restaurations simplifiées, répartition fine des ressources, migrations entre serveurs. S’il existe plusieurs distributions Linux permettant de manipuler des machines virtuelles au travers d’une interface web (voir la Liste des distributions Linux sur homeserver-diy.net pour ça), il peut être parfois intéressant voire nécessaire de passer par d’autres moyens, un peu plus empiriques certes, notamment avec la sacro-sainte ligne de commande.

Préambule et définitions

Le noyau Linux possède sa propre infrastructure de virtualisation, nommée Kernel Virtualization Module (KVM pour la suite). Utilisée au travers de l’outil qemu, il permet de lancer des machines virtuelles avec des configurations diverses et variées, jusqu’à l’architecture du CPU que qemu peut émuler au besoin. Mais tout puissant qu’il est, le couple qemu/KVM est aussi particulièrement difficile d’accès pour les moins aguerris à la ligne de commande. Juste un exemple de commande qu’il faut lancer pour avoir une vm en ligne :

Oui, on peut appeler ça imbuvable. Fort heureusement, Red Hat a lancé un projet qui a permis de grandement simplifier la création et la gestion des machines virtuelles, la libvirt. Cette bibliothèque regroupe plusieurs outils, dont un très puissant qui va très vite devenir vôtre ami, virsh. Pour le reste des fonctionnalités, je vous renvoie au site officiel du projet.

Cet outil va vous servir aussi bien à préparer la configuration réseau de la machine hôte qu’à créer, modifier, importer vos machines virtuelles. Il est aussi utilisable pour manipuler des snapshots, mais ce n’est pas au programme de cette première prise en main.

Dernière précision, la libvirt permet de manipuler différentes technologies de virtualisation (Xen, KVM, LXC…). Le jour où vous devez, pour diverses raisons, changer de format de machine virtuelle, vous pourrez continuer à utiliser les mêmes commandes !

Préparation

Il faut bien évidemment un matériel supportant la virtualisation, et donc un CPU possédant les instructions idoines. Pour vérifier cela, on peut utiliser cette commande emprunté à une connaissance Twitter, à savoir Nicolargo (qui a aussi fait une introduction à libvirt sur son blog) :

 

Pas besoin de beaucoup d’explications, si ça affiche « OK », vous pouvez continuer, si ça affiche « KO », pas de bol. Vous pouvez continuer à lire, mais ça ne restera que de la théorie, vous ne pourrez pas expérimenter correctement le reste de cette introduction au monde merveilleux de la virtualisation.

Cette présentation va se baser sur une Debian Wheezy (7.2), aka l’actuelle version stable au moment où j’écris ces lignes. La plupart des commandes sont effectuées en root, et sont transposables à d’autres distributions (du moment que les logiciels sont les mêmes). L’interface réseau utilise une adresse IPv4 fixe. Ce qui est conseillé pour un serveur hébergeant des services, et donc une ou plusieurs vms dans le cas présent. Les seuls paquets nécessaires au fonctionnement à installer sont libvirt-bin, virtinst, qemu-kvm. Votre gestionnaire de paquets s’en chargera (je suis un grand fan inconditionnel d’apt-get). Dans mon cas, c’est simple :

Petite précision avant de commencer vraiment : toutes les commandes virsh données sont tapées depuis le shell de la distribution (bash le plus souvent). Mais virsh peut lui-même fonctionner en mode « shell », simplement en l’invoquant avec virsh sans options ni paramètres. Il suffira ensuite de saisir les commandes sans le ‘virsh’ devant. Libre à vous de choisir comment vous allez travailler.

On peut maintenant passer aux choses sérieuses.

Mise en place du réseau

Pour commencer, la méthode la plus simple pour relier vos machines à vôtre réseau est de créer un pont, sur lequel toutes vos machines virtuelles vont se brancher. La méthode manuelle consiste à modifier un fichier texte, à savoir le fichier /etc/network/interfaces, et à redémarrer le réseau pour que le bridge soit opérationnel. Plus simple, la création d’un bridge avec virsh se résume à une seule commande :

C’est déjà beaucoup plus court, n’est-ce pas ? La suite sera un peu plus fournie, notamment la création de l’image disque. C’est d’ailleurs la prochaine étape. Mais avant ça, on termine en activant l’IP forwarding (que je sais pas traduire en français en deux mots), qui consiste à dire au noyau de transférer tous les paquets IP qui ne sont pas directement destinés à la machine hôte. Pour ça, deux méthodes à utiliser conjointement, la première est immédiate, la deuxième permet de garder en mémoire le réglage au fil des différents redémarrages qui parsèmeront la vie de votre serveur.

 

J’arrêterais ici les réglages, car il est possible de gérer le réseau de plusieurs manières, et pour cette première approche je me base sur deux cas d’utilisation les plus courants :

  • Un serveur dédié disposant de plusieurs adresses IP publiques pour en attribuer une directement à votre VM (moyennant l’attribution d’une adresse MAC virtuelle associée à une des IP supplémentaires)
  • Un serveur derrière un routeur NAT, typiquement une BiduleBox, qui est capable d’attribuer une IP privée par DHCP (il est alors nécessaire de créer une ou plusieurs règles de redirection au niveau du routeur)

Si par exemple vous disposez d’un serveur ne disposant pas de plusieurs adresses IP, il est possible de NATer ces mêmes machines à la manière du routeur, mais directement au niveau de la machine hôte, en ajoutant plusieurs règles à iptables. Nicolargo a détaillé ces fameuses règles.

Image disque

Il faut maintenant créer un disque dur « virtuel », qu’on appelle une image disque. C’est une des rares étapes qui ne se fera pas avec virsh directement. Qemu sait manipuler plusieurs formats, les répandus vmdk (VMWare), vdi (Virtualbox), et moins répandus raw (n’utilise que l’espace réel des données), cloop (reproduit le format des liveCD), qcow2 (format natif de qemu, utilise le Copy-on-write, remplaçant du format qcow utilisé avant). Ce dernier est le format conseillé, car il facilite notamment la prise de snapshots. On commence par créer un dossier qui contiendra l’image disque. J’ai choisi de la mettre dans le dossier /home, qui est souvent, en tout cas dans mon cas, sur la partition la plus étendue du/des disques :

Ensuite on se place dedans, et on crée l’image à proprement parler. C’est qemu qui nous donnes les outils, à la fois pour créer mais aussi pour convertir une image :

Le nom et la taille du disque seront à adapter à vos besoins et/ou envies.

Création de la VM

Créer la VM est facile et rapide en soit, mais pour y installer un système d’exploitation (au hasard, Debian 7 — comme c’est étonnant), il faut récupérer l’image ISO le permettant. Toujours dans le dossier /home/vm, on va créer un sous-dossier « iso », puis télécharger la fameuse image :

La machine d’exemple que j’utilise a un CPU 64bit, et donc j’utilise l’image disque supportant cette architecture; c’est aussi l’architecture utilisée pour le système hôte installé. Vous adapterez donc à votre matériel.

NB : un CPU 64bit peut indépendamment faire tourner des VM 32 et/ou 64bit; un CPU 32bit ne saura faire tourner que des VM 32bit. Bien que les CPU 32bit uniquement avec virtualisation soient rares, il vaut mieux s’en assurer avant de se demander pourquoi ça ne marche pas.

Inutile de rappeler que l’image pesant 650Mo, il est plus pratique d’avoir une grosse connexion (les serveurs dédiés ont l’avantage d’avoir souvent 100Mbps, si ce n’est plus), ou un bon stock de M&Ms. Bref, une fois l’image récupérée, on peut s’atteler à la création de la machine virtuelle. Dans les paquets que je vous avais demandé d’installer au tout début, il y avait un outil appelé virt-install. Voici donc comment s’en servir :

Dans cette commande, je vous laisse modifier à votre guise le nom de la vm, le nombre de cpus « virtuels » ou la quantité de ram allouée, et bien entendu les images disques et ISO. La machine va donc être créée, démarrée, et l’installation de Debian donc lancée. Pour terminer l’installation, il suffit le lancer un client VNC, soit en local si vous opérez physiquement sur la machine, soit à distance en contactant l’ip de l’hôte.

Création depuis une image disque existante

Il est possible aussi de créer une VM avec une image disque déjà utilisée, sans forcément passer par le fichier de configuration. Au hasard, quand vous utilisez une image disque provenant d’une VM VMWare. Quand on revient du bon côté de la force, c’est un gain de temps appréciable. On en revient donc à virt-install, mais la ligne sera un peu différente :

Réglages et gestion au quotidien

Vous allez me dire que jusqu’à maintenant, nous n’avons pas beaucoup utilisé virsh. C’est vrai. Vous allez donc maintenant voir à quoi, en dehors de la création du bridge, peut servir cet outil. On va commencer par activer le démarrage automatique en même temps que la machine. Autant à la main c’est vraiment long (création d’un script à placer dans init.d, ajout dans insserv), autant là… :

Avouez qu’il est très difficile de faire plus simple. Pour démarrer une vm (un domaine dans le jargon « libvirt »), là encore la commande est des plus triviales :

Pour la redémarrer, c’est tout aussi évident :

De manière similaire, pour l’arrêter (correctement), il suffit de saisir :

Pour ceux qui seraient intrigué par le « correctement », virsh envoie un signal ACPI pour que l’OS invité s’arrête normalement, un peu comme quand vous appuyez sur le bouton d’alimentation de votre machine. Si jamais ça ne marche pas et que vous voulez « couper le courant » (ce qui est la seule chose à faire si le système invité ne répond plus), la commande est là encore d’une simplicité déconcertante, même si son nom peut faire peur au premier abord :

Non, vous ne venez pas de détruire votre machine virtuelle, rassurez-vous. C’est l’équivalent du ‘poweroff’ de Virtualbox si vous voulez.

Pour mettre en pause une machine virtuelle, par exemple au cas où vous voudriez créer une sauvegarde de l’image disque, et pour la remettre en route, ces deux commandes vous serons d’une grande aide :

Bref, virsh regorge de paramètres, que vous pouvez découvrir sur la page de manuel.

La configuration XML

Allons un peu plus loin. Une des forces de la libvirt, c’est de stocker les informations nécessaires au fonctionnement de la VM dans un fichier de configuration au format XML. Ce fichier est modifiable et permet d’ajouter ou de modifier les caractéristiques du matériel configuré, ainsi que les périphériques attachés. Pour modifier ce fichier simplement, plutôt que de chercher son emplacement, on invoque là encore virsh (vous voyez qu’on s’en sert plus souvent maintenant) :

Cette commande invoque votre éditeur de texte par défaut, vi dans mon cas (pour connaitre les commandes de base de cet éditeur, je vous renvoie à une introduction sur l’outil). Dans mon cas, sur un serveur dédié avec une IP failover chez OVH, j’ai ajouté l’adresse MAC associée dans la section réservée à la carte réseau, ainsi que le modèle de la carte (apparemment j’avais des soucis si je ne le spécifiais pas) :

Avantage, après avoir enregistré la configuration modifiée, virsh la vérifie pour valider les modifications avant de les appliquer. Et inutile de rappeler que ces modifications seront plus efficaces avec la VM éteinte. Ce fichier de configuration XML permet aussi de créer manuellement des machines virtuelles sans forcément lancer une installation. Et là pour le coup, c’est virsh qui fait tout le travail. On commence donc par récupérer une copie du fichier de configuration de notre vm fraichement installée :

 Vous pouvez ensuite modifier ce fichier pour coller aux besoins de la future machine virtuelle. Nom, image disque, réseau, mémoire vive, nombre de CPUs, bref tout ce que peut contenir ce fichier. Ensuite, pour créer la nouvelle VM, il suffit de demander à virsh de se baser sur ce fichier modifié :

Bien évidemment je conseille de changer le nom du fichier modifié histoire de ne pas se mélanger les pinceaux. A noter que virsh lancera immédiatement la VM après sa création. Si vous voulez simplement la créer, mais sans la démarrer, il vaut mieux utiliser l’option ‘define’ :

Interface graphique

Ce tuto est essentiellement tourné vers la ligne de commande, parce que sur un serveur auquel on accède le plus souvent avec un client SSH, c’est la méthode la plus évidente. Mais si par chance vous utilisez une distribution Linux sur votre machine cliente, il existe un client graphique capable aussi bien de manipuler des VMs locales que celles de votre serveur. Car la libvirt, lors de son installation, lance un daemon, accessible à distance, aussi bien en ligne de commande qu’avec le client graphique.

Son doux nom est virt-manager, et est installable par le biais du gestionnaire de paquets, le même qui vous a servi à installer la libvirt. Ou comme il s’agit de travailler en mode graphique, de votre gestionnaire graphique de logiciels.

virt-manager-vm-list

Pour plus de détails concernant son utilisation, je vous renvoie au site officiel du projet.

Conclusion

Cette introduction au monde merveilleux de la libvirt est maintenant terminée. Vous avez en main le nécessaire pour démarrer correctement. Et ce même si la partie réseau mériterait d’être plus fournie (voir le blog de Nicolargo pour la mise en palce n’un NAT local). La libvirt simplifie grandement les choses, et comme cet article n’est qu’une introduction, je n’ai pas beaucoup fouillé ses possibilités ici. Car le nombre de technologies de virtualisation qu’il supporte est tout simplement hallucinant (la liste est sur le site officiel), tout comme les possibilités au niveau du stockage, et le fait qu’il est administrable en local et à distance aussi bien en ligne de commande qu’au travers de virt-manager ajoute à son charme (même si ce dernier n’est dispo que sous Linux pour l’instant).

6 Commentaires
Le plus ancien
Le plus récent
Commentaires en ligne
Afficher tous les commentaires
Wilkin André
Wilkin André
19/08/2014 21:11

salut j’ai suivit ton tuto mais il y a quelques « kouaks » :
Durant l’installation du systeme invité lorsque j’arrive au partitionement je n’ai q’un disque de 197kB ce qui n’est clairement pas asser pour installer un os j’ai recommancer plusieur fois la manipulation et tjs le meme volume de disque !!
comment resoudre ce probleme
merci de ton aide

Seboss666
20/08/2014 19:08

MMMh, je n’ai malheureusement pas de machine disponible actuellement pour tenter de reproduire le bug, et ma dernière réinstallation de serveur n’a concerné que l’hyperviseur, puisque j’ai simplement restauré les machines existantes (avec l’option define).

En cherchant, je n’arrive pas non plus à trouver de personnes qui se seraient trouvées dans une situation similaire (et ça ne m’est jamais arrivé). Tu testes avec quelle distribution ?

Sabine
Sabine
22/04/2016 13:50

Excellent tuto Seboss666. Je suis très intéressé par les formations concernant la virtualisation KVM depuis celui que j’ai fais sur http://www.alphorm.com/tutoriel/formation-en-ligne-kvm. Et le tien est aussi très bien !

Emmanuel GICQUEL
Emmanuel GICQUEL
27/12/2016 21:47

Bonjour à tous, j’aurais aimé étudier la virtualisation avec KVM sur une VM Debian Jessie qui tourne dans un environnement VMware Workstation. Ma machine physique est un Intel Core i7 mais malheureusement quand je check /proc/cpuinfo je n’ai pas les flags « vmx » ou « svm » Je suis frustré de devoir arrêter mon expérimentation ici à moins que l’un d’entre vous ait une solution miracle. Merci pour vos réponses root@debian7:/home/manu/vmware-tools-distrib# cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 60 model name : Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz stepping : 3 microcode : 0x1e cpu MHz… Lire la suite »