Aller au contenu
English
English
Virtualisation medium

Snapshots, clones et backups KVM : comprendre les différences

55 min de lecture

Logo KVM

Les snapshots ne sont pas des sauvegardes. C'est l'erreur la plus courante avec KVM/libvirt. Ce guide vous explique la différence, quand utiliser chaque technique, et comment protéger vraiment vos VMs.

  • Créer et gérer des snapshots pour tester sans risque
  • Cloner une VM pour la dupliquer proprement
  • Faire des backups indépendants et restaurables
  • Éviter les pièges de performance et de perte de données

Les manipulations qui suivent s'exécutent sur une VM réelle et certaines sont destructrices : menez-les sur une machine de test, jamais sur une VM de production. Trois acquis sont supposés :

Le critère qui sépare les trois techniques tient en un mot : l'indépendance. Un snapshot ne survit pas à la disparition du disque d'origine, alors qu'un clone et un backup sont des copies autonomes. Lisez donc la colonne « Indépendant » avant la colonne « Usage » : c'est elle qui décide si la technique protège ou non vos données.

TechniqueCe que c'estIndépendant ?Usage
SnapshotPhoto de l'état à un instant TNonTest rapide, rollback
CloneCopie complète de la VMOuiDupliquer un template
BackupExport de la config + copie du disqueOuiSauvegarde, reprise après sinistre

Le piège classique : un admin crée un snapshot avant une mise à jour, pensant être protégé. La mise à jour échoue, il veut restaurer... mais le disque original est corrompu. Le snapshot dépend du disque original, les deux sont perdus.

Dépendance snapshot au disque de base

La règle d'or : un snapshot protège contre les erreurs logiques (mauvaise config, update raté), pas contre les pannes matérielles ou la corruption.

Un snapshot capture l'état d'une VM à un instant T. Avec QCOW2, libvirt utilise une technique appelée copy-on-write :

  1. Le disque original est gelé en lecture seule
  2. Les nouvelles écritures partent dans un fichier delta
  3. Revenir en arrière consiste à supprimer ce delta

Avantage : création quasi-instantanée, peu d'espace disque. Inconvénient : dépendance au fichier original, performance dégradée si trop de snapshots.

La création d'un snapshot est l'opération la moins risquée du guide : elle n'écrase rien et prend moins d'une seconde. L'enjeu réel est le nom donné au point de retour, car c'est lui que vous taperez sous pression, six semaines plus tard, quand une mise à jour aura mal tourné. La description est facultative, elle se relit dans le XML rendu par snapshot-dumpxml.

  1. Vérifier l'état de la VM

    Fenêtre de terminal
    virsh domstate ma-vm

    Un snapshot peut être créé sur une VM en cours d'exécution ou arrêtée.

  2. Créer le snapshot

    Fenêtre de terminal
    virsh snapshot-create-as ma-vm \
    --name "avant-upgrade" \
    --description "État stable avant mise à jour kernel"

    Sortie attendue :

    Domain snapshot avant-upgrade created
  3. Vérifier la création

    Fenêtre de terminal
    virsh snapshot-list ma-vm

    Sortie attendue :

    Name Creation Time State
    ------------------------------------------------------
    avant-upgrade 2026-01-31 10:15:30 +0100 running

libvirt distingue deux types de snapshots, et la différence porte sur ce qui est capturé autant que sur l'endroit où le delta est écrit. Un snapshot interne range tout dans le fichier QCOW2 existant ; un snapshot externe crée un nouveau fichier. Les deux fonctionnent sur une VM allumée, mais ils ne se gèrent pas de la même façon.

TypeCe qu'il captureVM en cours ?Usage
InterneDisque + RAM (état complet)OuiRollback rapide
ExterneDisque uniquementOuiBackup avec delta externe

Par défaut, snapshot-create-as crée un snapshot interne si la VM tourne.

Pour créer un snapshot disque uniquement (externe) :

Fenêtre de terminal
virsh snapshot-create-as ma-vm \
--name "disk-only-snap" \
--disk-only \
--atomic

Trois commandes se partagent l'inspection, et elles ne répondent pas à la même question. snapshot-list dit ce qui existe, snapshot-info dit où en est un snapshot précis dans l'arbre, et snapshot-dumpxml sort la définition complète. Le champ Location d'un snapshot-info est celui qu'on regarde en premier : il vaut internal ou external, et cela change la façon de le supprimer.

Lister tous les snapshots d'une VM :

Fenêtre de terminal
virsh snapshot-list ma-vm

Voir l'arborescence (si plusieurs snapshots) :

