wiki/HowtoKVM.md

983 lines
30 KiB
Markdown
Raw Normal View History

2016-12-26 22:32:43 +01:00
# Howto KVM
2016-12-27 03:53:21 +01:00
* Documentation KVM : <http://www.linux-kvm.org/page/Documents>
* Documentation libvirt : <https://libvirt.org/docs.html>
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
[KVM](http://www.linux-kvm.org/) est une technologie de virtualisation intégrée au noyau Linux.
2016-12-26 22:32:43 +01:00
## Installation
2016-12-27 03:53:21 +01:00
Pour installer un hyperviseur (machine capable de faire tourner des machines virtuelles) :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# apt install qemu-kvm bridge-utils qemu-utils libvirt-bin virtinst netcat-openbsd
2016-12-26 22:32:43 +01:00
~~~
~~~
2016-12-27 03:53:21 +01:00
$ 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
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
## Utilisation basique de libvirt
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
[libvirt](https://libvirt.org) est une surcouche facilitant la gestion de la virtualisation.
2016-12-26 22:32:43 +01:00
2016-12-27 04:03:18 +01:00
Un démon **libvirtd** tourne sur l'hyperviseur, il peut être redémarré sans impact sur les VMs :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# systemctl restart libvirtd
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
La commande **virsh** permet de réaliser des opérations en ligne de commande :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# virsh list --all
# virsh start <vm-name>
# virsh shutdown <vm-name>
# virsh destroy <vm-name>
# virsh edit <vm-name>
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Pour un accès « graphique », installer sur le poste client :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# apt install virt-manager netcat-openbsd
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
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.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Cela s'active souvent via le BIOS de la machine.
Si ce n'est pas activé, vous aurez une erreur *KVM: disabled by BIOS*
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
### Configuration mémoire
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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).
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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 :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
@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
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### Configuration réseau
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
On conseille l'utilisation du mode **bridge** pour le réseau.
On crée un bridge _br0_ liée à l'interface _eth0_ :
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~
# brctl addbr br0
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Puis on ajuste le fichier `/etc/network/interfaces` ainsi :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 05:31:00 +01:00
#source-directory /etc/network/interfaces.d
2016-12-27 03:53:21 +01:00
auto br0
iface eth0 inet manual
iface br0 inet static
address <address>
netmask <netmask>
gateway <gateway>
bridge_ports eth0
up echo 0 > /sys/class/net/br0/bridge/multicast_snooping
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 05:31:00 +01:00
*Note 1* : il est nécessaire de désactiver le multicast_snooping pour assurer un bon fonctionnement de l'IPv6
*Note 2* : il est nécessaire de commenter *source-directory /etc/network/interfaces.d* car [cela fait boguer libvirt](http://bugs.debian.org/740114)
2016-12-27 03:53:21 +01:00
/!\\ : s'assurer d'avoir bien installé _bridge-utils_ et configuré le firewall avant de redémarrer
### Configuration stockage
<https://libvirt.org/storage.html>
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 <http://cdimage.debian.org/debian-cd/current/amd64/iso-cd/>) puis l'on crée une VM :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ virt-install --connect=qemu:///system \
2016-12-27 04:03:18 +01:00
--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
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
*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 :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ vncviewer -via kvm.example.com 127.0.0.1:5900
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### virt-manager
**Nous déconseillons l'installation via _virt-manager_ !!**
Certes, l'installation est plus conviviale (car graphique) mais :
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
* 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.)
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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
<http://libvirt.org/formatdomain.html>
Vous pouvez écrire votre propre fichier de définition XML puis l'injecter :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# virsh define template.xml
# virsh start template
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
## Stockage
2016-12-27 04:03:18 +01:00
### Volumes DRBD/LVM
TODO
2016-12-27 03:53:21 +01:00
### 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 test0.qcow2 5G
~~~
Information sur une image QCOW2 :
2016-12-26 22:32:43 +01:00
~~~
# qemu-img info debian1.qcow2
image: debian1.qcow2
file format: qcow2
virtual size: 12G (12884901888 bytes)
disk size: 908M
cluster_size: 65536
~~~
2016-12-27 03:53:21 +01:00
Agrandir une image :
De façon similaire au format RAW, on peut agrandir une image QCOW2. Voir <http://blog.majerti.fr/resize-qcow2.html>
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
~~~
2016-12-26 22:32:43 +01:00
### Format RAW
L'avantage de ce format est sa simplicité ! C'est tout simplement une suite d'octets..
Cela permet de monter les partitions facilement (merci _kpartx_).
Sous Linux, grâce au _sparse file_, c'est également un format à taille variable.
Création de l'image :
~~~
# qemu-img create -f raw test0.img 5G
~~~
Mountage de l'image (attention à ne jamais la monter en cours de fonctionnement) :
~~~
# modprobe dm-mod # Si kpartx renvoi un /proc/misc: No entry for device-mapper found
# kpartx -v -a test0.img
loop1p1 : 0 9912042 /dev/loop1 63
loop1p2 : 0 562275 /dev/loop1 9912105
loop1p5 : 0 562212 loop1p1 63
# fdisk -l /dev/loop1
# mount /dev/mapper/loop1p1 /mnt/test0
# umount /mnt/test0
# kpart -d test0.img
~~~
Convertir ume image RAW en QCOW2 :
~~~
# qemu-img convert -f raw -O qcow2 test0.img test0.qcow2
~~~
#### Agrandir une image
2016-12-27 03:53:21 +01:00
* Vérifier qu'aucun processus n'accède à l'image (la VM doit notamment être éteinte !)
* Agrandir le fichier image avec la taille désirée :
2016-12-26 22:32:43 +01:00
~~~
# qemu-img resize host.img +50G
Image resized.
~~~
2016-12-27 05:31:00 +01:00
ou on peut utiliser _dd_, exemple pour une taille finale de 80G :
2016-12-26 22:32:43 +01:00
~~~
# dd if=/dev/zero of=host.img seek=80G count=0 bs=1
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.302e-05 s, 0.0 kB/s
~~~
2016-12-27 03:53:21 +01:00
* Monter l'image et vérifier qu'elle a la bonne taille :
2016-12-26 22:32:43 +01:00
~~~
# kpartx -v -a host.img
add map loop0p1 (254:4): 0 314572737 linear /dev/loop0 63
# fdisk -l /dev/loop0
Disk /dev/loop0: 161.1 GB, 161061273600 bytes
[…]
~~~
2016-12-27 03:53:21 +01:00
* Supprimer puis recréer la partition avec la bonne taille à l'intérieur de l'image, après avoir sauvegarder la table des partitions :
2016-12-26 22:32:43 +01:00
~~~
# sfdisk -d /dev/loop0 >~/loop0.parts
# parted /dev/loop0
[…]
~~~
Voir <http://trac.evolix.net/infogerance/wiki/HowtoParted>
2016-12-27 03:53:21 +01:00
* Démonter et remonter l'image (un partprobe ne suffit visiblement pas pour détecter la nouvelle taille de la partition) :
2016-12-26 22:32:43 +01:00
~~~
# kpartx -d host.img
loop deleted : /dev/loop0
# kpartx -v -a host.img
add map loop0p1 (254:4): 0 314572737 linear /dev/loop0 63
~~~
2016-12-27 03:53:21 +01:00
* Lancer un fsck puis un resize2fs pour redimensionner le système de fichiers :
2016-12-26 22:32:43 +01:00
~~~
# e2fsck -f /dev/mapper/loop0p1
e2fsck 1.42.5 (29-Jul-2012)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/loop0p1: 46712/6111232 files (8.3% non-contiguous), 20257932/24414775 blocks
# resize2fs /dev/mapper/loop0p1
resize2fs 1.42.5 (29-Jul-2012)
Resizing the filesystem on /dev/mapper/loop0p1 to 39321592 (4k) blocks.
The filesystem on /dev/mapper/loop0p1 is now 39321592 blocks long.
~~~
2016-12-27 03:53:21 +01:00
* Vérifier que le système de fichiers voit la bonne taille en montant la partition :
2016-12-26 22:32:43 +01:00
~~~
# mount /dev/mapper/loop0p1 /mnt
# df -h /mnt
/dev/mapper/loop0p1 148G 76G 72G 52% /mnt
# umount /mnt
~~~
2016-12-27 03:53:21 +01:00
* Puis démonter l'image :
2016-12-26 22:32:43 +01:00
~~~
# kpartx -d host.img
loop deleted : /dev/loop0
~~~
2016-12-27 03:53:21 +01:00
## Réseau
2016-12-27 05:31:00 +01:00
~~~
# virsh iface-list --all
# virsh net-list --all
# virsh help interface
Interface (help keyword 'interface'):
iface-begin create a snapshot of current interfaces settings, which can be later committed (iface-commit) or restored (iface-rollback)
iface-bridge create a bridge device and attach an existing network device to it
iface-commit commit changes made since iface-begin and free restore point
iface-define define (but don't start) a physical host interface from an XML file
iface-destroy destroy a physical host interface (disable it / "if-down")
iface-dumpxml interface information in XML
iface-edit edit XML configuration for a physical host interface
iface-list list physical host interfaces
iface-mac convert an interface name to interface MAC address
iface-name convert an interface MAC address to interface name
iface-rollback rollback to previous saved configuration created via iface-begin
iface-start start a physical host interface (enable it / "if-up")
iface-unbridge undefine a bridge device after detaching its slave device
iface-undefine undefine a physical host interface (remove it from configuration)
# virsh help network
Networking (help keyword 'network'):
net-autostart autostart a network
net-create create a network from an XML file
net-define define (but don't start) a network from an XML file
net-destroy destroy (stop) a network
net-dhcp-leases print lease info for a given network
net-dumpxml network information in XML
net-edit edit XML configuration for a network
net-event Network Events
net-info network information
net-list list networks
net-name convert a network UUID to network name
net-start start a (previously defined) inactive network
net-undefine undefine a persistent network
net-update update parts of an existing network's configuration
net-uuid convert a network name to network UUID
~~~
2016-12-27 03:53:21 +01:00
### Adresse MAC
On peut générer l'adresse MAC d'une VM KVM avec le script suivant :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ echo $(echo -n 52:54:00 ; for i in `seq 1 3`; do echo -n `echo ":$RANDOM$RANDOM" | cut -n -c -3`; done)
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### Mode bridge + VLAN
Vous pouvez faire passer plusieurs VLANs dans votre bridge,
afin de permettre l'accès depuis vos VMs à différents VLANs.
Sur l'hyperviseur on aura ainsi une configuration réseau du type (paquet *vlan* à installer) :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
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 <address>
netmask <netmask>
gateway <gateway>
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Dans les VMs, on aura ainsi une configuration réseau VLANisé (voir [HowtoDebian/Reseau]).
### Mode bridge avec openvswith
Notamment utile pour utiliser avec le RPN Online.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
`/etc/network/interfaces` :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# LAN bridge over RPN
# <https://documentation.online.net/fr/dedicated-server/tutorials/network/rpn-proxmox-openvswitch>
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
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Créer un fichier XML définissant le réseau :
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~{.xml}
<network>
<name>br1</name>
<forward mode='bridge'/>
<bridge name='br1'/>
<virtualport type='openvswitch'/>
</network>
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
~~~
# virsh net-define br1.xml
# virsh net-start br1
# virsh net-autostart br1
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 05:31:00 +01:00
### Mode réseau NAT (avec libvirt)
Le mode NAT peut être intéressant si l'on ne peut pas avoir d'IP dans le réseau de l'hyperviseur.
Avec libvirt, il suffit d'installer :
~~~
# apt install dnsmaq ebtables
~~~
Et l'on peut configurer avec un réseau NAT avec _virt-manager_ ou `virsh net-create` et un fichier XML du type :
~~~{.xml}
<network connections='1'>
<name>reseau1</name>
<uuid>f94578a3-3b7f-4c60-a441-d1f86920fb59</uuid>
<forward dev='eth0' mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
<interface dev='eth0'/>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:06:2e:8c'/>
<domain name='nat0'/>
<ip address='192.168.100.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.100.128' end='192.168.100.254'/>
</dhcp>
</ip>
</network>
~~~
### Mode réseau NAT (sans libvirt)
2016-12-26 22:32:43 +01:00
2016-12-27 05:31:00 +01:00
Une raison d'utiliser le NAT est qu'une interface Wi-Fi n'est pas toujours utilisable dans un bridge :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# brctl addif br0 wlan0
can't add wlan0 to bridge br0: Operation not supported
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
On va donc prendre l'exemple où vous avez une interface Wi-Fi wlan0 :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Vous pouvez ainsi lancer votre KVM ainsi (on lance un CD-ROM d'OpenBSD dans notre cas) :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# kvm -hda routeur0.qcow2 -cdrom cd48.iso -boot d -m 384 -k fr -net nic,macaddr=52:54:00:de:ad:42,model=e1000 -net tap,vlan=0,ifname=tap0
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Une fois démarré, attribuez l'IP 10.0.0.1/24 à l'interface tap0 sur votre portable.
Dans vos machines virtuelles, prenez une adresse IP dans la plage 10.0.0.0/24 et indiquez 10.0.0.1 comme route par défaut.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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 elles, vous devrez simplement créer un bridge entre les interfaces tap :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# brctl addbr br0
# brctl addif br0 tap0
# brctl addif br0 tap1
# brctl addif br0 tap2
etc.
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
## Snapshots
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
### Avec libvirt
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Avec libvirt, création/restauration/suppression de snapshot se gère de façon conviviale avec *virt-manager*.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
On peut aussi utiliser virsh :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# virsh snapshot-list template
Name Creation Time State
------------------------------------------------------------
snapshot1 2016-12-27 01:46:58 +0000 running
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
# virsh snapshot-info --snapshotname snapshot1 template
Name: snapshot1
Domain: template
Current: yes
State: running
Location: internal
Parent: -
Children: 0
Descendants: 0
Metadata: yes
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
# 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
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### Sans libvirt
On peut gérer les snapshots via le [Mode Monitor](#mode-monitor) et les commandes *savevm*/*loadvm*/*info snapshots*.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
On peut démarrer directement sur un snapshot *s0* avec l'option `-loadvm` :
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~
$ kvm -hda debian1.qcow2 -m 512 -net nic,macaddr=<mac_address> -net tap,script=/etc/qemu-ifup \
-curses -monitor tcp:127.0.0.1:<port monitor>,server,nowait -loadvm s0
~~~
On peut démarrer une VM avec le mode `-snapshot` où rien n'est réellement écrit sur le disque :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ kvm -hda debian1.qcow2 -m 512 -net nic,macaddr=<mac_address> -net tap,script=/etc/qemu-ifup \
-curses -monitor tcp:127.0.0.1:<port monitor>,server,nowait -snapshot
2016-12-26 22:32:43 +01:00
~~~
Au prochain redémarrage, le système revient à son état précédent.
2016-12-27 03:53:21 +01:00
Si nécessaire on peut tout de même forcer l'écriture en passant l'option *commit all* en mode monitor :
2016-12-26 22:32:43 +01:00
~~~
(qemu) commit all
~~~
2016-12-27 03:53:21 +01:00
### Images dérivées d'une image QCOW2
2016-12-26 22:32:43 +01:00
<http://wiki.qemu.org/Documentation/CreateSnapshot>
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
2016-12-27 03:53:21 +01:00
Formatting 'serveur01.qcow2snap', fmt=qcow2 size=12884901888 backing_file='install-debian-base.qcow2base' encryption=off cluster_size=0
2016-12-26 22:32:43 +01:00
# 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)
~~~
2016-12-27 03:53:21 +01:00
/!\\ Attention, ne jamais modifier une image de base si elle a des images dérivées sous peine de tout perdre !!
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Mode monitor
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
<http://en.wikibooks.org/wiki/QEMU/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 :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ kvm […] -monitor tcp:127.0.0.1:<port monitor>,server,nowait
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Pour accéder au mode monitor :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ telnet 127.0.0.1 <port monitor>
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)
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### Extinction ACPI d'une VM
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~
$ echo system_powerdown | nc 127.0.0.1 <port monitor>
QEMU 0.12.5 monitor - type 'help' for more information
(qemu) system_powerdown
(qemu)
^C
~~~
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
### pause/resume d'une VM
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ nc 127.0.0.1 <port monitor>
QEMU 0.12.5 monitor - type 'help' for more information
(qemu) stop
stop
(qemu) cont
cont
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### Gestion des snapshots via le mode monitor
Ceci n'est disponible que pour les VMs utilisant un stockage QCOW2.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Créer et lister les snapshots :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
(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)
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Restauration à chaud :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
(qemu) loadvm s0
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Pour réaliser des snapshots automatiques sans arrêt de la machine, on pourra avoir un script du type :
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~{.bash}
#!/bin/sh
echo "savevm snap.current" | telnet 127.0.0.1 <port>
sync
cp debian1.qcow2 debian.current.qcow2
~~~
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## virsh
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
<http://libvirt.org/sources/virshcmdref/html-single/>
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
La commande **virsh** permet de faire de nombreuses manipulations en ligne de commande :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
## Lister les VMs actives
# virsh list
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Lister les VMs actives/inactives
# virsh list --all
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Démarrer/Stopper proprement une VM
# virsh start <vm-name>
# virsh shutdown <vm-name>
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Forcer l'extinction d'une VM (elle n'est pas détruite !)
# virsh destroy <vm-name>
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Informations avancées sur une VM
# virsh dominfo <vm-name>
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Activer/désactiver le démarrage automatique d'une VM
# virsh autostart <vm-name>
# virsh autostart --disable <vm-name>
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Dumper la configuration d'une VM dans un fichier de définition XML
# virsh dumpxml <vm-name> > <vm-name>.xml
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Créer/détruire une définition de VM
# virsh define <vm-name>.xml
# virsh undefine <vm-name>
## Modifier les options d'une VM
# virsh edit <vm-name>
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
/!\\ Attention, il faut toujours utiliser `virsh edit` et ne jamais éditer le fichier dans `/etc/libvirt/qemu/` qui est régulièrement écrasé !
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
La commande **virsh** peut également être utilisée à distance :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# VIRSH_DEFAULT_CONNECT_URI='qemu+ssh://root@kvm.example.com/system' virsh list --all
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
*Note* : par défaut *VIRSH_DEFAULT_CONNECT_URI='qemu:///system'*
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Cloner une VM
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Via clic-droit sur _virt-manager_ ou en CLI :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# virt-clone --original <mytemplate-domainame> --name <newmachine> --file <newmachine>.img
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
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.
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 04:03:18 +01:00
# rm /etc/udev/rules.d/70-persistent-net.rules
# hostname foo ; echo foo > /etc/hostname
# rm /etc/ssh/ssh_host_* ; dpkg-reconfigure openssh-server
2016-12-26 22:32:43 +01:00
# vim /etc/network/interfaces
~~~
2016-12-27 03:53:21 +01:00
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 <mytemplate-domainame> --name <newmachine> --file <newmachine>.img --preserve-data
~~~
## Migrer une VM
2016-12-26 22:32:43 +01:00
<https://libvirt.org/migration.html>
2016-12-27 04:03:18 +01:00
*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 !
2016-12-26 22:32:43 +01:00
Pour une migration à chaud, il faut avoir un storage commun pour les disques (SAN, réplication DRBD, etc.).
2016-12-27 04:03:18 +01:00
Pour envoyer une VM locale _test_ vers l'hyperviseur _foo_ :
2016-12-26 22:32:43 +01:00
~~~
# VIRSH_DEFAULT_CONNECT_URI='qemu:///system' virsh migrate --live --unsafe test qemu+ssh://foo/system
~~~
2016-12-27 04:03:18 +01:00
Pour rappatrier une VM _test_ depuis l'hyperviseur _foo_ :
2016-12-26 22:32:43 +01:00
~~~
# VIRSH_DEFAULT_CONNECT_URI='qemu+ssh://foo/system' virsh migrate --live --unsafe test qemu:///system
~~~
2016-12-27 04:03:18 +01:00
*Note* : on peut faire cela via virt-manager mais le mode `--unsafe` (utile si un cache disque est configuré) n'est pas supporté…
2016-12-26 22:32:43 +01:00
2016-12-27 04:03:18 +01:00
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 :
2016-12-26 22:32:43 +01:00
~~~
# virsh migrate --live --unsafe test qemu+ssh://192.168.0.2/system tcp://192.168.0.2/
Migration: [100 %]
~~~
2016-12-27 03:53:21 +01:00
*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 :
2016-12-26 22:32:43 +01:00
~~~
error: internal error: Attempt to migrate guest to the same host 12341234-1234-1234-1234-1234123412341234
~~~
2016-12-27 03:53:21 +01:00
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.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
## Systemd
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
libvirt fait appel à systemd (machinectl/systemd-run) pour lancer les processus des VM et les suivre.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Pour avoir le statut :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# machinectl
MACHINE CONTAINER SERVICE
qemu-mavm vm libvirt-qemu
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
1 machines listed.
2016-12-26 22:32:43 +01:00
~~~
~~~
2016-12-27 03:53:21 +01:00
# 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…
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
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 :
2016-12-26 22:32:43 +01:00
~~~
# systemctl reset-failed machine-qemu\\x2dmavm.scope
~~~
## Munin
2016-12-27 03:53:21 +01:00
Il peut être intéressant de grapher quelques infos de KVM dans _Munin_.
Pour cela on peut utiliser quelques plugins :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ 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_*
~~~
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Le plugin *kvm_io* nécessite de tourner en root, `/etc/munin/plugin-conf.d/munin-node` :
~~~
2016-12-26 22:32:43 +01:00
[kvm_io]
user root
~~~
## FAQ
<http://www.linux-kvm.org/page/FAQ>
2016-12-27 03:55:33 +01:00
### Erreur avec certaines commandes virsh
2016-12-26 22:32:43 +01:00
2016-12-27 03:55:33 +01:00
Solution : tester de positionner la variable *VIRSH_DEFAULT_CONNECT_URI*
2016-12-26 22:32:43 +01:00
Dans certains cas, elle se positionne par défaut à _vbox:///system_
2016-12-27 03:55:33 +01:00
On peut donc la forcer :
2016-12-26 22:32:43 +01:00
~~~
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_.
2016-12-27 03:53:21 +01:00
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).
2016-12-26 22:32:43 +01:00
### Soucis réseau avec machine clonée
2016-12-27 03:53:21 +01:00
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.
2016-12-26 22:32:43 +01:00
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.
2016-12-27 03:53:21 +01:00
### Installation d'une VM sans libvirt
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~
# qemu-img create -f qcow2 debian1.qcow2 20G
# kvm -hda debian1.qcow2 -cdrom debian-amd64-netinst.iso -boot d -m 512 -net nic,macaddr=<mac_address> -net tap,script=/etc/qemu-ifup -vnc :1 -k fr
<installation via VNC 127.0.0.1:5901 puis boot final>
# /usr/bin/screen -S debian1 -d -m kvm -hda debian1.qcow2 -m 512 -net nic,macaddr=<mac_address> -net tap,script=/etc/qemu-ifup \
-curses -k fr -monitor tcp:127.0.0.1:<port>,server,nowait
~~~
### Accéder à virt-manager sur un hyperviseur
Installer sur l'hyperviseur et se connecter en `ssh -X`. Options recommandées :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
$ ssh -X -C -c arcfour root@kvm.example.com
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### 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" :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# virsh dumpxml <vm-name>
[…]
<interface type='bridge'>
<mac address='52:54:00:xx:xx:xx'/>
<source bridge='br2'/>
<target dev='vnet7'/>
<model type='virtio'/>
<alias name='net1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</interface>
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
~~~
# virsh detach-interface […]
~~~
Il suffit ensuite de la retirer du bridge :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
# brctl delif br2 vnet7
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
### Performances (TODO: à revoir)
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
Utiliser autant que possible les drivers virtio (disque et réseau) sur les invités le supportant.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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" :
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
<driver name='qemu' type='raw' cache='none'/>
2016-12-26 22:32:43 +01:00
~~~
2016-12-27 03:53:21 +01:00
Et désactiver les barrières si Ext4 est utilisé.
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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 :
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
~~~
<cpu mode='host-model'>
<model fallback='allow'/>
</cpu>
~~~
2016-12-26 22:32:43 +01:00
2016-12-27 05:31:00 +01:00
### Etendre une image RAW
Différentes méthodes pour étendre une image RAW :
~~~
# qemu-img resize host.img +50G
# dd if=/dev/zero of=host.img seek=80G count=0 bs=1
# dd oflag=append conv=notrunc if=/dev/zero of=host.img bs=1MB count=20480
~~~
2016-12-27 03:53:21 +01:00
### Erreur "Unable to create cgroup"
2016-12-26 22:32:43 +01:00
2016-12-27 03:53:21 +01:00
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* :
2016-12-26 22:32:43 +01:00
~~~
# systemctl status machine-qemu\\x2dfoo.scope
# systemctl reset-failed machine-qemu\\x2dfoo.scope
~~~