Fonctionnalités avancées de KVM : Pilotes paravirtualisés, Migration à chaud et KSM

  1. Pilotes paravirtualisés virtio

1.1 Principe de virtio

KVM exploite les extensions matérielles de virtualisation (Intel VT-x, AMD-V) pour une efficacité élevée au niveau du processeur. Avec la fonctionnalité Intel EPT, la virtualisation mémoire est également performante. QEMU/KVM fournit un environnement de virtualisation complète permettant l'exécution d'un système invité (GuestOS) non modifié. Cependant, la virtualisation des E/S (Entrées/Sorties) est traditionnellement assurée par une émulation logicielle via QEMU (cartes réseau, disques, cartes graphiques), ce qui peut s'avérer moins performant.

La virtualisation du CPU et de la mémoire est gérée par le module noyau KVM, tandis que l'émulation des périphériques d'E/S est prise en charge par QEMU.

Dans KVM, l'utilisation de la paravirtualisation via le framework virtio standard sous Linux permet d'améliorer les performances des E/S.

Virtualisation complète : Le GuestOS s'exécute sur l'hyperviseur sans être conscient de la virtualisation et ne nécessite aucune modification.

Paravirtualisation : Le GuestOS est conscient de l'hyperviseur et contient des pilotes optimisés pour communiquer directement avec lui, ce qui augmente l'efficacité mais nécessite des modifications du système invité.

En mode de virtualisation complète, l'hyperviseur doit émuler le matériel au niveau le plus bas, ce qui offre une flexibilité totale mais à un coût de performance élevé. En paravirtualisation, la coopération entre le GuestOS et l'hyperviseur permet une émulation plus efficace.

Principe et limites de l'émulation I/O par QEMU
Avec l'émulation QEMU :

  1. Le pilote du périphérique dans l'invité initie une requête d'E/S, interceptée par le module KVM.
  2. La requête est placée dans une page mémoire partagée et QEMU est notifié.
  3. QEMU émule l'opération matérielle correspondante.
  4. Le résultat est placé dans la page mémoire partagée, KVM est notifié.
  5. Le résultat est retourné à l'invité.

Ce processus est efficace pour supporter une large gamme de matériel émulé, même ancien ou rare, sans modifier l'invité. Cependant, le chemin d'accès aux E/S est long, avec de nombreux cycles VMEntry/VMExit, changements de contexte et copies de données, ce qui dégrade la performance. Principe et avantages de virtio
L'architecture virtio sépare le pilote frontal (frontend, ex: virtio-blk, virtio-net) dans l'invité du programme de traitement arrière (backend) dans QEMU. Deux couches intermédiaires facilitent la communication :

  • virtio : Interface de file d'attente virtuelle, abstraite, reliant le frontend au backend. Un frontend peut utiliser plusieurs files (ex: virtio-net utilise deux files pour l'émission/réception).
  • virtio-ring : Implémente un tampon circulaire (ring buffer) permettant de regrouper plusieurs requêtes d'E/S du frontend pour un traitement par lots par le backend, ce qui améliore l'efficacité des échanges.

Les performances des E/S avec virtio approchent celles d'un système natif. Il est donc recommandé d'utiliser virtio lorsque l'hôte et l'invité le supportent. Inconvénients : Nécessite l'installation de pilotes virtio spécifiques dans l'invité. Les systèmes Linux anciens ou certaines versions de Windows peuvent ne pas les inclure par défaut, bien que la plupart des distributions modernes les fournissent.

1.2 Installation des pilotes virtio

Les noyaux Linux 2.6 et supérieurs prennent en charge virtio. L'hôte requiert un noyau relativement récent ; aucun pilote spécifique n'est nécessaire côté hôte.

1.2.1 Pilotes virtio sous Linux

1.3 Utilisation de virtio_balloon

Le ballooning (ballonnement) permet d'ajuster dynamiquement la mémoire d'un invité en cours d'exécution sans l'arrêter. Le concept est celui d'un ballon mémoire dans l'invité. En le gonflant, la mémoire à l'intérieur du ballon est libérée pour l'hôte. En le dégonflant, la mémoire est rendue à l'invité.

