Ateliers — chapitre 4
Infrastructure : 3 nœuds —
pxe2<N>1(le vôtre, depuis le chapitre 1),pxe2<N>2etpxe2<N>3, joignables par leurs URL,https://pxe2<N>1.<ville>.pm.dawan.ovhet suivantes, données par le formateur. Sur chacun : disque/dev/sdb(70 Go) réservé à Ceph, et cinq cartes réseau.Réseaux internes (stagiaire N ; site 44 Nantes, 75 Paris, 67 Strasbourg) :
ens19→ cluster Corosync10.<site>.<N+10>.x;ens20→ Ceph cluster10.<site>.<N+20>.x;ens21→ Ceph public10.<site>.<N+30>.x;ens22→ migration10.<site>.<N+40>.x. Nœud 1 en.11, nœud 2 en.12, nœud 3 en.13. Ces réseaux ne sortent pas : ni passerelle, ni NAT.Les captures et les sorties proviennent du lab d'exemple, monté comme le vôtre : site
59, stagiaire1, Proxmox VE 9.2.21. Ses adresses suivent donc le même plan :vmbr0en10.59.1.x, Corosync en10.59.11.x, et ainsi de suite. Remplacez59par votre site et1par votre numéro.
État du lab en fin de chapitre :
- Cluster
cluster-tpde 3 nœuds, quorate, Link 0 survmbr1et Link 1 survmbr0. VM 120 migrée à froid, puis à chaud avec ses disques locaux, et éteinte surpxe2<N>2(ateliers 2 et 3) - Migration d'un conteneur en
--restartmesurée, perte et retour du quorum éprouvés (ateliers 3 et 4) ; CT 330 supprimé - Réseaux internes adressés :
ens20(Ceph cluster),ens21(Ceph public),ens22(migration, déclaré dans Datacenter → Options) - Ceph Tentacle : 3 MON, 3 MGR, 3 OSD sur
sdb, poolceph-vm(3/2) déclaré en stockage ; VM 300vm-ha-testdessus, migrée à chaud - (Atelier 6) VM 300 en ressource HA, basculement automatique constaté après une panne brutale ; maintenance du nœud 1 éprouvée
Préparation à la mise en cluster
Contexte
Votre nœud pxe2<N>1 va créer le cluster ; pxe2<N>2 et pxe2<N>3, livrés pour ce chapitre, vont le rejoindre. Avant de les assembler, deux préparations :
- Nettoyer
pxe2<N>1. À la création du cluster, la configuration de/etc/pvedevient commune aux trois nœuds : chaque stockage déclaré sur le vôtre sera proposé aux deux autres. Les objets de test des chapitres précédents occupent aussi la mémoire et le disque dont Ceph aura besoin. - Mettre
pxe2<N>2etpxe2<N>3à jour. Ils sortent d'installation, comme votre premier nœud au chapitre 1 : dépôts enterprise actifs,apt updateen erreur, aucune mise à jour. Les trois nœuds d'un cluster doivent tourner sur la même version.
Résultat à obtenir : pxe2<N>1 sans objet de test, zfs-vms limité à ce nœud, tous ses stockages active. pxe2<N>2 et pxe2<N>3 sur le dépôt no-subscription, à jour, vides de machines. Et la même version de Proxmox VE sur les trois.
Ce que vous devez faire
- Sur
pxe2<N>1: supprimer les objets de test encore présents, limiter le stockagezfs-vmsà ce nœud, vérifier que tous les stockages sontactive. - Sur
pxe2<N>2, puis surpxe2<N>3, chacun par sa propre interface web : désactiver les deux dépôts enterprise, ajouter le dépôt no-subscription, mettre à jour, redémarrer si le noyau a changé. - Vérifier : même version sur les trois nœuds, aucune machine sur
pxe2<N>2etpxe2<N>3.
Cliquez pour vous aider
Étape 1 — Nettoyer pxe2<N>1
| Ce qui doit avoir disparu | Pourquoi |
|---|---|
| Les objets de test : VM 140 (chapitre 3, atelier 4), CT 260 (atelier 5), CT 311 et 312 (atelier 2) | Ils occupent de la mémoire et du disque dont Ceph aura besoin |
Tout stockage dont le serveur n'existe plus (nfs-partage, chapitre 3, atelier 5) |
Il reste inactive dans pvesm status, et sa déclaration deviendrait commune aux trois nœuds |
| Les snapshots de test sur les machines qui restent | Ils retiennent de l'espace dans le stockage (chapitre 3, §4.7) |
| Ce qui reste | Pourquoi |
|---|---|
Le pont vmbr1 sur ens19, avec son adresse |
C'est le lien Corosync du cluster (atelier 1) |
| Le CT 200 et la VM vide 290 du chapitre 1, les VM 100 à 110 du chapitre 2 | Elles servent encore ; la VM 290 porte le droit du comptable |
Le pool datapool et le stockage zfs-vms |
Ils peuvent rester, limités à pxe2<N>1 |
Le pont vmbr9, isolé |
Sans port ni adresse, il ne gêne rien |
Dans le Shell de pxe2<N>1 (interface web de pxe2<N>1 → le nœud pxe2<N>1 → Shell) :
qm list # les VM du nœud : il ne doit rester que 100 à 110, et la 290
pct list # les conteneurs : il ne doit rester que le CT 200
pvesm status # tous les stockages en active, plus de nfs-partage
Supprimez ce qui dépasse : la machine → More → Remove, ou qm destroy <vmid> --purge et pct destroy <ctid> --purge. Un stockage en trop : Datacenter → Storage → le stockage → Remove, ou pvesm remove <id>.
Limiter zfs-vms à votre nœud. Le pool datapool n'existe que sur pxe2<N>1. Déclaré pour tous les nœuds (Nodes : All (No restrictions)), zfs-vms serait proposé à pxe2<N>2 et pxe2<N>3, qui n'ont pas ce pool.
Via l'interface : Datacenter → Storage → zfs-vms → Edit → Nodes : pxe2<N>1 → OK.
Équivalent CLI, dans le Shell de pxe2<N>1 :
pvesm set zfs-vms --nodes pxe2<N>1 # le stockage n'existe que sur ce nœud
grep -A6 "zfspool: zfs-vms" /etc/pve/storage.cfg # la ligne nodes apparaît
Résultat attendu (pxe211) :
zfspool: zfs-vms
pool datapool/vms
content rootdir,images
mountpoint /datapool/vms
nodes pxe211
sparse 1
La ligne nodes pxe211 limite le stockage à ce nœud. sparse 1 est la case Thin provision du stockage ; elle est absente si elle n'a pas été cochée.
Étape 2 — Dépôts et mise à jour de pxe2<N>2, puis de pxe2<N>3
C'est la procédure du chapitre 1, atelier 3, sur chacun des deux nouveaux nœuds. Ils ne sont pas encore en cluster : chacun s'administre par sa propre interface web, avec son URL.
Les sorties ci-dessous sont celles du chapitre 1, sur pxe211 juste après son installation : les nœuds pxe2<N>2 et pxe2<N>3 sortent de la même installation. Le nombre de paquets à mettre à jour et les versions dépendent du jour.
1. Lire l'état de départ. Interface web de pxe2<N>2 → le nœud → Updates → Repositories.
Le bandeau Status avertit : The enterprise repository is enabled, but there is no active subscription! Deux dépôts Proxmox sont cochés : pve-enterprise (fichier pve-enterprise.sources) et ceph-squid en enterprise (fichier ceph.sources). Tous deux pointent vers enterprise.proxmox.com, réservé aux abonnés.
2. Désactiver les deux dépôts enterprise. Sélectionnez la ligne https://enterprise.proxmox.com/debian/pve → Disable.
Puis la ligne https://enterprise.proxmox.com/debian/ceph-squid → Disable. Oublier la seconde laisse apt update en erreur.
Dans le Shell de pxe2<N>2 :
apt update # relire les dépôts
Résultat attendu, si ceph-squid est resté en enterprise :
Err:6 https://enterprise.proxmox.com/debian/ceph-squid trixie InRelease
401 Unauthorized [IP: 51.91.38.34 443]
401 Unauthorized : le serveur refuse l'accès, faute d'abonnement. Disable ne supprime rien : il ajoute la ligne Enabled: false au fichier du dépôt.
3. Ajouter le dépôt no-subscription. Même page → Add → Repository : No-Subscription → Add.
Équivalent CLI, dans le Shell de pxe2<N>2 :
# Dépôt no-subscription de PVE 9, au format DEB822
nano /etc/apt/sources.list.d/proxmox.sources # un fichier neuf
Le contenu de proxmox.sources, à taper dans nano, puis Ctrl + O, Entrée et Ctrl + X :
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
Dans le Shell de pxe2<N>2 :
cat /etc/apt/sources.list.d/proxmox.sources # relire le fichier créé
Le bandeau passe à You get updates for Proxmox VE. Un avertissement jaune s'ajoute : The no-subscription repository is not recommended for production use! Ce dépôt convient au lab ; en production, on prend un abonnement.
4. Mettre à jour. Dans le Shell de pxe2<N>2 :
apt update # relire la liste des paquets : plus aucune erreur 401
apt full-upgrade -y # appliquer toutes les mises à jour
pveversion # version de Proxmox VE et noyau en cours
ls /boot/vmlinuz-* # les noyaux installés
Résultat attendu au chapitre 1 (fin de apt update) :
Get:5 http://download.proxmox.com/debian/pve trixie/pve-no-subscription amd64 Packages [390 kB]
181 packages can be upgraded. Run 'apt list --upgradable' to see them.
Si pveversion affiche un running kernel plus ancien que le dernier vmlinuz installé, un nouveau noyau attend. Redémarrez alors le nœud (bouton Reboot de son interface, ou reboot dans son Shell), puis reconnectez-vous.
Recommencez les points 1 à 4 sur pxe2<N>3, par son interface web.
Le dépôt Ceph enterprise reste désactivé, sans dépôt Ceph de remplacement : c'est l'installation de Ceph, à l'atelier 5, qui écrit le bon dépôt.
Étape 3 — Vérifier
Dans le Shell de chacun des trois nœuds :
pveversion # la même version partout
Dans le Shell de pxe2<N>2, puis de pxe2<N>3 :
qm list # rien : un nœud qui rejoint un cluster doit être vide de VM
pct list # et de conteneurs
apt update 2>&1 | grep -i "401\|error" # rien : plus d'erreur de dépôt
Résultat attendu (sur pxe211, pxe212 et pxe213) : pve-manager/9.2.21/4f6e0ac86f9e8c7f (running kernel: 7.0.14-20-pve) partout.
Atelier 1 — Constitution du cluster 3 nœuds
Contexte
Jusqu'ici, chaque nœud vivait seul. Le cluster les réunit en une seule entité, administrée depuis n'importe lequel d'entre eux. C'est le socle du chapitre : sans cluster, ni Ceph, ni haute disponibilité, ni migration.
Vous le montez à trois nœuds. C'est le minimum sérieux : à trois, la perte d'un nœud laisse deux voix sur trois, et le quorum tient.
Les nœuds se parlent par Corosync. Ce trafic est court mais sensible au délai : on lui donne son propre réseau, vmbr1, créé au chapitre 3. Le réseau d'administration, vmbr0, sert de lien de secours.
Résultat à obtenir : un cluster cluster-tp de trois nœuds, quorate, dont le lien principal passe par vmbr1.
Ce que vous allez construire. Chaque nœud a deux adresses Corosync : une sur vmbr1 (Link 0, prioritaire), une sur vmbr0 (Link 1, secours).
Chaque nœud a une voix ; le cluster décide avec deux voix sur trois. Cliquez sur un lien ou sur le quorum pour lire le résultat obtenu.
Arborescence attendue
Cluster « cluster-tp » (quorum : 2 voix sur 3)
├── pxe2<N>1 ← nœud fondateur, garde ses VM et conteneurs
│ ├── Link 0 : 10.<site>.<N+10>.11 (vmbr1, réseau Corosync)
│ └── Link 1 : 10.<site>.<N>.11 (vmbr0, secours)
├── pxe2<N>2 ← rejoint le cluster, vierge de machines
│ ├── Link 0 : 10.<site>.<N+10>.12
│ └── Link 1 : 10.<site>.<N>.12
└── pxe2<N>3 ← rejoint ensuite, vierge de machines
├── Link 0 : 10.<site>.<N+10>.13
└── Link 1 : 10.<site>.<N>.13
Ce que vous devez faire
- Préparer le réseau des deux nouveaux nœuds (la préparation ci-dessus est faite) : pont
vmbr1. Vérifier que les trois se joignent sur le réseau Corosync. - Créer le cluster depuis
pxe2<N>1, avec le Link 0 survmbr1et le Link 1 survmbr0. - Faire adhérer
pxe2<N>2, puispxe2<N>3, l'un après l'autre. - Vérifier : trois nœuds, trois voix,
Quorate: Yes, deux liens connectés.
⚠️ On joint les nœuds un par un. On attend que le premier soit stable avant de joindre le second.
Cliquez pour vous aider
Étape 0 — Le réseau Corosync des trois nœuds
Les dépôts et les mises à jour sont faits (préparation à la mise en cluster). Il reste à donner aux deux nouveaux nœuds leur accès au réseau Corosync.
1. Pont vmbr1, sur pxe2<N>2 et pxe2<N>3. Celui du chapitre 3 n'existe que sur votre premier nœud.
| Nœud | vmbr0 (administration) |
vmbr1 (Corosync, sur ens19) |
|---|---|---|
pxe2<N>1 |
10.<site>.<N>.11 |
10.<site>.<N+10>.11/24 — déjà créé au chapitre 3 |
pxe2<N>2 |
10.<site>.<N>.12 |
10.<site>.<N+10>.12/24 |
pxe2<N>3 |
10.<site>.<N>.13 |
10.<site>.<N+10>.13/24 |
Avant tout Apply, le filet du chapitre 3 (atelier 1, étape 1 bis).
Dans le Shell de chaque nœud dont vous modifiez le réseau :
# Copie de la configuration réseau qui fonctionne, puis retour automatique dans 10 minutes
cp /etc/network/interfaces /root/interfaces.avant
systemd-run --on-active=10min --unit=filet-reseau sh -c "cp /root/interfaces.avant /etc/network/interfaces && ifreload -a" # si l'accès est perdu, restaurer la copie dans 10 min
Résultat attendu :
Running timer as unit: filet-reseau.timer
Will run service as unit: filet-reseau.service
Une fois l'accès et les pings vérifiés, annulez-le sur chacun : systemctl stop filet-reseau.timer.
Network → Create → Linux Bridge : Name vmbr1, IPv4/CIDR l'adresse de ce nœud-là, Gateway vide, Bridge ports ens19, Comment COROSYNC → Create → Apply Configuration.
(pxe212, lab d'exemple). La fenêtre Create: Linux Bridge remplie : vmbr1, 10.59.11.12/24, ens19, COROSYNC. Pas de passerelle : ce réseau ne sort pas.
Derrière, les cinq cartes du nœud : ens19 est libre, ens18 porte déjà vmbr0. Les cartes ens20 à ens22 serviront à Ceph et à la migration, à l'atelier 5.
2. Vérifier que les trois se voient, depuis pxe2<N>1 :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Les deux autres nœuds, sur le réseau Corosync
ping -c 3 10.<site>.<N+10>.12
ping -c 3 10.<site>.<N+10>.13 # puis le troisième
Résultat attendu (pxe211 vers 10.59.11.12, puis 10.59.11.13) :
3 packets transmitted, 3 received, 0% packet loss, time 2046ms
rtt min/avg/max/mdev = 0.394/0.575/0.727/0.137 ms
3 packets transmitted, 3 received, 0% packet loss, time 2046ms
rtt min/avg/max/mdev = 0.393/0.535/0.679/0.116 ms
Moins d'une milliseconde : c'est ce que Corosync attend.
N'allez pas plus loin tant qu'un ping échoue. Un cluster monté sur un réseau incomplet perd son quorum sans raison visible. Le diagnostic est bien plus pénible une fois les nœuds liés.
Les nœuds qui rejoignent doivent être vierges de machines. Une VM ou un conteneur présent sur pxe2<N>2 ou pxe2<N>3 bloque la jonction.
Vérifiez avec qm list et pct list. Le nœud fondateur, lui, garde ses machines : elles font partie du cluster dès sa création.
Étape 1 — Créer le cluster depuis pxe21
Sur pxe2<N>1 : Datacenter → Cluster → Create Cluster.
À l'ouverture, Link 0 est pré-rempli avec l'adresse de vmbr0. Si vous validez tel quel, le cluster dialogue par le réseau d'administration. Il faut changer ce champ.
1. Le nom : 15 caractères au plus.
Le nom formation-cluster (17 caractères) est refusé : le champ passe en rouge, Create reste grisé. L'infobulle indique : The maximum length for this field is 15.
La commande pvecm create applique la même limite. Nommez le cluster cluster-tp.
2. Link 0 : l'adresse de vmbr1. Ouvrez la liste du champ.
La liste affiche chaque adresse avec son interface et son commentaire. Choisissez la ligne vmbr1, commentaire COROSYNC. Le commentaire saisi à la création du pont sert ici à ne pas se tromper.
3. Link 1 : le secours. Cliquez Add.
Add crée le Link 1 et le remplit seul avec l'adresse de vmbr0. Le texte le rappelle : lower numbers have higher priority. Corosync passe par le Link 0 ; il bascule sur le Link 1 si le premier tombe.
Cliquez Create.
Le journal de la tâche : génération de la clé Corosync (/etc/corosync/authkey), écriture de /etc/pve/corosync.conf, redémarrage de Corosync et du système de fichiers du cluster, puis TASK OK.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI, pour référence
pvecm create cluster-tp --link0 10.<site>.<N+10>.11 --link1 10.<site>.<N>.11
Vérifiez que le cluster dialogue par le bon réseau :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Les adresses de chaque lien, telles qu'écrites dans la configuration
grep -E "name|ring" /etc/pve/corosync.conf
Résultat attendu :
name: pxe211
ring0_addr: 10.59.11.11
ring1_addr: 10.59.1.11
cluster_name: cluster-tp
ring0_addr est l'adresse du Link 0 : elle doit être sur 10.<site>.<N+10>.x. ring1_addr, celle du Link 1, est l'adresse de vmbr0.
Étape 2 — Récupérer les informations de jointure
Sur pxe2<N>1 : Datacenter → Cluster → Join Information → Copy Information.
Le nœud fondateur fournit trois choses : son adresse, l'empreinte de son certificat, et un bloc encodé qui contient les deux. Derrière, la liste des nœuds montre déjà les colonnes Link 0 et Link 1. Gardez le texte copié : il sert pour les deux autres nœuds.
Étape 3 — Joindre pxe22 au cluster
Sur pxe2<N>2 : Datacenter → Cluster → Join Cluster. Collez le bloc dans Information, puis saisissez le mot de passe root de pxe2<N>1 (proxmoxx).
Join Cluster, pas Create Cluster. Sur les nœuds 2 et 3, un clic sur Create Cluster fonde un second cluster, à un seul nœud. Son pvecm status affiche alors Nodes: 1, Config Version: 1, Expected votes: 1, et la jonction devient impossible (authentication key '/etc/corosync/authkey' already exists).
La réparation, sans réinstaller : cours, §2.5.
Peer Address et Fingerprint se remplissent seuls à partir du bloc collé. Mais les champs Link 0 et Link 1 restent vides et passent en rouge.
À droite, Proxmox rappelle l'adresse du pair pour chaque lien : peer's link address. Choisissez pour chaque lien l'adresse de ce nœud sur le même réseau.
Link 0 : 10.<site>.<N+10>.12, en face du pair …11. Link 1 : l'adresse vmbr0 du nœud. Le bouton s'intitule Join 'cluster-tp' : il confirme le cluster visé.
Cliquez Join 'cluster-tp'.
Le journal s'arrête sur stopping pve-cluster service, sans TASK OK. C'est normal : le service qui sert l'interface redémarre, et la page perd sa connexion.
Attendez une minute, puis rechargez la page. Le nœud apparaît alors dans le cluster.
Pour la ligne de commande, deux adresses sur deux réseaux différents. pvecm add <adresse> désigne le nœud fondateur, sur son interface d'administration.
--link0 address= désigne le nœud qui rejoint, sur le réseau Corosync. Ce n'est pas le même réseau, et c'est normal.
Étape 4 — Joindre pxe23 au cluster
Recommencez l'étape 3 sur pxe2<N>3, avec les mêmes informations de jointure. Sur le lab, ce nœud a été joint en ligne de commande, pour vérifier la méthode :
Dans le Shell du nœud 3 (pxe2<N>3) :
# Sur pxe2<N>3 : la jonction au fondateur, avec ses deux liens. pvecm demande le mot de passe
# root du fondateur (proxmoxx), puis fait accepter l'empreinte de son certificat (yes)
pvecm add 10.<site>.<N>.11 --link0 address=10.<site>.<N+10>.13 --link1 address=10.<site>.<N>.13
Résultat attendu ; le mot de passe tapé ne s'affiche pas :
Please enter superuser (root) password for '10.59.1.11':
Establishing API connection with host '10.59.1.11'
The authenticity of host '10.59.1.11' can't be established.
X509 SHA256 key fingerprint is …
Are you sure you want to continue connecting (yes/no)? yes
Login succeeded.
check cluster join API version
Request addition of this node
Join request OK, finishing setup locally
stopping pve-cluster service
backup old database to '/var/lib/pve-cluster/backup/config-1791307887.sql.gz'
waiting for quorum...OK
(re)generate node files
generate new node certificate
merge authorized SSH keys
generated new node certificate, restart pveproxy and pvedaemon services
successfully added node 'pxe213' to cluster.
C'est la suite du journal que l'interface n'a pas pu afficher à l'étape 3 : attente du quorum, nouveau certificat, échange des clés SSH entre nœuds.
Étape 5 — Vérifier l'état du cluster
Rechargez l'interface : les trois nœuds apparaissent sous Datacenter (cluster-tp).
Config Version: 3 : la configuration a changé trois fois (création, puis deux jonctions). Chaque nœud a une voix, et ses deux adresses : Link 0 sur 10.59.11.x (vmbr1), Link 1 sur 10.59.1.x (vmbr0). En bas, les trois tâches : Create Cluster, puis deux Join Cluster, toutes OK.
Dans le Shell de chaque nœud du cluster :
# Le quorum, puis l'état de chaque lien Corosync
pvecm status
corosync-cfgtool -s # l'état de chaque lien Corosync
Résultat sur pxe211 (pvecm status, extrait) :
Name: cluster-tp
Config Version: 3
Transport: knet
Secure auth: on
Quorum information
------------------
Nodes: 3
Quorate: Yes
Votequorum information
----------------------
Expected votes: 3
Highest expected: 3
Total votes: 3
Quorum: 2
Flags: Quorate
Membership information
----------------------
Nodeid Votes Name
0x00000001 1 10.59.11.11 (local)
0x00000002 1 10.59.11.12
0x00000003 1 10.59.11.13
Quorum: 2 : il faut deux voix sur trois pour que le cluster décide. La section Membership affiche les adresses du Link 0, pas les noms : c'est la preuve que Corosync passe bien par vmbr1. Pour les noms, pvecm nodes.
Résultat sur pxe211 (corosync-cfgtool -s) :
Local node ID 1, transport knet
LINK ID 0 udp
addr = 10.59.11.11
status:
nodeid: 1: localhost
nodeid: 2: connected
nodeid: 3: connected
LINK ID 1 udp
addr = 10.59.1.11
status:
nodeid: 1: localhost
nodeid: 2: connected
nodeid: 3: connected
Les deux liens sont connected vers les deux autres nœuds. Si le Link 0 tombe, le cluster continue par le Link 1.
Validation finale
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Le quorum, puis le nombre de membres
pvecm status | grep Quorate # le quorum
pvecm nodes | grep -c pxe # nombre de nœuds membres
Résultat attendu : Quorate: Yes, puis 3.
Atelier 2 — Migration à froid
Contexte
Le premier bénéfice tangible d'un cluster, c'est de pouvoir déplacer une VM d'un nœud à l'autre. À froid — VM éteinte — l'opération est simple et sans risque : Proxmox copie le disque vers le nœud cible puis y recrée la VM. C'est la brique que Ceph rendra ensuite possible à chaud, sans arrêt.
Résultat à obtenir : une VM éteinte migrée avec succès d'un nœud vers un autre, et la compréhension de ce que Proxmox a dû copier faute de stockage partagé.
Ce que Proxmox fait quand vous cliquez Migrate sur une VM éteinte. Il inventorie les disques, crée le volume sur la cible, copie le disque en entier, puis supprime l'original. Cliquez sur une étape pour lire la ligne de journal correspondante.
Arborescence attendue
VM de test (éteinte)
pxe2<N>1 ──[ migration à froid ]──▶ pxe2<N>2
(copie du disque, puis recréation sur la cible) ← 4 Gio copiés, même vide
Ce que vous devez faire
- Disposer d'une VM de test éteinte sur l'un des nœuds (en recréer une au besoin).
- Lancer la migration à froid depuis l'interface, vers un autre nœud du cluster.
- Observer ce qui se passe : sans stockage partagé, Proxmox recopie l'intégralité du disque sur le nœud cible. Notez le temps que cela prend — c'est exactement ce que Ceph supprimera à l'atelier suivant.
Cliquez pour vous aider
Étape 0 — Créer une VM de test
Les VM 101 et 102 du chapitre 2 sont toujours là, sur votre nœud — mais elles servent aux ateliers suivants, et les deux nœuds qui vous ont rejoint sont vides. Créez donc une VM dédiée à l'exercice, la 120. Deux façons de faire, selon le temps dont vous disposez — les deux permettent de faire l'atelier en entier.
| Option A — VM sans système | Option B — VM avec Debian | |
|---|---|---|
| Durée | environ une minute | une vingtaine de minutes |
| Ce que vous pourrez montrer | le disque et la mémoire changés de serveur, la VM jamais redémarrée | la même chose, plus un service qui ne s'interrompt pas pendant la bascule |
| Il vous faut | rien | l'ISO Debian, encore présente dans local depuis le chapitre 1 |
Si vous hésitez, prenez l'option B. Refaire une installation n'est pas du temps perdu : c'est le geste que vous répéterez le plus souvent en production.
Et la migration à chaud d'une machine qui rend réellement un service est autrement plus convaincante qu'un écran de firmware. L'option A, elle, va droit à la migration.
Deux règles valables dans les deux cas. Elles ne sont pas des détails : chacune empêche la migration si on la néglige.
-
Le lecteur d'ISO doit être vide au moment de migrer. Le stockage
localn'est pas partagé : chaque nœud a le sien.Une VM dont le lecteur pointe vers une ISO de
localsurpxe2<N>1refusera de partir, puisque le fichier n'existe pas sur la cible. En option A on ne monte rien ; en option B on détache l'ISO une fois l'installation finie. -
Le type de CPU doit rester générique. Le type
hostexpose le processeur réel du nœud, et la VM ne peut alors migrer que vers un serveur au processeur identique. Le type par défautx86-64-v2-AESprésente un CPU commun aux trois nœuds — c'est lui qui rend la migration possible.
Option A — une VM sans système, en une minute
Pourquoi ça suffit. Ce que la migration déplace, c'est le disque quand la VM est éteinte et la mémoire quand elle tourne.
Une VM sans système a bien les deux : elle démarre sur son firmware, affiche No bootable device, et reste un processus vivant avec sa mémoire. Le mécanisme démontré est exactement le même.
En interface graphique. Sur pxe2<N>1, bouton Create VM en haut à droite :
| Onglet | Champ | Valeur |
|---|---|---|
| General | Node | pxe2<N>1 |
| VM ID | 120 |
|
| Name | vm-migration |
|
| OS | Storage / ISO image | Do not use any media |
| Guest OS — Type | Linux |
|
| Guest OS — Version | 7.x - 2.6 Kernel |
|
| System | Machine | Default (i440fx) |
| BIOS | Default (SeaBIOS) |
|
| SCSI Controller | VirtIO SCSI single |
|
| Qemu Agent | ✓ | |
| Disks | Bus/Device | SCSI / 0 |
| Storage | local-lvm |
|
| Disk size (GiB) | 4 |
|
| CPU | Sockets / Cores | 1 / 2 |
| Type | x86-64-v2-AES (surtout pas host) |
|
| Memory | Memory (MiB) | 1024 |
| Network | Bridge | vmbr0 |
| Model | VirtIO (paravirtualized) |
|
| Confirm | Start after created | ☐ |
→ Finish
En ligne de commande :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# créer la VM 120, sans système
qm create 120 \
--name vm-migration \
--memory 1024 \
--cores 2 \
--cpu x86-64-v2-AES \
--ostype l26 \
--scsihw virtio-scsi-single \
--scsi0 local-lvm:4 \
--net0 virtio,bridge=vmbr0 \
--agent 1
qm start 120 # la démarrer
qm status 120 # vérifier qu'elle tourne
Résultat attendu : status: running. La console affiche No bootable device ou l'invite du firmware — c'est normal, la VM occupe bien un disque et de la mémoire.
Attention à l'uptime de Proxmox. qm status 120 --verbose | grep uptime compte la vie du processus QEMU, pas celle du système. Après une migration à chaud, la VM tourne dans un nouveau processus, sur le nœud cible : le compteur repart de zéro, sans qu'il y ait eu redémarrage.
Sur le lab : uptime: 20 avant la bascule, uptime: 16 juste après. Pour prouver qu'une VM n'a pas redémarré, il faut le demander à son système (uptime -s dans la VM), ce que seule l'option B permet.
Option B — une VM avec Debian, comme en production
C'est l'installation du chapitre 2, en version minimale : ni bureau graphique ni serveur web, juste le système et de quoi répondre au réseau.
1. Vérifier que l'ISO est toujours là
Dans le Shell du nœud (interface web → votre nœud → Shell) :
ls -lh /var/lib/vz/template/iso/ # les ISO présentes sur le stockage local
Résultat attendu : l'ISO Debian téléchargée au chapitre 2. Si elle a disparu, reprenez-la : votre serveur → local → ISO Images → Download from URL.
2. Créer la VM — mêmes valeurs que l'option A, avec deux différences : l'ISO dans le lecteur, et un disque de 12 Go pour loger le système.
| Onglet | Champ | Valeur |
|---|---|---|
| OS | Storage / ISO image | local / l'ISO Debian |
| Disks | Disk size (GiB) | 12 |
Tout le reste est identique — x86-64-v2-AES compris.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Relevez d'abord le nom exact de l'ISO avec la commande ci-dessus
qm create 120 \
--name vm-migration \
--memory 2048 \
--cores 2 \
--cpu x86-64-v2-AES \
--ostype l26 \
--scsihw virtio-scsi-single \
--scsi0 local-lvm:12 \
--ide2 local:iso/<nom-exact-de-l-iso>,media=cdrom \
--net0 virtio,bridge=vmbr0 \
--boot 'order=ide2;scsi0' \
--agent 1
qm start 120 # démarrer sur l'ISO pour installer Debian
3. Installer Debian depuis la console.
Allez au plus simple : langue et clavier, nom de machine vm-migration, mot de passe root, un utilisateur. Partitionnement assisté — tout dans une seule partition.
Et surtout, à l'écran Sélection des logiciels : décochez tout sauf Utilitaires usuels du système. Sans environnement de bureau, l'installation tient en une dizaine de minutes.
4. Après le redémarrage, dans la VM, installer l'agent invité — c'est lui qui permettra à Proxmox d'afficher l'adresse IP de la machine :
Dans la VM (sa Console, ou en SSH) :
apt update # la liste des paquets
apt install -y qemu-guest-agent # installer l'agent invité
# Lancer l'agent maintenant ; il redémarrera seul à chaque démarrage (VM créée avec --agent enabled=1)
systemctl start qemu-guest-agent
ip -br addr # l'adresse IP de la VM
5. Détacher l'ISO — à ne pas oublier
Dans le Shell du nœud (interface web → votre nœud → Shell) :
qm set 120 --ide2 none,media=cdrom # vider le lecteur CD de la VM
qm config 120 | grep ide2 # vérifier : plus d'ISO
Par l'interface : VM 120 → Hardware → CD/DVD Drive → Edit → Do not use any media → OK.
C'est l'oubli le plus fréquent de cet atelier. Tant que le lecteur pointe vers local:iso/..., la fenêtre Migrate affiche Cannot migrate VM with local CD/DVD et refuse de partir. Le fichier ISO existe sur pxe2<N>1, pas sur la cible : local n'est pas partagé.
Résultat attendu : qm agent 120 ping ne renvoie rien (c'est le signe qu'il répond), et la ligne IPs de l'onglet Summary affiche l'adresse de la VM. Notez-la : elle vous servira pour le ping continu de l'étape 2.
Étape 1 — Migration à froid depuis l'interface
Si la VM est allumée, éteignez-la d'abord : VM 120 → Shutdown.
VM 120 → Migrate (bouton en haut à droite).
L'ISO Debian est restée dans le lecteur. La fenêtre le détecte avant toute tentative : Cannot migrate VM with local CD/DVD, et le bouton Migrate reste grisé. Détachez l'ISO (étape 0, option B, point 5), puis rouvrez la fenêtre.
En ligne de commande, la même VM est refusée avec un message plus précis.
Dans le Shell du nœud 1 :
# Tenter la migration vers le nœud 2, ISO encore attachée
qm migrate 120 pxe2<N>2
found local disk 'local:iso/debian-13.6.0-amd64-netinst.iso' (attached)
can't migrate local disk 'local:iso/debian-13.6.0-amd64-netinst.iso': local cdrom image
ERROR: migration aborted (duration 00:00:00): Problem found while scanning volumes - can't migrate VM - check log
Lecteur vide, la fenêtre ne garde qu'un avertissement : Migration with local disk might take long, suivi du disque et de sa taille. Mode : Offline, puisque la VM est éteinte.
Choisissez Target node pxe2<N>2, puis Migrate. Le disque atterrit sur le stockage de même nom du nœud cible : local-lvm.
Le journal complet : disque local repéré, volume créé sur la cible, copie, puis suppression du volume source.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI
qm migrate 120 pxe2<N>2
Résultat attendu (option A, disque de 4 Gio) :
starting migration of VM 120 to node 'pxe212' (10.59.1.12)
found local disk 'local-lvm:vm-120-disk-0' (attached)
copying local disk images
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 4.97538 s, 863 MB/s
successfully imported 'local-lvm:vm-120-disk-0'
Logical volume "vm-120-disk-0" successfully removed.
migration finished successfully (duration 00:00:06)
Sur le lab (10.59.1.x : remplacez par votre réseau). Deux constats. Les 4 Gio ont traversé le réseau, alors que le disque est vide : sans stockage partagé, Proxmox copie le volume entier.
Et la copie est passée par 10.59.1.12, l'adresse vmbr0 de la cible : le réseau d'administration. L'atelier 5 supprime la copie grâce à Ceph, et envoie la migration sur son propre réseau.
Validation finale
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# qm list ne montre que les VM du nœud local : on interroge pxe2<N>2 par l'API
pvesh get /nodes/pxe2<N>2/qemu --output-format text | grep 120
Résultat attendu : une ligne pour la VM 120, stopped, vm-migration. Dans l'arbre de gauche, la VM apparaît sous pxe2<N>2.
Atelier 3 — Migrer sans stockage partagé : VM allumée et conteneur
Contexte
À l'atelier 2, la VM 120 a changé de nœud éteinte. En production, on déplace plutôt des machines en service, pour vider un nœud avant une intervention. Sans stockage partagé, deux cas se présentent, et ils ne coûtent pas la même chose :
- une VM allumée peut migrer à chaud, à condition de demander la copie de ses disques locaux (
--with-local-disks) ; - un conteneur ne migre jamais à chaud : il est arrêté, déplacé, puis redémarré (
--restart). Son service est coupé pendant l'opération.
On mesure les deux, et on les compare à la migration à froid de l'atelier 2.
Résultat à obtenir : la VM 120, allumée, migrée de pxe2<N>2 vers pxe2<N>3 sans être arrêtée. Un conteneur neuf, le CT 330, est migré de pxe2<N>1 vers pxe2<N>2 avec --restart, et la durée de sa coupure est mesurée au ping.
Les deux refus sont expliqués (VM sans --with-local-disks, conteneur avec --online). En fin d'atelier, la VM 120 est éteinte sur pxe2<N>2 et le CT 330 supprimé.
Les trois cas côte à côte, avec ce qui voyage et ce qui reste en service. Sans Ceph, le disque voyage toujours. Cliquez sur un cas pour lire la ligne de journal obtenue sur le lab.
Arborescence attendue
pxe2<N>2 ── VM 120 allumée ──[ --online --with-local-disks ]──▶ pxe2<N>3
(disque recopié pendant que la VM tourne, puis mémoire)
pxe2<N>1 ── CT 330 « ct-migration » ──[ --restart ]──▶ pxe2<N>2
(arrêt, copie du disque, redémarrage) ← mesuré par un ping depuis pxe2<N>3
Fin d'atelier : VM 120 éteinte, de retour sur pxe2<N>2 ; CT 330 supprimé
Ce que vous devez faire
- Démarrer la VM 120 sur
pxe2<N>2, puis tenter de la migrer à chaud verspxe2<N>3, sans option. Lire le refus. - Relancer la migration avec la copie des disques locaux. Lire le journal : qu'est-ce qui voyage, dans quel ordre, et combien de temps la VM est-elle figée ?
- Créer sur
pxe2<N>1un petit conteneur Debian, le CT 330, en adresse fixe10.<site>.<N>.60, et le démarrer. - Lancer depuis
pxe2<N>3unpingcontinu vers ce conteneur. - Tenter une migration à chaud du conteneur vers
pxe2<N>2, puis le migrer avec--restart. Compter les réponses perdues auping. - Remettre en état : supprimer le CT 330, éteindre la VM 120 et la ramener sur
pxe2<N>2.
Cliquez pour vous aider
Sur le lab (pxe211 à pxe213, réseau 10.59.1.x). Chez vous, les nœuds s'appellent pxe2<N>1 à pxe2<N>3 et le réseau est 10.<site>.<N>.x.
Étape 1 — La VM allumée refuse de partir
En ligne de commande.
Dans le Shell de pxe2<N>2 :
qm start 120 # démarrer la VM
qm migrate 120 pxe2<N>3 --online # migration à chaud, sans autre option
Résultat attendu :
found local disk 'local-lvm:vm-120-disk-0' (attached)
can't migrate local disk 'local-lvm:vm-120-disk-0': can't live migrate attached local disks without with-local-disks option
ERROR: Problem found while scanning volumes - can't migrate VM - check log
Le disque est sur local-lvm, que chaque nœud possède en propre : la cible ne le voit pas. En ligne de commande, Proxmox refuse de déplacer une VM en service sans qu'on lui demande explicitement de recopier ce disque.
Étape 2 — Migration à chaud avec les disques locaux
En interface graphique. VM 120 → Migrate.
La fenêtre indique Mode : Online, puisque la VM tourne. Elle ajoute un champ Target storage (Current layout : le disque garde le stockage de même nom sur la cible) et prévient : Migration with local disk might take long.
L'interface ajoute d'elle-même la copie du disque : elle ne propose pas de case à cocher. Choisissez Target node pxe2<N>3, puis Migrate.
En ligne de commande, la copie du disque se demande avec l'option --with-local-disks.
Dans le Shell de pxe2<N>2 :
qm migrate 120 pxe2<N>3 --online --with-local-disks # recopier le disque, puis la mémoire
Résultat attendu (extrait) :
starting migration of VM 120 to node 'pxe213' (10.59.1.13)
found local disk 'local-lvm:vm-120-disk-0' (attached)
starting VM 120 on remote node 'pxe213'
starting storage migration
mirror-scsi0: transferred 1.0 GiB of 4.0 GiB (25.12%) in 1s
mirror-scsi0: transferred 4.0 GiB of 4.0 GiB (100.00%) in 4s, ready
switching mirror jobs to actively synced mode
starting online/live migration on unix:/run/qemu-server/120.migrate
average migration speed: 1.0 GiB/s - downtime 3 ms
migration completed, transferred 4.9 MiB VM-state
mirror-scsi0: Completed successfully.
migration finished successfully (duration 00:00:14)
Le journal se lit en trois temps :
| Temps | Lignes | Ce qui se passe |
|---|---|---|
| ① Le disque | starting storage migration, mirror-scsi0 … |
Le disque est recopié vers la cible (drive mirror) pendant que la VM tourne ; les écritures en cours sont recopiées aussi (actively synced mode) |
| ② La mémoire | starting online/live migration, downtime 3 ms |
Comme à chaud sur un stockage partagé : la mémoire passe, puis la VM est figée 3 ms et bascule |
| ③ La fin | Completed successfully, duration 00:00:14 |
La copie du disque est close ; l'ancien volume est supprimé sur la source |
14 secondes au lieu de 6 pour la migration à froid de l'atelier 2, mais la VM n'a jamais été arrêtée. Avec un vrai disque de 100 Gio, c'est la copie du disque qui dicterait la durée : c'est ce que Ceph supprimera à l'atelier 5.
L'uptime affiché par Proxmox repart de zéro après la bascule (uptime: 16 sur pxe2<N>3). Ce n'est pas un redémarrage : ce compteur suit le processus QEMU, et la VM tourne désormais dans un nouveau processus, sur la cible.
Étape 3 — Créer un conteneur à déplacer
En interface graphique. Sur pxe2<N>1, Create CT :
| Onglet | Champ | Valeur |
|---|---|---|
| General | CT ID / Hostname | 330 / ct-migration |
| Unprivileged container / Nesting | ✓ / ✓ | |
| Password | celui du lab | |
| Template | Storage / Template | local / debian-13-standard_… |
| Disks | Storage / Disk size | local-lvm / 4 |
| CPU / Memory | Cores / Memory | 1 / 512 |
| Network | Bridge / IPv4 / Gateway | vmbr0 / 10.<site>.<N>.60/24 / 10.<site>.<N>.1 |
| Confirm | Start after created | ✓ |
En ligne de commande.
Dans le Shell de pxe2<N>1 :
# Un conteneur Debian minimal, en adresse fixe
pct create 330 local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst \
--hostname ct-migration --memory 512 --cores 1 \
--rootfs local-lvm:4 \
--net0 name=eth0,bridge=vmbr0,ip=10.<site>.<N>.60/24,gw=10.<site>.<N>.1 \
--unprivileged 1 --features nesting=1 \
--password
pct start 330 # le démarrer
pct status 330 # status: running
--password sans valeur demande le mot de passe au clavier. --features nesting=1 évite l'avertissement Systemd 257 detected. You may need to enable nesting., obtenu sans cette option : le système Debian 13 du conteneur en a besoin.
Étape 4 — Un ping continu pour mesurer la coupure
Dans le Shell de pxe2<N>3 (interface web de pxe2<N>3 → Shell) :
ping -i 0.5 10.<site>.<N>.60 # une requête toutes les 0,5 s ; laisser tourner
Étape 5 — Migrer le conteneur
Dans le Shell de pxe2<N>1 :
pct migrate 330 pxe2<N>2 --online # essai de migration à chaud
pct migrate 330 pxe2<N>2 --restart # arrêt, déplacement, redémarrage
En interface graphique : CT 330 → Migrate → Target node pxe2<N>2.
Pour un conteneur allumé, la fenêtre impose Mode : Restart Mode : aucune option ne permet de le déplacer sans l'arrêter.
Résultat attendu :
ERROR: migration aborted (duration 00:00:00): lxc live migration is currently not implemented
shutdown CT 330
starting migration of CT 330 to node 'pxe212' (10.59.1.12)
found local volume 'local-lvm:vm-330-disk-0' (in current VM config)
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 5.95972 s, 721 MB/s
successfully imported 'local-lvm:vm-330-disk-0'
start container on target node
migration finished successfully (duration 00:00:11)
Arrêtez le ping (Ctrl+C) et lisez sa fin. Sur le lab, les numéros icmp_seq sautaient de 9 à 31 : 21 réponses perdues à 0,5 s d'intervalle, soit environ 10 secondes sans service. C'est le temps d'arrêter le conteneur, de copier ses 4 Gio et de le redémarrer.
Pourquoi pas à chaud ? Une VM est un seul processus, dont on sait copier la mémoire. Un conteneur, ce sont les processus du noyau de l'hôte, avec leurs fichiers ouverts et leurs connexions : rien qu'on puisse transporter vers un autre noyau (cours, §2.1).
Étape 6 — Remettre en état
Dans le Shell de pxe2<N>2 :
pct stop 330 # arrêter le conteneur
pct destroy 330 --purge # le supprimer
Dans le Shell de pxe2<N>3 :
qm stop 120 # la VM 120 n'a pas de système : un arrêt brutal suffit
qm migrate 120 pxe2<N>2 # migration à froid, retour sur pxe2<N>2
Si vous avez installé Debian dans la VM 120 (option B de l'atelier 2), préférez qm shutdown 120. Sans système, qm shutdown attend une réponse qui ne vient pas, puis échoue sur got timeout.
Validation finale
| Contrôle | Résultat attendu |
|---|---|
| Migration à chaud sans option | refusée : can't live migrate attached local disks without with-local-disks option |
Migration à chaud avec --with-local-disks |
réussie, downtime de quelques millisecondes, disque recopié d'abord |
Conteneur avec --online |
refusé : lxc live migration is currently not implemented |
Conteneur avec --restart |
réussi, une dizaine de secondes de coupure au ping |
| État final | VM 120 éteinte sur pxe2<N>2 ; plus de CT 330 |
Atelier 4 — Le quorum à l'épreuve
Contexte
Sur le lab, un nœud isolé s'est figé tandis que les deux autres continuaient (cours, §2.2). On va plus loin : on prive votre nœud pxe2<N>1 de ses deux voisins, l'un après l'autre, et l'on observe ce qu'il peut encore faire.
La panne est simulée en arrêtant Corosync sur les voisins, depuis leur propre Shell. Elle est donc réversible : on relance Corosync, et tout revient. On ne coupe aucun nœud et l'on ne touche à aucun réseau : un nœud éteint ne se rallume pas depuis l'interface web.
Résultat à obtenir : l'état du quorum sur pxe2<N>1 avec trois, deux, puis une seule voix. La preuve qu'à deux voix sur trois, le cluster écrit encore. À une voix, /etc/pve passe en lecture seule, la création et le démarrage de VM sont refusés, mais la VM 101 continue de tourner.
Les événements correspondants sont lus dans le journal de Corosync. Enfin, le quorum revient sans rien forcer.
Les trois étapes de l'atelier, vues depuis pxe2<N>1. Le quorum reste fixé à deux voix ; seul change le nombre de voix présentes. Cliquez sur une étape pour lire le résultat.
Arborescence attendue
Cluster « cluster-tp » (3 voix attendues, quorum = 2)
├── pxe2<N>1 ← on observe ici : la VM 101 y tourne
├── pxe2<N>2 ← Corosync arrêté en premier → 2 voix sur 3 : quorate
└── pxe2<N>3 ← Corosync arrêté ensuite → 1 voix sur 3 : figé
Retour : Corosync relancé sur pxe2<N>2, puis pxe2<N>3 → 3 voix
Ce que vous devez faire
- Relever l'état de départ sur
pxe2<N>1:pvecm status, et l'uptimede la VM 101 (démarrez-la si besoin). - Arrêter Corosync sur
pxe2<N>2. Surpxe2<N>1: relever le quorum, puis tenter une écriture dans/etc/pve. - Arrêter Corosync sur
pxe2<N>3. Surpxe2<N>1: relever le quorum, tenter une écriture, créer une VM, démarrer une VM éteinte, et vérifier que la VM 101 tourne toujours. - Lire le journal de Corosync sur
pxe2<N>1. - Relancer Corosync sur
pxe2<N>2, puis surpxe2<N>3, et vérifier le retour au quorum.
Ne jamais utiliser pvecm expected 1 pour « débloquer » le nœud resté seul. La commande abaisse le nombre de voix attendues : le nœud isolé se croit majoritaire.
Si les autres nœuds tournent toujours de leur côté, deux parties du cluster écrivent en même temps : c'est le split-brain (cours, §2.4). Ici, la bonne réponse est de rétablir Corosync.
Cliquez pour vous aider
Sur le lab (pxe211 à pxe213). Chez vous, les nœuds s'appellent pxe2<N>1 à pxe2<N>3. Ouvrez trois onglets, un Shell par nœud : l'interface web de pxe2<N>1 restera utilisable pour lire, pas pour modifier.
Étape 1 — L'état de départ
Dans le Shell de pxe2<N>1 :
qm start 101 # la VM 101 doit tourner ; si elle tourne déjà, qm le dit, sans conséquence
qm status 101 --verbose # état et durée de fonctionnement ; à lire : status, uptime
pvecm status # les voix du cluster ; à lire : Nodes, Expected votes, Total votes, Quorum, Quorate
Résultat attendu (les lignes qui comptent) :
status: running
uptime: 271
Nodes: 3
Quorate: Yes
Expected votes: 3
Total votes: 3
Quorum: 2
Trois voix attendues, trois présentes ; il en faut deux (Quorum: 2) pour décider.
Étape 2 — Un voisin perdu : deux voix sur trois
Dans le Shell de pxe2<N>2 :
systemctl stop corosync # ce nœud ne parle plus au cluster
Dans le Shell de pxe2<N>1 :
pvecm status # deux voix sur trois ; à lire : Nodes, Total votes, Quorum, Quorate
touch /etc/pve/essai-2-voix # écrire dans /etc/pve
echo "code : $?" # 0 : écriture acceptée
rm /etc/pve/essai-2-voix # retirer le fichier d'essai
Résultat attendu (les lignes qui comptent) :
Nodes: 2
Quorate: Yes
Total votes: 2
Quorum: 2
code : 0
Deux voix sur trois, c'est encore la majorité : le cluster continue sans rien perdre. Dans l'interface web, pxe2<N>2 apparaît avec une croix rouge.
L'arbre de l'interface de pxe2<N>1 après l'étape 3 : les deux voisins portent une croix rouge, leurs machines restent listées. Ce que l'interface ne montre pas d'un coup d'œil, c'est que pxe2<N>1 a perdu le quorum : il faut le lire dans pvecm status, ou dans Datacenter → Summary.
Étape 3 — Le second voisin perdu : une voix sur trois
Dans le Shell de pxe2<N>3 :
systemctl stop corosync # le second voisin quitte le cluster
Dans le Shell de pxe2<N>1 :
pvecm status # une voix sur trois ; à lire : Nodes, Expected votes, Total votes, Quorum, Quorate
touch /etc/pve/essai-1-voix # écrire dans /etc/pve
qm create 199 --name essai-sans-quorum --memory 256 # créer une VM
qm start 105 # démarrer une VM éteinte
qm status 101 --verbose # la VM qui tournait ; à lire : status, uptime
Résultat attendu (les lignes qui comptent) :
Nodes: 1
Quorate: No
Expected votes: 3
Total votes: 1
Quorum: 2 Activity blocked
touch: cannot touch '/etc/pve/essai-1-voix': Permission denied
cluster not ready - no quorum?
cluster not ready - no quorum?
status: running
uptime: 286
| Ce qu'on tente | Réponse | Pourquoi |
|---|---|---|
Écrire dans /etc/pve |
Permission denied |
Le nœud minoritaire passe la configuration commune en lecture seule |
| Créer une VM | cluster not ready - no quorum? |
Une création écrit une configuration dans /etc/pve |
| Démarrer une VM | cluster not ready - no quorum? |
Le démarrage est refusé : la même VM pourrait être lancée ailleurs, par la partie majoritaire |
| La VM 101 déjà lancée | status: running, uptime qui continue |
Rien ne l'arrête : le quorum protège la configuration, pas les machines qui tournent |
Étape 4 — Ce que dit le journal
Dans le Shell de pxe2<N>1 :
journalctl -u corosync --no-pager -n 8 # les 8 derniers événements de Corosync
Résultat attendu :
[QUORUM] This node is within the non-primary component and will NOT provide any services.
[QUORUM] Members[1]: 1
[MAIN ] Completed service synchronization, ready to provide service.
[KNET ] link: host: 3 link: 0 is down
[KNET ] host: host: 3 (passive) best link: 1 (pri: 1)
[KNET ] link: host: 3 link: 1 is down
[KNET ] host: host: 3 (passive) best link: 1 (pri: 1)
[KNET ] host: host: 3 has no active links
non-primary component: ce nœud est du côté minoritaire, il ne rendra plus de service de cluster.Members[1]: 1: il ne voit plus que lui-même (le nœud n°1).link: 0 is down, puislink: 1 is down: les deux liens vers le nœud 3 tombent l'un après l'autre. Avec un seul lien perdu, Corosync aurait basculé sur l'autre (best link: 1) sans perdre le nœud.
Étape 5 — Revenir au quorum
Dans le Shell de pxe2<N>2, puis dans celui de pxe2<N>3 :
systemctl start corosync # le nœud revient dans le cluster
Dans le Shell de pxe2<N>1, après le premier redémarrage puis après le second :
pvecm status # les voix revenues ; à lire : Nodes, Total votes, Quorate
Résultat attendu (les lignes qui comptent) :
Nodes: 2
Quorate: Yes
Total votes: 2
[…]
Nodes: 3
Quorate: Yes
Total votes: 3
Dès que pxe2<N>2 revient, le journal annonce This node is within the primary component and will provide service. : avec deux voix, pxe2<N>1 retrouve l'écriture. Aucune VM 199 n'a été créée pendant la panne (ls /etc/pve/qemu-server/ ne la montre pas).
Validation finale
Dans le Shell de pxe2<N>1 :
pvecm status | grep Quorate # Quorate: Yes
corosync-cfgtool -s | grep -c connected # 4 : deux liens vers deux voisins
touch /etc/pve/essai # /etc/pve accessible en écriture ?
echo "code : $?" # 0 : oui
rm /etc/pve/essai # retirer le fichier d'essai
Résultat attendu : Quorate: Yes, 4, code : 0. Le cluster est revenu à son état de départ, sans rien forcer.
Atelier 5 — Déploiement de Ceph Tentacle
Contexte
À l'atelier 2, migrer une VM a coûté la copie de tout son disque. Ceph supprime cette copie.
C'est un stockage distribué : chaque donnée existe en trois exemplaires, un par nœud. Le disque d'une VM est donc déjà partout, et seule sa mémoire doit voyager.
Ceph a besoin de deux réseaux à lui. Le réseau public transporte le trafic entre les VM et Ceph. Le réseau cluster transporte la réplication entre les disques.
Vos cartes ens20 et ens21 sont là pour eux. La carte ens22, elle, portera la migration à chaud.
Résultat à obtenir : Ceph sain (HEALTH_OK) sur les trois nœuds, un pool répliqué déclaré en stockage, et une VM migrée à chaud par le réseau de migration.
Ce que vous allez déployer. Sur chaque nœud, un moniteur, un manager et un OSD.
En dessous, les trois réseaux internes, chacun sur sa carte. Cliquez sur un réseau ou sur un type de démon pour lire son rôle et le résultat obtenu.
Arborescence attendue
Réseaux internes (une adresse par nœud : .11, .12, .13)
├── ens20 → Ceph cluster 10.<site>.<N+20>.x réplication entre OSD
├── ens21 → Ceph public 10.<site>.<N+30>.x VM ↔ Ceph, moniteurs
└── ens22 → migration 10.<site>.<N+40>.x mémoire des VM migrées
Ceph Tentacle (20.2)
├── Monitors : 1 par nœud (quorum de Ceph, distinct de celui de Corosync)
├── Managers : 1 par nœud (1 actif, 2 en attente)
├── OSD : 1 par nœud, sur /dev/sdb
└── pool « ceph-vm » (3 copies, 2 minimum) → stockage RBD partagé
VM 300 « vm-ha-test » sur ceph-vm ──[ migration à chaud ]──▶ pxe2<N>2 ← seule la mémoire voyage
Ce que vous devez faire
- Adresser
ens20,ens21etens22sur les trois nœuds. - Installer Ceph sur les trois nœuds, puis l'initialiser sur les réseaux dédiés.
- Créer un Monitor et un Manager par nœud, puis un OSD par nœud sur
/dev/sdb. - Vérifier
HEALTH_OK, puis créer un pool répliqué déclaré en stockage. - Désigner le réseau de migration, puis migrer à chaud une VM posée sur Ceph. Comparez avec l'atelier 2.
⚠️ Ceph exige un disque totalement vierge pour ses OSD. Si un pool ZFS occupe
sdb, il faudra le détruire d'abord (étape 4 bis).
Cliquez pour vous aider
Étape 0 — Adresser les réseaux de Ceph et de migration
Ces trois réseaux n'ont pas besoin de pont : aucune VM ne s'y branche. L'adresse se pose directement sur la carte.
| Carte | Rôle | pxe2<N>1 |
pxe2<N>2 |
pxe2<N>3 |
Comment |
|---|---|---|---|---|---|
ens20 |
Ceph cluster | 10.<site>.<N+20>.11/24 |
….12/24 |
….13/24 |
CEPH-CLUSTER |
ens21 |
Ceph public | 10.<site>.<N+30>.11/24 |
….12/24 |
….13/24 |
CEPH-PUBLIC |
ens22 |
Migration | 10.<site>.<N+40>.11/24 |
….12/24 |
….13/24 |
MIGRATION |
Avant tout Apply, le filet du chapitre 3 (atelier 1, étape 1 bis).
Dans le Shell de chaque nœud dont vous modifiez le réseau :
# Copie de la configuration réseau qui fonctionne, puis retour automatique dans 10 minutes
cp /etc/network/interfaces /root/interfaces.avant
systemd-run --on-active=10min --unit=filet-reseau sh -c "cp /root/interfaces.avant /etc/network/interfaces && ifreload -a" # si l'accès est perdu, restaurer la copie dans 10 min
Une fois l'accès et les pings vérifiés, annulez-le sur chacun : systemctl stop filet-reseau.timer.
Sur chaque nœud : Network → double-clic sur la carte → IPv4/CIDR, Autostart coché, Comment → OK. Une fois les trois cartes faites : Apply Configuration.
(pxe211). La fenêtre Edit: Network Device de ens20.
Pas de passerelle : ces réseaux ne sortent pas. Autostart coché : sans lui, la carte resterait éteinte au prochain démarrage.
Après Apply Configuration, les cinq cartes sont actives. ens20, ens21 et ens22 portent leur adresse en direct ; ens18 et ens19 la portent par leur pont (vmbr0, vmbr1).
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Depuis pxe2<N>1 : les deux autres nœuds, sur chacun des trois réseaux
ping -c 2 -q 10.<site>.<N+20>.12 # le nœud 2, réseau Ceph cluster
ping -c 2 -q 10.<site>.<N+20>.13 # le nœud 3
ping -c 2 -q 10.<site>.<N+30>.12 # le nœud 2, réseau Ceph public
ping -c 2 -q 10.<site>.<N+30>.13 # le nœud 3
ping -c 2 -q 10.<site>.<N+40>.12 # le nœud 2, réseau de migration
ping -c 2 -q 10.<site>.<N+40>.13 # le nœud 3
Remplacez <N+20>, <N+30> et <N+40> par leurs valeurs (21, 31 et 41 pour le stagiaire 1).
Résultat attendu : pour chaque ping, 2 packets transmitted, 2 received, 0% packet loss, puis une ligne rtt min/avg/max/mdev sous la milliseconde (de 0,36 à 0,71 ms en moyenne).
Étape 1 — Installer Ceph
Sur pxe2<N>1, par l'assistant. Le serveur → Ceph. Le panneau affiche Ceph is not installed on this node → Install Ceph.
L'assistant propose tentacle (20.2), mais le dépôt Enterprise (recommended). Sans abonnement, ce dépôt répond 401 et l'installation échoue. L'indice en bas le signale : The enterprise repository is enabled, but there is no active subscription!
Repository passé sur No-Subscription. L'indice change : ce dépôt n'est pas le meilleur choix en production.
Pour le lab, c'est le bon. Cliquez Start tentacle installation.
L'onglet Installation est un vrai terminal. apt liste les paquets (27 à installer, 13 à mettre à jour), puis attend une réponse : Do you want to continue? [Y/n]. Cliquez dans le terminal, tapez y, puis Entrée.
Les paquets en version 20.2.4-pve4, puis installed Ceph 20.2 Tentacle successfully!. Le bouton Next devient actif.
Sur pxe2<N>2 et pxe2<N>3, en ligne de commande — dans le Shell de chaque nœud :
# La question d'apt reçoit « y » par le tube
yes | pveceph install --version tentacle --repository no-subscription
ceph --version # version de Ceph installée
Résultat attendu :
installed Ceph 20.2 Tentacle successfully!
reloading API to load new Ceph RADOS library...
ceph version 20.2.4 (a12e197e4613a9d6be90e8fb073ac4fc3656aee2) tentacle (stable)
apt failed during ceph installation (256) : lisez la ligne au-dessus. Sans le yes |, et sans terminal pour répondre, apt reçoit une réponse vide. Il abandonne : `Do you want to continue?
[Y/n] Abort.Ce n'est pas le dépôt : relancez avecyes |. Si la ligne au-dessus parle de401ou de dépôt introuvable, c'est bien le dépôt : relancez avec--repository no-subscription.pvecephréécrit lui-même/etc/apt/sources.list.d/ceph.sources; n'ajoutez pas de fichier.list` à côté.
Étape 2 — Initialiser Ceph sur ses réseaux
Avec l'assistant, cette étape suit l'installation : onglet Configuration. Si vous l'avez fermé, rouvrez Ceph sur pxe2<N>1 : le panneau affiche Ceph is not initialized → Configure Ceph.
Public Network : l'adresse de ens21 (10.44.31.11/24 sur le lab). Cluster Network : celle de ens20 (10.44.21.11/24).
Par défaut, le second vaut Same as Public Network : laissé ainsi, la réplication partagerait le réseau des VM. À droite, le premier moniteur sera pxe211. → Next.
Installation successful! et la suite à faire : installer Ceph sur les autres nœuds, créer les moniteurs, les OSD, les pools. → Finish.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI, si vous n'avez pas utilisé l'assistant
pveceph init --network 10.<site>.<N+30>.0/24 --cluster-network 10.<site>.<N+20>.0/24
pveceph mon create # le premier moniteur
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Ce que l'assistant a écrit, et ce qui tourne déjà
grep -E "network|mon_host|pool_default" /etc/pve/ceph.conf
ceph -s # état du cluster Ceph
Résultat attendu (lab, pveceph init en ligne de commande, réseaux 10.59.x) :
cluster_network = 10.59.21.0/24
mon_host = 10.59.31.11
osd_pool_default_min_size = 2
osd_pool_default_size = 3
public_network = 10.59.31.0/24
...
health: HEALTH_OK
mon: 1 daemons, quorum pxe211 (age 6s) [leader: pxe211]
mgr: pxe211(active, since 5s)
osd: 0 osds: 0 up, 0 in
Par l'assistant, les deux réseaux s'écrivent avec l'adresse du nœud (10.<site>.<N+20>.11/24) ; en ligne de commande, avec l'adresse du réseau (.0/24). Ceph comprend les deux de la même façon : le réseau entier.
L'assistant, comme pveceph mon create, a créé d'un coup le premier Monitor et le premier Manager. Le moniteur écoute sur le réseau public. Les valeurs par défaut des pools sont fixées : 3 copies, 2 au minimum.
Étape 3 — Monitors et Managers sur les deux autres nœuds
Le Monitor tient la carte du cluster Ceph ; il en faut une majorité pour que Ceph fonctionne. Le Manager collecte les statistiques ; un seul est actif, les autres attendent.
Sur pxe2<N>2 : Ceph → Monitor → section Monitor → Create → Create. Puis section Manager → Create → Create. Même chose sur pxe2<N>3.
(pxe212). Deux moniteurs, running, Quorum : Yes, à l'écoute sur le port 6789 du réseau public.
Un seul manager pour l'instant, celui créé par l'assistant. La page a deux boutons Create : le premier pour les moniteurs, le second pour les managers.
Dans le Shell de chacun des deux autres nœuds (pxe2<N>2, puis pxe2<N>3) :
# Équivalent CLI, sur chaque nœud qui n'en a pas encore
pveceph mon create
pveceph mgr create # un manager
ceph -s # état du cluster Ceph
Résultat attendu, une fois les trois nœuds faits :
health: HEALTH_WARN
OSD count 0 < osd_pool_default_size 3
services:
mon: 3 daemons, quorum pxe211,pxe212,pxe213 (age 11s) [leader: pxe211]
mgr: pxe211(active, since 34s), standbys: pxe212, pxe213
osd: 0 osds: 0 up, 0 in
Ce HEALTH_WARN est attendu : les pools veulent 3 copies, et il n'y a encore aucun disque.
Étape 4 — Un OSD par nœud
L'OSD est le démon qui gère un disque. Sur chaque nœud : Ceph → OSD → Create: OSD.
(pxe211). La liste ne propose que les disques libres. Sur ce nœud, sdc et sdd portent le pool ZFS du chapitre 3 : seul /dev/sdb reste.
Sa taille, 75.16 GB, correspond aux 70 Gio du disque, exprimés en Go. DB Disk : use OSD disk — tout sur le même disque, ce qui suffit au lab. → Create.
La liste des OSD ne se rafraîchit pas seule : cliquez Reload après la création.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI, sur chaque nœud
pveceph osd create /dev/sdb
Résultat attendu (pxe212, fin) :
Running command: /bin/systemctl start ceph-osd@1
--> ceph-volume lvm activate successful for osd ID: 1
--> ceph-volume lvm create successful for: /dev/sdb
Un OSD par nœud, osd.0 à osd.2, tous up / in, type bluestore, 70 Gio chacun. La classe ssd vient du disque virtuel, que Ceph détecte comme non rotatif.
Étape 4 bis — Si pveceph osd create refuse le disque
Ceph exige un disque totalement vierge. La moindre signature — table de partition, LVM, ZFS, ancien OSD — fait échouer la création.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Le disque destiné à Ceph porte-t-il encore une signature ?
lsblk /dev/sdb
wipefs /dev/sdb # signatures présentes sur le disque
Résultat attendu, disque vierge : lsblk ne montre que la ligne sdb 8:16 0 70G 0 disk, sans partition dessous, et wipefs n'affiche rien.
Si wipefs affiche des lignes, deux cas.
Cas A — un pool ZFS occupe le disque. Cela arrive si le pool du chapitre 3 a été monté sur sdb au lieu de sdc et sdd. On le démonte dans cet ordre :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# 1. Retirer le stockage côté Proxmox
pvesm remove zfs-vms
# 2. Détruire le pool — les données qu'il contient sont perdues
zpool destroy datapool
# 3. Vérifier
zpool list
Vérifiez d'abord que ce pool ne contient plus rien d'utile : zfs list et pvesm status disent ce qui y vit encore. Un disque de VM hébergé dessus serait perdu avec le pool. Déplacez-le d'abord avec Move Storage.
Cas B — le disque porte de vieilles signatures, d'une session précédente ou d'un autre usage :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
wipefs -a /dev/sdb # effacer les signatures du disque
wipefs /dev/sdb # vérifier : plus aucune signature
lsblk /dev/sdb # le disque est libre
Relisez le nom du disque avant de valider wipefs -a. La commande efface sans confirmation ni retour possible. Si /dev/sda apparaît dans votre ligne, arrêtez-vous : c'est le système Proxmox.
Reprenez ensuite l'étape 4.
Étape 5 — Vérifier l'état de Ceph
Sur un nœud : Ceph (la page d'accueil du panneau).
HEALTH_OK, No Warnings/Errors, version 20.2.4. Trois OSD Up et In. Tous les PG active+clean.
Trois moniteurs et trois managers, cochés. L'infobulle d'un manager montre son adresse : le réseau public.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
ceph -s # état du cluster Ceph
ceph osd tree # les OSD, par nœud
Résultat attendu :
cluster:
id: e21ecf15-c9ac-4c0f-8621-bf4281df1e24
health: HEALTH_OK
services:
mon: 3 daemons, quorum pxe211,pxe212,pxe213 (age 44s) [leader: pxe211]
mgr: pxe211(active, since 67s), standbys: pxe212, pxe213
osd: 3 osds: 3 up (since 17s), 3 in (since 22s)
data:
pools: 1 pools, 1 pgs
objects: 2 objects, 577 KiB
usage: 81 MiB used, 210 GiB / 210 GiB avail
pgs: 1 active+clean
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.20517 root default
-3 0.06839 host pxe211
0 ssd 0.06839 osd.0 up 1.00000 1.00000
-5 0.06839 host pxe212
1 ssd 0.06839 osd.1 up 1.00000 1.00000
-7 0.06839 host pxe213
2 ssd 0.06839 osd.2 up 1.00000 1.00000
Le pool déjà présent (1 pools) s'appelle .mgr : le manager le crée pour ses propres données. 210 GiB : l'espace brut des trois disques, avant réplication.
Un HEALTH_WARN passager est normal pendant les premières minutes : moniteurs qui se synchronisent, OSD qui démarrent. ceph health detail en donne la raison exacte.
S'il persiste au-delà de cinq minutes, lisez-la avant d'aller plus loin. C'est souvent une horloge décalée entre nœuds (clock skew detected), que corrige la synchronisation NTP.
Étape 6 — Créer un pool Ceph pour les VM
Les écrans Ceph sont sous le nœud, pas sous le Datacenter. Sélectionnez un serveur, puis Ceph : vous y trouvez Configuration, Monitor, OSD, CephFS, Pools et Log. Un pool créé depuis un nœud existe pour les trois.
Sur pxe2<N>1 : Ceph → Pools → Create.
Name ceph-vm. Size 3 : trois copies. PG Autoscaler Mode on : Ceph ajuste seul le découpage du pool.
Add as Storage coché : le pool devient aussitôt un stockage Proxmox. **Min.
Size n'apparaît qu'en cochant Advanced ; il vaut 2. Derrière, le pool .mgr existe déjà. → Create**.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI : pool répliqué, déclaré aussitôt comme stockage
pveceph pool create ceph-vm --pg_autoscale_mode on --add_storages 1
pvesm status | grep ceph-vm # le stockage ceph-vm est-il actif ?
ceph osd pool ls detail | grep ceph-vm # taille, taille minimale et règle du pool
Résultat attendu :
ceph-vm rbd active 69698728 0 69698728 0.00%
pool 2 'ceph-vm' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 128 pgp_num 128 autoscale_mode on ...
Environ 66 Gio utiles pour 210 Gio bruts : un tiers, puisque chaque donnée existe en trois exemplaires. Le pool part avec pg_num 128.
Relisez la même ligne quelques minutes plus tard : sur le lab, elle portait pg_num 100 pgp_num 100 pg_num_target 32. L'autoscaler a jugé 128 trop pour un pool presque vide, et réduit pas à pas vers 32 (ceph osd pool autoscale-status, colonne PG_NUM).
Étape 7 — Désigner le réseau de migration
Par défaut, une migration passe par le réseau d'administration : c'est ce qu'a montré l'atelier 2. On lui donne ens22.
Datacenter → Options → double-clic sur Migration Settings → Network : choisir l'adresse de ens22 → OK.
Type : secure — la mémoire voyage chiffrée dans un tunnel SSH. Network : la liste propose les adresses du nœud ; on prend celle de ens22. Le réglage vaut pour tout le cluster : chaque nœud utilisera son adresse dans ce réseau.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Le réglage, tel qu'enregistré pour tout le cluster
grep migration /etc/pve/datacenter.cfg
Résultat attendu : migration: network=10.59.41.11/24,type=secure (lab 10.59 : chez vous, 10.<site>.<N+40>.11/24).
Étape 8 — Migration à chaud via Ceph
1. Une VM sur Ceph. Clonez le template 100 du chapitre 2 directement sur le pool.
Template 100 → clic droit → Clone : VM ID 300, Name vm-ha-test, Mode Full Clone, Target Storage ceph-vm → Clone. Puis VM 300 → Cloud-Init : IP 10.<site>.<N>.85/24, Gateway 10.<site>.<N>.1 → Regenerate Image → Start.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Clone complet du template, son disque posé sur le pool Ceph
qm clone 100 300 --name vm-ha-test --full --storage ceph-vm
qm set 300 --ipconfig0 ip=10.<site>.<N>.85/24,gw=10.<site>.<N>.1 # son adresse fixe
qm start 300 # la démarrer
Résultat attendu : transferred 20.0 GiB of 20.0 GiB (100.00%) en une dizaine de secondes (9,6 s sur le lab), puis scsi0: ceph-vm:vm-300-disk-0 dans qm config 300.
2. L'agent invité.
Le template vient de l'image cloud Debian, qui n'a pas l'agent QEMU : qm agent 300 ping répond QEMU guest agent is not running. Installez-le comme au chapitre 2, depuis le Shell du nœud :
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Dans la VM, par SSH avec l'utilisateur cloud-init du template
ssh devops@10.<site>.<N>.85 # puis, dans la VM :
sudo apt-get update # la liste des paquets
sudo apt-get install -y qemu-guest-agent # l'agent invité
sudo systemctl start qemu-guest-agent # le lancer
exit # retour au nœud
qm agent 300 ping # l'agent répond-il ?
echo "code : $?" # 0 : oui
Résultat attendu : code : 0. L'atelier 6 en a besoin.
3. La migration. Depuis un autre nœud, lancez un ping continu vers la VM : il mesurera la coupure.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Sur pxe2<N>3 : 300 pings, un toutes les 0,2 s
ping -i 0.2 -c 300 10.<site>.<N>.85
Puis VM 300 → Migrate.
Mode : Online : la VM tourne, la migration sera à chaud. Il n'y a rien à cocher pour cela. Aucun avertissement de disque local : le disque est sur Ceph.
Conntrack state transporte l'état des connexions suivies par le pare-feu. Target node pxe2<N>2 → Migrate.
La première ligne confirme le réseau : use dedicated network address for sending migration traffic. Puis la VM démarre sur la cible, la mémoire est copiée, et la bascule ne dure que quelques dizaines de millisecondes (42 ms sur cette capture).
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI
qm migrate 300 pxe2<N>2 --online
Résultat attendu (réseau de migration 10.59.41.x) :
use dedicated network address for sending migration traffic (10.59.41.12)
starting migration of VM 300 to node 'pxe212' (10.59.41.12)
starting VM 300 on remote node 'pxe212'
migration downtime limit: 100 ms
average migration speed: 2.0 GiB/s - downtime 16 ms
migration completed, transferred 552.6 MiB VM-state
migration finished successfully (duration 00:00:06)
Comparez avec l'atelier 2 : aucun disque copié, seulement 553 Mio de mémoire, par le réseau de migration. Côté ping :
300 packets transmitted, 299 received, 0.333333% packet loss, time 61926ms
Un paquet perdu sur 300 : 0,2 seconde de silence, au pire.
L'uptime affiché par Proxmox repart de zéro, et ce n'est pas un redémarrage. Il compte la vie du processus QEMU. Or la VM tourne désormais dans un nouveau processus, sur la cible.
Sur le lab : uptime: 42 avant, uptime: 8 après. Pour prouver que le système n'a pas redémarré, demandez-le à la VM : ssh devops@10.<site>.<N>.85 uptime -s. Sur le lab, elle répondait 2026-10-07 12:06:19 avant, et 2026-10-07 12:06:20 après (heure UTC) : la même date de démarrage, à l'arrondi près.
Validation finale
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Ceph sain, stockage actif, VM 300 en marche sur pxe2<N>2
ceph health # la santé de Ceph
pvesm status | grep ceph-vm # le stockage ceph-vm est actif
pvesh get /nodes/pxe2<N>2/qemu/300/status/current --output-format json-pretty | grep '"status"' # la VM 300 tourne-t-elle sur le nœud 2 ?
ssh devops@10.<site>.<N>.85 uptime -s # depuis quand la VM tourne
Résultat attendu : HEALTH_OK ; ceph-vm rbd active ; "status" : "running" ; une date de démarrage antérieure à la migration.
Atelier 6 — Haute disponibilité
Contexte
La migration à chaud protège d'une maintenance planifiée. La haute disponibilité (HA) protège d'une panne subie.
Une VM déclarée ressource HA redémarre seule sur un autre nœud si le sien tombe. C'est possible parce que son disque est sur Ceph, donc accessible depuis les autres nœuds.
Résultat à obtenir : la VM 300 déclarée ressource HA, puis son redémarrage automatique sur un autre nœud après une panne brutale du sien. Ensuite, une mise en maintenance chronométrée du nœud 1, puis le retour.
La panne de l'étape 2, telle qu'elle s'est déroulée sur le lab. La barre montre à quoi sert chaque période ; la plus longue est une attente volontaire. Cliquez sur un jalon pour lire la ligne de journal correspondante.
Le scénario de l'atelier : le nœud qui porte la VM 300 est coupé. Les deux autres gardent le quorum (2 voix sur 3) et la VM est relancée sur l'un d'eux.
C'est possible parce que son disque est dans Ceph, lisible depuis les trois nœuds. Survolez un élément pour lire le résultat du lab.
Arborescence attendue
VM 300 « vm-ha-test » → ressource HA (état souhaité : started)
Panne brutale du nœud qui l'héberge
├── Corosync : 2 voix sur 3, le quorum tient
├── le nœud est déclaré mort, puis isolé (fence)
└── la VM redémarre sur un nœud survivant ← environ 4 min sur le lab
Ce que vous devez faire
- Déclarer la VM 300 en ressource HA, état souhaité
started. - Simuler une panne brutale du nœud qui l'héberge, et chronométrer : quand le nœud est-il déclaré mort, quand la VM redémarre-t-elle ?
- Comprendre le délai : pourquoi le cluster attend-il avant de relancer la VM ?
- Mettre le nœud 1 en maintenance, chronométrer la bascule et la coupure du ping, puis le sortir de maintenance et observer le retour.
💡 La HA n'est pas une migration sans coupure : la VM redémarre ailleurs. Il y a une interruption de quelques minutes. C'est le prix d'une panne que personne n'a prévue.
Cliquez pour vous aider
Étape 1 — Déclarer la VM 300 en ressource HA
Datacenter → HA → section Resources → Add.
VM 300 : la liste propose toutes les VM et tous les conteneurs du cluster, avec leur nœud. Max. Restart 3 : trois redémarrages sur place avant d'abandonner (1 par défaut).
Max. Relocate 1 : un déplacement vers un autre nœud. Request State started.
Failback et Auto-Rebalance sont cochés d'office ; ils n'agissent qu'avec des règles d'affinité. En haut, Arm HA / Disarm HA permet de suspendre toute la HA pendant une maintenance. → Add.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Équivalent CLI
ha-manager add vm:300 --state started --max_restart 3 --max_relocate 1
ha-manager status # état de la HA
Résultat attendu :
quorum OK
master pxe212 (active, Wed Oct 7 14:13:21 2026)
fencing armed (CRM watchdog active)
lrm pxe211 (idle, watchdog standby, Wed Oct 7 14:13:24 2026)
lrm pxe212 (active, watchdog active, Wed Oct 7 14:13:21 2026)
lrm pxe213 (idle, watchdog standby, Wed Oct 7 14:13:24 2026)
service vm:300 (pxe212, started)
Lisez les lignes. Le master décide pour tout le cluster. Chaque nœud a un lrm qui exécute ses décisions.
Le lrm du nœud qui porte une ressource passe active, et son chien de garde (watchdog) s'arme : si ce nœud perd le cluster, le chien de garde le redémarre. Sur le lab, le master était lui aussi sur pxe212.
Étape 2 — Panne brutale du nœud de la VM
Moment clé de l'atelier. Lisez l'étape en entier avant d'agir. Le nœud que vous allez couper ne se rallumera pas seul : c'est le formateur qui le relancera, depuis l'hôte qui l'héberge.
Repérez le nœud de la VM 300 : celui de la ligne service vm:300 (…, started). Sur le lab, pxe212, où l'atelier 5 l'avait migrée.
Gardez Datacenter → HA ouvert sur un autre nœud. Puis, dans le Shell du nœud de la VM :
Dans le Shell du nœud qui porte la VM 300 :
# Coupure immédiate, sans arrêt propre : l'équivalent d'une panne de courant
echo o > /proc/sysrq-trigger
Pourquoi pas poweroff ? Un arrêt propre est une maintenance : le gestionnaire HA en est prévenu, et il applique sa politique d'arrêt (shutdown_policy).
On ne verrait pas la reprise sur panne. La coupure par sysrq ne prévient personne.
(3 minutes après la panne). pxe212 porte une croix rouge dans l'arbre. Son lrm affiche old timestamp - dead?.
Le master est passé sur pxe213. La ressource vm:300 est en fence : le cluster s'assure que pxe212 ne fait plus tourner la VM.
vm:300 started sur pxe213. En bas, la tâche VM 300 - Start sur pxe213, lancée par la HA, sans personne.
Chronologie sur le lab (panne à 14:13:35, ha-manager status toutes les 5 secondes depuis pxe213, ping toutes les secondes) :
| Heure | Délai | Ce qui se passe |
|---|---|---|
| 14:13:43 | +8 s | Total votes: 2 — le quorum tient (2 voix sur 3) |
| 14:14:06 | +31 s | lrm pxe212 (old timestamp - dead?…), et le master aussi : il était sur pxe212 |
| 14:15:35 | +2 min 00 | pxe213 devient master |
| 14:16:37 | +3 min 02 | service vm:300 (pxe212, fence) |
| 14:16:43 | +3 min 08 | fencing: acknowledged → recovery → service vm:300 (pxe213, starting) |
| 14:17:05 | +3 min 30 | service vm:300 (pxe213, started) |
| 14:17:33 | +3 min 58 | la VM répond de nouveau au ping |
Le journal du nouveau master détaille la fin de la séquence :
Dans le Shell du nœud devenu maître HA (celui qu'indique ha-manager status) :
# Sur le nouveau master
journalctl -u pve-ha-crm --since "-10min" --no-pager -n 12 # les 12 dernières lignes
Résultat attendu (pxe213, extrait) :
successfully acquired lock 'ha_manager_lock'
status change slave => master
node 'pxe212': state changed from 'online' => 'unknown'
service 'vm:300': state changed from 'started' to 'fence'
node 'pxe212': state changed from 'unknown' => 'fence'
successfully acquired lock 'ha_agent_pxe212_lock'
fencing: acknowledged - got agent lock for node 'pxe212'
node 'pxe212': state changed from 'fence' => 'unknown'
service 'vm:300': state changed from 'fence' to 'recovery'
recover service 'vm:300' from fenced node 'pxe212' to node 'pxe213'
service 'vm:300': state changed from 'recovery' to 'started' (node = pxe213)
Pourquoi attendre ? Le nœud perdu est peut-être seulement coupé du réseau, VM toujours en marche.
Relancer la VM ailleurs tout de suite, ce serait deux exemplaires qui écrivent sur le même disque Ceph. Le cluster attend donc que le verrou du nœud perdu expire : à ce moment-là, son chien de garde l'a forcément redémarré.
got agent lock signifie exactement cela. Ici, l'attente a été plus longue d'une minute, parce que le master était sur le nœud mort : il a d'abord fallu en élire un nouveau.
La VM, elle, a redémarré : ssh devops@10.<site>.<N>.85 uptime -s répondait 2026-10-07 12:17:04 (UTC, soit 14:17:04 à Paris), l'heure de la reprise. Comparez avec l'atelier 5, où la migration à chaud gardait la VM en vie.
Le retour du nœud. Le formateur rallume la VM qui porte pxe212.
Sur le lab, le cluster avait retrouvé ses 3 voix moins d'une minute après, et Ceph son HEALTH_OK dans la foulée (3 OSD up). La VM 300 reste sur pxe213 : sans règle d'affinité, Failback n'a pas de nœud préféré où la ramener.
Étape 3 — Mettre le nœud 1 en maintenance, et chronométrer
On vide le nœud 1 pour une intervention. Avant : un ping continu vers la VM 300, depuis le Shell du nœud 2, pour mesurer la coupure.
Dans le Shell du nœud 2 :
ping -D -i 0.5 10.<site>.<N>.85 # ping horodaté toutes les 0,5 s
Dans le Shell du nœud 1 :
date +%T # l'heure
ha-manager crm-command node-maintenance enable pxe2<N>1 # puis le nœud 1 en maintenance
watch -n 2 "ha-manager status | grep -E 'lrm|service'" # suivre les LRM et les services toutes les 2 s
Quand la VM 300 est started ailleurs, quittez watch (Ctrl+C) et relisez le journal.
Dans le Shell du nœud 1 :
journalctl -u pve-ha-crm -u pve-ha-lrm --since "-5min" # le journal HA des 5 dernières minutes ; à lire : maintenance, vm:300, watchdog
Résultat attendu (les lignes qui comptent) :
14:24:20 (commande envoyée)
14:24:28 pve-ha-lrm: status change active => maintenance
14:24:33 pve-ha-crm: node 'pxe211': state changed from 'online' => 'maintenance'
14:24:33 pve-ha-crm: migrate service 'vm:300' to node 'pxe213' (running)
14:24:43 pve-ha-crm: service 'vm:300': state changed from 'migrate' to 'started' (node = pxe213)
14:24:44 pve-ha-lrm: watchdog closed (disabled)
| Mesure | Sur le lab |
|---|---|
| Commande → VM 300 démarrée ailleurs | 23 s |
Commande → watchdog closed (disabled) sur le nœud 1 |
24 s |
| Coupure du ping | une réponse manquée, environ 1 s |
Deux constats. La maintenance migre à chaud (running) : la VM ne redémarre pas, contrairement à la panne de l'étape 2.
watchdog closed (disabled) signale que le nœud 1 n'a plus rien à protéger : on peut l'arrêter.
Étape 4 — Sortir de maintenance : le retour
Dans le Shell du nœud 1 :
date +%T # l'heure
ha-manager crm-command node-maintenance disable pxe2<N>1 # puis sortie de maintenance
watch -n 2 "ha-manager status | grep service" # suivre les services toutes les 2 s
Résultat attendu :
14:25:14 (commande envoyée)
14:25:24 pve-ha-lrm: status change maintenance => active
14:25:33 pve-ha-crm: node 'pxe211': state changed from 'maintenance' => 'online'
14:25:33 pve-ha-crm: moving service 'vm:300' back to 'pxe211', node came back from maintenance.
14:25:53 pve-ha-crm: service 'vm:300': state changed from 'migrate' to 'started' (node = pxe211)
La VM 300 est revenue sur le nœud 1, en 39 s, de nouveau à chaud : une réponse au ping manquée, comme à l'aller. C'est le comportement annoncé par la documentation. Le ping lancé sur le nœud 2 s'arrête par Ctrl+C : sur le lab, 240 packets transmitted, 238 received sur l'ensemble, les deux réponses manquées étant les deux bascules.
Validation finale
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Où tourne la VM 300, et le cluster a-t-il gardé son quorum ?
ha-manager status | grep vm:300
pvecm status | grep Quorate # le cluster a-t-il gardé son quorum ?
Résultat attendu : service vm:300 (pxe2<N>1, started), puis Quorate: Yes.
Dépannage — Erreurs fréquentes
Create Cluster reste grisé, champ du nom en rouge. Nom de cluster de plus de 15 caractères. Remède : Un nom court : cluster-tp (atelier 1).
Le cluster dialogue par vmbr0. Link 0 laissé à sa valeur proposée. Remède : Choisir l'adresse de vmbr1 dans la liste du Link 0 (atelier 1).
pvecm add échoue EOF while reading password. Commande interactive lancée sans terminal. Remède : echo 'motdepasse' | pvecm add … --fingerprint "$FP".
Un nœud affiche Nodes: 1, Config Version: 1, Expected votes: 1, et pvecm add répond authentication key '/etc/corosync/authkey' already exists. Create Cluster cliqué sur ce nœud au lieu de Join Cluster : il a fondé son propre cluster. Remède : Le séparer sans le réinstaller, puis le joindre de nouveau (cours, §2.5).
apt failed during ceph installation (256), précédé de Abort.. Apt n'a pas eu de réponse à [Y/n]. Remède : yes | pveceph install --version tentacle --repository no-subscription.
apt failed during ceph installation, précédé d'une erreur 401. Dépôt Ceph enterprise sans abonnement. Remède : pveceph install --version tentacle --repository no-subscription.
Migration refusée « Cannot migrate VM with local CD/DVD ». ISO locale restée dans le lecteur. Remède : Détacher l'ISO : qm set <vmid> --ide2 none,media=cdrom.
La VM HA ne bascule pas après un poweroff. Arrêt propre traité comme une maintenance. Remède : Simuler la panne par echo o > /proc/sysrq-trigger.
HEALTH_WARN … POOL_TOO_MANY_PGS. Pool créé en ligne de commande, autoscaler en warn. Remède : pveceph pool set <pool> --pg_autoscale_mode on.
HEALTH_WARN avec le seul message noout flag(s) set. Le drapeau noout, posé pour une maintenance, est resté. Remède : ceph osd unset noout : HEALTH_OK une vingtaine de secondes plus tard.
systemctl start ceph-osd@0 échoue ; le journal dit OSD data directory /var/lib/ceph/osd/ceph-0 does not exist; bailing out. Cet OSD n'est pas sur ce nœud : les numéros suivent l'ordre de création des OSD, pas celui des nœuds. Le stop précédent n'a donc rien arrêté.
Remède : ceph osd tree : prendre le numéro affiché sous host <ce nœud>. Effacer l'échec avec systemctl reset-failed ceph-osd@0.
Start request repeated too quickly sur un service. Systemd bloque un service après plusieurs échecs rapprochés. Remède : Corriger la cause, puis systemctl reset-failed <service> avant de relancer.
Récapitulatif des commandes essentielles
| Situation | Commande |
|---|---|
| Créer / rejoindre un cluster | pvecm create <nom> --link0 <ip-vmbr1> --link1 <ip-vmbr0> / pvecm add <ip-fondateur> --link0 address=<ip-vmbr1-local> |
| État du cluster / des liens | pvecm status / corosync-cfgtool -s |
| Sortir un nœud du cluster | sur le nœud : systemctl stop pve-cluster corosync, pmxcfs -l, effacer /etc/pve/corosync.conf et /etc/corosync/*, killall pmxcfs, systemctl start pve-cluster ; sur un autre nœud : pvecm delnode <nœud> (cours, §2.5) |
| Migrer une VM (froid / chaud) | qm migrate <vmid> <nœud> / qm migrate <vmid> <nœud> --online |
| Installer / initialiser Ceph | yes | pveceph install --version tentacle --repository no-subscription / pveceph init --network … --cluster-network … |
| Créer MON / MGR / OSD | pveceph mon create / pveceph mgr create / pveceph osd create /dev/sdX |
| État Ceph | ceph -s / ceph osd tree / ceph df |
| Ajouter une ressource HA | ha-manager add vm:<vmid> --state started |
Proxmox VE — TSSR



































