Échecs de sauvegarde/restauration Proxmox LXC : erreurs tar, permissions et pièges de systèmes de fichiers

Cet article vous a aidé ?

Vous lancez vzdump sur un conteneur LXC Proxmox. Il tourne un moment. Puis il explose avec une plainte de tar qui ressemble à un post de forum Linux de 1998 :
« tar: … Cannot open: Permission denied », ou « xattrs not supported », ou le classique « Unexpected EOF in archive ».

Pendant ce temps, la direction pense « les sauvegardes sont passées » parce que le job s’est exécuté, pas parce qu’il a été restauré. Le stockage pense que c’est un problème applicatif. L’équipe appli pense que c’est « un truc Proxmox ».
C’est généralement un problème de système de fichiers déguisé en erreur tar.

Fiche de diagnostic rapide

L’objectif n’est pas d’admirer le message d’erreur. L’objectif est de trouver rapidement le goulot d’étranglement : capacité du stockage, fonctionnalités du système de fichiers, ou mappage d’identités.
Voici l’ordre qui fait gagner du temps.

1) Confirmer quelle phase a échoué : création de l’archive, compression ou extraction lors de la restauration

  • Si le fichier d’archive est absent ou minuscule, c’est un problème de création (erreurs de lecture, permissions, problèmes de snapshot).
  • Si l’archive existe mais que la restauration échoue tôt, c’est généralement xattrs/ACLs/mappage de propriétaires, ou le stockage cible ne peut pas représenter les métadonnées.
  • Si la restauration échoue tardivement, cherchez « No space left », épuisement d’inodes, ou timeouts sur un stockage réseau.

2) Identifier le type de stockage aux deux extrémités (rootfs source et cible de sauvegarde)

Un rootfs LXC sur ZFS se comporte différemment qu’un rootfs sur dir. La cible de sauvegarde sur NFS se comporte différemment qu’une cible sur ZFS.
« C’est juste un fichier » est un mensonge rassurant que votre stockage vous fera payer.

3) Vérifier si le conteneur est non privilégié et si le chemin de sauvegarde/restauration préserve la propriété

Les conteneurs non privilégiés s’appuient sur le mappage UID/GID. Si vous restaurez sur un stockage qui ne peut pas conserver ces IDs ou les xattrs, tar protestera et Proxmox abandonnera.

4) Reproduire sans compression et avec tar en mode verbeux

La compression masque la première erreur réelle. Désactivez-la, reproduisez et lisez le premier chemin de fichier échouant.

5) Ce n’est qu’ensuite que vous chassez les « bugs tar »

Tar est généralement le messager. Le tuer ne résout pas le message.

Comment Proxmox sauvegarde les LXC (et où tar intervient)

Les sauvegardes LXC de Proxmox sont généralement pilotées par vzdump. Pour les conteneurs, « l’artefact » par défaut est une archive tar du système de fichiers racine
du conteneur plus les métadonnées (config, points de montage). Selon le mode, Proxmox peut :

  • mode stop : arrêter le conteneur, tar du système de fichiers de manière cohérente, puis le redémarrer.
  • mode snapshot : si le stockage supporte les snapshots, en prendre un et tar depuis le snapshot pendant que le conteneur tourne.
  • mode suspend : compromis historique ; moins courant et moins apprécié.

Le point clé : même si votre rootfs est ZFS, la sauvegarde résultante est souvent un flux tar sauf si vous choisissez un stockage+format qui supporte les snapshots natifs.
Ce flux tar transporte des métadonnées : permissions, propriétaires, horodatages, nœuds de périphérique, ACLs et attributs étendus (xattrs).
Si le système de fichiers source a des fonctionnalités que la destination (cible de sauvegarde) ou la destination d’extraction ne peut pas représenter, vous obtenez des échecs qui paraissent arbitraires.

Faits intéressants et contexte historique (parce que ça a des racines)

  1. Tar a été inventé avant Linux. Il a été conçu pour les bandes ; son comportement « streaming » explique pourquoi des archives partielles surviennent quand quelque chose coupe le tuyau.
  2. GNU tar a ajouté le support xattr/ACL progressivement. Les anciennes distributions considéraient les ACL comme une cerise optionnelle ; les conteneurs modernes traitent cela comme de l’identité.
  3. Les conteneurs LXC non privilégiés ont normalisé le décalage d’UID. La convention « root à l’intérieur = 100000 à l’extérieur » n’est pas universelle, mais elle est courante.
  4. Proxmox a hérité de l’ADN d’OpenVZ. Le nom vzdump est un fossile de cette époque ; il fait toujours le job.
  5. Les snapshots ZFS sont peu coûteux ; les restaurations ne le sont pas toujours. Les snapshots sont des métadonnées, mais envoyer/recevoir ou extraire un tar implique un vrai I/O.
  6. NFS a plusieurs personnalités. v3 vs v4, root_squash et le cache d’attributs peuvent transformer un « permission denied » en théâtre de performance.
  7. CIFS/SMB n’est pas un système de fichiers POSIX. Il peut émuler des bits de mode Unix, mais les xattrs et nœuds de périphérique sont une négociation, pas une garantie.
  8. Les systèmes de fichiers en overlay ont changé les attentes. Les conteneurs ont fait s’attendre aux couches copy-on-write ; tar attend des inodes et chemins stables.

