5. PBS : sauvegarder, restaurer, vérifier
PBS est connecté. On en vient à ce qui compte : planifier les sauvegardes et leur rétention, restaurer une machine entière ou un simple fichier. Et s'assurer, par des vérifications régulières, que les sauvegardes sont réellement restaurables.
5.1 Jobs de backup et politique de rétention
Une fois PBS déclaré comme stockage, les backups se planifient dans Datacenter → Backup → Add. On y définit le planning (expression CRON), les VMs concernées, le mode et la politique de rétention.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Déclencher un backup manuel (mode snapshot = sans arrêter la VM)
# Pas de --compress : PBS compresse lui-même chaque bloc en zstd
vzdump 101 --storage pbs-backup --mode snapshot
# Backup de toutes les VMs et conteneurs d'un nœud
vzdump --all --storage pbs-backup --mode snapshot
Résultat attendu :
INFO: starting new backup job: vzdump 101 --mode snapshot --storage pbs-backup
INFO: Starting Backup of VM 101 (qemu)
INFO: Backup started at 2026-09-29 13:59:55
INFO: status = running
INFO: VM Name: vm-web-01
INFO: include disk 'scsi0' 'local-lvm:vm-101-disk-0' 20G
INFO: backup mode: snapshot
INFO: ionice priority: 7
INFO: snapshots found (not included into backup)
INFO: creating Proxmox Backup Server archive 'vm/101/2026-09-29T11:59:55Z'
INFO: issuing guest-agent 'fs-freeze' command
INFO: starting backup via QMP command
INFO: issuing guest-agent 'fs-thaw' command
INFO: started backup task '1acbee3f-34f1-47d0-8a08-e31e8f84c121'
INFO: resuming VM again
INFO: scsi0: dirty-bitmap status: created new
INFO: 63% (12.7 GiB of 20.0 GiB) in 3s, read: 4.2 GiB/s, write: 97.3 MiB/s
INFO: 100% (20.0 GiB of 20.0 GiB) in 5s, read: 3.7 GiB/s, write: 0 B/s
INFO: backup is sparse: 18.57 GiB (92%) total zero data
INFO: backup was done incrementally, reused 19.71 GiB (98%)
INFO: transferred 20.00 GiB in 5 seconds (4.0 GiB/s)
INFO: Finished Backup of VM 101 (00:00:06)
INFO: Backup finished at 2026-09-29 14:00:01
INFO: Backup job finished successfully
INFO: notified via target `mail-to-root`
La même commande, relancée juste après :
INFO: scsi0: dirty-bitmap status: OK (24.0 MiB of 20.0 GiB dirty)
INFO: using fast incremental mode (dirty-bitmap), 24.0 MiB dirty of 20.0 GiB total
INFO: backup was done incrementally, reused 19.98 GiB (99%)
INFO: transferred 24.00 MiB in 1 seconds (24.0 MiB/s)
INFO: Finished Backup of VM 101 (00:00:01)
dirty-bitmap status: created new annonce la première sauvegarde depuis le démarrage de la VM : QEMU n'a pas encore de carte des blocs modifiés, tout est relu. À la sauvegarde suivante, la mention devient OK (24.0 MiB of 20.0 GiB dirty) : seuls les 24 Mo modifiés sont lus et envoyés, en une seconde.
reused 19.71 GiB (98%) dès la première sauvegarde : le datastore contenait déjà ces blocs, venus des sauvegardes précédentes de la même VM. C'est la déduplication de PBS : un bloc déjà stocké n'est jamais renvoyé.
backup is sparse mesure les blocs vides du disque virtuel, ignorés plutôt que transférés.
Le mode snapshot sauvegarde sans arrêter la VM, mais l'état obtenu est celui d'un arrêt brutal du point de vue de l'invité. Les bases de données peuvent en souffrir. Le QEMU Guest Agent, installé dans la VM, permet à Proxmox de figer les systèmes de fichiers pendant l'instantané : la sauvegarde devient cohérente.
Les deux autres modes ont leur place : suspend met en pause pendant la copie, stop arrête la VM. Le premier est un compromis rarement satisfaisant, le second la seule garantie absolue.
La politique de rétention (pruning) évite que les sauvegardes n'occupent un espace croissant indéfiniment. PBS utilise un système à niveaux hiérarchiques :
| Paramètre | Signification |
|---|---|
keep-last=7 |
Conserver les 7 dernières sauvegardes, quelle que soit leur date |
keep-daily=30 |
Conserver 1 sauvegarde par jour sur les 30 derniers jours |
keep-weekly=12 |
Conserver 1 sauvegarde par semaine sur les 12 dernières semaines |
keep-monthly=6 |
Conserver 1 sauvegarde par mois sur les 6 derniers mois |
Après le pruning, les chunks qui ne sont plus référencés par aucune sauvegarde restent sur disque jusqu'au garbage collection (GC : le nettoyage des chunks orphelins) :
Dans le Shell de PBS (interface web de PBS → Administration → Shell) :
# Sur le serveur PBS — forcer le GC manuellement ; il affiche son journal en direct
proxmox-backup-manager garbage-collection start demo-store
Résultat attendu (extrait du journal) :
starting garbage collection on store demo-store
Start GC phase1 (mark used chunks)
marked 100% (12 of 12 index files)
Start GC phase2 (sweep unused chunks)
Removed garbage: 12.30 GiB
Removed chunks: 4821
Pending removals: 0 B (in 0 chunks)
Original data usage: 78.40 GiB
On-Disk usage: 12.20 GiB (15.56%)
Deduplication factor: 6.43
TASK OK
Les deux phases sont le mécanisme lui-même. La phase 1 parcourt tous les index de sauvegarde et marque chaque bloc encore utilisé. La phase 2 balaie le datastore et supprime les blocs non marqués.
Pourquoi l'espace ne revient qu'après le ramasse-miettes. Le prune ne retire que des index ; la phase 1 marque les blocs encore utilisés, la phase 2 supprime les autres. Cliquez sur une étape pour la ligne de journal correspondante.
Supprimer une sauvegarde ne libère rien tout de suite. PBS retire l'index, mais les blocs restent sur le disque tant qu'un autre index peut encore y faire référence. C'est le ramasse-miettes qui vérifie et libère.
Pending removals mérite d'être compris : il compte les blocs devenus orphelins mais conservés pendant 24 h par sécurité, au cas où une sauvegarde en cours viendrait à les référencer. Une valeur non nulle est donc normale ; elle passera à zéro au passage suivant.
Un datastore qui se remplit alors que la rétention semble respectée est presque toujours un ramasse-miettes qui ne tourne pas. Vérifiez qu'il est planifié : Datastore → Prune & GC → GC Schedule.
L'interface propose un planning quotidien à la création. Mais un datastore créé en ligne de commande, ou repris d'une ancienne installation, peut en être dépourvu.
L'ordre compte : prune d'abord, GC ensuite. Le prune retire les index selon la politique de rétention, le GC libère les blocs devenus inutiles. L'inverse ne libère rien.
Séquence à comprendre : pruning → GC → espace libéré. Le pruning supprime les références aux vieilles sauvegardes dans les métadonnées de PBS.
Le GC supprime ensuite les chunks qui ne sont plus référencés. Ces deux étapes peuvent être planifiées automatiquement dans l'interface PBS (Datastore → Prune & GC).
▶ À pratiquer maintenant — Atelier 4
Sauvegarder le CT 201 et la VM du chapitre 4, puis constater ce que la déduplication économise dès la deuxième passe.
5.2 Restauration complète et file-level restore
PBS offre deux niveaux de restauration que vzdump seul ne permettait pas facilement.
Restauration complète d'une VM depuis PVE :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Via l'interface : VM → Backup → sélectionner une sauvegarde → Restore
# Via la CLI :
# (196 : un identifiant libre — la VM 110 existe déjà depuis le chapitre 2)
qmrestore "pbs-backup:backup/vm/101/2026-10-07T13:19:23Z" 196 \
--storage local-lvm \
--unique
# --unique génère de nouvelles adresses MAC, pour cohabiter avec l'original.
# L'adresse IP, elle, vient de cloud-init : la restauration reprend celle de la VM 101.
# Avant tout démarrage, lui donner une adresse libre (onglet Cloud-Init, ou qm set --ipconfig0).
Résultat attendu :
new volume ID is 'local-lvm:vm-196-cloudinit'
new volume ID is 'local-lvm:vm-196-disk-0'
restore proxmox backup image: /usr/bin/pbs-restore --repository root@pam@10.59.1.14:demo-store --ns pxe211 vm/101/2026-10-07T13:19:23Z drive-scsi0.img.fidx /dev/pve/vm-196-disk-0 --verbose --format raw --skip-zero
connecting to repository 'root@pam@10.59.1.14:demo-store'
using up to 4 threads
open block backend for target '/dev/pve/vm-196-disk-0'
starting to restore snapshot 'vm/101/2026-10-07T13:19:23Z'
download and verify backup index
fetching up to 16 chunks in parallel
[...]
progress 100% (read 21474836480 bytes, zeroes = 92% (19822280704 bytes), duration 3 sec)
restore image complete (bytes=21474836480, duration=3.57s, speed=5729.46MB/s)
rescan volumes...
Sur le lab (PBS en 10.59.1.14), vers un identifiant d'essai (196, supprimé ensuite) ; les lignes d'avertissement de LVM sur le provisionnement fin sont omises. Le stockage du lab se connecte en root@pam et range les sauvegardes dans le namespace pxe211 (--ns pxe211, § 4.3) ; avec un jeton, le dépôt s'écrit utilisateur@realm!jeton@serveur:datastore.
La commande sous-jacente, pbs-restore, est visible en deuxième ligne : c'est elle qui lit les blocs sur PBS et les écrit dans le nouveau volume. --skip-zero et le compteur zeroes = 92% montrent que les zones vides du disque ne sont pas écrites — c'est ce qui rend la restauration plus rapide que la sauvegarde initiale.
Restauration de fichier individuel (file-level restore) : c'est la fonctionnalité qui justifie PBS dans de nombreuses infrastructures. Récupérer un fichier /etc/nginx/nginx.conf accidentellement supprimé sans avoir à restaurer toute la VM.
La voie la plus simple est l'interface : sélectionnez la sauvegarde (VM → Backup, ou le stockage pbs-backup → Backups) → File Restore. Proxmox ouvre une arborescence navigable du disque sauvegardé, et un bouton Download récupère le fichier ou le dossier voulu.
En coulisses, il démarre une toute petite machine virtuelle de lecture, qui monte le disque sauvegardé sans jamais toucher au nœud. C'est vrai même si le système de fichiers de la sauvegarde est corrompu, ou d'un type que le nœud ne connaît pas.
En ligne de commande, le principe est le même, mais en deux temps. Une sauvegarde de VM est une image de disque, pas une arborescence de fichiers. On la présente d'abord comme un disque local, puis on monte sa partition.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Définir les variables de connexion (le secret du jeton va dans PBS_PASSWORD)
export PBS_REPOSITORY="backup@pbs!pve-token@<ip-du-serveur-pbs>:demo-store"
# Lister les sauvegardes disponibles
proxmox-backup-client snapshot list --repository "$PBS_REPOSITORY"
# Présenter l'image disque sauvegardée comme un périphérique bloc local (lecture seule)
proxmox-backup-client map "vm/101/2026-10-07T13:19:23Z" drive-scsi0.img --repository "$PBS_REPOSITORY"
# Repérer la partition qui porte le système
lsblk /dev/loop0
# Monter sa première partition, en lecture seule
mkdir -p /mnt/restore-tmp
mount -o ro /dev/loop0p1 /mnt/restore-tmp # montage en lecture seule
# Explorer puis copier le fichier souhaité
ls /mnt/restore-tmp/etc/ssh/
cp /mnt/restore-tmp/etc/ssh/sshd_config ./sshd_config.restaure # copier le fichier hors de la sauvegarde
# Démonter, puis libérer le périphérique
umount /mnt/restore-tmp
proxmox-backup-client unmap /dev/loop0 # libérer le périphérique
Résultat attendu, sur le lab — sur pxe211, (dépôt du lab : root@pam@10.59.1.14:demo-store, avec --ns pxe211 puisque ses sauvegardes sont rangées dans ce namespace, § 4.3). snapshot list (extrait) :
┌─────────────────────────────┬─────────────┬────────────────────────────────────────────────────────┐
│ snapshot │ size │ files │
╞═════════════════════════════╪═════════════╪════════════════════════════════════════════════════════╡
│ ct/200/2026-10-07T13:19:45Z │ 663.231 MiB │ catalog.pcat1 client.log index.json pct.conf root.pxar │
├─────────────────────────────┼─────────────┼────────────────────────────────────────────────────────┤
│ ct/201/2026-10-07T13:19:30Z │ 524.485 MiB │ catalog.pcat1 client.log index.json pct.conf root.pxar │
Sortie de map, puis de lsblk /dev/loop0 :
Image 'root@pam@10.59.1.14:8007:demo-store:vm/101/2026-10-07T13:19:23Z/drive-scsi0.img' mapped on /dev/loop0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 20G 1 loop
├─loop0p1 259:0 0 19.9G 1 part
├─loop0p14 259:1 0 3M 1 part
└─loop0p15 259:2 0 124M 1 part
La colonne RO à 1 : le disque présenté est en lecture seule. loop0p1 (19,9 Go) porte le système ; les deux petites partitions sont celles du démarrage de l'image cloud. Après mount, ls /mnt/restore-tmp/etc/ssh/ liste moduli, ssh_config, ssh_config.d, sshd_config…
map rend un périphérique /dev/loop0 dont les partitions apparaissent comme /dev/loop0p1, /dev/loop0p2… — lsblk /dev/loop0 les liste si l'on ne sait pas laquelle porte /. Le montage en lecture seule (-o ro) n'est pas une précaution de style : la sauvegarde est immuable, et le système refuserait de toute façon d'y écrire. Pour une sauvegarde de conteneur, archive de fichiers et non image disque, proxmox-backup-client mount monte directement l'arborescence, sans passer par map.
Prérequis de l'interface : le bouton File Restore a besoin du paquet proxmox-backup-file-restore sur le nœud PVE. Il est installé d'office sur les versions récentes ; s'il manque, apt install proxmox-backup-file-restore.
▶ À pratiquer maintenant — Atelier 5
Restaurer sous un autre identifiant, puis récupérer un seul fichier sans toucher à la machine d'origine — c'est ce second geste qui sert le plus souvent en production.
5.3 Vérification d'intégrité — verify jobs
Avoir une sauvegarde ne suffit pas — encore faut-il qu'elle soit restaurable. La corruption silencieuse (bitrot), les pannes de stockage partielles, ou même des bugs logiciels peuvent rendre une sauvegarde inutilisable sans déclencher d'alerte visible.
Un verify job PBS relit tous les chunks d'un ensemble de sauvegardes, recalcule leur SHA-256 et compare avec les métadonnées stockées. Si un chunk est corrompu ou manquant, PBS génère une alerte.
Dans le Shell de PBS (interface web de PBS → Administration → Shell) :
# Sur PBS : planifier une vérification hebdomadaire du datastore
proxmox-backup-manager verify-job create verify-weekly \
--store demo-store \
--schedule "sun 03:00"
proxmox-backup-manager verify-job list # vérifier que le job est enregistré
# Vérifier tout de suite le datastore, en sautant ce qui l'a déjà été
proxmox-backup-manager verify demo-store --ignore-verified true
Résultat attendu :
┌─────────────┬────────────┬───────────┬─────────────────┬────────────────┬─────────┐
│ id │ store │ schedule │ ignore-verified │ outdated-after │ comment │
╞═════════════╪════════════╪═══════════╪═════════════════╪════════════════╪═════════╡
│ essai-verif │ demo-store │ sun 03:00 │ │ │ │
└─────────────┴────────────┴───────────┴─────────────────┴────────────────┴─────────┘
verify datastore demo-store
found 19 groups
using 1 read and 4 verify thread(s)
verify group demo-store:ct/200 (1 snapshots)
verify demo-store:ct/200/2026-09-25T15:30:13Z
check pct.conf.blob
check root.pxar.didx
verified 225.69/659.51 MiB in 0.69 seconds, speed 327.37/956.61 MiB/s (0 errors)
[...]
percentage done: 100.00% (19/19 groups)
TASK OK
Sur pbs1, avec une tâche d'essai nommée essai-verif (supprimée ensuite) ; le datastore des ateliers contient 19 groupes de sauvegardes.
(0 errors) et TASK OK signifient que chaque bloc a été relu et comparé à sa somme de contrôle. Les deux nombres de verified se lisent ainsi, pour le conteneur 200. 225,69 Mio réellement lus sur le disque de PBS : les blocs stockés, compressés. Pour 659,51 Mio de données une fois décompressées.
Une sauvegarde vérifiée porte ensuite une coche verte dans l'onglet Content du datastore, et un bloc corrompu fait marquer la sauvegarde en échec — à refaire. C'est la seule preuve qu'une sauvegarde est restaurable ; le fait qu'elle apparaisse dans la liste ne prouve rien.
Une sauvegarde jamais vérifiée est une sauvegarde dont on ignore l'état. La corruption silencieuse existe : un bloc altéré sur le disque ne se signale pas, et ne se découvre qu'au moment de la restauration — c'est-à-dire au pire moment.
La vérification est coûteuse en entrées-sorties : d'où la planification de nuit, le dimanche, hors des fenêtres de sauvegarde. --ignore-verified permet de ne revérifier que ce qui ne l'a jamais été, ce qui rend l'opération beaucoup plus légère sur un gros datastore.
Bonne pratique : testez régulièrement la restauration. Par exemple une fois par trimestre, restaurez une VM de test depuis PBS et vérifiez qu'elle démarre correctement. La vérification automatique des chunks (verify job) contrôle l'intégrité des données, mais seul un test de restauration réel valide le processus complet.
Réponse
**Le ramasse-miettes ne tourne pas.** Le *pruning* retire les références aux vieilles sauvegardes, mais les chunks restent sur le disque tant que le **garbage collection** ne les a pas supprimés. La séquence est toujours : pruning, puis GC, puis espace libéré. On vérifie donc qu'une tâche GC est planifiée sur le datastore et qu'elle aboutit.À retenir : un job planifie les sauvegardes, la rétention (keep-daily, keep-weekly…) décide lesquelles garder ; le ramasse-miettes (GC) libère réellement l'espace. On restaure une VM entière ou un seul fichier (File Restore). Un verify job relit les chunks : une sauvegarde jamais vérifiée est une sauvegarde dont on ignore l'état.
Proxmox VE — TSSR