From 2982ce25958d9ea6a24570ab9cc78a1961587977 Mon Sep 17 00:00:00 2001 From: gcolpart Date: Tue, 27 Dec 2016 03:53:21 +0100 Subject: [PATCH] =?UTF-8?q?grosse=20relecture=20et=20mise=20=C3=A0=20jour?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HowtoKVM.md | 1184 +++++++++++++++++++++++++++++---------------------- 1 file changed, 677 insertions(+), 507 deletions(-) diff --git a/HowtoKVM.md b/HowtoKVM.md index 2851213b..db7cec9b 100644 --- a/HowtoKVM.md +++ b/HowtoKVM.md @@ -1,111 +1,193 @@ # Howto KVM -[Site officiel](http://www.linux-kvm.org/) +* Documentation KVM : +* Documentation libvirt : -KVM est une technologie de machines virtuelles (comme Xen ou VMware) intégrée au noyau Linux. +[KVM](http://www.linux-kvm.org/) est une technologie de virtualisation intégrée au noyau Linux. ## Installation -~~~ -# apt install qemu-kvm bridge-utils qemu-utils libvirt-bin netcat-openbsd virtinst drbd-utils -~~~ - -On conseille l'utilisation du mode _bridge_ pour le réseau. Voici un exemple de fichier `/etc/network/interfaces` : +Pour installer un hyperviseur (machine capable de faire tourner des machines virtuelles) : ~~~ -auto lo br0 -iface lo inet loopback +# apt install qemu-kvm bridge-utils qemu-utils libvirt-bin virtinst netcat-openbsd +~~~ + +~~~ +$ kvm --version +QEMU emulator version 2.1.2 (Debian 1:2.1+dfsg-12+deb8u6), Copyright (c) 2003-2008 Fabrice Bellard + +$ virsh -V +Virsh command line tool of libvirt 1.2.9 +See web site at http://libvirt.org/ + +Compiled with support for: + Hypervisors: QEMU/KVM LXC UML Xen LibXL OpenVZ VMWare VirtualBox Test + Networking: Remote Network Bridging Interface netcf Nwfilter VirtualPort + Storage: Dir Disk Filesystem SCSI Multipath iSCSI LVM RBD Sheepdog + Miscellaneous: Daemon Nodedev AppArmor SELinux Secrets Debug DTrace Readline Modular +~~~ + +## Utilisation basique de libvirt + +[libvirt](https://libvirt.org) est une surcouche facilitant la gestion de la virtualisation. + +Un démon **libvirtd** tourne sur l'hyperviseur, il peut être redémarrer sans impacter les VM : + +~~~ +# systemctl restart libvirtd +~~~ + +La commande **virsh** permet de réaliser des opérations en ligne de commande : + +~~~ +# virsh list --all +# virsh start +# virsh shutdown +# virsh destroy +# virsh edit +~~~ + +Pour un accès « graphique », installer sur le poste client : + +~~~ +# apt install virt-manager netcat-openbsd +~~~ +puis ajouter une clé SSH permettant de se connecter au serveur avec un utilisateur dans le groupe _libvirt_ +puis démarrer `virt-manager` et ajouter une _connexion à un hôte distant_ via SSH. + +Les VMs définies pour tourner sur l'hyperviseur ont un fichier de définition XML dans le répertoire `/etc/libvirt/qemu/`. + +## Configuration + +Un hyperviseur KVM doit avoir des CPUs supportant la virtualisation, une bonne quantité de RAM, une configuration réseau spécifique et l'accès à du stockage adapté à votre utilisation (si besoin, un SAN ou un setup DRBD/LVM). + +### Configuration CPU + +Un hyperviseur KVM doit avoir des CPUs supportant la virtualisation. + +Cela s'active souvent via le BIOS de la machine. +Si ce n'est pas activé, vous aurez une erreur *KVM: disabled by BIOS* + +### Configuration mémoire + +On conseille d'avoir une certaine marge de RAM par rapport à la somme de la mémoire allouée à chaque VM, surtout si vous activer du cache au niveau des disques des VMs (ce qui est conseillé pour de bonnes performances). + +On conseille également de configurer **au moins 10 Go de swap sur l'hyperviseur** afin d'éviter que le mécanisme *Out-Of-Memory Killer* ne se déclenche au moindre pic de mémoire. + +Enfin, on conseille d'ajuster le paramètre *oom_score_adj* entre les machines critiques et non critiques : + +~~~ +@hourly test -s /var/run/libvirt/qemu/VM-non-critique.pid && echo '800' > /proc/$(cat /var/run/libvirt/qemu/VM-non-critique.pid)/oom_score_adj +@hourly test -s /var/run/libvirt/qemu/VM-critique.pid && echo '-800' > /proc/$(cat /var/run/libvirt/qemu/VM-critique.pid)/oom_score_adj +~~~ + +### Configuration réseau + +On conseille l'utilisation du mode **bridge** pour le réseau. +On crée un bridge _br0_ liée à l'interface _eth0_ : + +~~~ +# brctl addbr br0 +~~~ + +Puis on ajuste le fichier `/etc/network/interfaces` ainsi : + +~~~ +auto br0 iface eth0 inet manual iface br0 inet static address
netmask gateway bridge_ports eth0 + up echo 0 > /sys/class/net/br0/bridge/multicast_snooping ~~~ -## Réseau bridgé avec openvswith +*Note* : il est nécessaire de désactiver le multicast_snooping pour assurer un bon fonctionnement de l'IPv6 -Notamment utile pour utiliser avec le RPN Online. +/!\\ : s'assurer d'avoir bien installé _bridge-utils_ et configuré le firewall avant de redémarrer -/etc/network/interfaces +### Configuration stockage + + + +Nous utilisons principalement : + +* Volumes DRBD over LVM (supporte les migrations à chaud) +* Format QCOW2 (supporte les snapshots à chaud) +* Format RAW (plus performant que QCOW2) + + +## Création d'une VM + +### virt-install + +Avoir un ISO disponible sur l'hyperviseur (pour Debian, télécharger l'ISO _netinst_ sur ) puis l'on crée une VM : ~~~ -# LAN bridge over RPN -# -auto br1 -iface br1 inet manual - ovs_type OVSBridge - post-up ovs-vsctl add-port br1 gre0 -- set interface gre0 type=gre options:remote_ip='10.XX.XX.XX' - post-up ip link set ovs-system up - post-up ip link set br1 up +$ virt-install --connect=qemu:///system \ +--name=template \ +--vcpus=1 \ +--ram=512 \ +--disk path=/srv/machines/template.qcow2,bus=virtio,cache=none,size=42,format=qcow2 \ +--network=bridge:br0,model=virtio \ +--noautoconsole --graphics vnc,listen=127.0.0.1,keymap=fr \ +--cdrom=/srv/isos/debian-8.6.0-amd64-netinst.iso ~~~ -Créer un fichier xml définissant le réseau. +*Note* : si besoin de performance, on pourra mettre *cache=writeback* + +*TODO* : à voir la valeur de --cpu=??? + +On peut ensuite se connecter en VNC via l'hyperviseur et réaliser l'installation : ~~~ - - br1 - - - - +$ vncviewer -via kvm.example.com 127.0.0.1:5900 ~~~ +### virt-manager + +**Nous déconseillons l'installation via _virt-manager_ !!** +Certes, l'installation est plus conviviale (car graphique) mais : + +* les options disponibles sont limitées (impossible de sélectionner un volume DRBD par exemple) +* les choix réalisés par défaut sont incorrects (ajout de périphériques Tablette, Video QXL, USB etc.) + +Si vous utilisez tout de même _virt-manager_, la démarche est similaire à _virt-install_, on choisira bien les options suivantes : + +* Choix processor : Configuration > ne PAS cocher *Copier la configuration CPU de l'hôte* et choisir *Modèle : ???* +* NIC : choisir *Device model : virtio* +* VirtIO Disk : sélectionner *Mode cache : none* (ou *writeback*) +* IDE CDROM 1 : bien vérifier que le CDROM est déconnecté une fois l'installation terminée + + +### virsh define + + + +Vous pouvez écrire votre propre fichier de définition XML puis l'injecter : + ~~~ -# virsh net-define br1.xml -# virsh net-start br1 -# virsh net-autostart br1 +# virsh define template.xml +# virsh start template ~~~ -## Installation d'une VM Debian (sans libvirt) +## Stockage -Création d'une image pour le système (exemple en QCOW2) : +### Format QCOW2 +Ce format est spécifique à QEMU. C'est un format à taille variable (indépendamment du système de fichiers), +et il dispose de fonctionnalités avancées permettant notamment de gérer des snapshots à chaud. + +Création d'une image QCOW2 : ~~~ -# qemu-img create -f qcow2 debian1.qcow2 20G +# qemu-img create -f qcow2 test0.qcow2 5G ~~~ -Génération d'une adresse MAC aléatoire pour la machine avec le script suivant (issu de la documentation de KVM) : - -~~~ - -# echo $(echo -n DE:AD:BE:EF ; for i in `seq 1 2` ; do echo -n `echo ":$RANDOM$RANDOM" | cut -n -c -3` ;done) -~~~ - -Démarrage de la machine virtuelle sur le fichier _debian-504-amd64-netinst.iso_ : - -~~~ -# kvm -hda debian1.qcow2 -cdrom debian-amd64-netinst.iso -boot d -m 512 -net nic,macaddr= -net tap,script=/etc/qemu-ifup -vnc :1 -k fr -~~~ - -Ouverture d'un tunnel SSH vers le port VNC 5901 dans le cas où celui-ci n'est pas accessible directement : - -~~~ -$ ssh -L 5901:127.0.0.1:5901 -~~~ - -Lancement du client VNC : - -~~~ -$ xvncviewer localhost:5901 -~~~ - -Effectuer alors une installation Debian traditionnelle, et valider l'installation du boot loader Grub. - -/!\ Faire l'installation d'un ordinateur utilisant la touche Fn, seule façon de saisir le caractère "point". Ensuite, mettre un mot de passe trivial (ex: toto) pour le mot de passe root, a changer dans la foulée après l'installation - -À la fin de l'installation, lors du redémarrage, arrêter KVM (avec "CTRL+C" ou "kill ") puis on relance dans un screen avec une sortie en "ncurses" : - -~~~ -# /usr/bin/screen -S debian1 -d -m kvm -hda debian1.qcow2 -m 384 -net nic,macaddr= -net tap,script=/etc/qemu-ifup \ - -curses -k fr -monitor tcp:127.0.0.1:,server,nowait -~~~ - -## Gestion des images KVM - -Info sur une image : +Information sur une image QCOW2 : ~~~ # qemu-img info debian1.qcow2 @@ -116,6 +198,42 @@ disk size: 908M cluster_size: 65536 ~~~ +Agrandir une image : + +De façon similaire au format RAW, on peut agrandir une image QCOW2. Voir + +Convertir une image RAW en QCOW2 : + +~~~ +# qemu-img convert -f qcow2 -O raw test0.qcow2 test0.img +~~~ + +#### Monter une image QCOW2 via qemu-NBD + +*qemu-nbd* permet de créer un point de montage NBD (Network Block Device) : + +~~~ +# modprobe nbd max_part=16; +# qemu-nbd -c /dev/nbd0 test0.qcow2; +# partprobe /dev/nbd0; +~~~ + +/dev/nbd0 est ensuite utilisable pour fdisk : + +~~~ +# fdisk /dev/nbd0 +Command (m for help): p +~~~ + +Vous pouvez ensuite (un)mounter vos partitions situées dans votre image QCOW2. +Note : si vous avez du LVM, vous devez activer les VG via `vgscan && vgchange -ay` + +Cela peut ensuite être stoppé via : + +~~~ +# qemu-nbd -d /dev/nbd0 +~~~ + ### Format RAW L'avantage de ce format est sa simplicité ! C'est tout simplement une suite d'octets.. @@ -149,25 +267,14 @@ Convertir ume image RAW en QCOW2 : ~~~ #### Agrandir une image + * Vérifier qu'aucun processus n'accède à l'image (la VM doit notamment être éteinte !) - -~~~ -# virsh list --all - Id Name State ----------------------------------------------------- - 1 foo running - 2 bar running - - my_vm shut off - -# ps aux |grep -~~~ -* agrandir le fichier image avec la taille désirée : +* Agrandir le fichier image avec la taille désirée : ~~~ # qemu-img resize host.img +50G Image resized. ~~~ - ou on peut utiliser dd, exemple pour une taille finale de 80G : ~~~ @@ -176,7 +283,7 @@ ou on peut utiliser dd, exemple pour une taille finale de 80G : 0+0 records out 0 bytes (0 B) copied, 1.302e-05 s, 0.0 kB/s ~~~ -* monter l'image et vérifier qu'elle a la bonne taille : +* Monter l'image et vérifier qu'elle a la bonne taille : ~~~ # kpartx -v -a host.img @@ -187,7 +294,7 @@ Disk /dev/loop0: 161.1 GB, 161061273600 bytes […] ~~~ -* supprimer puis recréer la partition avec la bonne taille à l'intérieur de l'image, après avoir sauvegarder la table des partitions : +* Supprimer puis recréer la partition avec la bonne taille à l'intérieur de l'image, après avoir sauvegarder la table des partitions : ~~~ # sfdisk -d /dev/loop0 >~/loop0.parts @@ -196,7 +303,7 @@ Disk /dev/loop0: 161.1 GB, 161061273600 bytes ~~~ Voir -* démonter et remonter l'image (un partprobe ne suffit visiblement pas pour détecter la nouvelle taille de la partition) : +* Démonter et remonter l'image (un partprobe ne suffit visiblement pas pour détecter la nouvelle taille de la partition) : ~~~ # kpartx -d host.img @@ -205,7 +312,7 @@ loop deleted : /dev/loop0 add map loop0p1 (254:4): 0 314572737 linear /dev/loop0 63 ~~~ -* lancer un fsck puis un resize2fs pour redimensionner le système de fichiers : +* Lancer un fsck puis un resize2fs pour redimensionner le système de fichiers : ~~~ # e2fsck -f /dev/mapper/loop0p1 @@ -222,7 +329,7 @@ Resizing the filesystem on /dev/mapper/loop0p1 to 39321592 (4k) blocks. The filesystem on /dev/mapper/loop0p1 is now 39321592 blocks long. ~~~ -* vérifier que le système de fichiers voit la bonne taille en montant la partition : +* Vérifier que le système de fichiers voit la bonne taille en montant la partition : ~~~ # mount /dev/mapper/loop0p1 /mnt @@ -231,455 +338,89 @@ The filesystem on /dev/mapper/loop0p1 is now 39321592 blocks long. # umount /mnt ~~~ -* puis démonter l'image : +* Puis démonter l'image : ~~~ # kpartx -d host.img loop deleted : /dev/loop0 ~~~ -### Format QCOW2 -Ce format est spécifique à QEMU. C'est un format à taille variable (indépendamment du système de fichiers), -et il dispose de fonctionnalités avancées permettant notamment de gérer des snapshots à chaud. +### Volumes DRBD/LVM -Création d'une image QCOW2 : +TODO -~~~ -# qemu-img create -f qcow2 test0.qcow2 5G -~~~ - -Convertir une image RAW en QCOW2 : - -~~~ -# qemu-img convert -f qcow2 -O raw test0.qcow2 test0.img -~~~ - -On passe en mode "monitor" sur l'image QCOW2 : - -~~~ -$ telnet 127.0.0.1 -Trying 127.0.0.1… -Connected to 127.0.0.1. -Escape character is '^]'. -QEMU 0.9.1 monitor - type 'help' for more information -(qemu) savevm s0 -savevm s0 -(qemu) info snapshots -info snapshots -Snapshot devices: ide0-hd0 -Snapshot list (from ide0-hd0): -ID TAG VM SIZE DATE VM CLOCK -1 s0 20M 2010-11-14 20:07:09 00:16:01.182 -(qemu) -~~~ - -Ce snapshot permet une restauration de l'état à chaud ou un redémarrage sur l'état courant. - -Pour une restauration à chaud : - -~~~ -(qemu) loadvm s0 -~~~ - -Ou alors un (re)démarrage sur cet état sauvegardé : - -~~~ -# /usr/bin/screen -S debian1 -d -m kvm -hda debian1.qcow2 -m 384 -net nic,macaddr= -net tap,script=/etc/qemu-ifup \ - -curses -monitor tcp:127.0.0.1:,server,nowait -loadvm s0 -~~~ - - -En terme de sauvegarde, cela permet de réaliser des sauvegardes de l'état de la machine (et données) sans arrêt de la machine. -Exemple : - -~~~ -#!/bin/sh -echo "savevm snap.current" | telnet 127.0.0.1 -sync -cp debian1.qcow2 debian.current.qcow2 -~~~ - -L'un des inconvénients est la difficulté à monter une image QCOW2. -Dans les dernières versions, on peut le faire via NBD. -Voir -#### qemu-NBD -*qemu-nbd* permet de créer un point de montage NBD (Network Block Device) : +## Réseau -~~~ -# modprobe nbd max_part=16; -# qemu-nbd -c /dev/nbd0 test0.qcow2; -# partprobe /dev/nbd0; -~~~ +### Adresse MAC -/dev/nbd0 est ensuite utilisable pour fdisk : +On peut générer l'adresse MAC d'une VM KVM avec le script suivant : ~~~ -# fdisk /dev/nbd0 -Command (m for help): p +$ echo $(echo -n 52:54:00 ; for i in `seq 1 3`; do echo -n `echo ":$RANDOM$RANDOM" | cut -n -c -3`; done) ~~~ -Vous pouvez ensuite (un)mounter vos partitions situées dans votre image QCOW2. -Note : si vous avez du LVM, vous devez activer les VG via `vgscan && vgchange -ay` - -Cela peut ensuite être stoppé via : - -~~~ -# qemu-nbd -d /dev/nbd0 -~~~ - -#### Agrandir une image - -De façon similaire au format RAW, on peut agrandir une image QCOW2. Voir +### Mode bridge + VLAN +Vous pouvez faire passer plusieurs VLANs dans votre bridge, +afin de permettre l'accès depuis vos VMs à différents VLANs. -## Mode MONITOR de QEMU/KVM - - - -### Extinction ACPI d'une VM +Sur l'hyperviseur on aura ainsi une configuration réseau du type (paquet *vlan* à installer) : ~~~ -$ echo system_powerdown | nc localhost -QEMU 0.12.5 monitor - type 'help' for more information -(qemu) system_powerdown -(qemu) -^C +auto br0 +iface eth0 inet manual +iface br0 inet manual + bridge_ports eth0 + up echo 0 > /sys/class/net/br0/bridge/multicast_snooping +auto br0.42 +iface br0.42 inet static + address
+ netmask + gateway ~~~ -### pause/resume d'une VM - -~~~ -$ nc localhost -QEMU 0.12.5 monitor - type 'help' for more information -(qemu) stop -stop -(qemu) cont -cont -~~~ +Dans les VMs, on aura ainsi une configuration réseau VLANisé (voir [HowtoDebian/Reseau]). -## Killer features de KVM +### Mode bridge avec openvswith -### Snapshot temporaire +Notamment utile pour utiliser avec le RPN Online. -Un mode de démarrage intéressant est le mode "-snapshot" où rien n'est réellement écrit sur le disque : +`/etc/network/interfaces` : ~~~ -# kvm -hda debian1.qcow2 -m 384 -net nic,macaddr= -net tap,script=/etc/qemu-ifup \ - -curses -monitor tcp:127.0.0.1:,server,nowait +# LAN bridge over RPN +# +auto br1 +iface br1 inet manual + ovs_type OVSBridge + post-up ovs-vsctl add-port br1 gre0 -- set interface gre0 type=gre options:remote_ip='10.XX.XX.XX' + post-up ip link set ovs-system up + post-up ip link set br1 up ~~~ -Au prochain redémarrage, le système revient à son état précédent. -Si nécessaire on peut tout de même forcer l'écriture en passant en mode monitor : +Créer un fichier XML définissant le réseau : +~~~{.xml} + + br1 + + + + ~~~ -(qemu) commit all -~~~ - -Note : à vérifier si les images RAW supportent le mode "-snapshot" - -### Images dérivées d'une image de base - - - -Une option intéressante est de créer une image d'une installation de base et de créer des dérivées -à partir de cette image. Non seulement permet de repartir d'une installation déjà faite, mais cela -permet aussi une optimisation de la place (l'image dérivée est en Copy-on-Write de celle de base) -voire même de la mémoire selon les rumeurs :-) - -Création d'une image dérivée : ~~~ -# qemu-img create -f qcow2 -b install-debian-base.qcow2base serveur01.qcow2snap -Formatting 'serveur01.qcow2snap', fmt=qcow2 size=12884901888 backing_file='install-debian-base.qcow2base' encryption=off cluster_size=0 -# qemu-img info serveur01.qcow2snap -image: serveur01.qcow2snap -file format: qcow2 -virtual size: 12G (12884901888 bytes) -disk size: 140K -cluster_size: 65536 -backing file: install-debian-base.qcow2base (actual path: install-debian-base..qcow2base) +# virsh net-define br1.xml +# virsh net-start br1 +# virsh net-autostart br1 ~~~ -Attention, ne jamais modifier une image de base si elle a des images dérivées sous peine de tout perdre !! - -## Libvirt - -### Installation - -~~~ -# aptitude install libvirt-bin -~~~ - -Pour un accès graphique distant, sur le poste client : - -~~~ -# aptitude install virt-manager netcat-openbsd -~~~ - -Ajouter une clé SSH permettant de se connecter en root au serveur KVM ou ajouter votre utilisateur dans le groupe libvirt (recommandé). - -Démarrer virt-manager, et ajouter une connexion qemu+ssh vers le serveur. - -Ou bien, installer virt-manager sur le serveur, et se connecter en SSH -X. Options recommandés : - -~~~ -ssh -X -C -c arcfour root@machine.kvm -~~~ - -### Mode CLI : virsh - -La commande virsh permet de faire de nombreuses manipulations en ligne de commande. - -~~~ -# virsh list -# virsh list --all -# virsh dominfo -# virsh autostart -# virsh autostart --disable -# virsh dumpxml > .xml -# virsh define .xml -# virsh undefine -~~~ - -Pour modifier les options avancées d'une machine créée avec virsh/virt-manager : - -~~~ -# virsh edit -~~~ -*/!\ Attention, sans utiliser "virsh edit" les modifications sont systématiquement écrasées /!\* - -### Installation d'une nouvelle VM - -Nécessite le paquet `virtinst`. - -Pour installer une nouvelle machine virtuelle à partir d'une image ISO : - -~~~ -virt-install \ ---connect=qemu:///system \ ---name= \ ---vcpus=2 \ ---ram=1024 \ ---disk path=/srv/.raw,device=disk,format=raw ---network=bridge:lan1 \ ---noautoconsole \ ---vnc \ ---vnclisten=127.0.0.1 \ ---keymap=fr \ ---cdrom=/path/to/image.iso -~~~ - -Si l'image disque est déjà existante, remplacer `--cdrom=/path/to/image.iso` par `--import`. - -Pour éditer le fichier XML généré : - -~~~ -virsh edit -~~~ - -### Performances - -Utiliser autant que possible les drivers virtio (disque et réseau) sur les invités le supportant. - -Dans le cas d'un hyperviseur avec une carte RAID HW disposant d'un cache avec batterie, créer les machines avec l'option "cache=none" : - -~~~ - -~~~ -Et désactiver les barrières si Ext4 est utilisé. - -Le scheduler deadline semble également donner les meilleures performances tant sur l'hôte que sur les invités. - -On peut aussi présenter toutes les instructions du CPU hôte aux machines virtuelles : - -~~~ - - - -~~~ - -### Cloner une machine - -Via clic-droit sur virt-manager ou en CLI : - -~~~ -# virt-clone --original mytemplate-domainame --name newmachine --file newmachine.img -~~~ - -Cela permet de dupliquer un domaine existante avec notamment changement de l'adresse MAC de la carte réseau. - -Si besoin d'étendre l'image : - -~~~ -# dd oflag=append conv=notrunc if=/dev/zero of=./newmachine.img bs=1MB count=20480 #+20Go -~~~ - -En cas de fichier image de type « sparse file » que l'on veut conserver. Il faut d'abord le créer, l'étendre (si besoin), puis l'indiquer en chemin lors du clone. - -~~~ -# rsync -avS source.img destination.img -## Extend to 100G -# dd if=/dev/zero of=file.img bs=1 count=0 seek=100G -# virt-clone --original mytemplate-domainame --name newmachine --file destination.img --preserve-data -~~~ - -Une fois la machiné démarré, il faudra modifier son hostname, son adresse IP et ses clés SSH. - -~~~ -# echo example > /etc/hostname -# rm /etc/ssh/ssh_host_* -# dpkg-reconfigure openssh-server -# vim /etc/network/interfaces -## En Squeeze supprimer la règle pour eth0 et renommer eth1 en eth0 -# vi /etc/udev/rules.d/70-persistent-net.rules -~~~ - -### Migrer une machine - - - -Note : Il faut s'assurer d'ouvrir les ports TCP 49152 à 49215 entre les machines car par défaut libvirtd utilisent ces ports pour faire des netcat des données ! - -Pour une migration à chaud, il faut avoir un storage commun pour les disques (SAN, réplication DRBD, etc.). - -Pour envoyer une VM locale vers la machine foo : - -~~~ -# VIRSH_DEFAULT_CONNECT_URI='qemu:///system' virsh migrate --live --unsafe test qemu+ssh://foo/system -~~~ - -Pour rappatrier une VM depuis la machine foo : - -~~~ -# VIRSH_DEFAULT_CONNECT_URI='qemu+ssh://foo/system' virsh migrate --live --unsafe test qemu:///system -~~~ - -Note : on peut faire cela via virt-manager (attention, le mode --unsafe parfois pratique n'est pas supporté…) - -Si l'on a plusieurs interfaces réseau sur l'hyperviseur (par exemple un réseau dédié entre les hyperviseurs), il faut l'indiquer à libvirtd sinon il tente de passer par l'interface principale : - -~~~ -# virsh migrate --live --unsafe test qemu+ssh://192.168.0.2/system tcp://192.168.0.2/ -Migration: [100 %] -~~~ - -rem : sur des machines très proches matériellement, il est possible d'avoir un soucis du fait d'un system-uuid identique sur les deux hyperviseurs - -~~~ -error: internal error: Attempt to migrate guest to the same host 12341234-1234-1234-1234-1234123412341234 -~~~ -Il faut éditer /etc/libvirt/libvirtd.conf (cf # UUID of the host) et ajouter un autre uuid puis redémarrer le service libvirtd pour prise en compte - - -### Désactiver l'interface réseau d'une VM à chaud - -Pour ne pas avoir besoin de redémarrer une VM pour retirer une interface, on peut retirer son interface vnetX sur l'hyperviseur du bridge associé. Le nom de cette interface se trouve avec la commande "virsh dumpxml" : - -~~~ -# virsh dumpxml test -[…] - - - - - - -
- -~~~ - -Il suffit ensuite de la retirer du bridge : - -~~~ -brctl delif br2 vnet7 -~~~ - -## Systemd - -Libvirt fait appel à systemd (machinectl/systemd-run) pour lancer les processus des VM et les suivre. -Pour avoir le status : - -~~~ -# machinectl -MACHINE CONTAINER SERVICE -qemu-mavm vm libvirt-qemu - -1 machines listed. -~~~ - -~~~ -# machinectl status qemu-mavm -qemu-mavm(db0b0ff5e71e4ed9813b226f6843729a) - Since: Mon 2016-02-22 18:17:49 CET; 8 months 25 days ago - Leader: 33012 (qemu-system-x86) - Service: libvirt-qemu; class vm - Address: 192.0.2.1 - OS: Debian GNU/Linux 8 (jessie) - Unit: machine-qemu\x2dmavm.scope - ??33012 qemu-system-x86_64 -enable-kvm -name mavm -S -machine pc-i440fx-2.1,accel=kvm,usb=off -cpu SandyBridge… -~~~ - -En cas de plantage du processus qemu-system (OOMKill par exemple), il sera peut être nécessaire de faire un systemctl reset-failed avant de redémarrer la VM : - -~~~ -# systemctl reset-failed machine-qemu\\x2dmavm.scope -~~~ - -## Munin - -Il peut être intéressant de grapher quelques infos de KVM dans Munin. Pour cela on peut utiliser quelques plugins. - - -~~~ -# mkdir -p /usr/local/share/munin/plugins/ -# cd /usr/local/share/munin/plugins/ -# wget -# wget -# wget -# sed -i 's/pidof kvm/pidof qemu-system-x86_64/' kvm_* -# chmod -R 755 /usr/local/share/munin -# cd /etc/munin/plugins/ -# ln -s /usr/local/share/munin/plugins/kvm_* . -# cat <> /etc/munin/plugin-conf.d/munin-node - -[kvm_io] -user root -EOT -~~~ - - -## FAQ - - - -### Je n'arrive pas à exécuter certaines commandes virsh - -Solution : assurez-vous que vous avez bien positionnez la variable VIRSH_DEFAULT_CONNECT_URI ! - -Dans certains cas, elle se positionne par défaut à _vbox:///system_ -On peut évidemment s'assurer en la forçant : - -~~~ -VIRSH_DEFAULT_CONNECT_URI='qemu:///system' virsh list -~~~ - -### En Debian 8, je ne trouve pas kvm-img - -C'est désormais _qemu-img_ inclu dans le paquet _qemu-utils_. -a priori en Debian 6, c'était _qemu-img_ (inclus par défaut) et en Debian 7 c'était _kvm-img_ (inclus par défaut). - -### Soucis réseau avec machine clonée - -Lorsqu'une machine est clonée avec virt-manager ou virsh, une nouvelle adresse MAC est générée (pour éviter les conflits). Cependant, comme il s'agit d'un clone, l'adresse MAC connue de Udev est toujours présente (dans /etc/udev/rules.d/z25_persistent-net.rules) et l'interface apparait donc comme eth1. - -Deux solutions, utiliser eth1 au lieu de eth0, ou corriger /etc/udev/rules.d/z25_persistent-net.rules en mettant à jour l'adresse MAC de eth0 et en supprimant eth1. - -### Mode réseau NAT avec un laptop +### Mode réseau NAT Le mode NAT peut être intéressant si l'on ne peut pas avoir d'IP dans le réseau local. -Une autre raison d'utiliser le NAT, est qu'une interface Wi-Fi n'est pas toujours utilisable dans un bridge : +Une autre raison d'utiliser le NAT est qu'une interface Wi-Fi n'est pas toujours utilisable dans un bridge : ~~~ # brctl addif br0 wlan0 @@ -705,7 +446,7 @@ Dans vos machines virtuelles, prenez une adresse IP dans la plage 10.0.0.0/24 et Normalement, c'est tout ! Si vous lancez plusieurs machines virtuelles, vous penserez à modifier l'adresse MAC et à utiliser des tapN différents. -Si vous voulez les faire communiquer entre elle, vous devrez simplement créer un bridge entre les interfaces tap : +Si vous voulez les faire communiquer entre elles, vous devrez simplement créer un bridge entre les interfaces tap : ~~~ # brctl addbr br0 @@ -715,13 +456,442 @@ Si vous voulez les faire communiquer entre elle, vous devrez simplement créer u etc. ~~~ -### Erreur "KVM: disabled by BIOS" -Vous devez activer la virtualisation sur votre processeur (cela se fait par le BIOS). +## Snapshots -### Erreur "Unable to create cgroup for $VIRTIMAGE: No such file or directory" et problème avec machine-qemu\x2dfoo.scope +L'utilisation du format de stockage QCOW2 permet d'avoir des snapshots à chaud ! +On peut créer plusieurs snapshots de l'état disque/mémoire, et restaurer en quelques secondes. -Si votre VM a crashée et n'est pas "redémarrable", notamment il reste des « traces » dans /run/systemd/system/machine-qemu\x2dfoo.scope vous pouvez faire un *reset-failed* : +### Avec libvirt + +Avec libvirt, création/restauration/suppression de snapshot se gère de façon conviviale avec *virt-manager*. + +On peut aussi utiliser virsh : + +~~~ +# virsh snapshot-list template + Name Creation Time State +------------------------------------------------------------ + snapshot1 2016-12-27 01:46:58 +0000 running + +# virsh snapshot-info --snapshotname snapshot1 template +Name: snapshot1 +Domain: template +Current: yes +State: running +Location: internal +Parent: - +Children: 0 +Descendants: 0 +Metadata: yes + +# virsh help snapshot + Snapshot (help keyword 'snapshot'): + snapshot-create Create a snapshot from XML + snapshot-create-as Create a snapshot from a set of args + snapshot-current Get or set the current snapshot + snapshot-delete Delete a domain snapshot + snapshot-dumpxml Dump XML for a domain snapshot + snapshot-edit edit XML for a snapshot + snapshot-info snapshot information + snapshot-list List snapshots for a domain + snapshot-parent Get the name of the parent of a snapshot + snapshot-revert Revert a domain to a snapshot +~~~ + +### Sans libvirt + +On peut gérer les snapshots via le [Mode Monitor](#mode-monitor) et les commandes *savevm*/*loadvm*/*info snapshots*. + +On peut démarrer directement sur un snapshot *s0* avec l'option `-loadvm` : + +~~~ +$ kvm -hda debian1.qcow2 -m 512 -net nic,macaddr= -net tap,script=/etc/qemu-ifup \ + -curses -monitor tcp:127.0.0.1:,server,nowait -loadvm s0 +~~~ + +On peut démarrer une VM avec le mode `-snapshot` où rien n'est réellement écrit sur le disque : + +~~~ +$ kvm -hda debian1.qcow2 -m 512 -net nic,macaddr= -net tap,script=/etc/qemu-ifup \ + -curses -monitor tcp:127.0.0.1:,server,nowait -snapshot +~~~ + +Au prochain redémarrage, le système revient à son état précédent. +Si nécessaire on peut tout de même forcer l'écriture en passant l'option *commit all* en mode monitor : + +~~~ +(qemu) commit all +~~~ + +### Images dérivées d'une image QCOW2 + + + +Une option intéressante est de créer une image d'une installation de base et de créer des dérivées +à partir de cette image. Non seulement permet de repartir d'une installation déjà faite, mais cela +permet aussi une optimisation de la place (l'image dérivée est en Copy-on-Write de celle de base) +voire même de la mémoire selon les rumeurs :-) + +Création d'une image dérivée : + +~~~ +# qemu-img create -f qcow2 -b install-debian-base.qcow2base serveur01.qcow2snap +Formatting 'serveur01.qcow2snap', fmt=qcow2 size=12884901888 backing_file='install-debian-base.qcow2base' encryption=off cluster_size=0 +# qemu-img info serveur01.qcow2snap +image: serveur01.qcow2snap +file format: qcow2 +virtual size: 12G (12884901888 bytes) +disk size: 140K +cluster_size: 65536 +backing file: install-debian-base.qcow2base (actual path: install-debian-base..qcow2base) +~~~ + +/!\\ Attention, ne jamais modifier une image de base si elle a des images dérivées sous peine de tout perdre !! + + + +## Mode monitor + + + +Le mode *monitor* permet d'effectuer diverses actions. Attention, il n'est pas disponible pour les VM utilisant libvirt. + +Pour créer un mode monitor : + +~~~ +$ kvm […] -monitor tcp:127.0.0.1:,server,nowait +~~~ + +Pour accéder au mode monitor : + +~~~ +$ telnet 127.0.0.1 +Trying 127.0.0.1… +Connected to 127.0.0.1. +Escape character is '^]'. +QEMU 0.9.1 monitor - type 'help' for more information +(qemu) +~~~ + +### Extinction ACPI d'une VM + +~~~ +$ echo system_powerdown | nc 127.0.0.1 +QEMU 0.12.5 monitor - type 'help' for more information +(qemu) system_powerdown +(qemu) +^C +~~~ + +### pause/resume d'une VM + +~~~ +$ nc 127.0.0.1 +QEMU 0.12.5 monitor - type 'help' for more information +(qemu) stop +stop +(qemu) cont +cont +~~~ + +### Gestion des snapshots via le mode monitor + +Ceci n'est disponible que pour les VMs utilisant un stockage QCOW2. + +Créer et lister les snapshots : + +~~~ +(qemu) savevm s0 +savevm s0 +(qemu) info snapshots +info snapshots +Snapshot devices: ide0-hd0 +Snapshot list (from ide0-hd0): +ID TAG VM SIZE DATE VM CLOCK +1 s0 20M 2010-11-14 20:07:09 00:16:01.182 +(qemu) +~~~ + +Restauration à chaud : + +~~~ +(qemu) loadvm s0 +~~~ + +Pour réaliser des snapshots automatiques sans arrêt de la machine, on pourra avoir un script du type : + +~~~{.bash} +#!/bin/sh +echo "savevm snap.current" | telnet 127.0.0.1 +sync +cp debian1.qcow2 debian.current.qcow2 +~~~ + + +## virsh + + + +La commande **virsh** permet de faire de nombreuses manipulations en ligne de commande : + +~~~ +## Lister les VMs actives +# virsh list + +## Lister les VMs actives/inactives +# virsh list --all + +## Démarrer/Stopper proprement une VM +# virsh start +# virsh shutdown + +## Forcer l'extinction d'une VM (elle n'est pas détruite !) +# virsh destroy + +## Informations avancées sur une VM +# virsh dominfo + +## Activer/désactiver le démarrage automatique d'une VM +# virsh autostart +# virsh autostart --disable + +## Dumper la configuration d'une VM dans un fichier de définition XML +# virsh dumpxml > .xml + +## Créer/détruire une définition de VM +# virsh define .xml +# virsh undefine + +## Modifier les options d'une VM +# virsh edit +~~~ + +/!\\ Attention, il faut toujours utiliser `virsh edit` et ne jamais éditer le fichier dans `/etc/libvirt/qemu/` qui est régulièrement écrasé ! + +La commande **virsh** peut également être utilisée à distance : + +~~~ +# VIRSH_DEFAULT_CONNECT_URI='qemu+ssh://root@kvm.example.com/system' virsh list --all +~~~ + +*Note* : par défaut *VIRSH_DEFAULT_CONNECT_URI='qemu:///system'* + + +## Cloner une VM + +Via clic-droit sur _virt-manager_ ou en CLI : + +~~~ +# virt-clone --original --name --file .img +~~~ + +Cela permet de dupliquer un domaine existant avec notamment changement de l'adresse MAC de la carte réseau. + +Une fois la machiné démarrée, il faudra modifier son *hostname*, son adresse IP et ses clés SSH. + +~~~ +# echo example > /etc/hostname +# rm /etc/ssh/ssh_host_* +# dpkg-reconfigure openssh-server +# vim /etc/network/interfaces +## En Squeeze supprimer la règle pour eth0 et renommer eth1 en eth0 +# vi /etc/udev/rules.d/70-persistent-net.rules +~~~ + +On peut utiliser l'option `--preserve-data` pour copier les données vers une image vierge existante (par exemple de taille différente) : + +~~~ +# virt-clone --original --name --file .img --preserve-data +~~~ + + +## Migrer une VM + + + +Note : Il faut s'assurer d'ouvrir les ports TCP 49152 à 49215 entre les machines car par défaut libvirtd utilisent ces ports pour faire des netcat des données ! + +Pour une migration à chaud, il faut avoir un storage commun pour les disques (SAN, réplication DRBD, etc.). + +Pour envoyer une VM locale vers la machine foo : + +~~~ +# VIRSH_DEFAULT_CONNECT_URI='qemu:///system' virsh migrate --live --unsafe test qemu+ssh://foo/system +~~~ + +Pour rappatrier une VM depuis la machine foo : + +~~~ +# VIRSH_DEFAULT_CONNECT_URI='qemu+ssh://foo/system' virsh migrate --live --unsafe test qemu:///system +~~~ + +Note : on peut faire cela via virt-manager (attention, le mode `--unsafe` n'est pas supporté !!) + +Si l'on a plusieurs interfaces réseau sur l'hyperviseur (par exemple un réseau dédié entre les hyperviseurs), il faut l'indiquer à libvirtd sinon il tente de passer par l'interface principale : + +~~~ +# virsh migrate --live --unsafe test qemu+ssh://192.168.0.2/system tcp://192.168.0.2/ +Migration: [100 %] +~~~ + +*Note* : sur des machines très proches matériellement, il est possible d'avoir un souci du fait d'un system-uuid identique sur les deux hyperviseurs : + +~~~ +error: internal error: Attempt to migrate guest to the same host 12341234-1234-1234-1234-1234123412341234 +~~~ + +Il faut éditer `/etc/libvirt/libvirtd.conf` (cf # UUID of the host) et ajouter un autre uuid puis redémarrer le service _libvirtd_ pour prise en compte. + + +## Systemd + +libvirt fait appel à systemd (machinectl/systemd-run) pour lancer les processus des VM et les suivre. + +Pour avoir le statut : + +~~~ +# machinectl +MACHINE CONTAINER SERVICE +qemu-mavm vm libvirt-qemu + +1 machines listed. +~~~ + +~~~ +# machinectl status qemu-mavm +qemu-mavm(db0b0ff5e71e4ed9813b226f6843729a) + Since: Mon 2016-02-22 18:17:49 CET; 8 months 25 days ago + Leader: 33012 (qemu-system-x86) + Service: libvirt-qemu; class vm + Address: 192.0.2.1 + OS: Debian GNU/Linux 8 (jessie) + Unit: machine-qemu\x2dmavm.scope + ??33012 qemu-system-x86_64 -enable-kvm -name mavm -S -machine pc-i440fx-2.1,accel=kvm,usb=off -cpu SandyBridge… +~~~ + +En cas de plantage du processus _qemu-system_, il sera peut être nécessaire de faire un `systemctl reset-failed` avant de redémarrer la VM : + +~~~ +# systemctl reset-failed machine-qemu\\x2dmavm.scope +~~~ + +## Munin + +Il peut être intéressant de grapher quelques infos de KVM dans _Munin_. +Pour cela on peut utiliser quelques plugins : + +~~~ +$ wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/virtualization/kvm_cpu +$ wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/virtualization/kvm_io +$ wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/virtualization/kvm_mem +$ sed -i 's/pidof kvm/pidof qemu-system-x86_64/' kvm_* +~~~ + +Le plugin *kvm_io* nécessite de tourner en root, `/etc/munin/plugin-conf.d/munin-node` : + +~~~ +[kvm_io] +user root +~~~ + + +## FAQ + + + +### Je n'arrive pas à exécuter certaines commandes virsh + +Solution : assurez-vous que vous avez bien positionnez la variable VIRSH_DEFAULT_CONNECT_URI ! + +Dans certains cas, elle se positionne par défaut à _vbox:///system_ +On peut la forcer pour être sûr : + +~~~ +VIRSH_DEFAULT_CONNECT_URI='qemu:///system' virsh list +~~~ + +### En Debian 8, je ne trouve pas kvm-img + +C'est désormais _qemu-img_ inclu dans le paquet _qemu-utils_. +a priori en Debian 6, c'était _qemu-img_ (inclus par défaut) et en Debian 7 c'était _kvm-img_ (inclus par défaut). + +### Soucis réseau avec machine clonée + +Lorsqu'une machine est clonée avec _virt-manager_ ou _virsh_, une nouvelle adresse MAC est générée (pour éviter les conflits). +Cependant, comme il s'agit d'un clone, l'adresse MAC connue de Udev est toujours présente (dans /etc/udev/rules.d/z25_persistent-net.rules) et l'interface apparait donc comme eth1. + +Deux solutions, utiliser eth1 au lieu de eth0, ou corriger /etc/udev/rules.d/z25_persistent-net.rules en mettant à jour l'adresse MAC de eth0 et en supprimant eth1. + +### Installation d'une VM sans libvirt + +~~~ +# qemu-img create -f qcow2 debian1.qcow2 20G +# kvm -hda debian1.qcow2 -cdrom debian-amd64-netinst.iso -boot d -m 512 -net nic,macaddr= -net tap,script=/etc/qemu-ifup -vnc :1 -k fr + +# /usr/bin/screen -S debian1 -d -m kvm -hda debian1.qcow2 -m 512 -net nic,macaddr= -net tap,script=/etc/qemu-ifup \ + -curses -k fr -monitor tcp:127.0.0.1:,server,nowait +~~~ + +### Accéder à virt-manager sur un hyperviseur + +Installer sur l'hyperviseur et se connecter en `ssh -X`. Options recommandées : + +~~~ +$ ssh -X -C -c arcfour root@kvm.example.com +~~~ + +### Désactiver l'interface réseau d'une VM à chaud + +Pour ne pas avoir besoin de redémarrer une VM pour retirer une interface, on peut retirer son interface vnetX sur l'hyperviseur du bridge associé. Le nom de cette interface se trouve avec la commande "virsh dumpxml" : + +~~~ +# virsh dumpxml +[…] + + + + + + +
+ +~~~ + +~~~ +# virsh detach-interface […] +~~~ + +Il suffit ensuite de la retirer du bridge : + +~~~ +# brctl delif br2 vnet7 +~~~ + +### Performances (TODO: à revoir) + +Utiliser autant que possible les drivers virtio (disque et réseau) sur les invités le supportant. + +Dans le cas d'un hyperviseur avec une carte RAID hardware disposant d'un cache avec batterie, créer les machines avec l'option "cache=none" : + +~~~ + +~~~ +Et désactiver les barrières si Ext4 est utilisé. + +Le scheduler deadline semble également donner les meilleures performances tant sur l'hôte que sur les invités. + +On peut aussi présenter toutes les instructions du CPU hôte aux machines virtuelles : + +~~~ + + + +~~~ + +### Erreur "Unable to create cgroup" + +Si votre VM a crashé et n'est pas "redémarrable" avec un message "Unable to create cgroup for $VIRTIMAGE: No such file or directory", notamment il reste des « traces » dans /run/systemd/system/machine-qemu\x2dfoo.scope vous pouvez faire un *reset-failed* : ~~~ # systemctl status machine-qemu\\x2dfoo.scope