Une règle opérationnelle qui tient dans le temps : si vous ne pouvez pas restaurer, vous n’avez pas de sauvegarde. Ce n’est pas de la poésie, c’est de la comptabilité.

Citation (idée paraphrasée) de Werner Vogels : « Tout échoue, tout le temps — concevez et opérez en supposant l’échec. » Cela s’applique cruellement bien aux sauvegardes.

Modes d’échec : erreurs tar et ce qu’elles signifient vraiment

« tar: Cannot open: Permission denied »

Il s’agit rarement de « tar qui n’a pas la permission ». C’est généralement le processus de sauvegarde Proxmox sur l’hôte qui tente de parcourir un chemin que l’hôte ne peut pas lire
à cause d’un mappage d’IDs, de bind mounts, ou d’un rootfs qui n’est pas ce que vous pensez.
Déclencheurs courants :

  • Bind mount dans le conteneur depuis un répertoire aux permissions restrictives sur l’hôte.
  • Montage NFS avec root_squash où root de l’hôte devient nobody.
  • Conteneur non privilégié où certains chemins ont une propriété inattendue après un chown manuel ou un rsync.

« tar: Cannot set xattr » / « Operation not supported »

C’est un décalage de fonctionnalités du système de fichiers. La cible d’extraction ne supporte pas l’espace de noms xattr que tar tente de restaurer.
Cas classiques :

  • Restauration sur CIFS sans les extensions Unix appropriées.
  • Restauration sur une exportation NFS qui supprime les xattrs ou les mappe de façon étrange.
  • Restauration dans un système de fichiers monté avec xattr/acl désactivés (oui, certaines personnes font encore ça).

« tar: Cannot change ownership to uid … »

D’ordinaire l’un des cas suivants :

  • Vous restaurez dans un rootfs de conteneur non privilégié sur un système de fichiers qui n’aime pas les UIDs/GIDs élevés, ou vous restaurez sans le bon contexte de mappage.
  • L’extraction se fait en tant qu’utilisateur qui ne peut pas chown (par exemple, la sauvegarde s’exécute dans un environnement restreint ou sur certains systèmes de fichiers réseau).
  • La sauvegarde a été prise depuis un conteneur privilégié et restaurée sur un non privilégié (ou vice versa) sans ajuster les attentes.

« Unexpected EOF in archive »

Tar est un flux. Si le processus qui écrit le flux meurt, le lecteur voit EOF. Causes racines :

  • Plus d’espace sur la cible de sauvegarde en plein milieu du flux.
  • Problème réseau vers NFS/CIFS provoquant une écriture échouée et la rupture du pipe.
  • OOM kill, ou timeout dans l’étape de compression (zstd/gzip).

« File changed as we read it »

C’est ce qui arrive quand vous sauvegardez un système de fichiers en activité sans barrière de snapshot. Un peu de churn est bénin ; certains cas donnent un état applicatif corrompu.
Si vous voyez cela souvent, passez en mode snapshot sur le stockage supporté, ou en mode stop pour la cohérence.

Blague #1 : Les sauvegardes sont comme les parachutes — si vous attendez de les tester pendant le saut, vous vous êtes engagé dans une expérience d’apprentissage.

Modèle de permissions : privilégié vs non privilégié, idmaps, et pourquoi root n’est pas root

Les conteneurs ne sont pas des VM. Ils partagent le noyau de l’hôte. Proxmox LXC utilise les espaces de noms d’utilisateur Linux pour les conteneurs non privilégiés.
Cela signifie :

  • Conteneur privilégié : root du conteneur se mappe au root de l’hôte (UID 0).
  • Conteneur non privilégié : root du conteneur se mappe à un UID élevé de l’hôte (souvent 100000). La propriété des fichiers sur le disque reflète les UIDs de l’hôte, pas ceux du conteneur.

Pourquoi cela importe pour la sauvegarde/la restauration :

  • Tar stocke les UIDs/GIDs numériques. Si votre sauvegarde contient des UIDs décalés sur l’hôte (ex. 100000+), la restauration doit les recréer exactement.
  • Certains systèmes de fichiers et exports ne préservent pas bien les UIDs élevés, ou les mappent de façon étrange.
  • Les bind mounts peuvent introduire des mondes de propriété mixtes : une partie de l’arborescence est décalée, une autre non.

Les bind mounts sont le saboteur silencieux

Proxmox autorise des points de montage de conteneur (mp0, mp1, etc.) qui bindent des chemins hôtes dans le conteneur.
C’est pratique jusqu’au moment de la sauvegarde. Selon la configuration, ces chemins peuvent être inclus, exclus, ou se comporter différemment pendant tar.
Les permissions de l’hôte sur le chemin source décident de ce que tar peut lire.

