Dawan Proxmox VE — TSSR

Chapitre 5 — SDN, pare-feu et sauvegarde

Ateliers — chapitre 5

Infrastructure : le cluster cluster-tp du chapitre 4 (3 nœuds, Ceph HEALTH_OK). À côté, votre Proxmox Backup Server, déjà installé.

Service URL (navigateur) Identifiants Adresse interne
PVE https://pxe2<N>1.<ville>.pm.dawan.ovh (nœuds 2 et 3 : pxe2<N>2, pxe2<N>3) root / proxmoxx, domaine Linux PAM 10.<site>.<N>.11 à .13
PBS https://pbs2<N>4.<ville>.pm.dawan.ovh root / proxmoxx, domaine Linux PAM 10.<site>.<N>.14 — livré sans datastore (atelier 2)

Le formateur vous donne vos URL exactes (<ville> : nts, prs ou sbg). Elles sont votre seul accès depuis votre poste.

Les adresses internes 10.<site>.<N>.x ne servent qu'entre vos machines : déclarer PBS dans Proxmox VE.

Les captures proviennent du lab d'exemple (PVE 9.2.20, PBS 4.2.6), dont vmbr0 était alors en 192.168.1.x. Les résultats en texte viennent du même lab, passé sur le plan des stagiaires : 10.59.1.x (site 59, stagiaire 1). Versions : PVE 9.2.21, PBS 4.2.7, PDM (Proxmox Datacenter Manager) 1.1.7.


État du lab en fin de chapitre :

  • Pare-feu du Datacenter activé à l'atelier 1 (règles 22, 8006 et Ceph), puis désactivé en fin d'atelier, ses règles conservées
  • PBS : datastore demo-store-s<N> (atelier 2) ; namespaces pxe2<N>1 à pxe2<N>3, utilisateur pxe2<N>1-user@pbs limité au sien, stockage pbs-backup dans le namespace pxe2<N>1 (atelier 3)
  • PBS : job nocturne 02:00 avec rétention 7 + 4, facteur de déduplication noté (atelier 4)
  • CT 210 restauré depuis PBS, en .52 ; fichier /tmp/hostname-restore extrait (atelier 5)
  • (Atelier 6) copie des PBS voisins dans backup-store, un namespace voisin-s<N> par voisin, par job de synchronisation
  • Fil rouge (atelier 7) : VM 400 web-prod en .90 sur ceph-vm, sous HA, filtrée par son pare-feu ; groupe exploitation ; pare-feu du Datacenter réactivé ; checklist de livraison déroulée, chaque machine décrite

Atelier 1 — Activer le pare-feu Proxmox

Contexte

Le pare-feu Proxmox a une règle d'or : on écrit les règles d'autorisation avant d'activer le pare-feu. Activer d'abord, c'est risquer de se couper soi-même l'accès à l'interface web.

Sur votre lab, un filet de sécurité existe : Proxmox autorise d'office l'interface web et SSH depuis le réseau local du nœud. Or l'accès Dawan arrive par la passerelle de ce réseau.

Vous le vérifierez. Ce filet ne dispense pas du bon ordre : sur un serveur joint depuis un autre réseau, il ne protège rien.

Votre nœud est une machine distante : vous n'y avez aucun accès physique. Si le pare-feu vous coupe, personne ne pourra le rattraper depuis un clavier.

Vous allez donc ajouter une seconde précaution, que le cours ne montre pas : un filet automatique. Il désactive le pare-feu tout seul au bout de cinq minutes, si vous ne l'annulez pas.

Une dernière précaution concerne Ceph. Le filet de Proxmox ne couvre pas ses réseaux : sans règle, Ceph se bloque quelque temps après l'activation. Ses règles s'écrivent donc avec les autres, avant d'activer.

Résultat à obtenir : les règles d'accès (interface web, SSH, Ceph) créées et relues, et un filet automatique posé. Puis le pare-feu activé au niveau Datacenter, l'accès vérifié, Ceph toujours en bonne santé, et le filet annulé.

Ce que le pare-feu du Datacenter laisse entrer d'office, et ce qu'il jette

Ce qui passe d'office quand le pare-feu s'active : le réseau local de vmbr0 et Corosync. Vos règles servent aux autres réseaux.

Et les réseaux de Ceph ne sont couverts par rien. Cliquez sur un bloc pour lire le résultat obtenu.

Arborescence attendue

Datacenter → Firewall
├── Règles ACCEPT créées D'ABORD :
│   ├── tcp/8006 (interface web)   ← position 0, la dernière créée
│   ├── tcp/22   (SSH)
│   └── macro Ceph depuis les deux réseaux Ceph   ← sinon Ceph se bloque
└── Options → Firewall : Yes      ← APRÈS les règles

Ce que vous devez faire

  1. Créer les règles ACCEPT au niveau Datacenter, avant toute activation : interface web (8006), SSH (22), et la macro Ceph depuis les deux réseaux Ceph.
  2. Relire ces règles.
  3. Poser un filet automatique : programmer la désactivation du pare-feu dans cinq minutes (systemd-run).
  4. Activer le pare-feu du Datacenter, confirmer que l'accès est conservé et que Ceph reste HEALTH_OK, puis annuler le filet.
  5. Lire le filet de sécurité de Proxmox : le réseau qu'il considère comme local.

⚠️ L'ordre n'est pas négociable : règles d'abord, activation ensuite.

Cliquez pour vous aider

Étape 1 — Créer les règles ACCEPT au niveau Datacenter