Fenêtre de terminal
virsh snapshot-list ma-vm --tree

Sortie exemple :

avant-upgrade
|
+- test-nginx
|
+- test-postgres

Obtenir les détails d'un snapshot :

Fenêtre de terminal
virsh snapshot-info ma-vm --snapshotname avant-upgrade

Sortie attendue :

Name: avant-upgrade
Domain: ma-vm
Current: yes
State: running
Location: internal
Parent: -
Children: 2
Descendants: 2
Metadata: yes

Exporter la configuration XML du snapshot :

Fenêtre de terminal
virsh snapshot-dumpxml ma-vm --snapshotname avant-upgrade

C'est l'opération la plus importante : annuler les changements et revenir à l'état sauvegardé.

  1. Vérifier le snapshot actuel

    Fenêtre de terminal
    virsh snapshot-current ma-vm --name
  2. Revenir au snapshot

    Fenêtre de terminal
    virsh snapshot-revert ma-vm --snapshotname avant-upgrade
  3. Forcer le redémarrage après revert

    Si vous voulez que la VM redémarre immédiatement :

    Fenêtre de terminal
    virsh snapshot-revert ma-vm --snapshotname avant-upgrade --running

Une fois que vous n'avez plus besoin d'un snapshot, supprimez-le pour libérer l'espace et améliorer les performances :

Fenêtre de terminal
virsh snapshot-delete ma-vm --snapshotname avant-upgrade

Supprimer un snapshot et tous ses enfants :

Fenêtre de terminal
virsh snapshot-delete ma-vm --snapshotname avant-upgrade --children

Le piège des snapshots QCOW2 : la chaîne de dépendances

Section intitulée « Le piège des snapshots QCOW2 : la chaîne de dépendances »

Le schéma montre pourquoi un empilement de snapshots coûte cher en entrées/sorties : chaque fichier ne contient que les blocs modifiés depuis le précédent, donc une lecture peut traverser toute la chaîne avant de trouver sa donnée.

Chaîne de dépendances QCOW2

Pour lire un bloc de données, QEMU doit :

  1. Chercher dans snap2, la couche active
  2. Si le bloc est absent, chercher dans snap1
  3. Si le bloc est encore absent, lire dans vm.qcow2

Plus la chaîne est longue, plus les I/O sont lents.

Recoller la chaîne s'appelle un commit : les blocs des couches supérieures sont réécrits dans le disque de base, et la VM finit par ne plus lire qu'un seul fichier. L'option --pivot implique --active, c'est-à-dire un commit en deux temps de la couche active, qui fait basculer la machine sur le disque de base une fois la synchronisation terminée. Cette forme s'exécute donc sur une VM en cours d'exécution.

Fenêtre de terminal
# Fusionner la couche active dans le disque de base (VM en cours d'exécution)
virsh blockcommit ma-vm vda --active --pivot

Le clonage crée une copie complète et indépendante d'une VM. Contrairement au snapshot, le clone n'a aucune dépendance avec l'original.

Le clonage répond à un besoin de duplication, jamais à un besoin de protection. Si la question que vous vous posez commence par « et si ça casse », c'est un snapshot ou un backup qu'il vous faut, pas un clone : le clone coûte le prix d'une copie intégrale du disque et vous laisse une seconde machine à administrer. Le tableau donne les quatre cas qui reviennent le plus souvent.

SituationCloner ?
Créer une VM de test à partir d'un templateOui
Dupliquer un serveur pour load balancingOui
Sauvegarder avant une mise à jourNon, c'est un backup
Tester une config temporairementNon, c'est un snapshot
  1. Arrêter la VM source (recommandé)

    Fenêtre de terminal
    virsh shutdown ma-vm
  2. Cloner la VM

    Fenêtre de terminal
    virt-clone \
    --original ma-vm \
    --name ma-vm-clone \
    --auto-clone

    Sortie attendue :

    Allocating 'ma-vm-clone.qcow2' | 20 GB 00:00:45
    Clone 'ma-vm-clone' created successfully.

    L'option --auto-clone :

    • Génère un nouveau nom de disque
    • Génère une nouvelle adresse MAC
    • Génère un nouvel UUID
  3. Vérifier le clone

    Fenêtre de terminal
    virsh list --all | grep -E "ma-vm|clone"

    Sortie attendue :

    - ma-vm shut off
    - ma-vm-clone shut off

Spécifier le chemin du nouveau disque :

Fenêtre de terminal
virt-clone \
--original ma-vm \
--name ma-vm-clone \
--file /var/lib/libvirt/images/ma-vm-clone.qcow2

Cloner avec un disque COW (reflink) sur Btrfs/XFS :