Conseil pratique : si vous utilisez des bind mounts pour des données applicatives, traitez ces données comme un domaine de sauvegarde séparé avec sa propre méthode (snapshot du système de fichiers, dump de base de données, etc.).
Tenter de « simplement les inclure dans vzdump » fonctionne jusqu’au jour où ça ne marche plus. Et ça échoue toujours un week-end.

Pièges des systèmes de fichiers : ZFS, dir, NFS, CIFS, btrfs et alliés

ZFS : les snapshots aident, mais les propriétés du dataset peuvent encore vous nuire

ZFS est l’adulte de la pièce : snapshots cohérents, checksums, compression et clones rapides. Mais ce n’est pas magique.
Les terrains minés habituels à la restauration sont :

  • Confusion de point de montage : restauration dans un dataset qui n’est pas monté là où Proxmox l’attend.
  • Permissions du dataset : mode ACL et stockage des xattrs configurés d’une manière qui ne correspond pas aux attentes du conteneur.
  • Refquota/refreservation : la restauration échoue en cours de route avec ENOSPC même si le pool a de la place.

Stockage « dir » : simple, lisible, et étonnamment facile à mal configurer

Un répertoire de système de fichiers simple comme stockage est souvent correct. Votre ennemi ici n’est pas la complexité ; ce sont des options de montage subtiles :
noacl, nouser_xattr, ou stocker les sauvegardes sur un truc comme exFAT parce que « c’est juste un disque de sauvegarde ».
ExFAT ne comprend pas vos besoins de métadonnées Linux. Il comprend le regret.

NFS : le modèle de permissions est le produit

Si vos sauvegardes résident sur NFS, vous devez comprendre :

  • root_squash : root de l’hôte devient anonyme ; tar ne peut pas chown et peut même ne pas lire.
  • idmapping : NFSv4 avec mapping basé sur les noms peut faire diverger les IDs numériques, entraînant des « mauvaises propriétés après restauration ».
  • verrouillage et cache d’attributs : peuvent provoquer d’étranges avertissements « file changed » lors d’une sauvegarde d’arbres actifs.

CIFS/SMB : adapté aux documents, risqué pour les sémantiques de rootfs conteneur

SMB peut convenir pour des archives de sauvegarde (un fichier tar.zst posé sur un partage) si les permissions sont correctes.
Mais restaurer un rootfs sur CIFS est une mauvaise idée à moins d’apprécier le débogage d’xattrs à 2 h du matin.
Si vous devez : assurez-vous des extensions Unix, des xattrs et des options de montage appropriées. Même dans ce cas, testez régulièrement les restaurations.

btrfs : les snapshots existent, mais la maturité opérationnelle varie

btrfs peut faire des snapshots et du send/receive. Dans Proxmox, le support btrfs existe mais est moins courant que ZFS dans la pratique.
Les pièges tendent à être :

  • Confusion de la disposition des sous-volumes conduisant à « restauration réussie mais le conteneur ne démarre pas ».
  • Les groupes de quotas provoquant des ENOSPC inattendus malgré de l’espace libre apparent.

Blague #2 : Tar ne vous « déteste » pas. Il refuse simplement de mentir sur la personnalité de votre système de fichiers.

Tâches pratiques : commandes, ce que signifie la sortie, et la décision à prendre

Ce sont les vrais gestes. Chaque tâche inclut une commande exécutable, une sortie d’exemple, ce que cela vous apprend, et ce qu’il faut faire ensuite.
Exécutez-les sur l’hôte Proxmox sauf indication contraire.

Task 1: Identify the container’s rootfs and storage backend

cr0x@server:~$ pct config 101 | egrep '^(arch|cores|hostname|ostype|rootfs|unprivileged|mp[0-9]+)'
hostname: app-lxc-01
ostype: debian
arch: amd64
cores: 4
unprivileged: 1
rootfs: local-zfs:subvol-101-disk-0,size=16G
mp0: /srv/data,mp=/var/lib/app-data

Signification : Le rootfs est un sous-volume ZFS. Le conteneur est non privilégié. Il y a un bind mount (mp0) depuis /srv/data.

Décision : Prévoir un décalage d’UID. Traiter mp0 séparément ; c’est probablement la première source d’échecs de permission.

Task 2: Verify the backup storage configuration and type

cr0x@server:~$ pvesm status
Name             Type     Status           Total            Used       Available        %
local             dir     active        196529976        42108740       144544184   21.43%
local-zfs         zfspool active        2147483648      126903296      2020580352    5.91%
backup-nfs        nfs     active       1953514588      110154852      1843369736    5.64%

Signification : Les sauvegardes vont probablement vers backup-nfs. NFS implique que root_squash et le comportement des xattrs sont suspects.

Décision : Confirmer les options d’export NFS avant d’accuser Proxmox ou tar.