Datacenter → Firewall (l'entrée seule, pas VNet Firewall) → Add.

Fenêtre Add: Rule pour SSH

Direction in, Action ACCEPT, Protocol tcp, Dest. port 22, Comment SSH admin, Enable coché. Source vide : la règle vaut pour toute provenance. → Add.

Même chose pour l'interface web : Dest. port 8006, Comment Interface web Proxmox VE.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Équivalent CLI, dans le Shell d'un nœud
pvesh create /cluster/firewall/rules \
  --action ACCEPT --type in --proto tcp --dport 22 --enable 1 --comment "SSH admin"
# règle 8006 : l'interface web
pvesh create /cluster/firewall/rules \
  --action ACCEPT --type in --proto tcp --dport 8006 --enable 1 --comment "Interface web Proxmox VE"
cat /etc/pve/firewall/cluster.fw   # les règles écrites dans cluster.fw

Résultat attendu :

[RULES]

IN ACCEPT -p tcp -dport 8006 -log nolog # Interface web Proxmox VE
IN ACCEPT -p tcp -dport 22 -log nolog # SSH admin

-log nolog est écrit par l'interface ; créées par pvesh, les mêmes règles n'ont pas cette mention (IN ACCEPT -p tcp -dport 8006 # Interface web Proxmox VE). Le comportement est le même : pas de journalisation.

Les deux règles du Datacenter

Deux règles, 8006 en position 0, 22 en position 1 : chaque nouvelle règle s'insère en tête. Les règles se lisent de haut en bas, la première qui correspond décide.

Puis les règles de Ceph. Proxmox fournit une macro Ceph qui regroupe ses ports.

Datacenter → Firewall → Add : Direction in, Action ACCEPT, Macro Ceph, Source le réseau Ceph public (10.<site>.<N+30>.0/24). Puis une seconde règle identique pour le réseau Ceph cluster (10.<site>.<N+20>.0/24).

Dans le Shell du nœud :

pvesh create /cluster/firewall/rules --type in --action ACCEPT --macro Ceph \
  --source 10.<site>.<N+30>.0/24 --enable 1 --comment "Ceph depuis 10.<site>.<N+30>.0/24"   # le réseau Ceph public
pvesh create /cluster/firewall/rules --type in --action ACCEPT --macro Ceph \
  --source 10.<site>.<N+20>.0/24 --enable 1 --comment "Ceph depuis 10.<site>.<N+20>.0/24"   # le réseau Ceph cluster
grep -E "^IN" /etc/pve/firewall/cluster.fw   # les quatre règles

Résultat attendu : quatre lignes, dont IN Ceph(ACCEPT) -source 10.<site>.<N+20>.0/24 et IN Ceph(ACCEPT) -source 10.<site>.<N+30>.0/24, au-dessus des règles 8006 et 22.

Pourquoi Ceph avant l'activation. Le filet de Proxmox (étape 3) couvre le réseau de vmbr0 et Corosync, pas les réseaux de Ceph. Les connexions déjà ouvertes survivent à l'activation ; les nouvelles sont jetées.

Sur le lab, sans ces règles, Ceph a semblé aller bien une vingtaine de minutes. Puis ses démons se sont reconnectés : HEALTH_WARN, 8 PG bloqués en peering, et une sauvegarde de VM figée 11 minutes. Les deux règles ont tout débloqué en moins de trois minutes.

Ne passez à l'étape 2 qu'après avoir vu vos quatre règles.

Étape 1 bis — Poser un filet automatique

Avant d'activer quoi que ce soit, programmez l'annulation. systemd-run crée un minuteur temporaire : dans cinq minutes, il lancera la commande qui désactive le pare-feu du Datacenter.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Dans 5 minutes, désactiver le pare-feu du Datacenter, sauf si on annule avant
systemd-run --on-active=5min --unit=filet-parefeu pvesh set /cluster/firewall/options --enable 0
# Vérifier que le minuteur est armé
systemctl is-active filet-parefeu.timer

Résultat attendu :

Running timer as unit: filet-parefeu.timer
Will run service as unit: filet-parefeu.service
active

Si l'activation de l'étape 2 vous coupait l'accès, il suffirait d'attendre : cinq minutes plus tard, le pare-feu repasse à enable: 0 et l'interface répond de nouveau. Sur le lab, avec un minuteur d'une minute, pve-firewall status est bien revenu à disabled/running, et cluster.fw à enable: 0.

Étape 2 — Activer le pare-feu

Datacenter → Firewall → Options → double-clic sur Firewall → cocher → OK.

Options du pare-feu du Datacenter, activé

Firewall : Yes. Input Policy : DROP par défaut : tout ce qu'aucune règle n'autorise est jeté. Output Policy et Forward Policy restent à ACCEPT.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Équivalent CLI
pvesh set /cluster/firewall/options --enable 1
pve-firewall status   # état du service de pare-feu
ceph health           # Ceph doit rester en bonne santé

Résultat attendu : Status: enabled/running, puis ceph health toujours à HEALTH_OK.

Vérifiez aussitôt, dans un nouvel onglet, sans fermer l'ancien : l'interface web se recharge normalement. Sur le lab, curl -sk -o /dev/null -w "%{http_code}" https://<nœud>:8006/ répondait 200.

L'accès est bon : annulez le filet, sinon il désactivera le pare-feu dans quelques minutes.

Dans le Shell du nœud :

# Arrêter le minuteur : la désactivation programmée n'aura pas lieu
systemctl stop filet-parefeu.timer
# Vérifier qu'il n'est plus armé
systemctl is-active filet-parefeu.timer

Résultat attendu : inactive.

Si vous ne retrouvez pas l'interface dans le nouvel onglet, ne touchez à rien : attendez la fin des cinq minutes, rechargez, puis corrigez vos règles avant de recommencer.

Étape 3 — Le filet de sécurité de Proxmox

Dans le Shell d'un nœud :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pve-firewall localnet   # le réseau que Proxmox considère comme local

Résultat attendu (lab 10.59.x) :

local hostname: pxe211
local IP address: 10.59.1.11
network auto detect: 10.59.1.0/24
using detected local_network: 10.59.1.0/24

accepting corosync traffic from/to:
 - pxe212: 10.59.11.12 (link: 0)
 - pxe212: 10.59.1.12 (link: 1)
 - pxe213: 10.59.11.13 (link: 0)
 - pxe213: 10.59.1.13 (link: 1)

Proxmox détecte le réseau local du nœud. Chez vous, c'est 10.<site>.<N>.0/24, celui de vmbr0. Il y autorise, sans aucune règle, ce dont l'administration a besoin : l'interface web (8006), les consoles, SSH (22) et la migration.

Sur le lab, avec nos règles 22 et 8006 désactivées, l'interface web répondait toujours 200 depuis ce réseau. Corosync, lui, est accepté entre les membres du cluster, sur les deux liens.

Retenez-le : vos règles 22 et 8006 servent aux accès hors du réseau local. Le filet ne couvre que ce réseau-là et Corosync : ni Ceph (d'où l'étape 1), ni rien d'autre.

Validation finale

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pvesh get /cluster/firewall/options --output-format json | grep -o '"enable":1'   # le pare-feu du Datacenter est-il activé ?
curl -sk -o /dev/null -w "%{http_code}\n" https://10.<site>.<N>.11:8006   # l'interface web répond-elle encore ?
ceph health   # Ceph n'a pas souffert

Résultat attendu : "enable":1, puis 200, puis HEALTH_OK.

Nettoyage — désactiver le pare-feu du Datacenter

En production, il resterait actif. Ici, un cluster filtré n'apporte plus rien aux ateliers suivants (sauvegarde), et une règle oubliée suffirait à les bloquer. Ses règles restent en place : le réactiver les remet en service.

Datacenter → Firewall → Options → Firewall → décocher → OK.

Dans le Shell du nœud :

pvesh set /cluster/firewall/options --enable 0   # désactiver, sans toucher aux règles
pve-firewall status                              # → Status: disabled/running

Atelier 2 — Connexion de PBS à Proxmox VE

Contexte

Jusqu'ici, vos sauvegardes restaient sur le nœud qui les produisait : le disque qui tombe emporte la machine et sa sauvegarde. Chaque stagiaire dispose de son propre Proxmox Backup Server, installé à côté de ses trois nœuds, en 10.<site>.<N>.14.

Il sort d'installation : pas encore de datastore. Vous allez le préparer, puis le déclarer comme stockage du cluster.

Résultat à obtenir : un datastore demo-store-s<N> sur le disque de données de PBS, et un stockage pbs-backup actif sur les trois nœuds, qui pointe vers lui.

Les ateliers PBS sauvegardent la VM 101 et le CT 201. La VM 101 vient des chapitres précédents. Créez le CT 201 sur vmbr0, avec la commande ci-dessous.

Dans le Shell du nœud 1 (interface web → votre nœud → Shell) :

# Le CT 201 du fil rouge, sur vmbr0, en .51 (nesting=1 : sinon avertissement systemd)
pct create 201 local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst \
  --hostname ct-sdn-test --storage local-lvm --rootfs local-lvm:4 \
  --cores 1 --memory 512 --unprivileged 1 --features nesting=1 \
  --net0 name=eth0,bridge=vmbr0,ip=10.<site>.<N>.51/24,gw=10.<site>.<N>.1
pct start 201   # démarrer le conteneur

Si le modèle manque (pveam list local), téléchargez-le comme au chapitre 1.

Ce que demande le stockage PBS : datastore, empreinte, compte

Les trois informations que réunit le stockage pbs-backup. Cliquez sur un élément pour lire le résultat obtenu.

Arborescence attendue

PBS (https://pbs2<N>4.<ville>.pm.dawan.ovh, root / Linux PAM)
├── dépôt pbs-no-subscription      ← à la place du dépôt enterprise
├── disque sdb (100 Go) → Directory ext4 → datastore demo-store
└── jeton root@pam!formation-token + droit DatastoreAdmin sur demo-store
Votre cluster → Datacenter → Storage
└── pbs-backup   (type pbs, active)   ← vu par les trois nœuds

Ce que vous devez faire

  1. Se connecter à PBS et parcourir son interface.
  2. Passer PBS sur le dépôt sans abonnement et le mettre à jour.
  3. Créer le datastore demo-store-s<N> sur le disque de données (<N> = votre numéro de stagiaire).
  4. Relever l'empreinte du certificat de PBS.
  5. Ajouter PBS comme stockage du cluster, d'abord par mot de passe, puis par jeton API.

Personnalisez le nom de votre datastore : demo-store-s<N> (stagiaire 3 : demo-store-s3). À l'atelier 6, vos PBS échangent leurs sauvegardes : avec un nom personnel, chacun sait d'où vient chaque copie.

Dans la suite du chapitre, remplacez partout demo-store par votre nom. Les sorties du lab gardent demo-store.

L'atelier suivant (6) range vos sauvegardes dans des namespaces, avant la toute première : faites-le avant de sauvegarder quoi que ce soit.

Cliquez pour vous aider

Étape 1 — Se connecter à PBS

L'URL de votre PBS, https://pbs2<N>4.<ville>.pm.dawan.ovh : utilisateur root, domaine Linux PAM standard authentication, mot de passe proxmoxx.

Tableau de bord de PBS, avant tout datastore

(PBS 4.2.6 du lab). Le tableau de bord : processeur, mémoire, disque système. Datastore Usage : No Data, aucun datastore n'existe encore.

À gauche, Configuration (dont Access Control pour les utilisateurs et les jetons) et Administration (dont Storage / Disks). Le bouton Show Fingerprint servira à l'étape 4.

Étape 2 — Passer PBS sur le dépôt sans abonnement

PBS sort d'installation comme Proxmox VE au premier jour : le dépôt réservé aux abonnés est actif, et toute mise à jour échoue sur une erreur 401.

PBS, onglet Repositories : le dépôt enterprise activé sans abonnement

L'onglet Administration → Repositories, avec l'avertissement « The enterprise repository is enabled, but there is no active subscription! ». Les deux dépôts Debian restent en place. Seul pbs-enterprise se désactive.

  1. Administration → Repositories → la ligne https://enterprise.proxmox.com → Disable
  2. Add → No-Subscription → valider
  3. Administration → Updates → Refresh, puis Upgrade

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

# Même chose en ligne de commande, depuis Administration → Shell
apt update                                        # la liste des paquets
apt full-upgrade -y                               # la mise à jour

Résultat attendu : plus d'erreur 401. Le tableau de bord indique alors, en face de Repository Status, Non production-ready repository enabled! : c'est le dépôt sans abonnement, adapté au lab.

Étape 3 — Créer le datastore

Administration → Storage / Disks → onglet Directory → Create: Directory.

Fenêtre Create: Directory remplie

Disk /dev/sdb, le disque de données de 100 Go, seul disque libre. Filesystem ext4 — le champ est obligatoire et vide par défaut : sans lui, Create reste grisé.

Name demo-store-s<N> (votre numéro ; demo-store sur le lab d'exemple). Add as Datastore coché : le répertoire devient aussitôt un datastore. → Create.

Le datastore créé

Le répertoire /mnt/datastore/demo-store, en ext4. À gauche, sous Datastore, demo-store est apparu.

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

# Vérification, dans le Shell de PBS
proxmox-backup-manager datastore list
df -h /mnt/datastore/demo-store   # espace du disque du datastore

Résultat attendu :

│ demo-store │ /mnt/datastore/demo-store │         │
/dev/sdb1              98G  260M   93G   1% /mnt/datastore/demo-store

Étape 4 — Relever l'empreinte du certificat

Tableau de bord → Show Fingerprint → Copy.

L'empreinte du certificat de PBS

L'empreinte SHA-256 du certificat de PBS. Proxmox VE l'exige pour s'assurer qu'il parle au bon serveur. Derrière, Datastore Usage montre désormais demo-store, 99,70 GB.

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

# Même chose dans le Shell de PBS
proxmox-backup-manager cert info | grep -i fingerprint

Résultat attendu (PBS 4.2.7 du lab) : Fingerprint (sha256): cd:d6:5b:92:…:a5:6b. Chaque PBS a la sienne : c'est celle de votre serveur qu'il faut recopier.

Étape 5 — Ajouter PBS comme stockage du cluster

Méthode 1 — par mot de passe (la plus simple en formation). Sur un nœud : Datacenter → Storage → Add → Proxmox Backup Server.

Fenêtre Add: Proxmox Backup Server remplie

ID pbs-backup. Server 10.<site>.<N>.14. Username root@pam, Password proxmoxx.

Datastore demo-store. Fingerprint : celle de l'étape 4.

Namespace Root pour l'instant (atelier 3). Content backup : un stockage PBS ne reçoit que des sauvegardes. → Add.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Équivalent CLI
pvesm add pbs pbs-backup --server 10.<site>.<N>.14 --username root@pam --password proxmoxx \
  --datastore demo-store --fingerprint '<empreinte>'
pvesm status | grep pbs-backup   # le stockage pbs-backup est-il actif ?

Résultat attendu :

pbs-backup         pbs     active       102625188          265256        97100724    0.26%

Le stockage pbs-backup dans la liste

pbs-backup, type Proxmox Backup Server, contenu Backup, Shared : Yes : les trois nœuds l'utilisent.

Méthode 2 — par jeton API (la méthode de production). Dans PBS : Configuration → Access Control → onglet API Token → Add : User root@pam, Token Name formation-token → Add.

Fenêtre Add: API token de Proxmox Backup Server 4.2 : utilisateur root@pam, nom formation-token

Dans PBS 4.2, Configuration → Access Control → API Token → Add : l'utilisateur root@pam, le nom du jeton formation-token, sans date d'expiration (never). Contrairement à Proxmox VE, aucune case Privilege Separation : le jeton naît sans aucun droit, d'où l'étape suivante.

Le secret du jeton, affiché une seule fois

Le Token ID root@pam!formation-token et son Secret, masqué ici. Il ne s'affiche qu'une fois : copiez-le.

Un jeton PBS n'a aucun droit par défaut. La fenêtre de PBS n'a pas de case Privilege Separation : les droits d'un jeton se donnent à part. Sur le lab, sans droit, l'ajout du stockage a échoué.

Dans le Shell du nœud :

# Ajouter le stockage avec le jeton, avant de lui donner un rôle
pvesm add pbs pbs-token --server 10.<site>.<N>.14 --username 'root@pam!formation-token' \
  --password '<secret-du-jeton>' --datastore demo-store --fingerprint '<empreinte>'
create storage failed: pbs-token: Cannot find datastore 'demo-store', check permissions and existence!

Donnez-lui un rôle sur le datastore — Configuration → Access Control → Permissions → Add, ou dans le Shell de PBS :

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

proxmox-backup-manager acl update /datastore/demo-store DatastoreAdmin --auth-id 'root@pam!formation-token'   # rôle DatastoreAdmin du jeton sur le datastore

Ensuite, sur un nœud :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# ajouter le stockage avec le jeton
pvesm add pbs pbs-token --server 10.<site>.<N>.14 --username 'root@pam!formation-token' \
  --password '<secret-du-jeton>' --datastore demo-store --fingerprint '<empreinte>'
pvesm status | grep pbs-token   # le stockage est-il actif ?
# Un seul stockage suffit pour la suite : retirez celui-ci
pvesm remove pbs-token

Résultat attendu : pbs-token pbs active 102625188 …, identique à pbs-backup.

Validation finale

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pvesm status | grep pbs-backup   # le stockage pbs-backup est-il actif ?

Résultat attendu : pbs-backup pbs active.


Atelier 3 — Namespaces PBS

Contexte

Un PBS sert rarement un seul cluster. Or deux clusters ont chacun leur VM 101 : sans précaution, leurs sauvegardes vm/101 se retrouvent dans le même groupe.

Les namespaces donnent à chaque source son propre rangement. Un utilisateur PBS limité à son namespace garantit ensuite que chacun ne touche qu'à ses sauvegardes.

Vous les créez tout de suite, avant la première sauvegarde. Vos sauvegardes des ateliers 4 et 5 iront dans votre namespace, et à l'atelier 6, la copie de chaque voisin ira dans le sien : rien ne se mélange. Vous simulez plusieurs sources avec vos trois nœuds : un namespace chacun.

Résultat à obtenir : un namespace par nœud, et pbs-backup qui écrit dans celui de votre nœud 1. Un utilisateur PBS qui ne voit que ce namespace, et seulement les sauvegardes qui sont les siennes.

Namespaces et propriétaires des groupes de sauvegardes

Les namespaces rangent, les propriétaires décident de qui voit et écrit quoi. Cliquez sur un élément pour lire le résultat obtenu.

Arborescence attendue

PBS → demo-store-s<N>
├── (racine)            ← vide : vos sauvegardes vont dans votre namespace
├── pxe2<N>1/           ← vm/101, ct/201 (root@pam) ; ct/200 (pxe2<N>1-user@pbs)
├── pxe2<N>2/
└── pxe2<N>3/
PBS → Access Control
└── pxe2<N>1-user@pbs   ← DatastoreBackup sur /datastore/demo-store-s<N>/pxe2<N>1 seulement

Ce que vous devez faire

  1. Créer un namespace par nœud dans votre datastore.
  2. Faire pointer pbs-backup sur le namespace de votre nœud 1, puis sauvegarder la VM 101 et le CT 201.
  3. Créer un utilisateur PBS limité à ce namespace, et constater ce qu'il voit.
  4. Sauvegarder avec ce compte, et comprendre la notion de propriétaire.
Cliquez pour vous aider

Les commandes et les sorties gardent le nom demo-store du lab d'exemple : remplacez-le par votre datastore, demo-store-s<N>.

Étape 1 — Créer les namespaces

Dans PBS : Datastore → votre datastore → Content → Add Namespace, une fois par nœud.

En ligne de commande, avec proxmox-backup-client, installé sur PBS comme sur vos nœuds. (proxmox-backup-manager, l'outil du serveur, n'a pas de sous-commande namespace.)

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

export PBS_REPOSITORY='root@pam@10.<site>.<N>.14:demo-store'   # le dépôt : utilisateur@serveur:datastore
export PBS_PASSWORD='proxmoxx'   # le mot de passe
export PBS_FINGERPRINT='<empreinte>'   # l'empreinte du certificat de PBS
proxmox-backup-client namespace create pxe2<N>1   # le namespace du nœud 1
proxmox-backup-client namespace create pxe2<N>2   # celui du nœud 2
proxmox-backup-client namespace create pxe2<N>3   # celui du nœud 3
proxmox-backup-client namespace list   # les namespaces créés

Résultat attendu : les trois namespaces, pxe211, pxe212 et pxe213 (l'ordre d'affichage peut varier).

Étape 2 — Faire écrire pbs-backup dans votre namespace

Datacenter → Storage → pbs-backup → Edit → Namespace : pxe2<N>1 → OK.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pvesm set pbs-backup --namespace pxe2<N>1   # le stockage écrit dans le namespace du nœud 1
grep -A 8 '^pbs: pbs-backup' /etc/pve/storage.cfg   # la déclaration du stockage
ls -l /etc/pve/priv/storage/pbs-backup.pw   # le fichier du mot de passe du stockage

Résultat attendu (PBS en 10.59.1.14) :

pbs: pbs-backup
    datastore demo-store
    server 10.59.1.14
    content backup
    fingerprint cd:d6:5b:92:…:a5:6b
    namespace pxe211
    username root@pam

-rw------- 1 root www-data 9 Oct  7 15:14 /etc/pve/priv/storage/pbs-backup.pw

Un stockage ajouté par l'interface porte en plus la ligne prune-backups keep-all=1 (la rétention par défaut du stockage : tout garder).

Le mot de passe n'est pas dans storage.cfg : il est rangé à part, lisible par root seul.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

vzdump 101 --storage pbs-backup --mode snapshot   # sauvegarder la VM 101
vzdump 201 --storage pbs-backup --mode snapshot   # puis le CT 201

Résultat attendu : creating Proxmox Backup Server archive 'vm/101/…', puis pour le CT 201 : had to backup 524.068 MiB of 524.068 MiB. Tout est envoyé : c'est la première sauvegarde de ce conteneur dans ce namespace.

Désormais, tout ce que vous sauvegardez par pbs-backup va dans pxe2<N>1, y compris aux ateliers 4 et 5.

Étape 3 — Un utilisateur limité à son namespace

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

# un utilisateur PBS pour le nœud 1
proxmox-backup-manager user create pxe2<N>1-user@pbs \
  --comment "Accès restreint au namespace pxe2<N>1" --password 'FormationPbs2026!'
# Le chemin d'un namespace : celui du datastore, suivi du nom du namespace
proxmox-backup-manager acl update /datastore/demo-store/pxe2<N>1 DatastoreBackup --auth-id pxe2<N>1-user@pbs
proxmox-backup-manager acl list   # les ACL de PBS

Résultat attendu : une ligne pxe211-user@pbs │ /datastore/demo-store/pxe211 │ 1 │ DatastoreBackup.

Connectez-vous à PBS avec ce compte : utilisateur pxe2<N>1-user, domaine Proxmox Backup authentication server.

Erreur 403 à l'ouverture du datastore

En ouvrant le datastore, le compte reçoit permission check failed (403) : il n'a aucun droit sur la racine du datastore. C'est voulu. Fermez, puis onglet Content.

Le choix de namespace du compte restreint

La liste Namespace ne propose que pxe211 : ni pxe212, ni pxe213, ni les groupes de la racine. Sélectionnez-le.

Surprise : le namespace paraît vide. La VM 101 et le CT 201 y sont pourtant.

Le rôle DatastoreBackup ne montre que les sauvegardes dont le compte est propriétaire. Celles-ci ont été faites par root@pam.

Étape 4 — Sauvegarder avec le compte restreint

C'est la bonne pratique : chaque source écrit avec son propre compte. Déclarez un second stockage, limité au nœud 1 :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# stockage limité au namespace du nœud 1, avec cet utilisateur
pvesm add pbs pbs-pxe2<N>1 --server 10.<site>.<N>.14 --datastore demo-store --namespace pxe2<N>1 \
  --username pxe2<N>1-user@pbs --password 'FormationPbs2026!' --fingerprint '<empreinte>' --nodes pxe2<N>1
vzdump 101 --storage pbs-pxe2<N>1 --mode snapshot   # sauvegarder la VM 101 par ce stockage

Résultat attendu :

ERROR: VM 101 qmp command 'backup' failed - backup connect failed: command error: backup owner check failed (pxe211-user@pbs != root@pam)

Chaque groupe de sauvegardes a un propriétaire. Le groupe vm/101 de ce namespace appartient à root@pam : un autre compte ne peut pas y ajouter de sauvegarde. Essayez avec une machine jamais sauvegardée dans ce namespace, le CT 200 :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

vzdump 200 --storage pbs-pxe2<N>1 --mode snapshot   # sauvegarder le CT 200 par ce stockage

Résultat attendu : creating Proxmox Backup Server archive 'ct/200/2026-10-07T16:51:17Z', puis Finished Backup of VM 200 (00:00:05).

Le compte restreint voit sa propre sauvegarde

Rechargez Content avec le compte restreint : ct/200 apparaît, Owner pxe211-use…. Les sauvegardes de root@pam restent invisibles. Leçon : créez le compte et son stockage avant la première sauvegarde d'une source.

Retirez le stockage de test : pvesm remove pbs-pxe2<N>1. Les sauvegardes restent dans PBS.

Validation finale

Dans le Shell de PBS, avec les variables PBS_* de l'étape 1 :

proxmox-backup-client namespace list   # les namespaces du datastore

Dans le Shell du nœud (interface web → votre nœud → Shell) :

grep -A 8 '^pbs: pbs-backup' /etc/pve/storage.cfg | grep namespace   # le namespace du stockage pbs-backup

Résultat attendu : les trois namespaces, puis namespace pxe211.


Atelier 4 — Sauvegardes avec PBS

Contexte

Le stockage est en place ; il faut s'en servir. Une sauvegarde lancée à la main prouve que la chaîne fonctionne.

C'est le job planifié qui protège réellement : personne ne pense à sauvegarder la veille de la panne. La rétention décide combien de versions on garde.

Résultat à obtenir : le CT 201 sauvegardé deux fois, pour voir l'effet incrémental. Toutes les machines de votre nœud sauvegardées, un job nocturne avec rétention, et le facteur de déduplication noté dans PBS.

La déduplication par blocs de PBS, en trois mesures

La première sauvegarde, la seconde, puis le datastore entier. Cliquez sur une étape pour lire les chiffres obtenus.

Arborescence attendue

PBS → Datastore demo-store-s<N> → Content → namespace pxe2<N>1
├── ct/201   ← 2 sauvegardes : la seconde n'envoie rien
├── vm/101, vm/102, vm/300 …   ← vzdump --all
Votre cluster → Datacenter → Backup
└── job 02:00 · pbs-backup · All · keep-last=7, keep-weekly=4

Ce que vous devez faire

  1. Sauvegarder le CT 201 vers pbs-backup, deux fois de suite, et comparer les journaux.
  2. Sauvegarder toutes les machines de votre nœud en une commande.
  3. Créer un job planifié chaque nuit à 2 h : 7 sauvegardes récentes, 4 hebdomadaires.
  4. Relever dans PBS le nombre de sauvegardes et le facteur de déduplication.
Cliquez pour vous aider

Étape 1 — Sauvegarde manuelle, deux fois

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Mode snapshot : le CT reste démarré. Pas de --compress : PBS compresse lui-même.
vzdump 201 --storage pbs-backup --mode snapshot

Ou : CT 201 → Backup → Backup now → Storage pbs-backup.

Résultat attendu (première sauvegarde, extrait) :

INFO: Starting backup: ct/201/2026-10-07T13:15:07Z
INFO: No previous manifest available.
INFO: root.pxar: had to backup 524.068 MiB of 524.068 MiB (compressed 178.918 MiB) in 3.91 s (average 133.99 MiB/s)
INFO: Finished Backup of VM 201 (00:00:05)

Relancez la même commande aussitôt.

Résultat attendu (seconde sauvegarde) :

INFO: Downloading previous manifest (Wed Oct  7 15:15:07 2026)
INFO: root.pxar: had to backup 0 B of 524.068 MiB (compressed 0 B) in 3.51 s (average 0 B/s)
INFO: root.pxar: backup was done incrementally, reused 524.068 MiB (100.0%)

0 octet envoyé. PBS découpe les données en blocs et ne transmet que les blocs qu'il n'a pas. Rien n'a changé dans le conteneur : rien ne voyage, et pourtant la seconde sauvegarde est complète et restaurable seule.

Étape 2 — Sauvegarder toutes les machines du nœud

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# --all : toutes les VM et tous les CT du nœud où la commande est lancée
vzdump --all --storage pbs-backup --mode snapshot
pvesh get /nodes/<nœud>/storage/pbs-backup/content --output-format json | grep -o '"volid":"[^"]*"'   # les sauvegardes présentes sur le stockage

Résultat attendu (extrait, pxe211) : skip external VMs: 102, 120 (les VM 102 et 120 sont sur un autre nœud). Suit une sauvegarde par machine : Finished Backup of VM 100 (00:00:08), VM 101 (00:00:06)… et un disque de 20 Gio sauvegardé en quelques secondes. Douze machines en 1 min 48 sur le lab.

Étape 3 — Configurer un job planifié

Datacenter → Backup → Add :

Onglet Champ Valeur
General Storage pbs-backup
General Schedule 02:00
General Selection mode All
General Mode Snapshot
Retention Keep Last 7
Retention Keep Weekly 4

Onglet Retention du job

Keep Last 7, Keep Weekly 4. Le bandeau jaune rappelle que, sans option ici, c'est la rétention du stockage qui s'applique. Or celle de pbs-backup vaut keep-all=1 : on garderait tout.

Le job dans la liste

Le job : tous les nœuds, 02:00, Next Run le lendemain à 2 h, stockage pbs-backup, rétention keep-last=7,ke…, sélection All. Le bouton Schedule Simulator, à droite, montre les prochaines exécutions d'une planification.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Le job, tel qu'enregistré pour tout le cluster
cat /etc/pve/jobs.cfg

Résultat attendu (extrait) :

vzdump: backup-9d5e8c9c-eff8
    schedule 02:00
    all 1
    mode snapshot
    prune-backups keep-last=7,keep-weekly=4
    storage pbs-backup

Créé en ligne de commande (pvesh create /cluster/backup --schedule 02:00 --all 1 --mode snapshot --storage pbs-backup --prune-backups keep-last=7,keep-weekly=4), le job porte un identifiant sans préfixe, vzdump: 9b4d9c25-840d-4c46-9e65-26cadae22f9e sur le lab, et une ligne enabled 1 en plus.

keep-last=7 garde les 7 dernières sauvegardes ; keep-weekly=4 en garde une par semaine sur 4 semaines. Les sauvegardes au-delà sont supprimées à chaque exécution du job.

Étape 4 — Explorer PBS après sauvegarde

Le facteur de déduplication se calcule au passage du ramasse-miettes (garbage collection). Il se planifie dans Datastore → demo-store → onglet Prune & GC Jobs. Pour le lancer tout de suite, dans le Shell de PBS :

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

proxmox-backup-manager garbage-collection start demo-store   # lancer le ramasse-miettes du datastore

Résumé du datastore après le ramasse-miettes

Usage : 2,14 GB sur 99,70 GB. Backup Count : 2 groupes CT et 4 sauvegardes, 6 groupes VM et 6 sauvegardes. Deduplication Factor : 64.86.

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

proxmox-backup-manager garbage-collection status demo-store --output-format json-pretty   # volume logique et volume réellement stocké ; à lire : index-data-bytes, disk-bytes

Résultat attendu (les lignes qui comptent) :

  "disk-bytes": 3210698747,
  "index-data-bytes": 200611205470,

200,6 Go de sauvegardes occupent 3,2 Go de disque : le ramasse-miettes annonçait Deduplication factor: 62.48. Les disques de VM sont en grande partie vides, et les systèmes Debian se ressemblent : leurs blocs ne sont stockés qu'une fois.

Contenu du datastore

Un groupe par machine (ct/201, vm/101…), la date de la dernière sauvegarde, et leur nombre : 3 pour le CT 201. Propriétaire root@pam, non chiffrées, pas encore vérifiées (Verify State None).

Validation finale

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pvesh get /nodes/<nœud>/storage/pbs-backup/content --output-format json | grep -c volid   # nombre de sauvegardes
grep prune-backups /etc/pve/jobs.cfg   # la rétention du job

Résultat attendu : une sauvegarde par machine de votre nœud, plus les deux du CT 201 (14 sur le nœud du lab, qui porte aussi des machines d'exemple), puis prune-backups keep-last=7,keep-weekly=4.


Atelier 5 — Restauration depuis PBS

Contexte

Une sauvegarde jamais restaurée n'est qu'une hypothèse. Cet atelier l'éprouve de deux façons : recréer une machine entière à côté de l'originale, puis récupérer un seul fichier. C'est le cas le plus fréquent : « j'ai supprimé un fichier de configuration hier ».

Résultat à obtenir : le CT 210, copie du CT 201, démarré à côté de l'original sans conflit d'adresse ; et le fichier /etc/hostname du CT 201 extrait de la sauvegarde.

Les deux restaurations de l'atelier : machine entière ou fichier seul

Une sauvegarde, deux usages. La restauration entière recopie aussi l'identité réseau : c'est le piège de l'étape 1. Cliquez sur une voie pour lire le résultat.

Arborescence attendue

Votre nœud
├── CT 201   ← l'original, intact, en .51
├── CT 210   ← restauré depuis PBS, nouvelle MAC, en .52
└── /tmp/hostname-restore   ← un seul fichier, extrait de la sauvegarde

Ce que vous devez faire

  1. Restaurer la sauvegarde du CT 201 sous l'identifiant 210, lui donner une autre adresse, puis le démarrer.
  2. Monter la sauvegarde en lecture seule sur le nœud, en extraire /etc/hostname, puis démonter.
Cliquez pour vous aider

La restauration se pilote depuis Proxmox VE, pas depuis PBS. Dans PBS, l'onglet Content d'un datastore sert à consulter. Le bouton Restore est côté Proxmox VE : votre nœud → stockage pbs-backup → onglet Backups.

Étape 1 — Restaurer une machine sous un nouvel identifiant

Une sauvegarde de conteneur (ct/) se restaure avec pct restore. Une sauvegarde de VM (vm/), avec qmrestore.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Les sauvegardes du CT 201 : l'identifiant complet est en première colonne
pvesm list pbs-backup | grep 'ct/201/'

pct restore 210 'pbs-backup:backup/ct/201/<date>' --storage local-lvm --unprivileged 1   # restaurer le CT 201 sous l'ID 210
pct config 210   # nom et réseau de la copie ; à lire : hostname, net0

Résultat attendu (les lignes qui comptent) :

restoring 'pbs-backup:backup/ct/201/2026-10-07T13:15:07Z' now..
restore complete (524.068 MiB processed in 2.1s, average 251.724 MiB/s)
hostname: ct-sdn-test
net0: name=eth0,bridge=vmbr0,gw=10.59.1.1,hwaddr=BC:24:11:8A:92:EF,ip=10.59.1.51/24,type=veth

Ne démarrez pas le CT 210 tel quel. La restauration reprend la même adresse IP et la même adresse MAC que le CT 201, qui tourne toujours. Deux machines, une seule identité réseau : conflit.

Changez sa carte avant de le démarrer. Sans hwaddr, Proxmox tire une nouvelle MAC :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pct set 210 --net0 name=eth0,bridge=vmbr0,ip=10.<site>.<N>.52/24,gw=10.<site>.<N>.1,firewall=1   # une autre adresse fixe pour la copie
pct start 210   # la démarrer
pct exec 210 -- ip -4 -br addr show eth0   # son adresse

Résultat attendu : net0: …,hwaddr=BC:24:11:11:40:D4,ip=10.59.1.52/24… (une MAC neuve), puis eth0@if66 UP 10.59.1.52/24. Le CT 201 garde .51 ; les deux répondent au ping.

Pour une machine virtuelle, l'ordre des arguments s'inverse, et --unique régénère la MAC :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

qmrestore 'pbs-backup:backup/vm/101/<date>' 151 --storage local-lvm --unique 1   # restaurer la VM 101 sous l'ID 151, nouvelle adresse MAC

Résultat attendu : progress 100% (read 21474836480 bytes, zeroes = 92% …, duration 4 sec), puis une adresse MAC neuve sur net0 (virtio=BC:24:11:C1:0B:A6, contre BC:24:11:0D:6D:68 pour l'original). Les zones vides du disque (92 %) ne sont pas réécrites : 20 Gio restaurés en 4,2 s. L'adresse IP, elle, vient de cloud-init : à changer aussi avant le démarrage.

Ou : votre nœud → pbs-backup → onglet Backups → la sauvegarde → Restore, en changeant l'ID et en cochant Unique.

Étape 2 — Restaurer un seul fichier

Pour un conteneur, la sauvegarde est une archive de fichiers, root.pxar. proxmox-backup-client, présent sur chaque nœud, la monte comme un répertoire.

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Le dépôt : utilisateur@serveur:datastore. Mot de passe et empreinte par variables.
export PBS_REPOSITORY='root@pam@10.<site>.<N>.14:demo-store'
export PBS_PASSWORD='proxmoxx'   # le mot de passe
export PBS_FINGERPRINT='<empreinte>'   # empreinte du certificat de PBS

# --ns : vos sauvegardes sont dans le namespace de votre nœud 1 (atelier 3)
proxmox-backup-client snapshot list --ns pxe2<N>1   # les sauvegardes du namespace

mkdir -p /mnt/pbs-restore   # le point de montage
proxmox-backup-client mount --ns pxe2<N>1 'ct/201/<date>' root.pxar /mnt/pbs-restore   # monter l'archive du conteneur
ls /mnt/pbs-restore/   # son contenu
cp /mnt/pbs-restore/etc/hostname /tmp/hostname-restore   # copier un fichier
cat /tmp/hostname-restore   # le fichier restauré

# Un umount ordinaire : le client n'a pas de sous-commande umount
umount /mnt/pbs-restore

Résultat attendu : la liste des sauvegardes (ct/200/…, ct/201/…), puis FUSE library version: 3.17.2, la racine du conteneur (bin boot dev etc home …), et ct-sdn-test. proxmox-backup-client umount répond bien Error: no such command 'umount'.

Sans --ns, la liste ne montre que la racine du datastore : vide chez vous, puisque tout est dans pxe2<N>1. Sur le lab : snapshot list seul affichait la sauvegarde de la racine, snapshot list --ns pxe221 celle du namespace, et mount --ns pxe221 a monté son root.pxar.

Pour une machine virtuelle, la sauvegarde est une image disque : on passe par proxmox-backup-client map (cours, chapitre 5).

Validation finale

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pct status 210   # le conteneur restauré
cat /tmp/hostname-restore   # le fichier restauré

Résultat attendu : status: running, puis ct-sdn-test.


Atelier 6 — Réplication inter-PBS

Contexte

Un seul PBS reste un point de défaillance unique : son disque tombe, toutes les sauvegardes partent avec lui. La réplication recopie les sauvegardes sur un second PBS, dans une autre salle ou un autre site. C'est le second serveur qui tire les sauvegardes du premier : le serveur principal n'a aucun droit d'écriture sur la copie, ce qui la protège s'il est compromis.

Résultat à obtenir : les sauvegardes de demo-store recopiées dans un datastore backup-store, par un job de synchronisation quotidien.

La réplication PBS : la copie tire les sauvegardes de la source

Qui tire quoi, et pourquoi la source n'a aucun droit sur la copie. Cliquez sur un élément pour lire le résultat obtenu.

Arborescence attendue

PBS source                          PBS de copie
└── demo-store  ──── tiré par ────► ├── remote « pbs1 »        ← connexion vers la source
                                    ├── sync-job depuis-pbs1   (quotidien)
                                    └── backup-store           ← la copie

Ce que vous devez faire

  1. Sur le PBS de copie, déclarer la source comme remote, avec son empreinte.
  2. Créer un job de synchronisation qui tire le datastore du voisin (demo-store-s<N>) vers backup-store, dans un namespace au nom du voisin (voisin-s<N>), sans supprimer les sauvegardes disparues.
  3. Lancer une première synchronisation et vérifier la copie.
Cliquez pour vous aider

Avec un seul PBS par stagiaire, chacun déclare en remote, sur son PBS, les PBS des stagiaires de la même ville de lab. Le réseau interne d'un autre lab n'est pas joignable : --host est l'adresse de l'hyperviseur du voisin et --port son port 82M4, qui mène à son PBS.

Les adresses sont dans l'annexe « Accès au lab ». Seul dans votre ville, déclarez votre propre PBS (son adresse .14, sans --port) et tirez vers un second datastore. C'est ce qui a été fait sur le lab, avec exactement les mêmes commandes.

L'empreinte est celle du PBS source (le voisin), lue dans son PBS : Dashboard → Show Fingerprint. Collez la vraie valeur : <empreinte-source> tel quel est refusé (value does not match the regex pattern). remote create ne teste pas la connexion : une adresse injoignable n'apparaît qu'au pull.

Le PBS d'un voisin, par l'interface

Entre deux labs isolés comme ceux des stagiaires. Le PBS du lab 1 (10.59.1.14) tire celui du lab 2 (10.59.2.14), joignable seulement par l'hôte 192.168.1.100, port 8224. L'accès direct à 10.59.2.14 échoue (curl : délai dépassé), l'accès par 192.168.1.100:8224 répond.

Chez le voisin : Dashboard → Show Fingerprint → Copy. Il vous envoie la valeur.

L'empreinte du PBS voisin, fenêtre Fingerprint

Le datastore du voisin contient la sauvegarde ct/400 (tâches en bas).

Sur votre PBS : Configuration → Remotes → Add.

La fenêtre Add: Remote remplie

Champ Valeur
Remote ID un nom au choix : pbs-voisin (ou pbs-s<N>)
Host l'hyperviseur et le port du voisin dans le même champ : 192.168.1.100:8224 sur le lab, 192.168.44.203:8234 pour le stagiaire 2 de Nantes
Auth ID / Password root@pam / proxmoxx
Fingerprint celle du voisin

Datastore → backup-store → onglet Sync Jobs → Add → Add Pull Sync Job. La liste Source Datastore est lue chez le voisin : si elle se remplit, la connexion passe.

Le job de synchronisation, Local Namespace voisin-s2

Champ Valeur
Local Namespace un namespace au nom du voisin (voisin-s2) : la copie de chaque voisin reste à part
Sync Schedule daily
Source Remote / Source Datastore pbs-voisin / le datastore du voisin
Remove Vanished décoché

Sélectionnez le job → Run now. L'équivalent en ligne de commande :

Dans le Shell de votre PBS (interface web de PBS → Administration → Shell) :

# --ns : le namespace local qui reçoit la copie (créé s'il n'existe pas)
proxmox-backup-manager pull pbs-voisin demo-store backup-store --ns voisin-s2

Résultat attendu :

Syncing datastore 'demo-store', root namespace into datastore 'backup-store', namespace 'voisin-s2'
Created namespace voisin-s2
Found 1 groups to sync (out of 1 total)
[ct/400]: 2026-10-09T14:07:52Z: sync done
pull datastore 'backup-store' end
TASK OK

La copie du voisin dans le namespace voisin-s2

Dans Content, la copie est rangée sous Namespace 'voisin-s2', à part de vos propres sauvegardes.

Étape 1 — Préparer la copie et déclarer la source

Sur le PBS de copie, un datastore de destination. Sur le lab, le datastore va sur le disque système, faute de second disque :

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

proxmox-backup-manager datastore create backup-store /var/lib/backup-store   # le datastore qui recevra la copie

Résultat attendu : Access time update check successful. puis TASK OK.

Configuration → Remotes → Add : ID pbs1, Host (l'adresse de la source), Auth ID root@pam, Password, Fingerprint (celle de la source).

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

# Sur la source : son empreinte
proxmox-backup-manager cert info | grep -i fingerprint
# Sur la copie : déclarer la source
# Voisin : --host <hyperviseur du voisin> --port <son port 82M4> ; seul : --host <votre adresse .14>
proxmox-backup-manager remote create pbs1 --host <adresse-source> --port <port-source> --auth-id root@pam \
  --password '<mot-de-passe>' --fingerprint '<empreinte-source>'
proxmox-backup-manager remote list   # le serveur distant enregistré

Résultat attendu (le PBS du lab déclaré comme sa propre source) : une ligne pbs1 │ 10.59.1.14 │ root@pam │ cd:d6:5b:92:….

L'empreinte protège de l'homme du milieu : la copie vérifie le certificat de la source avant tout échange. En production, on utilise un jeton limité au rôle DatastoreReader plutôt que root@pam.

Étape 2 — Le job de synchronisation

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

# --store : le datastore local (la copie) ; --remote-store : celui de la source
# --remove-vanished false : une sauvegarde supprimée à la source reste dans la copie
proxmox-backup-manager sync-job create depuis-pbs1 --store backup-store --remote pbs1 \
  --remote-store demo-store --remove-vanished false --schedule daily
proxmox-backup-manager sync-job list   # le sync-job enregistré

# Première synchronisation, sans attendre la planification
proxmox-backup-manager pull pbs1 demo-store backup-store

Dans l'interface : Datastore → backup-store → Sync Jobs → Run now.

Résultat attendu (fin de la tâche, 30 secondes) :

[vm/300]: 2026-10-07T13:17:03Z: sync done
[vm/300]: percentage done: 100.00% (12/12 groups)
Finished syncing root namespace, current progress: 12 groups, 0 snapshots
pull datastore 'backup-store' end
TASK OK

12 groupes recopiés : ls /var/lib/backup-store/vm listait 100 101 103 105 106 107 110 290 300, et ls /var/lib/backup-store/ct listait 200 201 250. Le nombre de groupes dépend des machines sauvegardées aux ateliers 3 et 4. Le job copie aussi les namespaces de la source (pxe2<N>1…), sous le namespace local choisi.

--remove-vanished false pour débuter : une suppression accidentelle à la source laisse la sauvegarde intacte dans la copie. Passez à true seulement une fois votre rétention maîtrisée.

Validation finale

Dans le Shell de PBS (interface web de PBS → Administration → Shell) :

proxmox-backup-manager remote list   # le serveur distant
proxmox-backup-manager sync-job list   # le sync-job

Résultat attendu : le remote pbs1, puis le job depuis-pbs1 : backup-store, pbs1, demo-store, daily.


Atelier 7 — Fil rouge : mettre un service en production, puis livrer l'infrastructure

Contexte

Cinq chapitres ont construit, pièce par pièce, une infrastructure complète. On y trouve un nœud installé et mis à jour, des comptes nominatifs, un conteneur de service, des VM tirées d'un template, du stockage ZFS. S'y ajoutent un cluster de trois nœuds avec Ceph et la haute disponibilité, un pare-feu, des sauvegardes sur PBS et leur copie chez un voisin.

Ce dernier atelier s'en sert deux fois.

Partie A : une demande arrive, un serveur web à mettre en production. Vous la traitez de bout en bout, avec un outil de chaque chapitre. Il faut un compte pour l'équipe qui l'exploitera et une VM tirée du template, posée sur Ceph, sous HA, filtrée par le pare-feu, sauvegardée, et dont la restauration est prouvée.

Partie B : vous passez l'ensemble en revue comme si vous le livriez à un client. Chaque brique est vérifiée par une commande, chaque machine documentée, et les points faibles sont nommés avant la remise.

Résultat à obtenir : la VM 400 web-prod qui sert sa page en 10.<site>.<N>.90, sur ceph-vm, sous HA, filtrée (Web et SSH seulement), sauvegardée et restaurée à l'essai. Un groupe exploitation n'a de droits que sur elle.

Puis les dix points de la checklist sont vérifiés, avec une description sur chaque machine qui reste, les tâches en échec comprises. Une réponse écrite est donnée à la question de l'étape 11.

Atelier 7 : fil rouge, un service en production

Le schéma suit la VM 400, de sa création jusqu'à la livraison. Cliquez sur chaque bloc pour son détail.

Arborescence attendue

Infrastructure livrée
├── Nœuds pxe2<N>1 à pxe2<N>3   ← cluster-tp, quorate ; dépôt no-subscription, à jour
├── Ceph                         ← HEALTH_OK ; pool ceph-vm en 3/2, sous 80 %
├── Machines                     ← CT 200 cache-apt, VM 101 et 102, VM 300 sous HA ; chacune décrite
│   └── VM 400 web-prod          ← 10.<site>.<N>.90, nginx + agent QEMU, disque sur ceph-vm, sous HA (étapes 2 à 5)
├── Comptes                      ← groupe exploitation (exploitant@pve) : PVEVMUser sur /vms/400 seulement (étapes 1 et 2)
├── Pare-feu                     ← Datacenter réactivé ; VM 400 : Web et SSH acceptés, le reste jeté (étape 6)
└── PBS                          ← job planifié, sauvegarde de la VM 400, restauration prouvée sur une copie 401 supprimée (étape 7)

Ce que vous devez faire

Partie A — mettre un service en production

  1. Préparer l'accès de l'équipe d'exploitation : un groupe exploitation, un compte exploitant@pve qui en est membre ; le droit PVEVMUser sera donné au groupe, sur la seule VM 400.
  2. Créer la VM 400 web-prod : clone complet du template 100, disque sur ceph-vm, adresse fixe 10.<site>.<N>.90 par cloud-init ; la faire porter par le nœud 3 avant de la démarrer.
  3. Installer le service dans la VM : nginx et l'agent QEMU ; vérifier depuis le nœud que la page répond et que l'agent est joignable.
  4. Placer la VM sous haute disponibilité, avec les mêmes limites que la VM 300.
  5. La déplacer à chaud vers le nœud 2 par la HA, pendant qu'une boucle interroge la page chaque seconde : le service ne doit pas s'interrompre.
  6. La filtrer : pare-feu de la VM avec une politique d'entrée DROP, le Web et SSH acceptés, la case Firewall sur sa carte. Puis réactiver le pare-feu du Datacenter, avec un filet automatique comme à l'atelier 1. Constater ce qui passe et ce qui ne passe plus.
  7. La sauvegarder sur PBS et prouver la restauration : restaurer la sauvegarde sous le numéro 401, carte débranchée, vérifier que le service y tourne, puis supprimer la copie.

Partie B — livrer l'infrastructure

  1. Relever l'état général du cluster : versions, quorum, Ceph, stockages, HA.
  2. Chercher les tâches en échec parmi les trente dernières du nœud 1, et ouvrir le journal de chacune.
  3. Documenter chaque machine qui reste, puis dérouler la checklist, point par point, avec la commande ou l'écran qui le prouve.
  4. Répondre par écrit à la question finale : si le cluster disparaissait cette nuit, que faudrait-il pour remonter le service demain matin ?

💡 Une vérification qui échoue n'est pas un échec de l'atelier : c'est exactement ce qu'une revue de livraison sert à trouver. Notez-la, corrigez-la, puis recommencez la vérification.

Cliquez pour vous aider

Les sorties viennent du lab d'exemple (10.59.1.x : site 59, stagiaire 1 ; nœuds pxe211 à pxe213). Chez vous, l'adresse de la VM 400 est 10.<site>.<N>.90 et les nœuds pxe2<N>1 à pxe2<N>3.

Partie A — Mettre un service en production

Étape 1 — Le groupe et le compte de l'équipe d'exploitation

On prépare l'accès avant de créer la machine : le jour de la livraison, l'équipe d'exploitation se connecte avec son propre compte, jamais avec root. Comme au chapitre 1, le droit va au groupe : un nouvel arrivant n'aura qu'à y être ajouté.

Par l'interface : Datacenter → Permissions → Groups → Create : exploitation. Puis Users → Add : exploitant, realm Proxmox VE authentication server, groupe exploitation, mot de passe proxmoxx.

Dans le Shell du nœud 1 :

pveum group add exploitation --comment "Exploitation des services livrés"   # le groupe
pveum user add exploitant@pve --password 'proxmoxx' --groups exploitation \
  --comment "Exploitation du serveur web"                                    # le compte, membre du groupe
pveum group list | grep exploitation                                         # vérifier

Résultat attendu : aucune sortie pour les deux créations, puis une ligne exploitation … exploitant@pve. Le droit sera posé à l'étape 2, une fois la VM 400 créée.

Étape 2 — Créer la VM 400 sur Ceph, et la confier au nœud 3

Le template 100 est sur le local-lvm du nœud 1. Un clone complet peut écrire son disque ailleurs : sur ceph-vm, la VM devient migrable à chaud et peut être relancée par la HA sur n'importe quel nœud.

Par l'interface : clic droit sur le template 100 → Clone : VM ID 400, Name web-prod, Mode Full Clone, Target Storage ceph-vm → Clone. Puis VM 400 → Cloud-Init → IP Config (net0) : 10.<site>.<N>.90/24, passerelle 10.<site>.<N>.1. Puis Migrate vers pxe2<N>3, et Start.

Le droit : VM 400 → Permissions → Add → Group Permission : groupe exploitation, rôle PVEVMUser.

Dans le Shell du nœud 1 :

qm clone 100 400 --name web-prod --full --storage ceph-vm        # clone complet, disque sur Ceph
qm set 400 --ipconfig0 ip=10.<site>.<N>.90/24,gw=10.<site>.<N>.1 \
  --description "Serveur web nginx du fil rouge - chapitre 5"     # adresse fixe et description
qm migrate 400 pxe2<N>3                                          # VM éteinte : migration à froid
pveum acl modify /vms/400 --groups exploitation --roles PVEVMUser   # le droit du groupe de l'étape 1

Puis dans le Shell du nœud 3 (la VM y est désormais) :

qm start 400    # premier démarrage : cloud-init applique l'adresse
qm status 400   # la VM tourne-t-elle ?

Résultat attendu : le clone recopie les 20 Gio du disque (transferred 20.0 GiB of 20.0 GiB (100.00%)), puis update VM 400: -description … -ipconfig0 ip=10.59.1.90/24,gw=10.59.1.1, puis :

use dedicated network address for sending migration traffic (10.59.41.13)
starting migration of VM 400 to node 'pxe213' (10.59.41.13)
migration finished successfully (duration 00:00:01)

Une seconde de migration pour une VM de 20 Gio : rien n'a été copié. Le disque est sur Ceph, que les trois nœuds voient ; seule la configuration a changé de dossier dans /etc/pve. Au démarrage, generating cloud-init ISO, puis status: running.

Vérifier le droit du groupe. Dans le Shell du nœud 1 :

pveum user permissions exploitant@pve --path /vms/400   # ce que le compte peut faire sur la VM 400
pveum user permissions exploitant@pve --path /vms/101   # et sur une autre VM

Résultat attendu : sur /vms/400, dix privilèges, de VM.Audit à VM.PowerMgmt (console, démarrage et arrêt, sauvegarde, lecture par l'agent) ; sur /vms/101, une ligne vide : aucun droit. Le compte voit et pilote son serveur, et rien d'autre.

Étape 3 — Installer le service et l'agent

L'image cloud Debian n'a ni serveur web ni agent QEMU (chapitre 2, atelier 8). On les installe par SSH : la clé du nœud 1 a été déposée dans le template par cloud-init.

Dans le Shell du nœud 1 :

ssh devops@10.<site>.<N>.90    # accepter l'empreinte (yes) au premier essai

Dans la VM 400 :

cloud-init status --wait                                   # attendre la fin du premier démarrage (sinon apt est verrouillé)
sudo apt-get update                                        # la liste des paquets
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y nginx qemu-guest-agent   # le service et l'agent
sudo systemctl start qemu-guest-agent                      # l'agent ne démarre pas seul à l'installation
systemctl is-active nginx qemu-guest-agent                 # deux services actifs ?
exit                                                       # revenir sur le nœud

Résultat attendu : status: done, Setting up nginx (1.26.3-3+deb13u9) ..., puis active et active.

De retour dans le Shell du nœud 1, la page, puis l'agent (sur le nœud 3, qui porte la VM) :

curl -s -o /dev/null -w "%{http_code}\n" http://10.<site>.<N>.90/   # le code de réponse HTTP
curl -s http://10.<site>.<N>.90/ | grep -o "<title>.*</title>"      # le titre de la page servie
ssh 10.<site>.<N>.13 qm agent 400 ping                             # l'agent répond-il ?
echo "code : $?"                                                     # 0 : oui

Résultat attendu : 200, <title>Welcome to nginx!</title>, puis code : 0. Dans l'interface, l'onglet Summary de la VM 400 affiche maintenant son adresse sur la ligne IPs.

Étape 4 — Sous haute disponibilité

Par l'interface : Datacenter → HA → Resources → Add : VM 400, Max. Restart 3, Max. Relocate 1, Request State started.

Dans le Shell du nœud 1 :

ha-manager add vm:400 --state started --max_restart 3 --max_relocate 1   # comme la VM 300 au chapitre 4
ha-manager status   # les LRM et les ressources ; à lire : lrm, service

Résultat attendu, une quinzaine de secondes après :

lrm pxe211 (active, watchdog active, …)
lrm pxe212 (idle, watchdog standby, …)
lrm pxe213 (active, watchdog active, …)
service vm:300 (pxe211, started)
service vm:400 (pxe213, starting)

Le LRM de pxe213 est active : il porte une ressource HA, son chien de garde est armé. Quelques secondes plus tard, service vm:400 (pxe213, started).

Étape 5 — Un déplacement à chaud, sans coupure du service

Une VM sous HA se déplace par la HA, pas par qm migrate : c'est le gestionnaire qui décide, et il garde la trace de l'opération. Pour prouver que la VM ne s'arrête pas, un ping tourne en arrière-plan pendant le déplacement : une réponse par seconde, quarante en tout.

Dans le Shell du nœud 1 :

ping -c 40 -i 1 10.<site>.<N>.90 > /tmp/ping400.txt &   # 40 pings, un par seconde, en arrière-plan
ha-manager crm-command migrate vm:400 pxe2<N>2          # demander à la HA de la déplacer vers le nœud 2

Dans le Shell du nœud 1, quarante-cinq secondes plus tard, une fois les pings terminés :

tail -2 /tmp/ping400.txt                          # le bilan du ping
ha-manager status | grep vm:400                   # où est la VM maintenant ?

Résultat attendu : 40 packets transmitted, 40 received, 0% packet loss, puis service vm:400 (pxe212, started). Le journal de la migration, côté nœud 3 (Datacenter → Tasks, ligne VM 400 - Migrate) :

starting migration of VM 400 to node 'pxe212' (10.59.41.12)
migration downtime limit: 100 ms
average migration speed: 2.0 GiB/s - downtime 12 ms
migration finished successfully (duration 00:00:06)

Douze millisecondes d'arrêt : moins que l'intervalle entre deux pings. C'est ce que permettent le disque sur Ceph et le réseau de migration dédié (10.59.41.x) posé au chapitre 4.

Étape 6 — Filtrer la VM, puis réactiver le pare-feu du Datacenter

À l'atelier 1, le pare-feu du Datacenter a protégé les nœuds. Ici, c'est la VM qu'on filtre : la règle se pose dans le pare-feu de l'invité. Trois interrupteurs doivent être levés (cours §2.2) : le pare-feu du Datacenter, celui de la VM, et la case Firewall de sa carte.

Par l'interface : VM 400 → Firewall → Add : Direction in, Action ACCEPT, Macro Web, Enable coché ; idem avec la macro SSH. Puis Firewall → Options : Firewall Yes, Input Policy DROP. Puis Hardware → Network Device (net0) → cocher Firewall.

Dans le Shell du nœud 1 (l'API est la même depuis n'importe quel nœud ; le chemin nomme le nœud qui porte la VM) :

# Les règles d'abord, puis la politique : on n'écrit jamais un DROP avant ses exceptions
pvesh create /nodes/pxe2<N>2/qemu/400/firewall/rules --type in --action ACCEPT --macro Web --enable 1   # accepter le Web (80, 443)
pvesh create /nodes/pxe2<N>2/qemu/400/firewall/rules --type in --action ACCEPT --macro SSH --enable 1   # accepter SSH (22)
pvesh set /nodes/pxe2<N>2/qemu/400/firewall/options --enable 1 --policy_in DROP   # pare-feu de la VM actif, le reste jeté
cat /etc/pve/firewall/400.fw                    # le fichier écrit par ces trois commandes
ping -c 2 -W 1 -q 10.<site>.<N>.90             # le ping passe-t-il ? -q : le bilan seul

Résultat attendu :

[OPTIONS]

policy_in: DROP
enable: 1

[RULES]

IN SSH(ACCEPT)
IN Web(ACCEPT)

2 packets transmitted, 2 received, 0% packet loss, time 1041ms

La règle SSH, créée en second, est arrivée en tête (cours §2.3). Et le ping passe : rien n'est encore filtré, deux interrupteurs sur trois manquent.

La case Firewall de la carte, en gardant son adresse MAC (même méthode qu'au chapitre 2, atelier 9). Dans le Shell du nœud 2, qui porte la VM :

qm config 400 | grep ^net0                   # la carte actuelle, adresse MAC comprise
qm set 400 --net0 virtio=BC:24:11:D1:C6:7E,bridge=vmbr0,firewall=1   # la même carte, case cochée : l'adresse MAC recopiée de la ligne précédente
qm config 400 | grep ^net0                   # vérifier

Résultat attendu : update VM 400: -net0 virtio=BC:24:11:D1:C6:7E,bridge=vmbr0,firewall=1, puis la même ligne dans la configuration, appliquée à chaud (qm pending 400 montre cur net0: …,firewall=1, sans valeur en attente). Le ping passe toujours : le pare-feu du Datacenter est désactivé depuis la fin de l'atelier 1, et sans lui, aucune règle d'invité ne s'applique.

Le pare-feu du Datacenter, avec le filet de l'atelier 1. Ses règles (22, 8006, Ceph) sont toujours en place. Dans le Shell du nœud 1 :

grep -E "^IN" /etc/pve/firewall/cluster.fw   # les règles de l'atelier 1 sont-elles toujours là ?
systemd-run --on-active=5min --unit=filet-parefeu pvesh set /cluster/firewall/options --enable 0   # le filet
pvesh set /cluster/firewall/options --enable 1   # activer
pve-firewall status                              # l'état du pare-feu

Résultat attendu : les quatre règles IN Ceph(ACCEPT) -source 10.59.21.0/24, IN Ceph(ACCEPT) -source 10.59.31.0/24, IN ACCEPT -p tcp -dport 8006, IN ACCEPT -p tcp -dport 22, puis Running timer as unit: filet-parefeu.timer et Status: enabled/running.

Constater, puis annuler le filet. Dans le Shell du nœud 1 :

ping -c 2 -W 1 -q 10.<site>.<N>.90                                         # le ping, son bilan
curl -s -m 3 -o /dev/null -w "http %{http_code}\n" http://10.<site>.<N>.90/  # le Web
ssh -o ConnectTimeout=5 devops@10.<site>.<N>.90 hostname                     # SSH
curl -s -m 5 http://10.<site>.<N>.90:3142                                  # un port sans règle
echo "code $?"                                                               # 28 : délai dépassé
curl -sk -m 3 -o /dev/null -w "gui %{http_code}\n" https://10.<site>.<N>.11:8006   # l'interface du nœud
ceph health                                                                  # Ceph a-t-il souffert ?
systemctl stop filet-parefeu.timer                                           # tout va bien : annuler le filet

Résultat attendu :

2 packets transmitted, 0 received, 100% packet loss, time 1023ms
http 200
web-prod
code 28
gui 200
HEALTH_OK

Le ping et le port 3142 ne reçoivent aucune réponse (code 28 : délai dépassé pour curl) : c'est la signature d'un DROP, qui jette sans répondre. Le Web et SSH passent, l'interface du nœud reste joignable et Ceph est en bonne santé : les règles posées à l'atelier 1 font leur travail. Cette fois, le pare-feu reste actif : c'est l'état d'une infrastructure livrée.

Étape 7 — Sauvegarder, puis prouver la restauration

Le job nocturne de l'atelier 4 sauvegarde toutes les machines (all 1 dans /etc/pve/jobs.cfg) : la VM 400 y entre d'elle-même. Mais une sauvegarde dont on n'a jamais testé la restauration n'est qu'une hypothèse. On en fait une tout de suite, et on la restaure sur une copie.

Dans le Shell du nœud 2, qui porte la VM :

vzdump 400 --storage pbs-backup --mode snapshot   # sauvegarde à chaud, vers PBS
pvesm list pbs-backup --vmid 400                  # la sauvegarde, et son nom exact

Résultat attendu :

INFO: creating Proxmox Backup Server archive 'vm/400/2026-10-16T13:12:34Z'
INFO: backup is sparse: 18.45 GiB (92%) total zero data
INFO: transferred 20.00 GiB in 6 seconds (3.3 GiB/s)
INFO: Finished Backup of VM 400 (00:00:07)
INFO: Backup job finished successfully
Volid                                         Format  Type             Size VMID
pbs-backup:backup/vm/400/2026-10-16T13:12:34Z pbs-vm  backup    21474839418 400

92 % du disque est vide : PBS ne stocke que les morceaux qui contiennent des données (cours §3.2).

La restauration, sous le numéro 401, avec une nouvelle adresse MAC (--unique 1) et la carte débranchée avant le démarrage. La copie porte en effet la même adresse IP que la VM 400, qui tourne. Remplacez <date> par celle de votre sauvegarde.

Dans le Shell du nœud 2 :

qmrestore pbs-backup:backup/vm/400/<date> 401 --storage ceph-vm --unique 1   # restaurer sous l'ID 401
qm config 401 | grep ^net0                                                   # la carte de la copie, sa nouvelle adresse MAC
qm set 401 --name web-prod-test --net0 virtio=BC:24:11:99:06:56,bridge=vmbr0,link_down=1   # renommer, débrancher : l'adresse MAC recopiée
qm start 401                                                                 # démarrer la copie

Dans le Shell du nœud 2, une minute et demie plus tard, le temps que la copie démarre :

qm agent 401 ping                                                            # l'agent répond-il ?
echo "code : $?"                                                             # 0 : oui
qm guest exec 401 -- systemctl is-active nginx                               # le service tourne-t-il dans la copie ?

Résultat attendu : restore image complete (bytes=21474836480, duration=4.48s, speed=4574.32MB/s), une carte virtio=BC:24:11:99:06:56,… (la VM 400 a BC:24:11:D1:C6:7E), update VM 401: -name web-prod-test -net0 …,link_down=1, l'agent qui répond au bout d'environ une minute et quinze secondes, puis :

{
   "exitcode" : 0,
   "exited" : 1,
   "out-data" : "active\n",
   "out-truncated" : 0
}

La copie démarre, et nginx y tourne : la sauvegarde est utilisable, pas seulement présente. La restauration a aussi recréé le pare-feu de la VM (/etc/pve/firewall/401.fw) : les règles voyagent avec la sauvegarde.

Supprimer la copie. Dans le Shell du nœud 2 :

qm stop 401                # arrêter la copie
qm destroy 401 --purge     # la supprimer, avec ses références
qm list | grep -c " 401 "  # reste-t-il une VM 401 ?

Résultat attendu : Removing image: 100% complete...done., purging VM 401 from related configurations.., puis 0.

Partie B — Livrer l'infrastructure

Étape 8 — L'état général

Dans le Shell du nœud 1 (interface web → pxe2<N>1 → Shell) :

pveversion            # la version de Proxmox VE du nœud
pvecm status          # le cluster : nombre de nœuds, quorum
ceph status           # la santé de Ceph
pvesm status          # tous les stockages déclarés et leur remplissage
ha-manager status     # les ressources sous haute disponibilité

Résultat attendu : la même version sur les trois nœuds (relancez pveversion sur pxe2<N>2 et pxe2<N>3 ; sur le lab, pve-manager/9.2.21/4f6e0ac86f9e8c7f). On attend aussi Quorate: Yes avec Nodes: 3, HEALTH_OK, tous les stockages active et sous 80 %, et deux ressources HA : service vm:300 (…, started) et service vm:400 (…, started).

Étape 9 — Les tâches en échec

Dans le Shell du nœud 1 :

# Les tâches du nœud qui ne se sont pas terminées par OK (erreurs et avertissements)
pvesh get /nodes/$(hostname)/tasks --limit 30 --errors 1

Résultat attendu : seize lignes, triées par numéro de machine. La dernière colonne, Status, dit pourquoi chacune n'est pas OK :

Status (extrait) Ce que c'est
WARNINGS: 1 (vzcreate, vzstart des CT 200 et 201) Un avertissement à la création ou au démarrage d'un conteneur ; la tâche a abouti
job errors (vzdump de la VM 101) Une sauvegarde manuelle qui a échoué
broken pipe, puis VM is locked (VM 196) Une restauration d'essai interrompue, puis une suppression refusée tant que la VM était verrouillée
command 'apt-get update' failed (aptupdate) La mise à jour de la liste des paquets du premier jour, avant le changement de dépôts du chapitre 1

La liste n'est donc pas vide sur un nœud qui a servi : --errors 1 garde tout ce qui n'est pas OK, avertissements compris. Chaque ligne s'ouvre dans Datacenter → Tasks (double clic) : son journal dit ce qui s'est passé. Le travail de livraison consiste à les comprendre une par une, et à vérifier qu'aucune ne touche un service livré.

Étape 10 — Documenter chaque machine, puis dérouler la checklist

Par l'interface : la machine → Summary → bloc Notes → icône du crayon → saisir → OK.

Dans le Shell du nœud qui porte la machine :

# Une description par machine : ce qu'elle fait, d'où elle vient, depuis quand
pct set 200 --description "Cache de paquets apt-cacher-ng, port 3142 - chapitre 1"   # le conteneur du chapitre 1
qm set 101 --description "Serveur web, clone du template 100 (cloud-init) - chapitre 2"   # un clone du chapitre 2
qm set 300 --description "VM de test sur Ceph, ressource HA - chapitre 4"   # la VM sous HA

# Vérifier
pct config 200 | grep description   # la description du conteneur
qm config 101 | grep description    # celle de la VM

Résultat attendu : pct set ne répond rien ; chaque qm set répond par une ligne update VM … -description …. Puis description: Cache de paquets apt-cacher-ng, port 3142 - chapitre 1%0A (le %0A final est le saut de ligne, encodé dans la configuration du conteneur) et description: Serveur web, clone du template 100 (cloud-init) - chapitre 2. La VM 400 a reçu la sienne à l'étape 2.

Une commande qm set sur une VM portée par un autre nœud répond qu'elle n'existe pas : Configuration file 'nodes/pxe211/qemu-server/400.conf' does not exist. Cela a été sur le lab, depuis le nœud 1, pour la VM 400 alors sur le nœud 2. Lancez-la sur le bon nœud, ou passez par l'interface, qui voit tout le cluster.

La checklist :

# Point Votre vérification OK ?
1 Dépôt no-subscription, système à jour, sur les trois nœuds apt update sans erreur 401 ; apt list --upgradable vide
2 Aucun compte partagé ; droits donnés à des groupes pveum user list, pveum acl list : le groupe exploitation sur /vms/400
3 Double authentification sur les comptes d'administration Datacenter → Permissions → Two Factor
4 Cluster en quorum, trois nœuds pvecm status
5 Ceph HEALTH_OK, pool sous 80 % ceph status, ceph df
6 Les VM critiques sous HA ha-manager status : vm:300 et vm:400
7 Pare-feu actif : Datacenter et VM 400 pve-firewall status, cat /etc/pve/firewall/400.fw
8 Sauvegardes planifiées vers PBS, avec rétention Datacenter → Backup
9 Une restauration a été testée étape 7 : la copie 401 a démarré, nginx active
10 Une copie des sauvegardes hors du site atelier 6 : le job de synchronisation

Le point 3 est souvent celui qui manque : au chapitre 1, le second facteur a été testé sur un compte d'essai, puis retiré. Sur une infrastructure livrée, chaque compte d'administration en porte un. Nommez l'écart dans votre réponse finale.

Étape 11 — La question qui conclut la formation

Si votre cluster disparaissait cette nuit, sauriez-vous remonter le service demain matin ? Les éléments dont vous auriez besoin :

Élément Où il est
Les sauvegardes Sur PBS, machine séparée, et leur copie chez le voisin (atelier 6)
La procédure de restauration Atelier 5, et l'étape 7 de cet atelier
La configuration du cluster À reconstruire : installation, cluster, Ceph (chapitres 1 et 4), puis restauration des machines
Les règles du pare-feu des VM Dans leurs sauvegardes : la restauration les recrée (étape 7)
Les mots de passe et l'empreinte du certificat de PBS Hors de l'infrastructure, dans un gestionnaire de mots de passe

C'est le dernier point qui manque le plus souvent en entreprise : la sauvegarde est parfaite, mais les identifiants pour y accéder étaient sur le serveur disparu.

Validation finale

Contrôle Attendu
Étapes 1 et 2 pveum acl list : /vms/400 │ PVEVMUser │ group │ exploitation ; aucun droit ailleurs pour exploitant@pve
Étapes 2 et 3 curl http://10.<site>.<N>.90/ → 200 ; qm agent 400 ping sans erreur
Étapes 4 et 5 ha-manager status : service vm:400 (pxe2<N>2, started) ; la boucle : quarante 200
Étape 6 pve-firewall status → enabled/running ; ping vers la VM 400 jeté, Web et SSH acceptés ; HEALTH_OK
Étape 7 Une sauvegarde vm/400 dans pbs-backup ; plus de VM 401
Étape 8 Quorate: Yes, HEALTH_OK, stockages active, vm:300 et vm:400 started
Étape 9 Chaque tâche de la liste comprise
Étape 10 Une description dans Notes pour le CT 200, les VM 101, 300 et 400 ; dix lignes cochées, ou les écarts nommés
Étape 11 Une réponse écrite, qui dit où sont rangés les mots de passe

Dépannage — Erreurs fréquentes

Ceph en HEALTH_WARN, PG peering bloqués, écritures figées après l'activation du pare-feu. Le trafic Ceph n'est pas couvert par le réseau local autorisé d'office. Remède : Règles ACCEPT avec la macro Ceph depuis les deux réseaux Ceph (atelier 1, étape 1).

Connexion TCP refusée qui devient un silence (code 124). Pare-feu actif : les refus (RST) sont jetés comme INVALID. Remède : Tester avec un service réellement à l'écoute.

Create grisé en créant un datastore PBS. Champ Filesystem vide. Remède : Choisir ext4 ou xfs.

Cannot find datastore … check permissions avec un jeton PBS. Un jeton PBS n'a aucun droit par défaut. Remède : proxmox-backup-manager acl update /datastore/<store> DatastoreAdmin --auth-id '<jeton>'.

backup owner check failed (<compte> != root@pam). Le groupe de sauvegardes appartient déjà à un autre compte. Remède : Créer le compte et son stockage avant la première sauvegarde de la source.

Namespace vide pour un compte restreint. DatastoreBackup ne montre que les sauvegardes du compte. Remède : Faire écrire la source avec ce compte (atelier 3).

CT restauré en conflit d'adresse avec l'original. La restauration reprend l'IP et la MAC. Remède : Changer net0 avant de démarrer ; --unique pour une VM.

Règle IP Set inefficace après un moment. La VM a changé d'adresse. Remède : Mettre à jour l'IP Set, et fixer l'adresse de la VM.

Règles pare-feu d'un conteneur sans effet. Carte créée en CLI sans firewall=1. Remède : pct set <id> --net0 …,firewall=1, ou cocher Firewall sur la carte.

HEALTH_WARN : 1/3 mons down, sans lien avec le pare-feu. Le moniteur de ce nœud est désactivé et n'a pas démarré (systemctl is-enabled ceph-mon@<nœud> → disabled ; journalctl -b -u ceph-mon@<nœud> → -- No entries --), sur le lab. Remède : Sur ce nœud : systemctl enable --now ceph-mon@<nœud> ; HEALTH_OK une vingtaine de secondes plus tard.

Récapitulatif des commandes essentielles

Situation Commande
Règle pare-feu Datacenter / VM pvesh create /cluster/firewall/rules --enable 1 … / pvesh create /nodes/<nœud>/qemu/<vmid>/firewall/rules --enable 1 …
Réseau autorisé d'office par le pare-feu pve-firewall localnet
Créer un datastore PBS (Shell de PBS) interface : Storage / Disks → Directory → Create ; ou proxmox-backup-manager datastore create <nom> <chemin>
Ajouter PBS comme stockage pvesm add pbs <id> --server … --datastore … --fingerprint …
Sauvegarder / restaurer (VM / CT) vzdump <id> --storage pbs-backup / qmrestore ou pct restore
Monter un backup en lecture seule proxmox-backup-client mount <sauvegarde> root.pxar <point-de-montage>
Créer / lister les namespaces PBS proxmox-backup-client namespace create <nom> / namespace list (depuis un nœud)
Créer une remote / un sync job PBS proxmox-backup-manager remote create / sync-job create
Créer un jeton API Proxmox VE pveum user token add <user>@pve <nom> --privsep 0
Empreinte du certificat d'un nœud openssl x509 -in /etc/pve/local/pve-ssl.pem -noout -fingerprint -sha256