Fenêtre de terminal
virt-clone \
--original ma-vm \
--name ma-vm-clone \
--reflink

Cette option utilise la copie instantanée du système de fichiers (si supporté). Beaucoup plus rapide qu'une copie complète.

Cloner sans copier certains disques :

Fenêtre de terminal
virt-clone \
--original ma-vm \
--name ma-vm-clone \
--skip-copy vdb

Utile si vdb est un disque de données partagé.

Le clone est une copie exacte. Cela signifie que l'intérieur de la VM a :

  • Le même hostname
  • Les mêmes clés SSH hôte
  • La même adresse IP (si statique)
  • Le même machine-id

Pour nettoyer un clone, utilisez virt-sysprep :

Fenêtre de terminal
# Installer si nécessaire
sudo apt install guestfs-tools # Debian/Ubuntu
sudo dnf install guestfs-tools # Fedora/RHEL
# Nettoyer le clone (VM arrêtée)
virt-sysprep -d ma-vm-clone

virt-sysprep supprime :

  • Les clés SSH hôte (régénérées au boot)
  • Le machine-id
  • Les logs
  • L'historique bash
  • Les caches apt/dnf

Un backup est une copie indépendante que vous pouvez restaurer même si l'hôte KVM est détruit. C'est la seule protection contre :

  • Panne matérielle de l'hôte
  • Corruption du système de fichiers
  • Suppression accidentelle
  • Ransomware

Un backup KVM se résume à deux objets, et oublier l'un des deux rend l'autre inutilisable. Le XML sans les disques redéfinit une machine qui pointe sur des fichiers absents ; les disques sans le XML ne disent ni la quantité de RAM, ni le réseau, ni l'ordre de boot. Un backup complet contient donc :

  1. La configuration XML de la VM
  2. Le(s) disque(s) de la VM
Backup complet
├── ma-vm.xml ← Configuration (virsh dumpxml)
└── ma-vm.qcow2 ← Disque (copie)

C'est la méthode la plus fiable : pas de risque d'incohérence.

  1. Arrêter la VM

    Fenêtre de terminal
    virsh shutdown ma-vm
    # Attendre l'arrêt complet
    virsh domstate ma-vm
  2. Exporter la configuration XML

    Fenêtre de terminal
    virsh dumpxml ma-vm > /backup/ma-vm.xml
  3. Identifier le(s) disque(s)

    Fenêtre de terminal
    virsh domblklist ma-vm

    Sortie exemple :

    Target Source
    --------------------------
    vda /var/lib/libvirt/images/ma-vm.qcow2
    vdb /var/lib/libvirt/images/ma-vm-data.qcow2
  4. Copier les disques

    Fenêtre de terminal
    cp /var/lib/libvirt/images/ma-vm.qcow2 /backup/
    cp /var/lib/libvirt/images/ma-vm-data.qcow2 /backup/
  5. Vérifier l'intégrité

    Fenêtre de terminal
    qemu-img check /backup/ma-vm.qcow2

    Sortie attendue :

    No errors were found on the image.
  6. Redémarrer la VM

    Fenêtre de terminal
    virsh start ma-vm

Arrêter une machine pour la sauvegarder n'est pas toujours possible. libvirt expose pour cela une API de sauvegarde dédiée, backup-begin, qui fait le travail sans arrêter la VM et sans que vous manipuliez le moindre fichier de disque. C'est la méthode à employer, et elle remplace les recettes artisanales qui circulent encore.

Fenêtre de terminal
virsh backup-begin ma-vm

La commande répond Backup started et rend la main : la copie se déroule en arrière-plan, pilotée par QEMU. Sans autre argument, libvirt écrit la sauvegarde à côté du disque source, sous le nom du disque suffixé d'un horodatage, par exemple ma-vm.qcow2.1789800752. C'est le mode push, où QEMU pousse lui-même les données vers la destination.

Suivre l'avancement et savoir quand c'est fini :

Fenêtre de terminal
virsh domjobinfo ma-vm

Tant qu'un travail est en cours, la commande décrit son type et sa progression. Quand backup-dumpxml répond no domain backup job present, la sauvegarde est terminée.

Choisir la destination, et sauvegarder en incrémental

Section intitulée « Choisir la destination, et sauvegarder en incrémental »

Décrire la sauvegarde dans un fichier XML permet de choisir où elle atterrit, ce qui est indispensable dès que la destination est un autre disque ou un montage réseau. Le même fichier sert de base aux sauvegardes incrémentales.

