Live migration d'un invité KVM avec son stockage, pas à pas
Comment déplacer une machine virtuelle KVM en marche, avec son disque, entre deux hôtes avec libvirt : contrôles de compatibilité, préparation de la destination, la commande, et quand passer à froid.

Déplacer une machine virtuelle en marche entre deux hôtes sans stockage partagé ressemble à de la magie jusqu'à ce que vous l'ayez fait quelques fois. Ensuite, c'est une checklist : confirmer que les hôtes sont compatibles, préparer la destination pour que l'invité y trouve tout ce qu'il attend, lancer une commande, et savoir quand ne pas essayer. Voici cette checklist pour du KVM simple avec libvirt.
Ce qui se passe vraiment pendant une live migration
Avec --copy-storage-all, libvirt demande à QEMU sur la destination de créer l'invité, puis transfère le disque pendant que l'invité continue de tourner et d'écrire. Une fois le disque mis en miroir, la mémoire est copiée par tours : chaque tour envoie les pages que l'invité a modifiées pendant le précédent. Quand l'ensemble restant de pages modifiées est assez petit pour être envoyé dans le downtime autorisé, l'invité est mis en pause, les dernières pages et l'état des périphériques passent de l'autre côté, et il reprend sur la destination. La pause dure en général quelques centaines de millisecondes. Les connexions réseau survivent parce que l'invité garde ses adresses MAC et IP, et le switch apprend le nouvel emplacement à partir des premiers paquets de l'invité.
Tout ce qui peut mal tourner est un écart entre ce que l'invité attend et ce que la destination propose. Vérifiez donc cela d'abord.
Première étape : décider entre live et froid
La live migration est le bon outil quand la source et la destination sont compatibles et que le taux d'écriture de l'invité est modéré. C'est le mauvais outil quand tout change d'un coup : une autre génération de CPU, une autre topologie réseau et une autre version d'hyperviseur dans le même déplacement. Le chemin sûr est alors le froid : arrêter proprement l'invité, copier le disque, le définir sur la cible, le démarrer, et garder la source intacte comme retour arrière.
Un primaire de base de données avec un taux de modification de pages très élevé peut aussi ne jamais converger. Mesurez avant d'essayer :
virsh domdirtyrate-calc <guest> --seconds 5
virsh domstats <guest> --dirtyrate
Deuxième étape : vérifier la compatibilité CPU
Le modèle de CPU de l'invité doit exister sur la destination. Si l'invité utilise host-passthrough, les CPU des deux hôtes doivent en pratique correspondre. Comparez la définition de l'invité avec l'hôte de destination :
virsh dumpxml <guest> > guest.xml # on the source
xmllint --xpath '//cpu' guest.xml > guest-cpu.xml
virsh hypervisor-cpu-compare guest-cpu.xml # on the destination
identical ou superset veut dire que vous pouvez y aller. incompatible veut dire soit passer l'invité sur un modèle de CPU nommé que les deux hôtes supportent (à son prochain redémarrage), soit le déplacer à froid.
Troisième étape : préparer le réseau de destination
Chaque bridge, ou VLAN sur un bridge, auquel les interfaces de l'invité sont rattachées doit exister sur la destination avec le même nom, et doit transporter les mêmes VLAN sur l'uplink :
virsh domiflist <guest> # on the source: which bridges
ip -br link show type bridge # on the destination: do they exist?
Un bridge manquant fait échouer la migration proprement, dès le départ. Un bridge qui existe mais repose sur un uplink sans le VLAN migre avec succès et laisse l'invité injoignable, ce qui est pire. Vérifiez aussi le côté switch.
Quatrième étape : préparer le stockage de destination
La destination a besoin d'un endroit où poser le disque, à un chemin que libvirt gère comme storage pool :
virsh pool-define-as images dir --target /var/lib/libvirt/images
virsh pool-start images && virsh pool-autostart images
Pour la plupart des agencements, libvirt crée lui-même l'image cible. Pour les cas inhabituels, créez-la à l'avance avec exactement la même taille virtuelle et le même format que la source :
qemu-img info --output=json /var/lib/libvirt/images/<guest>.qcow2 # note virtual-size
qemu-img create -f qcow2 /var/lib/libvirt/images/<guest>.qcow2 <virtual-size>
Cinquième étape : migrer
Depuis l'hôte source, avec un accès SSH par clé vers la destination en tant qu'utilisateur libvirt :
virsh migrate --live --persistent --undefinesource \
--copy-storage-all --auto-converge --verbose \
<guest> qemu+ssh://<destination>/system
--livegarde l'invité en marche.--copy-storage-allmet en miroir le disque complet. (--copy-storage-incexiste pour les disques dont l'image de base est déjà sur la destination.)--auto-convergeralentit légèrement le CPU de l'invité si la mémoire est modifiée plus vite qu'elle ne peut être envoyée, pour que les invités très actifs finissent quand même.--persistentet--undefinesourcedéplacent la définition avec l'invité, pour qu'il ne réapparaisse pas sur l'ancien hôte au prochain redémarrage.
Nous utilisons le chemin de migration direct plutôt que --tunnelled quand le stockage est copié. Pendant l'exécution, suivez la progression depuis un second terminal :
virsh domjobinfo <guest>
domjobinfo montre les données restantes, le taux de modification et le downtime attendu. S'il est clair que cela ne converge pas, virsh domjobabort <guest> arrête le travail et laisse l'invité tourner sur la source, intact.
Sixième étape : vérifier à l'arrivée
Vérifiez, depuis l'extérieur de l'invité :
virsh list --all # running on the destination only
virsh domblklist <guest> # disk at the expected path
virsh domifaddr <guest> --source arp # address visible on the network
Si l'invité est un load balancer ou un réplica de base de données, confirmez qu'il a repris son rôle (état VRRP, threads de réplication) au lieu de le supposer.
Seulement après cela, supprimez l'ancienne image disque de la source, ou mieux, gardez-la jusqu'au prochain cycle de maintenance.
Votre checklist
- Live ou froid décidé délibérément, avec le taux de modification mesuré pour les invités très actifs.
- Modèle de CPU comparé à l'hôte de destination.
- Chaque bridge et chaque VLAN présents sur la destination, uplinks du switch compris.
- Un storage pool sur la destination, assez d'espace libre, et une image créée à l'avance là où l'agencement l'exige.
- La commande migrate lancée avec copie du stockage et auto converge, suivie avec
domjobinfo. - L'invité vérifié depuis l'extérieur, et la copie source conservée jusqu'à ce que vous soyez sûr.
Si vous souhaitez déplacer des invités sans les arrêter, ou si vous avez besoin d'une sortie de votre hyperviseur actuel, nous serons heureux de vous aider.
CTA
Related
Articles liés : Live migration et sorties d'hyperviseur · Private cloud sur KVM avec OLVM · Venir chez nous sans changer d'adresses : l'extension Layer 2
Publié le 4 août 2026.
Toutes les notes de terrain