Task 3: Inspect a failed job log for the first real error

cr0x@server:~$ journalctl -u pvedaemon -S -2h | egrep -i 'vzdump|tar:|error|exit'
Dec 26 11:01:02 server pvedaemon[2218]: vzdump 101 --storage backup-nfs --mode snapshot --compress zstd
Dec 26 11:01:45 server pvedaemon[2218]: tar: ./var/lib/app-data/cache: Cannot open: Permission denied
Dec 26 11:01:45 server pvedaemon[2218]: tar: Exiting with failure status due to previous errors
Dec 26 11:01:45 server pvedaemon[2218]: ERROR: Backup of VM 101 failed - command 'tar ...' failed: exit code 2

Signification : Le chemin en échec est dans le point de montage bindé (/var/lib/app-data), qui mappe vers /srv/data sur l’hôte.

Décision : Vérifier les permissions hôte sur /srv/data et le squashing NFS si c’est sur un montage NFS.

Task 4: Check whether the bind mount source is on NFS/CIFS and with what options

cr0x@server:~$ findmnt -T /srv/data -o TARGET,SOURCE,FSTYPE,OPTIONS
TARGET   SOURCE                  FSTYPE OPTIONS
/srv/data nfs01:/export/appdata  nfs4   rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.10

Signification : La source du bind mount est NFS. Si l’export a root_squash, root de l’hôte ne pourra pas lire tout.

Décision : Valider les permissions d’export. Envisager d’exclure les bind mounts de vzdump et les sauvegarder via un snapshot natif du stockage à la place.

Task 5: Confirm root squashing symptoms by trying to read as root

cr0x@server:~$ sudo -n ls -ld /srv/data /srv/data/cache
drwxr-x--- 10 100000 100000 4096 Dec 26 10:40 /srv/data
drwx------  2 100123 100123 4096 Dec 26 10:45 /srv/data/cache

Signification : La propriété est décalée (100000+), cohérent avec des données de conteneur non privilégié sur NFS. Root sur l’hôte peut encore lire, mais la politique d’export NFS peut l’outrepasser.

Décision : Si root ne peut pas traverser, corriger l’export NFS (no_root_squash pour un réseau de sauvegarde/host dédié) ou changer l’approche de sauvegarde.

Task 6: Re-run backup without compression to surface the true failure quickly

cr0x@server:~$ sudo vzdump 101 --storage backup-nfs --mode snapshot --compress none --stdout 0
INFO: starting new backup job: vzdump 101 --storage backup-nfs --mode snapshot --compress none --stdout 0
INFO: backup mode: snapshot
INFO: ionice priority: 7
INFO: creating Proxmox Backup archive 'vzdump-lxc-101-2025_12_26-11_07_10.tar'
ERROR: tar: ./var/lib/app-data/cache: Cannot open: Permission denied
ERROR: tar: Exiting with failure status due to previous errors
INFO: removing partial backup file 'backup-nfs:backup/vzdump-lxc-101-2025_12_26-11_07_10.tar'
ERROR: Backup of VM 101 failed - command 'tar' failed: exit code 2

Signification : Même échec, log plus propre. Ce n’est pas la compression.

Décision : Arrêtez d’essayer différents compresseurs. Corrigez les permissions ou excluez ce montage de la sauvegarde.

Task 7: Check container mount points and whether they’re included in backup

cr0x@server:~$ grep -E '^(mp[0-9]+|lxc.mount.entry)' /etc/pve/lxc/101.conf
mp0: /srv/data,mp=/var/lib/app-data

Signification : Ce montage est défini via la config Proxmox. Par défaut, vzdump l’inclura à moins d’être configuré autrement.

Décision : Si ce sont des données externes/partagées, excluez-les de la sauvegarde du conteneur et sauvegardez-les au niveau du dataset/export.

Task 8: Verify xattr/ACL capability on backup target filesystem

cr0x@server:~$ findmnt -T /mnt/pve/backup-nfs -o TARGET,FSTYPE,OPTIONS
TARGET            FSTYPE OPTIONS
/mnt/pve/backup-nfs nfs4   rw,relatime,vers=4.1,sec=sys,hard,timeo=600,retrans=2

Signification : NFSv4 peut supporter les xattrs, mais la configuration d’export du serveur compte. De plus, votre cible de sauvegarde n’a besoin que d’écrire le fichier tar ; les xattrs importent surtout pour la cible de restauration.

Décision : Séparez « peut écrire le fichier d’archive » de « peut restaurer les métadonnées ». Testez la restauration sur le stockage prévu.

Task 9: Validate a backup archive without restoring it (detect corruption)

cr0x@server:~$ sudo tar -tf /mnt/pve/backup-nfs/dump/vzdump-lxc-101-2025_12_26-10_00_00.tar.zst | head
./
./etc/
./etc/hostname
./etc/hosts
./var/
./var/lib/
./var/lib/app-data/
./var/lib/app-data/cache/