backup-full.xml
<domainbackup mode='push'>
<disks>
<disk name='vda' backup='yes' type='file'>
<driver type='qcow2'/>
<target file='/backup/ma-vm-full.qcow2'/>
</disk>
</disks>
</domainbackup>

Un checkpoint est le marqueur qui rend l'incrémental possible : il note l'état des blocs à un instant, et la sauvegarde suivante ne copiera que ce qui a changé depuis. On le crée en même temps que la sauvegarde complète.

checkpoint-base.xml
<domaincheckpoint>
<name>base</name>
</domaincheckpoint>
Fenêtre de terminal
virsh backup-begin ma-vm \
--backupxml /etc/libvirt/backup-full.xml \
--checkpointxml /etc/libvirt/checkpoint-base.xml

La sauvegarde incrémentale se déclare ensuite en nommant le checkpoint de départ, dans un élément <incremental> :

backup-incr.xml
<domainbackup mode='push'>
<incremental>base</incremental>
<disks>
<disk name='vda' backup='yes' type='file'>
<driver type='qcow2'/>
<target file='/backup/ma-vm-incr.qcow2'/>
</disk>
</disks>
</domainbackup>

Le gain se mesure immédiatement : sur une machine de test dont rien n'avait changé entre les deux passes, la sauvegarde complète pesait 524 Ko et l'incrémentale 196 Ko. Sur une VM réelle, l'écart se compte en dizaines de gigaoctets épargnés à chaque passage.

L'ancienne méthode, et pourquoi elle n'est plus la bonne

Section intitulée « L'ancienne méthode, et pourquoi elle n'est plus la bonne »

Avant backup-begin, sauvegarder à chaud imposait un enchaînement manuel : créer un snapshot externe, copier le disque devenu figé, puis refusionner avec blockcommit --active --pivot et supprimer l'overlay. Vous la croiserez dans beaucoup de tutoriels, et il est utile de la comprendre, parce qu'elle explique ce que backup-begin automatise.

Elle n'est plus recommandée pour une raison précise : chacune de ses étapes manipule des fichiers de disque à la main pendant que la VM écrit dedans. Une erreur d'ordre, un pivot oublié ou un overlay supprimé trop tôt ne donnent pas un message d'erreur, ils donnent une perte de données. L'API fait le même travail sans jamais vous confier ces fichiers.

Ne copiez jamais un .qcow2 en cours d'utilisation. Un cp ou un qemu-img convert lancé sur le disque d'une machine allumée lit un fichier que QEMU est en train de modifier. QEMU verrouille d'ailleurs ses images pour empêcher les accès concurrents incompatibles. Le résultat, quand il est produit, démarre parfois, avec un journal à rejouer et, pour une base de données, une corruption silencieuse.

Snapshot cohérent : les trois niveaux, et ce que --quiesce garantit

Section intitulée « Snapshot cohérent : les trois niveaux, et ce que --quiesce garantit »

L'option --quiesce demande au QEMU Guest Agent, installé dans la VM, de geler les systèmes de fichiers le temps de la prise. Sans cet agent, la commande ne se dégrade pas en silence, elle échoue franchement :

error: argument unsupported: QEMU guest agent is not configured

C'est un bon comportement : vous savez tout de suite que vous n'avez pas ce que vous croyiez avoir. Sans l'option, le même snapshot passe quand même, mais il ne vaut pas la même chose. Trois niveaux de cohérence se distinguent, et les confondre est l'erreur classique de la sauvegarde :

NiveauCe que vous obtenezComment
Crash-consistentL'équivalent d'une coupure de courant. Le système redémarre en rejouant son journalsnapshot d'une VM active, sans --quiesce
Filesystem-consistentLe système de fichiers est propre, aucun journal à rejouer--quiesce, avec l'agent installé
Application-consistentLes données applicatives sont cohérentes entre elles--quiesce plus un hook qui met la base en mode sauvegarde

La troisième ligne est celle qu'on oublie. Geler un ext4 ou un XFS ne dit rien de ce qu'une base de données garde encore dans ses tampons ou dans une transaction ouverte. Pour un PostgreSQL ou un MySQL, la cohérence des fichiers ne fait pas la cohérence des données : il faut soit un hook de gel côté applicatif, soit un pg_dump ou un mysqldump classique, soit la sauvegarde native du moteur.

