19
0
Bifurcation 0
wiki/HowtoKVM.md

55 KiB

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


On peut aussi gérer les snapshots via le [Mode Monitor](#mode-monitor) et les commandes `savevm`, `loadvm`, `info snapshots`.

*Note* : les snapshots créés avec `savevm` ne seront pas visible via _libvirt_.

### Options -loadvm / -snapshot (non gérées avec _libvirt_)

On peut démarrer directement sur un snapshot *s0* avec l'option `-loadvm` :

$ kvm -hda debian1.qcow2 -m 512 -net nic,macaddr=<mac_address> -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=<mac_address> -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

<http://wiki.qemu.org/Documentation/CreateSnapshot>

Une option intéressante avec le format QCOW2 est la possibilité de créer une image d'une installation
de base et de créer des dérivées à partir de cette image. Non seulement cela 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

<http://en.wikibooks.org/wiki/QEMU/Monitor>  
<https://doc.opensuse.org/documentation/leap/virtualization/html/book.virt/cha.qemu.monitor.html>

Le _mode monitor_ est une option de **kvm** et permet d'effectuer diverses actions (état de la VM, action sur la VM, snapshots, etc.).

_libvirt_ crée automatiquement un _mode monitor_ qu'il utilise (donc non accessible directement), mais on peut aussi l'utiliser via :

virsh qemu-monitor-command --hmp "info block"


Si on utilise _kvm_ sans _libvirt_, on peut créer un _mode monitor_ accessible via `telnet` :

$ kvm […] -monitor tcp:127.0.0.1:,server,nowait

$ 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)

$ echo system_powerdown | nc 127.0.0.1


### Infos sur une VM

(qemu) info block (qemu) info blockstats (qemu) info network (qemu) info uuid


### Actions sur une VM

Extinction ACPI d'une VM :

(qemu) system_powerdown


Pause/Resume d'une VM :

(qemu) stop (qemu) cont


Envoyer une combinaison clavier :

(qemu) sendkey ctrl-alt-f1


Mot de passe VNC :

(qemu) change vnc password


Ajout de disques/périphériques à chaud :

~~~
(qemu) drive_add ?
(qemu) device_add ?
~~~

### Actions sur les snapshots

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 <port>
sync
cp debian1.qcow2 debian.current.qcow2
~~~

/!\\ Attention, avec _libvirt_ si l'on passe directement par le _mode monitor_ les snapshots ne seront pas visibles par _libvirt_ qui gère un état XML des snapshots. On pourra néanmoins faire :

~~~
# virsh qemu-monitor-command <vm-name> --hmp "savevm snap.current"
# virsh qemu-monitor-command <vm-name> --hmp "info snapshots"
~~~


## virsh

<http://libvirt.org/sources/virshcmdref/html-single/>

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 <vm-name>
# virsh shutdown <vm-name>

## Forcer l'extinction d'une VM (elle n'est pas détruite !)
# virsh destroy <vm-name>

## Informations avancées sur une VM
# virsh dominfo <vm-name>

## Activer/désactiver le démarrage automatique d'une VM
# virsh autostart <vm-name>
# virsh autostart --disable <vm-name>

## Dumper la configuration d'une VM dans un fichier de définition XML
# virsh dumpxml <vm-name> > <vm-name>.xml

## Créer/détruire une définition de VM
# virsh define <vm-name>.xml
# virsh undefine <vm-name>

## Mettre sur pause/réactiver une VM
# virsh suspend <vm-name>
# virsh resume <vm-name>

## Modifier les options d'une VM
# virsh edit <vm-name>
~~~

/!\\ 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 <mytemplate-domainame> --name <newmachine> --file <newmachine>.img
~~~

Cela permet de dupliquer un domaine existant avec notamment changement de l'adresse MAC de la carte réseau.

Une fois la machine démarrée, il faudra modifier son *hostname*, son adresse IP et ses clés SSH.

~~~
# rm /etc/udev/rules.d/70-persistent-net.rules
# hostname foo ; echo foo > /etc/hostname
# rm /etc/ssh/ssh_host_* ; dpkg-reconfigure openssh-server
# vim /etc/network/interfaces
~~~

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

<https://libvirt.org/migration.html>

*Note* : Il faut s'assurer d'ouvrir les ports TCP 49152 à 49215 entre les machines car par défaut _libvirtd_ utilise ces ports pour faire des netcat des données !