Signification : Vous pouvez lister l’archive. Si cela échoue avec « Unexpected EOF », l’archive est corrompue/incomplète.

Décision : Si corrompue : investiguez une interruption réseau/de stockage, pas les permissions du conteneur.

Task 10: Confirm available space and inodes on restore target

cr0x@server:~$ df -h /rpool/data /rpool/data/subvol-101-disk-0
Filesystem      Size  Used Avail Use% Mounted on
rpool           1.8T  1.2T  600G  67% /
rpool/data      600G  410G  190G  69% /rpool/data

cr0x@server:~$ df -i /rpool/data
Filesystem       Inodes  IUsed    IFree IUse% Mounted on
rpool/data            0      0        0     - /rpool/data

Signification : Sur ZFS, le rapport d’inodes est différent ; l’absence de chiffres d’inodes est normale. Concentrez-vous sur les quotas de dataset et l’espace disponible.

Décision : Si vous restaurez sur ext4/xfs, l’épuisement d’inodes est réel ; sur ZFS, vérifiez plutôt les propriétés de quota.

Task 11: Check ZFS dataset quotas that can fake “no space left”

cr0x@server:~$ zfs get -o name,property,value -H refquota,quota,used,avail rpool/data/subvol-101-disk-0
rpool/data/subvol-101-disk-0	refquota	16G
rpool/data/subvol-101-disk-0	quota	none
rpool/data/subvol-101-disk-0	used	15.8G
rpool/data/subvol-101-disk-0	avail	200M

Signification : Le dataset est limité par refquota. Même si le pool a des téraoctets libres, ce sous-volume n’en a pas.

Décision : Augmentez la taille dans Proxmox ou augmentez le refquota avant la restauration, ou restaurez sur un dataset plus grand puis ajustez la taille du disque du conteneur après coup.

Task 12: Inspect mapping for unprivileged containers (host side)

cr0x@server:~$ sudo grep -E '^(root|lxc)' /etc/subuid /etc/subgid
/etc/subuid:root:100000:65536
/etc/subgid:root:100000:65536

Signification : Root de l’hôte a une plage pour le mappage. Si ces plages sont manquantes ou trop petites, les conteneurs non privilégiés et les restaurations peuvent se comporter étrangement.

Décision : Assurez la cohérence des plages subuid/subgid entre les nœuds du cluster, surtout si vous migrez/restaurez sur des hôtes différents.

Task 13: Run a restore in a scratch container ID to test without committing

cr0x@server:~$ sudo pct restore 999 /mnt/pve/backup-nfs/dump/vzdump-lxc-101-2025_12_26-10_00_00.tar.zst --storage local-zfs
restoring 'vzdump-lxc-101-2025_12_26-10_00_00.tar.zst' to VM 999 ...
extracting archive '/mnt/pve/backup-nfs/dump/vzdump-lxc-101-2025_12_26-10_00_00.tar.zst'
tar: ./var/lib/app-data/cache: Cannot open: Permission denied
tar: Exiting with failure status due to previous errors
ERROR: Restore failed - command 'zstd -q -d -c ... | tar ...' failed: exit code 2

Signification : La restauration échoue lors de l’extraction du contenu du bind mount. Cela prouve que le problème est dans le contenu de l’archive et le chemin des permissions, pas dans le runtime du conteneur.

Décision : Excluez ce montage de la sauvegarde, ou corrigez l’accès pendant la sauvegarde/restauration. Si ce sont des données externes, ne les mettez pas dans la sauvegarde du rootfs.

Task 14: Confirm whether mount points are inside the archive (and decide if they should be)

cr0x@server:~$ sudo tar -tf /mnt/pve/backup-nfs/dump/vzdump-lxc-101-2025_12_26-10_00_00.tar.zst | egrep '^./var/lib/app-data' | head
./var/lib/app-data/
./var/lib/app-data/cache/
./var/lib/app-data/cache/tmp.db

Signification : Les données bind-montées sont incluses dans l’archive.

Décision : Si ces données vivent sur un stockage partagé (NFS) et ont leur propre cycle de vie, excluez-les et sauvegardez-les au niveau du stockage. Sinon, corrigez l’accès hôte pour les lire.

Task 15: Catch AppArmor/LSM interference (rare, but painful)

cr0x@server:~$ dmesg -T | egrep -i 'apparmor|denied|audit' | tail
[Thu Dec 26 11:12:22 2025] audit: type=1400 audit(1766747542.123:410): apparmor="DENIED" operation="open" profile="lxc-pct" name="/srv/data/cache/tmp.db" pid=31222 comm="tar" requested_mask="r" denied_mask="r" fsuid=0 ouid=100123

Signification : Le noyau a refusé la lecture par tar, pas une permission Unix classique. C’est un problème de politique.

Décision : Ajustez le profile LXC/AppArmor ou déplacez le chemin de sauvegarde/restauration vers des emplacements autorisés par la politique. N’optez pas pour « désactiver AppArmor » en premier recours.