Une sauvegarde qui n'a jamais été restaurée reste une hypothèse. La restauration se joue en deux mouvements : remettre les disques à leur place, puis réinjecter la définition avec virsh define. L'ordre compte, car un domaine défini avant que ses fichiers existent refusera de démarrer.

  1. Copier les disques vers leur emplacement

    Fenêtre de terminal
    cp /backup/ma-vm.qcow2 /var/lib/libvirt/images/
  2. Adapter le XML si nécessaire

    Si vous restaurez sur un hôte différent, vérifiez :

    • Les chemins des disques
    • Le nom du réseau
    • Les capabilities CPU
  3. Importer la VM

    Fenêtre de terminal
    virsh define /backup/ma-vm.xml

    Sortie attendue :

    Domain 'ma-vm' defined from /backup/ma-vm.xml
  4. Démarrer la VM

    Fenêtre de terminal
    virsh start ma-vm
  5. Vérifier

    Fenêtre de terminal
    virsh console ma-vm
    # ou SSH si le réseau fonctionne

Voici un script simple pour automatiser les backups :

#!/bin/bash
# backup-vm.sh - Backup d'une VM KVM
# Usage: ./backup-vm.sh <nom-vm> <dossier-backup>
VM_NAME="${1:?Usage: $0 <vm-name> <backup-dir>}"
BACKUP_DIR="${2:?Usage: $0 <vm-name> <backup-dir>}"
DATE=$(date +%Y%m%d-%H%M%S)
# Créer le dossier de backup
mkdir -p "${BACKUP_DIR}/${VM_NAME}/${DATE}"
DEST="${BACKUP_DIR}/${VM_NAME}/${DATE}"
echo "=== Backup de ${VM_NAME} vers ${DEST} ==="
# Exporter la config XML
echo "[1/3] Export de la configuration..."
virsh dumpxml "${VM_NAME}" > "${DEST}/${VM_NAME}.xml"
# Identifier et copier les disques
echo "[2/3] Copie des disques..."
for DISK in $(virsh domblklist "${VM_NAME}" --details | awk '/disk/ {print $4}'); do
echo " → Copie de ${DISK}..."
DISK_NAME=$(basename "${DISK}")
cp "${DISK}" "${DEST}/${DISK_NAME}"
done
# Vérification
echo "[3/3] Vérification..."
for QCOW in "${DEST}"/*.qcow2; do
qemu-img check "${QCOW}" > /dev/null && echo " [OK] ${QCOW}" || echo " [ERREUR] ${QCOW}"
done
echo "=== Backup terminé : ${DEST} ==="
ls -lh "${DEST}"

Utilisation :

Fenêtre de terminal
chmod +x backup-vm.sh
./backup-vm.sh ma-vm /mnt/backup

Le réflexe utile n'est pas de connaître les commandes par cœur, c'est de partir du besoin et de laisser le tableau désigner l'outil. Les deux premières lignes relèvent du test réversible, les deux dernières de la protection réelle, et la ligne « Dupliquer » n'est ni l'une ni l'autre : elle fabrique une machine de plus.

BesoinTechniqueCommande clé
Tester une mise à jourSnapshotvirsh snapshot-create-as
Revenir en arrièreRevertvirsh snapshot-revert
Dupliquer une VMClonevirt-clone --auto-clone
Protéger contre les pannesBackupdumpxml + copie disque
Restaurer une VMImportvirsh define

Ces cinq situations couvrent la quasi-totalité des demandes d'aide sur le sujet. Les deux premières sont des messages d'erreur que libvirt affiche clairement. Les trois suivantes sont plus vicieuses, puisque la commande réussit : le défaut n'apparaît qu'à l'usage, au démarrage du clone ou le jour de la restauration.

ErreurCauseSolution
error: domain is not runningSnapshot avec --quiesce sur VM arrêtéeRetirer --quiesce
Snapshot not foundMauvais nom ou snapshot déjà supprimévirsh snapshot-list
Clone très lentCopie complète de gros disquesUtiliser --reflink si Btrfs/XFS
VM clone avec même IPIdentifiants non nettoyésvirt-sysprep
Backup corrompuCopie de VM en cours sans snapshotUtiliser la méthode snapshot + copie

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Si une seule idée doit rester de ce guide, c'est que le mot sauvegarde ne s'applique qu'à une copie qui survit à la destruction de l'hôte. Un snapshot n'y survit pas, un clone laissé sur le même disque non plus. Les six points ci-dessous découlent tous de cette distinction.

  1. Snapshot n'est pas backup, le snapshot dépend du disque original
  2. Snapshot = test temporaire, créez, testez, supprimez
  3. Clone = copie indépendante, pensez à nettoyer les identifiants
  4. Backup = XML + disque(s), testez la restauration régulièrement
  5. Pas plus de 2-3 snapshots, au-delà, les performances se dégradent
  6. Quiesce améliore la cohérence mais nécessite l'agent QEMU

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn