Tout administrateur Linux a une cicatrice due à une « simple mise à jour de routine ». Le noyau est monté d’un cran, l’initramfs reconstruit, redémarrage planifié.
Puis la machine revient… seulement dans l’imaginaire. En réalité elle reste coincée dans un shell initramfs, ou elle boucle au démarrage, ou elle fonctionne
mais sans les noms de NIC, les modules GPU ou les pilotes de stockage. Pendant ce temps, vous expliquez à une personne non technique pourquoi « nous enquêtons » veut dire « je fixe un écran noir à 2 h du matin ».
Les environnements de démarrage ZFS sont la réponse mature à cette douleur. Ce n’est pas spectaculaire. Ce n’est pas « cloud-native ».
C’est brutalement pragmatique : créez une copie bootable de votre système racine, mettez à jour celle-ci, et si ça tourne mal,
sélectionnez l’environnement précédent au démarrage et poursuivez. Les utilisateurs Linux l’ignorent parce que les distributions grand public ne le promeuvent pas,
et parce que l’expression « environnement de démarrage » sonne comme quelque chose dont parlent les gens de Solaris dans des conférences auxquelles vous n’assistez pas.
Ce qu’est un environnement de démarrage (et ce que ce n’est pas)
Un environnement de démarrage ZFS (BE) est une version distincte et bootable de votre système de fichiers racine, généralement implémentée comme un clone ZFS
(ou un ensemble de datasets clonés ensemble) plus une entrée de bootloader qui y pointe. Vous pouvez conserver plusieurs environnements : « current »,
« before-upgrade », « post-upgrade », « testing », « oh-no », etc. Chaque environnement est peu coûteux car il partage des blocs avec son origine
via copy-on-write. Vous ne payez que pour les changements.
Ce que ce n’est pas : une image disque complète que vous dd ; un snapshot de VM ; une sauvegarde ; un remplacement de la gestion de configuration.
Les environnements de démarrage sont un filet de sécurité pour le changement système : mises à jour, basculement de noyau, installation de pilotes, mouvements de libc,
refontes majeures de configuration. Ils vous permettent d’échouer vite et de revenir en arrière plus vite encore.
La propriété clé est la suivante : le rollback est un choix de démarrage. Pas une procédure de récupération. Pas un boot sur ISO, chroot, prière.
Si vous pouvez encore accéder au menu de démarrage, vous pouvez généralement revenir à un système fonctionnel.
Pourquoi les utilisateurs Linux continuent de jouer à la loterie lors des mises à jour
La culture Linux a historiquement traité la réinstallation comme un rite de passage et la récupération comme une compétence. Sur les serveurs, on atténue
avec des canaris, blue/green, verrouillage de paquets et snapshots dans les hyperviseurs. Sur les postes de travail, on croise les doigts et on garde « une clé USB bootable quelque part ».
Aucun de ces moyens n’est aussi direct que : « choisissez le système racine d’hier et démarrez dessus ».
Il existe des raisons pratiques pour lesquelles les gens évitent les BE sur Linux :
- Le support des distributions est inégal. Certains environnements le rendent fluide (par ex., ZFS-on-root d’Ubuntu avec ZSys autrefois ; divers outils communautaires maintenant),
d’autres sont bricolés avec des scripts. - Les bootloaders sont pointilleux. GRUB + ZFS fonctionne, mais il faut comprendre comment il trouve les datasets. systemd-boot est propre mais attend une
partition EFI avec des noyaux visibles ; cela change l’histoire des BE. - On confond snapshots et environnements de démarrage. Un snapshot est excellent ; un snapshot dont on peut démarrer est meilleur.
- Root sur ZFS reste « avancé » dans l’écosystème Linux. Beaucoup d’organisations utilisent ZFS pour les données, pas pour /.
Aucun de ces points n’est rédhibitoire. Ce sont juste des raisons pour lesquelles vous devriez concevoir votre configuration intentionnellement plutôt que d’espérer que les réglages par défaut vous sauveront le jour du reboot.
Faits et histoire qui expliquent la conception
Un peu de contexte rend les choix de conception moins magiques et plus de l’ingénierie — ma préférence.
- Les environnements de démarrage ont été popularisés sur Solaris/Illumos. Le flux opérationnel — cloner la racine, mettre à jour le clone, redémarrer — était courant bien avant l’adoption par Linux.
- ZFS a été conçu en pensant aux workflows administratifs. Snapshots, clones, send/receive et propriétés sont natifs, pas des ajouts.
- GRUB a gagné une conscience ZFS plus tard et de manière inégale. Beaucoup d’équipes Linux ont évité root-on-ZFS simplement parce que les outils d’amorçage ont pris du retard.
- Copy-on-write signifie « copies bon marché », pas « copies gratuites ». Les BE partagent des blocs jusqu’à modification ; de grosses mises à jour peuvent quand même consommer de l’espace réel.
- Les propriétés des datasets sont le plan de contrôle. mountpoints, canmount, bootfs et propriétés d’encryption décident si un BE est bootable.
- OpenZFS est devenu un effort multiplateforme. Le même modèle conceptuel couvre illumos, FreeBSD, Linux — les outils d’amorçage diffèrent, mais la sémantique ZFS reste cohérente.
- initramfs Linux est devenu le gardien. Sur beaucoup de systèmes Linux, c’est initramfs (et non le seul noyau) qui doit importer le pool et monter le dataset correct.
- UEFI a changé la question du placement du noyau. Certains flux conservent les noyaux dans le dataset racine ; d’autres les placent sur une partition EFI séparée partagée par tous les BE.
Un modèle mental : datasets, snapshots, clones et bootloaders
Root-on-ZFS ressemble typiquement à un arbre de datasets
Une disposition sensée sépare ce qui change souvent de ce que vous pourriez vouloir partager entre environnements de démarrage. Vous voulez que la racine
OS soit clonable, tandis que certains datasets doivent rester persistants à travers les BE (répertoires home, conteneurs, images VM, données de base de données).
Schéma courant :
rpool/ROOT/<BE-name>monté sur/rpool/USERDATAmonté sur/home(partagé entre BE)rpool/varparfois découpé en plusieurs datasets, en réfléchissant aux logs, caches et états
Snapshots vs clones
Un snapshot est une image en lecture seule à un instant donné. Un clone est un dataset modifiable créé à partir d’un snapshot. La plupart des implémentations
de BE utilisent des clones parce qu’il faut une racine modifiable pour démarrer et fonctionner.
Le cycle de vie d’un BE est essentiellement :
- Créer un snapshot du dataset racine actuel.
- Cloner le snapshot sous un nouveau nom de dataset.
- Faire en sorte que ce dataset puisse être monté comme
/(définir des propriétés). - Assurer que le bootloader/initramfs peut le trouver.
- Mettre à jour à l’intérieur du nouvel environnement.
- Redémarrer et le sélectionner.
- Conserver l’ancien jusqu’à ce que vous soyez confiant. Puis le détruire pour récupérer de l’espace.
Réalité du bootloader : il vous faut un pointeur vers « quelle racine »
Il y a trois approches courantes :
- GRUB lit ZFS et charge noyau/initrd depuis ZFS. Ensuite la ligne de commande du noyau pointe vers un dataset (ou la logique initramfs le sélectionne).
- GRUB charge noyau/initrd depuis un /boot séparé (ext4). La racine reste ZFS ; la sélection du BE dépend de la manière dont les entrées /boot correspondent aux datasets.
- systemd-boot charge les EFI stub kernels depuis la partition EFI. Cela signifie souvent que vos images noyau ne sont pas dans le BE, donc les BE doivent être gérés pour garder noyau+initramfs cohérents.
Vous n’êtes pas obligé d’aimer l’une ou l’autre. Il faut juste en choisir une et tester le rollback sous contrainte, pas seulement dans l’optimisme.
Une idée paraphrasée de Werner Vogels que les opérationnels respectent : tout échoue, prévoyez-le — puis automatisez la récupération pour que ce ne soit pas un acte héroïque
.
Tâches pratiques : commandes, sorties et décision
Ce sont les gestes quotidiens qui rendent les BE réels. Chaque tâche inclut : la commande, ce que signifie la sortie, et la décision à prendre.
Noms d’hôtes / noms de pool sont des exemples. Adaptez-les, mais n’improvisez pas les concepts.
Task 1: Confirm your root filesystem is ZFS (and which dataset)
cr0x@server:~$ findmnt -no SOURCE /
rpool/ROOT/ubuntu_1a2b3c
Sens : Votre racine système est un dataset ZFS nommé rpool/ROOT/ubuntu_1a2b3c.
Décision : Ce dataset (et tous les datasets enfants montés sous lui) est l’unité que vous devez snapshotter/cloner pour un BE.
Task 2: Inventory pools and basic health before you touch anything
cr0x@server:~$ sudo zpool status
pool: rpool
state: ONLINE
scan: scrub repaired 0B in 00:06:21 with 0 errors on Tue Dec 24 03:12:14 2025
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
nvme0n1p3 ONLINE 0 0 0
errors: No known data errors
Sens : Le pool est sain et a été scruté récemment.
Décision : Procédez. Si vous voyez des erreurs ou un vdev dégradé, corrigez cela d’abord ; déployer des BE sur un pool malade, c’est comme repeindre un bateau qui coule.
Task 3: Check free space so the “cheap copy” doesn’t become a disk-full outage
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint rpool
NAME USED AVAIL REFER MOUNTPOINT
rpool 64.1G 112G 96K /
Sens : Vous avez 112G disponibles, largement suffisant pour plusieurs BE.
Décision : Si avail est serré, détruisez d’abord d’anciens BE ou ajoutez de la capacité. Les mises à jour peuvent gonfler /usr, initramfs et caches rapidement.
Task 4: List the current root dataset properties that affect boot
cr0x@server:~$ sudo zfs get -o name,property,value -s local,received mountpoint,canmount,atime,compression rpool/ROOT/ubuntu_1a2b3c
NAME PROPERTY VALUE
rpool/ROOT/ubuntu_1a2b3c mountpoint /
rpool/ROOT/ubuntu_1a2b3c canmount noauto
rpool/ROOT/ubuntu_1a2b3c atime off
rpool/ROOT/ubuntu_1a2b3c compression zstd
Sens : Le dataset racine se monte sur /, mais canmount=noauto suggère qu’il est monté par une logique de boot spéciale (courant dans les setups BE).
Décision : Conservez ces propriétés lors du clonage ; mountpoint/canmount incohérents sont un piège classique « boot vers initramfs ».
Task 5: Create a snapshot of the current root dataset
cr0x@server:~$ sudo zfs snapshot rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52
Sens : Le snapshot existe instantanément ; c’est une vue cohérente à un instant donné (aussi cohérente que votre système en cours d’exécution le permet).
Décision : Vous avez maintenant une base sûre. Ensuite : clonez-la en un nouveau BE pour les changements.
Task 6: Verify the snapshot exists and see how much it “costs”
cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer | grep pre-upgrade
rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52 0B 32.4G
Sens : Le snapshot utilise 0B initialement car il référence des blocs existants ; il grossira à mesure que le dataset live change.
Décision : Le snapshot est sûr à conserver pendant que vous mettez à jour le clone. Si vous voyez un USED énorme immédiatement, vous avez probablement snapshoté un dataset avec beaucoup de churn ou des blocs supprimés retenus.
Task 7: Clone the snapshot into a new boot environment dataset
cr0x@server:~$ sudo zfs clone rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52 rpool/ROOT/ubuntu_1a2b3c-upg
Sens : Vous avez maintenant un dataset modifiable rpool/ROOT/ubuntu_1a2b3c-upg partageant des blocs avec l’original.
Décision : Définissez mountpoint/canmount correctement, et assurez-vous que le système de boot peut cibler ce dataset.
Task 8: Set properties on the new BE so it can mount as / when selected
cr0x@server:~$ sudo zfs set mountpoint=/ canmount=noauto rpool/ROOT/ubuntu_1a2b3c-upg
Sens : Le clone a le même comportement de montage que votre dataset racine existant.
Décision : Gardez un seul BE réellement monté en / au runtime. Si vous définissez accidentellement plusieurs datasets sur canmount=on avec mountpoint /, vous créerez un conflit au démarrage.
Task 9: Mount the new BE somewhere and chroot into it for the upgrade
cr0x@server:~$ sudo mkdir -p /mnt/be-upg
cr0x@server:~$ sudo mount -t zfs rpool/ROOT/ubuntu_1a2b3c-upg /mnt/be-upg
cr0x@server:~$ sudo mount --bind /dev /mnt/be-upg/dev
cr0x@server:~$ sudo mount --bind /proc /mnt/be-upg/proc
cr0x@server:~$ sudo mount --bind /sys /mnt/be-upg/sys
cr0x@server:~$ sudo chroot /mnt/be-upg /bin/bash
root@server:/# cat /etc/os-release | head -2
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
Sens : Vous opérez maintenant à l’intérieur du système racine du nouveau BE.
Décision : Effectuez les mises à jour ici, pas sur la racine en cours d’exécution, pour que le rollback reste propre.
Task 10: Run a controlled upgrade inside the new BE and confirm kernels/initramfs were built
cr0x@server:~$ sudo chroot /mnt/be-upg /bin/bash -lc "apt update && apt -y full-upgrade"
...output...
Setting up linux-image-6.8.0-45-generic ...
update-initramfs: Generating /boot/initrd.img-6.8.0-45-generic
Processing triggers for grub-pc ...
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-45-generic
Found initrd image: /boot/initrd.img-6.8.0-45-generic
done
Sens : L’environnement contient un noyau et un initramfs et la configuration de démarrage a été mise à jour.
Décision : Si vous ne voyez pas la génération d’initramfs ou les déclencheurs de mise à jour du bootloader, arrêtez-vous. Corrigez cela avant le reboot ; un BE sans artefacts de boot est une pièce de musée, pas un chemin de récupération.
Task 11: Confirm which dataset the pool will try to boot by default (bootfs)
cr0x@server:~$ sudo zpool get bootfs rpool
NAME PROPERTY VALUE SOURCE
rpool bootfs rpool/ROOT/ubuntu_1a2b3c local
Sens : Le bootfs du pool pointe vers le BE courant.
Décision : Si votre flux de boot respecte bootfs, définissez-le sur le nouveau BE avant de redémarrer. Si votre flux ignore bootfs et utilise des entrées GRUB, vous gérerez la sélection via le bootloader à la place.
Task 12: Switch default boot environment by changing bootfs (when applicable)
cr0x@server:~$ sudo zpool set bootfs=rpool/ROOT/ubuntu_1a2b3c-upg rpool
cr0x@server:~$ sudo zpool get bootfs rpool
NAME PROPERTY VALUE SOURCE
rpool bootfs rpool/ROOT/ubuntu_1a2b3c-upg local
Sens : Le pool préfère maintenant démarrer dans le BE mis à jour.
Décision : Redémarrez dans le nouveau BE. Conservez le BE précédent intact jusqu’à plusieurs démarrages réussis et que les services paraissent normaux.
Task 13: After reboot, verify you’re in the intended BE
cr0x@server:~$ findmnt -no SOURCE /
rpool/ROOT/ubuntu_1a2b3c-upg
Sens : Vous exécutez le système depuis le BE mis à jour.
Décision : Validez maintenant : réseau, stockage, agents, GPU, tout ce qui casse historiquement sur votre flotte.
Task 14: Compare BE space usage and decide what to prune
cr0x@server:~$ sudo zfs list -o name,used,refer,origin rpool/ROOT
NAME USED REFER ORIGIN
rpool/ROOT 128K 96K -
rpool/ROOT/ubuntu_1a2b3c 6.4G 32.4G -
rpool/ROOT/ubuntu_1a2b3c-upg 2.1G 33.0G rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52
Sens : Le BE mis à jour a divergé d’environ 2.1G de l’original ; le reste est partagé.
Décision : Gardez au moins un fallback connu bon. Supprimez les anciens BE une fois confiant et si vous avez besoin d’espace.
Task 15: Roll back by selecting the previous BE (pool bootfs method)
cr0x@server:~$ sudo zpool set bootfs=rpool/ROOT/ubuntu_1a2b3c rpool
cr0x@server:~$ sudo reboot
Sens : Au prochain démarrage, le pool préférera le dataset racine antérieur.
Décision : Utilisez ceci quand le nouveau BE est cassé mais que l’ancien démarre encore. Après rollback, diagnostiquez le BE défaillant depuis un environnement sûr.
Task 16: If you need to destroy a failed BE cleanly, do it in the right order
cr0x@server:~$ sudo zfs destroy rpool/ROOT/ubuntu_1a2b3c-upg
cr0x@server:~$ sudo zfs destroy rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52
Sens : Le clone doit être détruit avant son snapshot d’origine (ou vous obtiendrez une erreur de dépendance).
Décision : Ne « nettoyez » pas le snapshot tant qu’un clone BE en dépend. ZFS vous en empêchera, mais l’erreur survient souvent quand vous êtes déjà agacé.
Blague #1 : Les snapshots ZFS sont comme le café du bureau — tout le monde les adore jusqu’au moment où quelqu’un demande qui les supprime.
Feuille de diagnostic rapide
Les problèmes d’environnement de démarrage sont rarement mystérieux. Il s’agit généralement d’un petit décalage entre : ce que le bootloader pense être la racine,
ce que l’initramfs peut importer, et ce que les datasets ZFS sont configurés pour monter. L’astuce est de vérifier les bonnes choses dans le bon ordre.
First: can the pool import, and is it healthy?
Si le pool est dégradé, des appareils manquent ou l’import échoue dans l’initramfs, rien d’autre n’a d’importance.
cr0x@server:~$ sudo zpool import
pool: rpool
id: 16084073626775123456
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
rpool ONLINE
nvme0n1p3 ONLINE
Interprétation : Le pool est importable dans l’environnement courant.
Décision : Si cela échoue dans l’initramfs mais fonctionne dans l’OS en cours, vous avez probablement un initramfs sans modules ZFS, des IDs de périphériques manquants ou des problèmes de gestion de clés de chiffrement.
Second: what does the system think “/” is supposed to be?
Vérifiez le dataset racine actif et le pointeur bootfs du pool.
cr0x@server:~$ findmnt -no SOURCE /
rpool/ROOT/ubuntu_1a2b3c-upg
cr0x@server:~$ sudo zpool get bootfs rpool
NAME PROPERTY VALUE SOURCE
rpool bootfs rpool/ROOT/ubuntu_1a2b3c-upg local
Interprétation : Bootfs et la racine montée correspondent. Bien.
Décision : S’ils diffèrent, vous avez peut-être démarré un BE différent de celui que vous croyez (fréquent quand les entrées GRUB pointent ailleurs).
Third: are dataset mount properties consistent?
cr0x@server:~$ sudo zfs get -r -o name,property,value mountpoint,canmount rpool/ROOT
NAME PROPERTY VALUE
rpool/ROOT mountpoint none
rpool/ROOT canmount off
rpool/ROOT/ubuntu_1a2b3c mountpoint /
rpool/ROOT/ubuntu_1a2b3c canmount noauto
rpool/ROOT/ubuntu_1a2b3c-upg mountpoint /
rpool/ROOT/ubuntu_1a2b3c-upg canmount noauto
Interprétation : Plusieurs BE partagent mountpoint /, mais utilisent canmount=noauto, ce qui est normal pour le montage de type BE.
Décision : Si vous voyez canmount=on sur plus d’un dataset avec mountpoint /, corrigez-le avant de redémarrer.
Fourth: if boot fails, confirm initramfs can see ZFS and the pool
Depuis un shell initramfs (ou un environnement de secours), vérifiez la présence des modules et tentez l’import.
cr0x@server:~$ lsmod | grep zfs
zfs 4980736 5
zunicode 335872 1 zfs
znvpair 126976 2 zfs
zcommon 98304 1 zfs
icp 315392 1 zfs
spl 135168 5 zfs,icp
cr0x@server:~$ zpool import -N rpool
cr0x@server:~$ zfs list rpool/ROOT
NAME USED AVAIL REFER MOUNTPOINT
rpool/ROOT 128K 112G 96K none
Interprétation : Les modules ZFS sont chargés, le pool est importé sans monter les datasets.
Décision : Si les modules manquent, reconstruisez l’initramfs depuis un BE fonctionnel. Si l’import du pool échoue, recherchez le nommage des périphériques, des pilotes manquants ou le chiffrement.
Fifth: identify the real bottleneck quickly—bootloader, initramfs, or userspace?
Si vous atteignez le noyau et l’initramfs mais échouez avant l’espace utilisateur : c’est généralement « impossible de monter root » (sélection de dataset, import, clés).
Si vous atteignez l’espace utilisateur mais que des services échouent : c’est une régression normale de mise à jour ; le rollback reste votre allié, mais vous déboguerez comme pour tout problème de service.
Erreurs communes : symptôme → cause → correction
1) Symptom: boots to initramfs with “cannot import rpool”
Cause racine : initramfs sans modules ZFS ou sans hostid/cache correct pour l’import ; parfois une mise à jour du noyau n’a pas reconstruit correctement l’initramfs dans le nouveau BE.
Correction : Démarrez un BE connu bon, puis reconstruisez initramfs et mettez à jour le bootloader depuis le BE cible.
cr0x@server:~$ sudo chroot /mnt/be-upg /bin/bash -lc "update-initramfs -u -k all && update-grub"
...output...
update-initramfs: Generating /boot/initrd.img-6.8.0-45-generic
Generating grub configuration file ...
done
2) Symptom: system boots, but /home is empty or wrong
Cause racine : Vous avez cloné /home dans le BE alors que vous vouliez le partager, ou vous avez changé des mountpoints et maintenant le dataset persistant attendu n’est plus monté.
Correction : Séparez les datasets persistants des datasets BE. Assurez-vous que /etc/fstab ou les propriétés de montage ZFS montent le dataset partagé de manière cohérente.
cr0x@server:~$ sudo zfs list -o name,mountpoint | egrep 'USERDATA|home'
rpool/USERDATA /home
3) Symptom: GRUB shows only one entry; can’t choose older BE
Cause racine : La génération de config GRUB n’énumère pas les BE, ou les noyaux/initrds ne sont pas présents/cohérents pour chaque BE.
Correction : Adoptez une stratégie cohérente de placement des noyaux et un outil/workflow BE qui s’intègre à votre bootloader. Au minimum, régénérez GRUB depuis un BE ayant les bons scripts activés.
cr0x@server:~$ sudo grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
done
4) Symptom: “dataset is busy” when destroying an old BE
Cause racine : Vous tentez de détruire la racine actuellement montée, ou un processus a un mount à l’intérieur du BE monté ailleurs.
Correction : Vérifiez les montages et démontez le point de montage BE que vous avez utilisé pour des opérations chroot ; détruisez les clones avant les snapshots d’origine.
cr0x@server:~$ mount | grep be-upg
rpool/ROOT/ubuntu_1a2b3c-upg on /mnt/be-upg type zfs (rw,xattr,noacl)
cr0x@server:~$ sudo umount /mnt/be-upg
5) Symptom: rollback “works” but services behave inconsistently
Cause racine : Vous partagez de l’état mutable (comme /var/lib, images de conteneurs ou bases de données) entre BE sans vous en rendre compte. L’espace utilisateur ancien voit maintenant l’état nouveau.
Correction : Décidez délibérément ce qui est partagé entre BE. Soit gardez l’état dans des datasets dédiés en pensant à la compatibilité, soit snapshottez/clonnez l’état avec le BE pour des mises à jour risquées.
6) Symptom: upgraded BE consumes far more space than expected
Cause racine : Vous avez conservé un snapshot long-vivant qui retient beaucoup de blocs libérés ; ou vous avez mis à jour de gros paquets et caches, provoquant une divergence importante.
Correction : Émondez anciens snapshots/BE ; déplacez les caches vers des datasets séparés avec émondage agressif ; évitez de garder les snapshots « pré-upgrade » pendant des mois.
cr0x@server:~$ sudo zfs list -t snapshot -o name,used | sort -h | tail -5
rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52 9.8G
Blague #2 : Le moyen le plus rapide d’apprendre les bootloaders est d’en casser un un vendredi — soudainement vous aurez tout le week-end pour étudier.
Trois mini-récits d’entreprise depuis le terrain
Mini-story 1: The incident caused by a wrong assumption
Une entreprise de taille moyenne utilisait ZFS pour les « données », mais pas pour l’OS. Puis une équipe a construit une nouvelle passerelle analytique qui tournait root-on-ZFS,
parce que l’ingénieur aimait les snapshots et avait été brûlé par de mauvaises mises à jour auparavant. Elle a été déployée en production avec une hypothèse clé :
« Si GRUB peut lire ZFS, les rollbacks sont triviaux. »
La première grosse mise à jour du noyau a mal tourné. Pas catastrophiquement — juste assez. Le nouveau noyau a changé l’ordre d’un pilote au démarrage,
ce qui a fait varier le timing de découverte des périphériques. Le pool s’importait parfois, parfois non, selon la rapidité de montée du NVMe.
Ils ont essayé de « revenir en arrière » en sélectionnant l’ancienne entrée BE. La machine a atterri dans initramfs. Même symptôme. Même panique.
L’hypothèse erronée était que le BE était la seule pièce mobile. Ce n’était pas le cas. L’initramfs avait été construit dans le BE mis à jour et stocké
de façon partagée sur une partition /boot que tous les BE utilisaient. Quand ils ont démarré l’ancien BE, ils ont quand même chargé le nouvel initramfs.
Le rollback n’était donc pas un rollback ; c’était du cosplay.
La correction n’était pas compliquée, mais a exigé d’admettre l’architecture réelle. Ils ont changé le workflow pour que chaque BE ait ses artefacts noyau+initramfs
qui lui correspondent, et ils ont ajouté une vérification post-upgrade simple : « ce BE a-t-il le noyau/initramfs que nous pensons, et l’entrée de boot y pointe-t-elle ? »
Après cela, le rollback a fait ce qu’il promettait.
Mini-story 2: The optimization that backfired
Une autre organisation avait une flotte de postes développeurs avec root-on-ZFS et BE. L’équipe flotte a voulu accélérer les upgrades,
alors elle a modifié agressivement ZFS. Compression changée, recordsize ajusté, atime désactivé (OK) tout en expérimentant le comportement du cache
et le trimming. Le but : rendre les opérations d’upgrade et les compilations plus rapides.
Le retour de bâton n’a pas été immédiat. Il s’est manifesté lentement : des machines manquaient d’espace « aléatoirement », surtout après de grosses mises à jour.
On accusait les logs, les navigateurs et les systèmes de build. Le stockage paraissait hanté. Certaines machines avaient beaucoup d’espace un jour et plus le lendemain,
sans nouveaux fichiers évidents.
Le coupable était une politique, pas un bug. Ils gardaient beaucoup de BE et snapshots pour « sécurité », mais n’avaient pas budgété l’espace pour la divergence. Après les mises à jour,
d’anciens snapshots retenaient les blocs pré-upgrade. Les optimisations ont aggravé le churn car plus de contenu était réécrit pendant les upgrades, et
ils avaient aussi placé des caches dans des datasets qui faisaient involontairement partie de l’arbre BE.
La leçon : « tout garder pour toujours » n’est pas une stratégie de résilience ; c’est une panne longue. Ils ont mis en place une rétention :
garder les N derniers BE réussis, un « golden » mensuel, et supprimer les autres. Aussi, ils ont sorti les caches à fort churn de l’arbre BE.
La performance et la prévisibilité se sont améliorées.
Mini-story 3: The boring but correct practice that saved the day
Un service proche de la finance faisait tourner quelques machines Linux critiques sur root-on-ZFS. Rien de glamour : quelques services internes,
quelques bases de données, et les agents de monitoring habituels. Leur responsable SRE insistait sur une pratique ennuyeuse :
avant toute mise à jour, créer un nouveau BE ; après la mise à jour, exiger deux redémarrages propres et une checklist de services avant de supprimer l’ancien BE.
Un jour, une mise à jour a introduit une régression subtile dans un pilote réseau. Elle n’empêchait pas le boot. Elle ne plantait pas la machine.
Elle provoquait une perte de paquets intermittente sous charge, un bug qui fait douter tout le monde. Le monitoring était en dents de scie.
Les services étaient « majoritairement corrects », sauf quand ils ne l’étaient pas.
L’équipe n’a pas débogué en production. Ils sont revenus à l’ancien BE, ont stabilisé, puis ont reproduit le comportement sur le BE mis à jour en heures ouvrables.
Comme le BE mis à jour existait encore, ils ont pu démarrer dessus intentionnellement et tester, plutôt que d’essayer de ressusciter un état écrasé.
L’impact de la panne est resté faible, surtout parce que le rollback était une action routinière, pas un dernier recours. La règle ennuyeuse — deux redémarrages propres et une checklist —
a assuré qu’ils avaient un BE connu bon prêt lorsque la régression est apparue. Pas d’héroïsme. Pas d’archéologie nocturne dans /var/log.
Listes de contrôle / plan étape par étape
Plan A: Adopt boot environments for a single machine (workstation or one server)
- Vérifier root-on-ZFS et la disposition des datasets. Confirmez que
findmnt /montre un dataset sousrpool/ROOT. - Décider ce qui doit être partagé. Habituellement :
/home, éventuellement/var/libpour certains services, mais avec prudence. - Décider du mécanisme de sélection du boot.
bootfsdu pool, entrées GRUB, ou un outil BE intégré à votre distro. - Faire un essai à blanc sans changer de paquets. Créez snapshot, clonez, montez, chrootez dedans, puis sortez et détruisez-le.
- Effectuer une vraie mise à jour dans le clone. Les mises à jour du noyau sont le point essentiel ; incluez-les.
- Redémarrer et valider. Confirmez le dataset actif. Exécutez les vérifications de services.
- Pratiquer le rollback. N’attendez pas une panne pour découvrir que votre rollback est théorique.
- Définir une rétention. Gardez un petit nombre de BE ; supprimez les autres selon un calendrier.
Plan B: Operationalize it for a small fleet
- Standardiser les noms. Les humains liront ça à 3 h du matin. Utilisez des noms comme
prod-2025w52-kernel, pas « clone1 ». - Définir la politique des “datasets partagés”. Documentez quels mountpoints sont dans l’arbre BE et lesquels sont persistants.
- Automatiser création et nettoyage. Les BE sans rétention deviennent une fuite d’espace avec un badge.
- Faire du rollback une partie de la réponse aux incidents. Restaurez d’abord quand la disponibilité est en jeu ; déboguez ensuite dans un environnement contrôlé.
- Tester les mises à jour du bootloader. La dérive de flotte apparaît souvent ici : versions GRUB différentes, layouts EFI différents, comportements divergents.
- Surveiller l’espace du pool et le bloat des snapshots. Alertez sur la croissance de
zfs list -t snapshotused et sur l’espace libre faible.
Plan C: Recovery drill (when you already broke it)
- Au menu de démarrage, essayez de sélectionner le BE précédent (si disponible). Si ça marche, stabilisez et diagnostiquez depuis là.
- Si vous atterrissez dans initramfs, tentez
zpool import -Net listez les datasets aveczfs list. - Montez manuellement le dataset racine prévu en lecture seule pour inspecter logs et config.
- Démarrez un environnement de secours qui supporte ZFS si besoin, puis définissez
bootfssur le dataset connu bon et reconstruisez initramfs/GRUB.
FAQ
1) Are ZFS boot environments the same as ZFS snapshots?
Non. Un snapshot est une vue à un instant. Un environnement de démarrage est un système racine bootable, généralement un clone d’un snapshot plus l’intégration de boot.
Les snapshots sont des ingrédients ; les BE sont le repas.
2) Do boot environments replace backups?
Absolument pas. Les BE sont locales, sur le même pool, sujettes aux mêmes pannes matérielles. Elles servent au rollback de mise à jour, pas à la reprise après sinistre.
3) How many boot environments should I keep?
Gardez un petit nombre de BE connus bons : typiquement 2–5. Plus sans politique de rétention devient une fuite de stockage que vous découvrirez lors de la prochaine mise à jour.
4) What should be shared across boot environments?
Typiquement /home. Pour les serveurs, les données des services stateful devraient généralement vivre dans des datasets dédiés hors de l’arbre BE.
Partager /var en entier est tentant et souvent une erreur ; segmentez-le en connaissance de cause.
5) Can I use boot environments if my kernel and initramfs live on an EFI partition?
Oui, mais avec prudence : si tous les BE partagent les mêmes fichiers noyau/initramfs, votre rollback peut ne pas restaurer la chaîne de boot précoce.
Alignez vos artefacts de boot avec le BE ou acceptez que le rollback soit « uniquement userspace », ce qui est moins robuste.
6) What’s the minimum viable BE workflow on Linux?
Snapshotter la racine courante, la cloner, chrooter dans le clone pour mettre à jour, s’assurer que bootloader/initramfs correspondent, redémarrer dans le clone.
Conservez l’ancien dataset racine intact jusqu’à ce que le nouveau soit fiable.
7) What breaks boot environments most often?
Propriétés de montage incohérentes (mountpoint/canmount), entrées du bootloader pointant vers le mauvais dataset, et initramfs incapable d’importer le pool
(modules, hostid, clés de chiffrement, découverte des périphériques).
8) How do I know if snapshots are holding too much space?
Vérifiez les valeurs USED des snapshots. Si d’anciens snapshots ont grandi, ils épinglent des blocs anciens qui seraient autrement libérés.
cr0x@server:~$ sudo zfs list -t snapshot -o name,creation,used | sort -k3 -h | tail -10
rpool/ROOT/ubuntu_1a2b3c@pre-upgrade-2025w52 Tue Dec 24 10:01 9.8G
9) Is root-on-ZFS too risky for production?
Ce n’est pas « trop risqué ». C’est « vous devez traiter le boot précoce comme une partie du système ». Si vous ne pouvez pas tester les mises à jour bootloader/initramfs et pratiquer le rollback,
alors oui, c’est risqué — parce que vous l’avez rendu tel.
10) What’s the fastest “I’m down” rollback method?
Si votre menu de boot liste les BE, choisissez la dernière entrée connue bonne. Si votre configuration utilise bootfs, démarrez un environnement de secours et pointez bootfs vers le dataset précédent, puis redémarrez.
Prochaines étapes réalisables cette semaine
Si vous administrez des systèmes Linux et que vous faites des mises à jour, vous avez besoin d’une histoire de rollback qui n’implique pas une clé USB et des regrets. Les environnements
de démarrage ZFS sont cette histoire, à condition de respecter la chaîne de boot : propriétés de dataset, initramfs et entrées du bootloader doivent s’accorder sur ce que signifie « root ».
Faites ceci ensuite :
- Sur une machine, identifiez votre dataset racine et créez un clone BE avant la prochaine mise à jour.
- Pratiquez le rollback volontairement quand rien n’est en feu. Confirmez que vous pouvez démarrer dans les deux sens.
- Écrivez une règle de rétention et appliquez-la. L’espace n’est pas infini, et votre patience non plus.
- Standardisez une disposition où l’état persistant vit en dehors de
rpool/ROOT.
Quand la prochaine mise à jour vous mordra — et elle le fera — vous aurez une option calme : redémarrer dans hier. Ensuite, déboguez comme un professionnel, en plein jour, avec un café encore chaud.