Trois mini-histoires d’entreprise du terrain

Incident causé par une fausse hypothèse : « Le bind mount fait partie du conteneur, donc il est sauvegardé »

Une entreprise SaaS de taille moyenne utilisait Proxmox avec une flotte LXC propre. Les équipes applicatives utilisaient des bind mounts pour tout ce qui était état :
/srv/postgres dans le conteneur DB, /srv/uploads dans le conteneur web, etc.
L’équipe infra a supposé que parce que Proxmox affichait le montage dans la config du conteneur, il était « inclus dans la sauvegarde ».

La défaillance a commencé silencieusement. Les sauvegardes « réussissaient » pendant des semaines parce que les chemins bind-montés étaient lisibles la plupart du temps.
Puis un changement d’export NFS est intervenu : le root squashing a été activé largement dans le cadre d’un audit de sécurité.
Cette nuit-là, vzdump a échoué sur plusieurs conteneurs avec Permission denied. Le planificateur affichait toujours « job exécuté », et personne n’a vérifié.

Deux mois plus tard un conteneur a été corrompu pendant une mise à jour. La restauration « a fonctionné », le conteneur a démarré, et l’application est arrivée—vide.
L’archive contenait le rootfs, mais les données critiques bind-montées n’avaient jamais été capturées de manière cohérente. Certaines restaurations échouaient complètement ; d’autres restaurées un sous-ensemble obsolète.
C’était le pire type d’incident : une récupération apparemment réussie avec un état incorrect.

La correction n’a pas été héroïque. Ils ont cessé de traiter les bind mounts comme faisant partie de la portée de sauvegarde du conteneur.
Les conteneurs de base de données ont reçu des sauvegardes logiques plus des snapshots de stockage. Les uploads ont eu une réplication objet.
Les sauvegardes vzdump sont restées pour le rootfs et la config, mais elles ne prétendaient plus être la vérité entière.

Optimisation qui a mal tourné : « Sauvegardons sur SMB parce que c’est moins cher et déjà présent »

Une autre organisation disposait d’un NAS Windows et d’un mandat : consolider les sauvegardes dessus.
Quelqu’un a pointé le stockage de sauvegarde de Proxmox vers un partage SMB. Ça a fonctionné pour quelques conteneurs, alors ils ont généralisé.
Les coûts semblaient faibles. Le tableur souriait.

La première fissure est apparue pendant les tests de restauration. Les petits conteneurs se restaient bien ; les plus gros échouaient de façon intermittente avec des erreurs tar :
Cannot set xattr, Operation not supported, et parfois Unexpected EOF.
Ils ont « corrigé » EOF en augmentant les timeouts et ont réessayé jusqu’au vert.
Ce n’est pas une correction ; c’est jouer aux dés avec des étapes supplémentaires.

Le problème plus profond : les sémantiques SMB et les options de montage variaient selon les nœuds. Certains montages géraient différemment uid/gid.
Certains préservaient les xattrs, d’autres non. La même sauvegarde se restaurait différemment selon l’endroit où on la lançait.
La restauration est devenue une loterie avec un meilleur logging.

Finalement ils ont pivoté : SMB sert uniquement de dépôt bête pour des fichiers de sauvegarde produits ailleurs, pas comme système de fichiers pour restaurer des rootfs.
Pour les restaurations, ils extrayaient sur un stockage local ZFS sur l’hôte Proxmox. Le problème a disparu. Les coûts ont un peu augmenté. Le sommeil s’est beaucoup amélioré.

Pratique ennuyeuse mais correcte qui a sauvé la mise : exercices de restauration routiniers et un ID de « scratch restore »

Un environnement réglementé tournait Proxmox avec ZFS et un contrôle des changements strict. Leur job de sauvegarde avait une exigence « agaçante » :
chaque semaine, restaurer deux conteneurs aléatoires dans une plage d’IDs scratch (900–999) sur un réseau isolé.
Personne n’aimait y consacrer du temps, mais c’était la politique.

Une semaine, l’exercice de restauration a échoué sur un conteneur récemment converti en non privilégié.
Des erreurs tar sont apparues autour de la propriété et des xattrs. Ce n’était pas une crise parce que cela a été détecté pendant l’exercice, pas pendant un incident.

La cause était banale : un nœud avait des plages /etc/subuid inconsistantes après une reconstruction.
Les sauvegardes étaient correctes. Les restaurations dépendaient de l’hôte. Ils ont corrigé le mappage, relancé l’exercice et sont passés à autre chose.
Le vrai gain : ils l’ont trouvé avant qu’un incident ne les force à s’en préoccuper.

C’est la vérité ennuyeuse : l’exercice de restauration n’était pas glamour, mais il a empêché une panne stressante et visible plus tard.
Ils n’avaient pas besoin d’héroïsme parce qu’ils avaient une routine.

Erreurs courantes (symptôme → cause racine → correction)

1) Symptom: Backup fails with “Permission denied” on a path under /var/lib/...