Pour une migration à chaud, il faut avoir un CPU identique (à voir selon l'option un storage commun pour les disques (SAN, réplication DRBD, etc.).

Pour envoyer une VM locale _test_ vers l'hyperviseur _foo_ :

~~~
# VIRSH_DEFAULT_CONNECT_URI='qemu:///system' virsh migrate --live --unsafe --verbose test qemu+ssh://foo/system
Migration: [100 %]
~~~

Pour rappatrier une VM _test_ depuis l'hyperviseur _foo_ :

~~~
# VIRSH_DEFAULT_CONNECT_URI='qemu+ssh://foo/system' virsh migrate --live --unsafe --verbose test qemu:///system
Migration: [100 %]
~~~

> *Note* : on peut faire cela via virt-manager mais le mode `--unsafe` (utile si un cache disque est configuré) 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 à _libvirt_ sinon il tente de passer par l'interface principale :

~~~
# virsh migrate --live --unsafe --verbose test qemu+ssh://192.0.2.2/system tcp://192.0.2.2/
Migration: [100 %]
~~~

> **Attention** la migration d'une VM ne déplace **pas** sa définition ! Il est donc impératif de faire un `virsh define` de son fichier de définition sur l'hyperviseur de destination de la migration sous peine de n'avoir plus aucune trace de la VM une fois éteinte ! On conseille aussi de nettoyer `virsh undefine` sur l'hyperviseur de départ pour éviter les confusions.

> *Astuce* : si le lien entre les deux hyperviseurs n'est pas rapide et que la mémoire de ma VM est très sollicitée, la migration peut ne jamais se finir et boucler entre 80 et 99%... si c'est le cas, mettez sur "pause" la VM et cela devrait permettre de terminer la migration sans avoir à éteindre la VM (évidemment pendant qu'elle est sur "pause" la VM sera inaccessible).

### internal error: Attempt to migrate guest to the same host

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.

## Renommer une VM

Si un mauvais choix a été fait au départ et qu'il faut renommer toute la VM (y compris la partie LVM et DRBD), la procédure est facile et rapide mais elle doit se faire **à froid (VM éteinte)**. La plupart des opération doit se faire sur les 2 nœuds DRBD (ici **tic** et **tac**, et la VM est active seulement sur **tic**).

1. Une fois la VM éteinte il faut couper la synchro DRBD :

~~~
tic $ drbdadm down <old resource>
tac $ drbdadm down <old resource>
~~~

2. Il faut ensuite faire le renommage de la partie LVM, pour chaque volume de la VM

~~~
tic $ lvrename <VG name> <old LV name> <new LV name>
tac $ lvrename <VG name> <old LV name> <new LV name>
~~~

3. On renomme le fichier de définition de la ressource :

~~~
tic $ mv /etc/drbd.d/<old resource>.res /etc/drbd.d/<new resource>.res
tac $ mv /etc/drbd.d/<old resource>.res /etc/drbd.d/<new resource>.res
~~~

4. On renomme la ressource elle-même sur la première ligne de la définition et on adapte les chemins LVM.

~~~
tic $ vim /etc/drbd.d/<new resource>.res
tac $ vim /etc/drbd.d/<new resource>.res
~~~

5. On peut alors reconnecter les nœuds DRBD :

~~~
tic $ drbdadm up <new resource>
tac $ drbdadm up <new resource>
~~~

6. Sur le nœud DRBD principal, on remet la ressource en primaire :

~~~
tic $ drbdadm primary <new resource>
~~~

7. On renomme la VM elle même :

~~~
tic $ virsh domrename <old DOM name> <new DOM name>
~~~

Pour Debian 7 et inférieur, la commande `virsh domrename` n'existe pas. On peut alors contourner de cette manière :

~~~
# cd /etc/libvirt/qemu/
# cp <old DOM name>.xml <new DOM name>.xml
# virsh undefine <old DOM name>
# vim <new DOM name>.xml
# : faire les modifications de l'étape 8 ainsi que le changement de nom dans la balise <name>
# virsh define <new DOM name>.xml
~~~

8. On ajuste les chemins des volumes dans la définition de la VM

~~~
tic $ virsh edit <new DOM name>
~~~

9. On peut enfin démarrer la VM

~~~
tic $ virsh start <new DOM name>
~~~

## 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
~~~

## Modifier les ressources d'une VM

### Nombre de vCPU

Il faut éditer le fichier de définition de la VM et modifier la valeur de la partie `<vcpu>`:

~~~
# virsh edit <vm-name>
~~~

Il faut ensuite stopper la VM (bien attendre qu'elle soit réellement stoppée :

~~~
# virsh shutdown <vm-name> && watch "virsh list --all"
~~~

Ensuite la redémarrer

~~~
# virsh start <vm-name>
~~~

### RAM

L'opération est presque identique à celle pour les vCPU. Il faut changer 2 valeurs dans la définition de la VM : `<memory>` et `<currentMemory>`.

### Ajout un disque

Créer un fichier XML qui définit le nouveau disque. Exemple :

~~~
<disk type='block' device='disk'>
      <driver name='qemu' type='raw' cache='writeback' io='threads'/>
      <source dev='/dev/hdd0/mondisque'/>
      <target dev='vdc' bus='virtio'/>
</disk>
~~~

Puis l'ajouter à la machine, et à sa définition.

~~~
# virsh attach-device <nomMachine> add-disk.xml --persistent
~~~

De la même manière, on peut détacher un disque avec `virsh detach-device`.

### Interfaces réseau

L'ajout d'une interface réseau à chaud ne fonctionne pas sur les VMs avec des systèmes plus anciens, où l'interface ne sera pas reconnue et un reboot sera nécessaire. Pour les systèmes plus récents, l'interface sera directement visible et utilisable :

~~~
# virsh attach-interface <nomMachine> bridge <nomBridge> --live --config --mac 52:54:00:XX:YY:ZZ --model virtio
~~~

L'option ``--live`` indique d'appliquer la configuration à chaud.  
L'option ``--config`` indique d'enregistrer la configuration de manière persistente.  
L'option ``--mac`` est facultative, et une adresse MAC sera automatiquement définie si elle n'est pas indiquée.

On peut également supprimer une interface à chaud :

~~~
# virsh detach-interface <nomMachine> bridge --live --config --mac 52:54:00:XX:YY:ZZ
~~~

Ici, l'option ``--mac`` est obligatoire puisqu'elle permet d'identifier l'interface à supprimer.

## Monitoring

### Munin

Il existe des plugins _Munin_ pour grapher les ressources CPU/IO/Mémoire de chaque VM :

~~~
$ 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
~~~

## Déduplication de pages mémoire avec KSM

KSM est l’acronyme de Kernel Samepage Merging, le noyau Linux analyse la mémoire consommée et fusionne les données identiques qui sont stockées en mémoire.

Lorsque vous avez plusieurs instances du même logiciel, il est très courant que la mémoire soit utilisée pour stocker plussieurs fois la même chose, KSM permet déviter celà.

Ce système ne fonctionne pas avec tout les logiciels, car ils doivent être prévu pour cela, mais c'est le cas de KVM : <https://www.linux-kvm.org/page/KSM>

### Activation de KSM sur Debian

On vérifie que KSM n'est pas activé sur la machine avec la commande :

~~~
# cat /sys/kernel/mm/ksm/run 
0
~~~

S'il retourne 1 c'est que KSM est déjà activé sur la machine.

On installe le paquet `ksmtuned`

~~~
# apt install ksmtuned --no-install-recommends
~~~

Le service qui nous instéresse est `ksm.service` on peux arrêter et désactivé le service ksmtuned :

~~~
# systemctl stop ksmtuned.service
# systemctl disable ksmtuned.service
~~~

Puis on redémarre `ksm.service` :

~~~
# systemctl restart ksm.service
~~~

On vérifie que KSM est bien activé :

~~~
# cat /sys/kernel/mm/ksm/run
1
~~~

On peux regarder les statistiques d'utilisation de KMS comme ceci :

~~~
# grep -H '' /sys/kernel/mm/ksm/pages_*
/sys/kernel/mm/ksm/pages_shared:204
/sys/kernel/mm/ksm/pages_sharing:54476
/sys/kernel/mm/ksm/pages_to_scan:100
/sys/kernel/mm/ksm/pages_unshared:44874
/sys/kernel/mm/ksm/pages_volatile:95
~~~

On peux avoir les explications sur chaques variables de ces statistiques ici : <https://blog.siphos.be/2013/05/enabling-kernel-samepage-merging-ksm/>

## FAQ

<http://www.linux-kvm.org/page/FAQ>

### Erreur avec certaines commandes virsh

Solution : tester de positionner la variable *VIRSH_DEFAULT_CONNECT_URI*

Dans certains cas, elle se positionne par défaut à _vbox:///system_
On peut donc la forcer :

~~~
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=<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 :

~~~
$ 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 <vm-name>
[…]
    <interface type='bridge'>
      <mac address='52:54:00:de:ad:43'/>
      <source bridge='br2'/>
      <target dev='vnet7'/>
      <model type='virtio'/>
      <alias name='net1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </interface>
~~~

~~~
# virsh detach-interface […]
~~~

Il suffit ensuite de la retirer du bridge :

~~~
# brctl delif br2 vnet7
~~~

### Tips performance

<http://www.linux-kvm.org/page/Tuning_KVM>

* Utiliser le même CPU que sur l'hyperviseur via l'option `kvm -cpu host` qui se positionne avec `virt-install --cpu mode=host-passthrough` (attention, la VM ne pourra être migrée que sur un hyperviseur avec un CPU identique)

* Utiliser autant que possible les drivers _virtio_ (pour les disques et les interfaces réseau) sur les VMs

* Dans le cas d'un hyperviseur avec une carte RAID hardware disposant d'un cache avec batterie, on peut positionner `cache=none` pour les disques… une autre stratégie est d'utiliser `cache=writeback` et d'avoir beaucoup de mémoire disponible sur son hyperviseur.

* 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 :

~~~
  <cpu mode='host-model'>
    <model fallback='allow'/>
  </cpu>
~~~

### Étendre une image RAW

Pour le sport, voici 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
~~~

### Étendre un volume disque à chaud

> **Note** : Ne fonctionne qu'à partir de Jessie

Par exemple avec LVM :

~~~
# lvresize -L+100G /dev/vg0/example
# virsh blockresize domain path sizeB
~~~

Le blockresize indiquera à la VM de redimenssioner son disque à chaud.  

- **domain** : Nom de la machine ;
- **path** : Chemin du disque dans la définition XML ;
- **sizeB** : Taille en octets, `lvs --units B`.

~~~
# virsh blockresize myvm /dev/vg0/myvm_rootfs 214748364800B
~~~

### 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

# systemctl reset-failed machine-qemu\\x2dfoo.scope
~~~

### Souci d'allocation CPU

Admettons que vous avez sur l'hyperviseur 32 CPU (cores ou threads, qu'importe), vous affectez 32 vCPU à une VM. Vous constatez que la VM ne peut monter qu'à 1600% d'utilisation, soit 16 vCPU, et vous constatez un _steal_ important (voir `top`, `htop` ou Munin). Cela signifie en fait que la VM a démarré avec 32 vCPU, mais ceux-ci sont mappés seulement sur 16 CPU physiques (le premier CPU avec 16 cores par exemple).  

C'est un bug lié à libvirt, bug qui est bien connu et [corrigé](https://bugzilla.redhat.com/show_bug.cgi?id=1207257), cependant il impacte toujours le libvirt de Debian Jessie.

Pour corriger le souci à chaud, on peut faire les actions suivantes. Autoriser le CGroup de la machine à utiliser tous les CPU :

~~~
# cgset -r cpuset.cpus=0-31 /machine.slice/machine-qemu\\x2d<NOMVM>.scope
~~~

Mapper tous les vCPU sur les CPU physiques :

~~~
# for i in {0..31}; do virsh vcpupin <NOMVM> $i $i; done
~~~

### Problème lors de l'installation

Il se peut que apt n'arrive pas à installer complètement kvm. Pour pouvoir finir l'installation :

~~~
# systemctl disable libvirtd
# dpkg --configure libvirt-daemon-system
# apt install -f
~~~ 

Cela ne résoud pas forcément le problème.

### Le bloc nécessaire pour une iso

Parfois suite à la commande virt-install on n'a toujours pas de CD dans la définition de la VM. Un bloc fonctionnel ressemble à :

~~~{.xml}
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/home/iso/install61.iso'/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
~~~

Il faudra possiblement rajouter 

~~~{.xml}
  <boot dev='cdrom'/>
~~~

avant `hd` dans le block

~~~{.xml}
<os>
  <type arch='x86_64' machine='pc-0.12'>hvm</type>
  <boot dev='hd'/>
</os>
~~~

afin de bien booter sur le CD.

### Disposition qwerty

Si on veut que le vnc mis en place utilise une disposition de clavier qwerty

~~~{.xml}
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'>
~~~

### Virtualisation imbriquée

Dans le cas où l'on veut créer des VMs dans une VM, il peut être nécessaire d'activer la virtualisation imbriquée.

Il faut pour cela éteindre toutes les VMs sur l'hyperviseur, et activer l'option *nested* avant de redémarrer les VMs :

~~~
# modprobe -r kvm_intel
# echo "options kvm-intel nested=1" > /etc/modprobe.d/kvm.conf
# modprobe kvm_intel
~~~

### Machine reboot lors du boot sur fichier .iso pour installation d'un systeme (Debian ou autre).

Sur certains hyperviseurs et certains CPU, il est possible que le mode CPU `host-passthrough` provoque un reboot de la VM lorsque l'on boot sur le cd d'install, et que l'on sélectionne le début de l'installation.

Il faut donc, dans le fichier xml, mettre le modèle de CPU de l'hyperviseur correspondant, exemple avec un modèle Sandy Bridge :

~~~{.xml}
 <cpu mode='custom' match='exact'>
    <model fallback='allow'>SandyBridge</model>
  </cpu>
~~~

### Erreur de connection en tant qu'utilisateur

Même avec une configuration valide et utilisteur ayant les droits approriés, il est possible que libvirt ne veuille pas laisser les utilisateurs non root à se connecter à l'instance système de libvirt en produisant l'erreur suivante :

~~~
$ virsh --connect qemu:///system --debug 4
error: failed to connect to the hypervisor
error: error from service: CheckAuthorization: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
~~~

Erreur avec Virt-Manager :

~~~
Unable to connect to libvirt qemu+ssh://- user@server/system.
authentication unavailable: no polkit agent avaible eto authenticate action 'org.libvirt.unix.manage'
Vérifiez que le démon « libvirtd » est en cours d'exécution sur l'hôte distant.
~~~

1. Vérifier que l'utilisateur est bien dans le groupe `libvirt`
2. Vérifier le statut du service « libvirtd » Dans ce cas il faut redémarrer l'instance libvirt `systemctl restart libvirtd`, cela n'arretera pas les machines en cours d'exécution.


### Erreur de migration de VM relative à AppArmor

Exemple d'erreur rencontrée : 

```
error: unsupported configuration: Unable to find security driver for model apparmor
```

Il est probable que la migration tentée pousse la machine virtuelle vers un hôte où AppArmor n'est pas actif, ou n'a pas les profils relatifs à libvirt.


Pour vérifier, on utilise la commande `aa-status` sur l'hôte de destination. 

Exemple : 

```
# aa-status 
apparmor module is loaded.
0 profiles are loaded.
0 profiles are in enforce mode.
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
```

Dans ce cas, AppArmor est bien présent, chargé et actif. Mais il n'a pas de profils de configurés (ils sont définis dans `/etc/apparmor.d/` en temps normal). C'est la raison de l'échec de la migration de la machine virtuelle.
On peut forcer AppArmor à recharcher tous les profils avec la commande `apparmor_parser /etc/apparmor.d/`

Si ça marche, on obtient après le résultat suivant en rejouant `aa-status` (l'important est de voir les profils AppArmor relatifs à libvirt dans la liste) :

```
# aa-status
apparmor module is loaded.
10 profiles are loaded.
10 profiles are in enforce mode.
   /usr/bin/man
   /usr/sbin/libvirtd
   /usr/sbin/libvirtd//qemu_bridge_helper
   /usr/sbin/ntpd
   /usr/sbin/tcpdump
   man_filter
   man_groff
   nvidia_modprobe
   nvidia_modprobe//kmod
   virt-aa-helper
0 profiles are in complain mode.
2 processes have profiles defined.
2 processes are in enforce mode.
   /usr/sbin/libvirtd (2642) 
   /usr/sbin/ntpd (2654) 
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

```

Normalement, re-esayer la migration de la machine virtuelle marchera.


> **Note**  : Bien vérifier que **apparmor.service** soit *enabled* pour systemd. C'est le lancement de ce service au démarrage qui s'assure que tous les profils soient bien chargés.
> Un coup de `systemctl enable --now apparmor.service`