Principe dans KVM :

  1. L'hyperviseur demande à l'invité de restituer de la mémoire.
  2. Le pilote virtio_balloon de l'invité reçoit la demande.
  3. Le ballon se gonfle, libérant de la mémoire (si possible, même en swap).
  4. L'invité restitue la mémoire libérée à l'hyperviseur.
  5. L'hyperviseur peut réaffecter cette mémoire.
  6. Pour rendre de la mémoire à l'invité, l'hyperviseur demande de dégonfler le ballon.

Avantages : Économie potentielle de mémoire, allocation flexible.
Inconvénients : Dépend du pilote dans l'invité, peut dégrader les performances de l'invité (cache disque, swap), gestion manuelle (via le moniteur QEMU), risque de fragmentation mémoire. #### Exemple d'utilisation

Dans l'invité, vérifier le périphérique PCI

lspci -k

Devrait montrer un périphérique virtio-pci (ID: 1af4:1002)

Surveiller la mémoire actuelle dans l'invité

free -m

Depuis le moniteur QEMU (accès via VNC, ou -monitor telnet:...)

(qemu) info balloon

Affiche la mémoire actuelle (ex: actual=1024)

(qemu) balloon 512

Ajuste à 512 Mo

(qemu) info balloon

Vérifie le nouveau réglage (actual=512)

Vérifier dans l'invité après ajustement

free -m


</div>La gestion du ballooning n'est pas mature pour un déploiement à grande échelle. Son utilisation doit être prudente.

### 1.4 Utilisation de virtio\_net

Le pilote virtio\_net offre de meilleures performances réseau (débit, latence) que l'émulation pure.

#### 1.4.1 Vérification du support virtio\_net par QEMU