Cause racine : Ce chemin est un bind mount depuis l’hôte ; les permissions de l’hôte (ou NFS root_squash) bloquent tar.

Correction : Assurez-vous que root de l’hôte peut lire la source du bind mount ; ou excluez le montage de la sauvegarde du conteneur et sauvegardez-le séparément.

2) Symptom: Restore fails with “Cannot set xattr” or “Operation not supported”

Cause racine : Le système de fichiers/export cible ne supporte pas les xattrs/ACLs de l’archive.

Correction : Restaurez sur un stockage POSIX natif (ZFS, ext4, xfs). Évitez de restaurer un rootfs sur CIFS ; validez le support xattr de l’export NFS.

3) Symptom: Restore fails with “Cannot change ownership” or lots of numeric UIDs in logs

Cause racine : Décalage d’UID pour conteneur non privilégié ; l’environnement de restauration ne peut pas représenter ou appliquer ces propriétaires.

Correction : Gardez des subuid/subgid cohérents entre les nœuds. Restaurez sur un stockage qui supporte chown et les UIDs élevés. Ne mélangez pas privilégié/non privilégié sans plan.

4) Symptom: “Unexpected EOF” when listing or restoring an archive

Cause racine : Archive incomplète (écriture interrompue, plus d’espace, coupure réseau, processus tué).

Correction : Vérifiez la capacité du stockage, la stabilité NFS, et les logs système pour des OOM kills. Privilégiez un staging local rapide pour les sauvegardes si le réseau est instable.

5) Symptom: Backup succeeds but restore produces wrong permissions inside the container

Cause racine : Restauration sur un système de fichiers qui remappe la propriété (certaines configurations NFSv4) ou perd les ACLs/xattrs.

Correction : Restaurez sur ZFS/ext4/xfs local, puis migrez. Ou ajustez l’idmapping NFS pour être cohérent et testez.

6) Symptom: Restore fails with ENOSPC though the pool has space

Cause racine : refquota/quota ZFS ou qgroups btrfs limitent le dataset/sous-volume.

Correction : Augmentez la taille/les quotas du dataset avant la restauration. Ne vous fiez pas au « pool free » comme réponse finale.

7) Symptom: “File changed as we read it” warnings, sometimes followed by broken app state

Cause racine : Sauvegarde effectuée sans barrière de snapshot pour une charge active.

Correction : Utilisez le mode snapshot sur un stockage qui le supporte, ou le mode stop pour la cohérence. Pour les bases de données, faites des sauvegardes logiques.

8) Symptom: Restore works on one node but fails on another

Cause racine : Configuration hôte inconsistante : subuid/subgid, options de montage, versions du plugin de stockage, ou montages NFS.

Correction : Standardisez les configurations des nœuds, traitez-les comme du « cattle », et lancez des exercices de restauration sur plusieurs nœuds.

Listes de contrôle / plan étape par étape

Étape par étape : du log échoué à la cause racine en moins de 30 minutes

  1. Obtenez le premier chemin en échec depuis journalctl ou le log vzdump. Ignorez la dernière ligne d’erreur ; elle est généralement générique.
  2. Mappez le chemin à la config du conteneur : est-il sous un bind mount (mpX) ? Si oui, traitez-le comme stockage externe.
  3. Confirmez les types de stockage (stockage rootfs, stockage de sauvegarde, stockage cible de restauration) avec pvesm status et findmnt.
  4. Vérifiez les permissions sur l’hôte pour le fichier/répertoire exactement en échec. Si c’est NFS/CIFS, vérifiez la politique d’export/partage, pas seulement les bits de mode.
  5. Relancez sans compression pour obtenir des erreurs déterministes et éviter le bruit CPU.
  6. Validez l’intégrité de l’archive via tar -t avant de tenter la restauration à répétition.
  7. Pour les conteneurs non privilégiés, vérifiez la cohérence subuid/subgid et évitez de restaurer sur des systèmes de fichiers non POSIX.
  8. Corrigez la cause, puis lancez une restauration scratch vers un nouveau CTID avant de toucher l’ID de production.

Checklist opérationnelle : rendre les restaurations LXC banales

  • Gardez le rootfs des conteneurs sur ZFS ou un système de fichiers POSIX correct.
  • Utilisez des backups par snapshot quand supporté ; utilisez stop pour les services sensibles à la cohérence.
  • Ne comptez pas sur les bind mounts pour être « inclus automatiquement » dans les sauvegardes. Décidez explicitement.
  • Standardisez /etc/subuid et /etc/subgid sur tous les nœuds du cluster.
  • Stockez les archives où vous voulez, mais restaurez sur un stockage qui préserve les métadonnées.
  • Exécutez des restaurations scratch routinières. Faites tourner le nœud qui les effectue.
  • Traquez les échecs de sauvegarde comme des alertes, pas comme « quelqu’un verra ».

Guide de décision : choisir la bonne portée de sauvegarde

  • Rootfs du conteneur + config : vzdump suffit. Les restaurations sont rapides et prévisibles sur ZFS/stockage local.
  • Données d’état montées par bind : sauvegardez via le système de stockage qui les possède (snapshots ZFS, snapshots serveur NFS, dumps natifs de base de données).
  • Bases de données : priorisez les sauvegardes logiques et la réplication plutôt que la cohérence tar du système de fichiers.

FAQ

1) Pourquoi Proxmox utilise-t-il tar pour les sauvegardes LXC plutôt que seulement des snapshots ?

Portabilité. Une archive tar peut être stockée partout et restaurée sur des backends différents. Les snapshots sont spécifiques au stockage ; tar est le plus bas dénominateur commun.

2) Le « exit code 2 » de tar est-il toujours une défaillance fatale de sauvegarde ?

Dans ce contexte, traitez-le comme fatal. Tar utilise le code 2 pour les « erreurs fatales ». Proxmox marquera généralement la sauvegarde comme échouée et peut supprimer les sorties partielles.

3) Puis-je ignorer les avertissements « file changed as we read it » ?

Pour un serveur applicatif très actif, parfois. Pour une base de données ou tout ce qui est transactionnel, non. Si vous voulez des restaurations cohérentes, utilisez le mode snapshot ou stop, plus des sauvegardes applicatives.

4) Pourquoi les conteneurs non privilégiés compliquent-ils la restauration ?

Parce que la propriété sur disque est décalée (UIDs/GIDs élevés). Le processus de restauration doit recréer fidèlement ces IDs numériques et métadonnées. Certains backends de stockage ne le font pas.

5) Mes sauvegardes sont stockées sur NFS. Est-ce mauvais ?

Pas intrinsèquement. Stocker des archives sur NFS est courant. Le risque augmente si vos données de conteneur sont elles‑mêmes sur NFS via des bind mounts, ou si vous tentez de restaurer un rootfs sur NFS.

6) Pourquoi restaurer sur CIFS échoue parfois avec des erreurs xattr/ACL ?

CIFS n’est pas POSIX natif. Le support des xattrs Linux, ACLs et nœuds de périphérique dépend des fonctionnalités du serveur et des options de montage. Les conteneurs attendent des sémantiques Linux.

7) Quel est le workflow de restauration le plus sûr ?

Restaurer vers un nouveau CTID sur ZFS local (ou ext4/xfs), valider le démarrage et les vérifications applicatives, puis basculer le trafic et décommissionner le conteneur défaillant.
Ne restaurez pas in-place sauf si vous acceptez d’allonger l’indisponibilité.

8) Pourquoi la restauration échoue avec « no space left » alors que le pool ZFS a beaucoup d’espace ?

Parce que le dataset peut être limité par refquota ou similaire. La restauration écrit dans le dataset, pas dans l’ensemble du pool.
Vérifiez la valeur avail du dataset, pas l’espace libre du pool.

9) Comment gérer correctement les bind mounts dans les sauvegardes ?

Décidez si les données bind-montées font partie de l’objectif de récupération du conteneur. Si oui, sauvegardez-les explicitement avec une méthode adaptée au stockage. Si non, excluez-les de la portée de la sauvegarde du conteneur et documentez la dépendance.

10) Dois-je passer tous les conteneurs en privilégié pour éviter les problèmes de mappage UID ?

Non. Cela échange une commodité opérationnelle contre une plus grande surface de risque. Corrigez la cohérence des mappages et la compatibilité du stockage à la place. Les conteneurs privilégiés ne sont pas une solution gratuite.

Conclusion : étapes suivantes qui réduisent vraiment le risque

Quand une sauvegarde/restauration Proxmox LXC échoue avec des erreurs tar, le bon mouvement est d’arrêter de lire la sortie tar comme une énigme.
Elle vous dit généralement une des trois vérités : l’hôte ne peut pas lire un chemin, la cible ne peut pas représenter les métadonnées, ou le stockage a manqué de quelque chose en plein flux.

Faites ceci ensuite :

  1. Effectuez aujourd’hui une restauration scratch pour un conteneur représentatif. Si vous ne pouvez pas restaurer à la demande, traitez cela comme un incident.
  2. Inventoriez les bind mounts dans vos conteneurs et décidez si chacun entre dans le périmètre des sauvegardes au niveau conteneur.
  3. Standardisez subuid/subgid et les options de montage du stockage entre les nœuds Proxmox. La dérive est la cause des « ça marche sur mon nœud ».
  4. Privilégiez la restauration sur ZFS/stockage POSIX local. Utilisez les partages réseau pour stocker des archives, pas pour héberger le rootfs du conteneur à restaurer.
  5. Transformez les exercices de restauration en routine. L’ennui est le but.
← Précédent
PCIe et GPU : quand x8 suffit et quand ça fait mal
Suivant →
Le bug du missile Patriot : quand la dérive du temps est devenue un problème sur le champ de bataille

Laisser un commentaire