<div>```
qemu-system-x86_64 -net nic,model=? 2>&1 | grep virtio
# Affiche: virtio

Pour de meilleures performances, le traitement du backend peut être déplacé dans l'espace noyau avec le module vhost_net :

1.5 Utilisation de virtio_blk

Le pilote virtio_blk fournit un accès efficace aux périphériques blocs. Configuration requise : le module virtio_blk dans l'invité.

Exemple de lancement

  1. Migration dynamique (Live Migration)

2.1 Concept

La migration d'une charge de travail (VM) d'un hôte physique à un autre peut être statique (hors-ligne) ou dynamique (à chaud, live migration). La migration statique implique une interruption de service. La migration dynamique déplace l'invité avec un temps d'arrêt minimal (quelques secondes), préservant l'état de l'invité et la connectivité réseau.

2.2 Mesure d'efficacité et cas d'usage

Mesures : Temps total de migration, durée d'arrêt, impact sur les performances.
Cas d'usage : Équilibrage de charge (migration vers un hôte moins chargé), maintenance matérielle sans arrêt, consolidation serveur pour économiser l'énergie, migration géographique.

2.3 Principe et pratique avec KVM

KVM supporte la migration statique et dynamique.

Migration statique (avec sauvegarde d'état) :
Utiliser la commande savevm dans le moniteur QEMU pour sauvegarder l'état complet (CPU, mémoire, périphériques, disques) dans une image qcow2/qed. Copier l'image sur l'hôte cible, démarrer la VM avec -loadvm.

Migration dynamique (live migration) :
En cas de stockage partagé (ex: NFS, GlusterFS), seuls l'état du CPU, la mémoire et les périphériques sont transférés via le réseau. Sinon, le contenu des disques est également copié.

Processus (stockage partagé) :

  1. La VM continue de fonctionner sur l'hôte source pendant que ses pages mémoire sont transférées.
  2. Les pages mémoire modifiées après leur transfert sont trackées.
  3. Lorsqu'il reste peu de données à transférer (capable de l'être dans un intervalle configuré), la VM sur l'hôte source est suspendue.
  4. Les données restantes (pages mémoire modifiées, état CPU) sont transférées.
  5. La VM est restaurée et redémarrée sur l'hôte cible.

Conditions et recommandations :

  • Utiliser un stockage partagé avec un chemin identique sur les deux hôtes.
  • Préférer des hôtes avec des CPU similaires.
  • Les VM 64 bits ne migrent que vers des hôtes 64 bits. Les VM 32 bits peuvent migrer vers des hôtes 32 ou 64 bits.
  • La configuration NX (No-Execute) doit être identique sur les deux hôtes.
  • Le nom de la VM doit être unique sur l'hôte cible.
  • La configuration réseau (ponts) doit être similaire sur les deux hôtes.

Exemple pratique

Pré-requis : Stockage partagé NFS.

Sur l'hôte source (192.168.1.10)

mount 192.168.1.100:/exports/vms /mnt/vms qemu-system-x86_64 -smp 2 -m 512
-drive file=/mnt/vms/inviter.qcow2,if=virtio
-monitor telnet:localhost:4444,server,nowait
-daemonize

Sur l'hôte cible (192.168.1.11)

mount 192.168.1.100:/exports/vms /mnt/vms qemu-system-x86_64 -smp 2 -m 512
-drive file=/mnt/vms/inviter.qcow2,if=virtio
-incoming tcp:0:7777
-daemonize

Connecter au moniteur sur l'hôte source (via telnet localhost 4444)

(qemu) migrate tcp:192.168.1.11:7777

Surveillance avec 'info migrate'

(qemu) info migrate


</div>La migration dynamique avec copie incrémentielle des disques est également possible en utilisant des images qcow2 avec backing file.

3. KSM (Kernel Same-page Merging)
---------------------------------

KSM permet au noyau Linux de fusionner des pages mémoire identiques entre différents processus. La mémoire fusionnée est marquée comme "copy-on-write". Si un processus modifie une page fusionnée, il en reçoit une copie privée.

**Intérêt dans KVM :** Si plusieurs VM sur un même hôte exécutent le même OS ou les mêmes applications, elles peuvent partager de nombreuses pages mémoire identiques via KSM.

**Avantages :**

- Réduction de la consommation mémoire globale.
- Amélioration des performances (plus de mémoire disponible pour le cache).
- Possibilité de sur-engagement mémoire (overcommitment) en toute sécurité.

**Inconvénients et considérations :**

- Augmentation de la charge CPU due au scan des pages mémoire par ksmd.
- L'efficacité dépend de la similarité des charges de travail des VM.
- Nécessite un espace swap suffisant pour gérer les situations de pression mémoire.

### 3.1 Configuration et pratique

KSM est contrôlé via le daemon `ksmd` et les fichiers sous `/sys/kernel/mm/ksm/` :

<div>```
# Vérifier la compilation du support KSM
grep -i ksm /boot/config-$(uname -r)

# Fichiers de configuration (principaux) :
# /sys/kernel/mm/ksm/run : 0 (inactif), 1 (actif), 2 (arrêter et libérer)
# /sys/kernel/mm/ksm/sleep_millisecs : Temps d'attente entre les scans (ms)
# /sys/kernel/mm/ksm/pages_to_scan : Nombre de pages scannées par itération

# Activer KSM manuellement
echo 1 > /sys/kernel/mm/ksm/run

# Ou via les services systemd (CentOS/RHEL)
systemctl enable --now ksm
systemctl enable --now ksmtuned

# Vérifier l'état
cat /sys/kernel/mm/ksm/run
# 1 signifie actif

# Surveiller l'effet de KSM
cat /sys/kernel/mm/ksm/pages_sharing
# Nombre de pages partagées (économie de mémoire)
# La mémoire sauvée est : pages_sharing * taille_page (généralement 4096 octets)

# Exemple de calcul
echo "Mémoire sauvée par KSM : $(( $(cat /sys/kernel/mm/ksm/pages_sharing) * 4096 / 1024 / 1024 )) Mo"

Étiquettes: kvm virtio paravirtualization live-migration ballooning

Publié le 10 juillet à 03h46