Dépanner un serveur qui ne démarre plus
Pourquoi
Lundi, 7 h 40. La mise à jour automatique du noyau a programmé un redémarrage de sig-outils dans la nuit. Depuis, la machine ne répond plus : ssh expire, la réception des journaux est muette, et l'export CSV de la mairie n'est pas parti. Dans la console Scaleway, l'instance est pourtant « Running ». Vous ouvrez la fiche de serveur que vous avez rédigée à la leçon 1 et vous y lisez, dans le journal des changements de Camille, une ligne de vendredi : « ajout du volume de sauvegarde dans fstab ».
Un serveur qui ne démarre plus est la panne la plus intimidante qui soit, parce que tous les outils habituels disparaissent avec lui : pas de SSH, pas de journalctl, pas de supervision. Sans méthode, on choisit l'une des deux mauvaises options. La première consiste à détruire l'instance et à en recréer une, ce qui est parfait pour une machine sans état comme sig-app-2, mais désastreux pour sig-outils, qui porte les journaux reçus et l'état des sauvegardes. La seconde consiste à redémarrer en boucle en espérant que cela passe, ce qui n'arrive jamais : le démarrage est déterministe, et ce qui a échoué une fois échouera de nouveau.
La bonne nouvelle, c'est qu'une machine qui ne démarre plus est presque toujours réparable en quelques minutes par quelqu'un qui sait trois choses : lire le premier message d'erreur, obtenir un shell par une autre porte que le réseau, et savoir quoi corriger une fois dedans. C'est l'objet de cette leçon. Elle s'appuie sur la chaîne de démarrage décrite à la leçon 2, que nous allons cette fois parcourir à l'envers, panne par panne.
Warning
Toutes les manipulations de cette leçon s'apprennent sur une machine virtuelle jetable, jamais sur un serveur qui compte. Cassez volontairement le démarrage de votre VM de test, puis réparez-le : c'est le seul entraînement qui prépare vraiment à une nuit d'astreinte.
Les concepts
Situer la panne dans la chaîne
La leçon 2 a décrit le démarrage comme une course de relais : firmware, chargeur GRUB, noyau, initramfs (le petit système de fichiers en mémoire chargé avec le noyau, qui sait trouver et monter la vraie racine), puis systemd, qui monte les systèmes de fichiers et démarre les services. Chaque coureur a sa façon d'échouer, et surtout sa façon de le dire. Reconnaître l'étape, c'est déjà savoir quel outil prendre.
| Étape | Ce que vous voyez sur la console | Ce que cela veut dire | Porte d'entrée |
|---|---|---|---|
| Firmware | rien, ou un message du firmware sur l'absence de disque amorçable | le chargeur n'est pas trouvé | mode de secours |
| GRUB | grub rescue> ou grub> | GRUB ne trouve pas ses modules ou sa configuration | commandes GRUB, puis mode de secours |
| Noyau | Kernel panic - not syncing: ... | le noyau ne peut pas continuer (pas de racine, pas d'initramfs, bogue) | ancien noyau dans le menu GRUB |
| initramfs | Gave up waiting for root file system device, invite (initramfs) | la racine n'est pas trouvée ou pas vérifiable | shell de l'initramfs, puis mode de secours |
| systemd | A start job is running for ..., Dependency failed for ..., You are in emergency mode | un montage ou une unité requise a échoué | mode emergency, ou ligne de commande du noyau |
| Services | la machine démarre mais SSH ou l'application ne répondent pas | panne de service ou de réseau, pas de démarrage | console série, systemctl --failed |
La règle d'or tient en une phrase : lisez jusqu'à la première erreur, pas jusqu'à la dernière. Une racine introuvable produit des dizaines de messages en cascade ; seul le premier dit la cause. Les suivants sont des conséquences.
Trois portes quand SSH est fermé
Quand le réseau ne répond plus, il reste trois façons d'entrer, de la plus légère à la plus lourde.
- La console série. Le noyau et systemd écrivent leurs messages sur une console ; sur une instance cloud, elle est reliée à un port série virtuel (
ttyS0) que le fournisseur expose dans son interface web. Chez Scaleway, c'est le bouton Console de la page de l'instance. Elle montre le démarrage en direct et offre une invite de connexion même si le réseau de la machine est mort. Elle exige en revanche un mot de passe : la documentation Scaleway précise qu'il faut en avoir défini un pour l'utilisateur Linux, au préalable, via SSH. Une clé SSH ne sert à rien sur une console. - La ligne de commande du noyau, via le menu GRUB. Si le menu de GRUB s'affiche sur la console, on peut modifier, pour un seul démarrage, les paramètres passés au noyau et à systemd : démarrer dans une cible minimale, masquer une unité, obtenir un shell de débogage. Rien n'est écrit sur le disque ; au redémarrage suivant, tout redevient normal.
- Le système de secours. On démarre la machine sur un autre système (une image de secours fournie par l'hébergeur, ou une clé USB sur une machine physique), qui voit le disque de l'instance comme un simple disque de données. On le monte, on entre dedans par
chroot, et on répare. C'est la porte qui marche toujours, même quand GRUB est détruit.
flowchart TD
A[SSH ne répond plus] --> B{La console série<br/>montre-t-elle quelque chose ?}
B -- "invite de connexion" --> C[Se connecter sur la console<br/>panne réseau ou de service]
B -- "emergency mode" --> D[Shell de maintenance<br/>si root a un mot de passe]
B -- "(initramfs), grub rescue>,<br/>kernel panic, rien" --> E{Le menu GRUB<br/>est-il accessible ?}
D -- "root verrouillé" --> E
E -- oui --> F[Modifier la ligne du noyau<br/>ancien noyau, rescue, debug shell]
E -- non --> G[Mode de secours Scaleway<br/>montage et chroot]
F -- "insuffisant" --> G
Les modes de démarrage réduits
systemd lit la ligne de commande du noyau (/proc/cmdline) et y cherche ses propres paramètres. La page kernel-command-line(7) les recense ; ceux qui servent au dépannage sont peu nombreux.
| Paramètre | Ce qui démarre | Ce qui est monté | Mot de passe root |
|---|---|---|---|
systemd.unit=rescue.target (alias rescue, single, 1) | les services de base, puis un shell | tous les systèmes de fichiers de fstab | demandé |
systemd.unit=emergency.target (alias emergency, -b) | presque rien : PID 1 et un shell | la racine seulement, en lecture seule ou en écriture selon le chemin suivi | demandé |
systemd.mask=<unité> | le démarrage normal, sans cette unité | normal | sans objet |
systemd.debug_shell | le démarrage normal, plus un shell root sur tty9 (ou sur le terminal indiqué) | normal | aucun |
break=premount (initramfs-tools) ou rd.break (dracut, Red Hat) | un shell dans l'initramfs, avant le montage de la racine | rien ou la racine en lecture seule | aucun |
init=/bin/bash | Bash à la place de systemd, comme PID 1 | la racine, en lecture seule | aucun |
La page systemd.special(7) résume la différence entre les deux cibles : emergency.target « ne tire aucun autre service ni montage », c'est le minimum absolu pour obtenir un shell ; rescue.target tire le système de base, montages compris, sans les services. Si le problème est un montage, rescue.target échouera au même endroit que le démarrage normal : prenez emergency.target.
Le shell de débogage (debug-shell.service, activé par systemd.debug_shell) mérite une mention particulière : il démarre très tôt, sans mot de passe, et tourne en parallèle du démarrage normal, ce qui permet d'observer une unité bloquée pendant qu'elle bloque. Dans systemd 255, on peut lui indiquer le terminal : systemd.debug_shell=ttyS0 le place sur la console série, la seule que l'on voie sur une instance cloud. La page systemd-debug-generator(8) l'accepte avec ou sans préfixe /dev/.
Le compte root verrouillé
Les modes rescue et emergency ne donnent pas un shell à n'importe qui : systemd y lance sulogin, qui demande le mot de passe de root. Or, sur Ubuntu, le compte root n'a pas de mot de passe utilisable : il est verrouillé, et l'administration passe par sudo. C'est aussi le cas des images cloud Debian, et donc de sig-outils. Dans ce cas, sulogin refuse d'ouvrir le shell et affiche ce message, tiré de son code source :
Cannot open access to console, the root account is locked.
See sulogin(8) man page for more details.
Press Enter to continue.C'est un choix de sécurité délibéré, et il change la stratégie : sur ces machines, le mode emergency ne sert à rien tel quel. Il faut soit l'autoriser sans mot de passe pour ce démarrage (le paramètre SYSTEMD_SULOGIN_FORCE=1, que nous verrons), soit passer par init=/bin/bash, soit aller directement au mode de secours.
En pratique
Les sorties de cette section sont construites d'après le code source et la documentation des outils cités ; elles ne proviennent pas d'une machine réelle. Les identifiants (UUID, numéros de version de noyau, identifiants d'instance) sont des exemples.
Lire la console série
Dans la console Scaleway : CPU & GPU Instances, choisissez la zone (PAR1 pour sig-app-1 et sig-outils, PAR2 pour sig-app-2), cliquez sur l'instance, puis sur Console. La fenêtre affiche ce que la machine écrit sur ttyS0. Si la machine est figée, rien n'apparaît : provoquez un redémarrage depuis l'interface pour voir défiler le démarrage depuis le début.
Pour que cette console soit utile, deux conditions doivent avoir été remplies avant la panne, ce que nous reprendrons dans « En production » :
- le noyau doit écrire sur le port série (
console=ttyS0dans sa ligne de commande, ce que font les images cloud ; vérifiez aveccat /proc/cmdline) ; - un compte doit avoir un mot de passe, sans quoi vous verrez l'invite
login:sans pouvoir l'utiliser.
Afficher et modifier le menu GRUB
Sur la plupart des serveurs, le menu de GRUB est caché ou affiché très brièvement. Le manuel de GRUB décrit le réglage GRUB_TIMEOUT_STYLE : avec hidden ou countdown, GRUB attend la durée de GRUB_TIMEOUT puis démarre l'entrée par défaut, sauf si l'on appuie sur Échap (ou F4) ou si l'on maintient Maj pendant ce délai, auquel cas il affiche le menu. Avec GRUB_TIMEOUT=0, la fenêtre est quasi nulle : appuyez sur Échap à répétition dès le début du redémarrage. L'exemple de configuration publié par Scaleway pour ses images Debian utilise GRUB_TIMEOUT=5, ce qui laisse le temps. Regardez ce qu'il en est sur vos machines dans /etc/default/grub et dans /etc/default/grub.d/, où les images cloud déposent souvent leurs propres réglages.
Une fois le menu affiché :
- placez-vous sur l'entrée voulue avec les flèches (la première, ou une entrée de « Advanced options » pour un ancien noyau) ;
- appuyez sur
epour l'éditer ; - descendez jusqu'à la ligne qui commence par
linux; - allez en fin de ligne (
Ctrl-eou Fin) et ajoutez vos paramètres, séparés par une espace ; - démarrez avec
Ctrl-xou F10. Échap abandonne la modification.
La ligne ressemble à ceci sur sig-app-1 (l'UUID et la version sont des exemples) :
linux /boot/vmlinuz-6.8.0-85-generic root=UUID=0b6f8c2e-5d0a-4f8e-9a63-2a7c1d9e4b10 ro console=tty1 console=ttyS0root= désigne la racine, ro demande de la monter d'abord en lecture seule (systemd la remonte en écriture plus tard, d'après fstab), console= liste les consoles ; la dernière citée devient /dev/console, celle où arrivent les invites de systemd. Pour démarrer en mode emergency sur une machine dont root est verrouillé, ajoutez :
systemd.unit=emergency.target SYSTEMD_SULOGIN_FORCE=1SYSTEMD_SULOGIN_FORCE est lu par systemd-sulogin-shell sur la ligne de commande du noyau ; il ajoute l'option --force à sulogin, qui accepte alors d'ouvrir un shell sans mot de passe quand le compte root est verrouillé. Le code source de systemd 255 le commente ainsi : il « autorise les connexions sans mot de passe si le compte root est verrouillé ». Ce n'est valable que pour ce démarrage.
Note
Le menu GRUB ne s'affiche sur la console série que si GRUB lui-même y écrit (GRUB_TERMINAL incluant serial, ou une image qui le configure). Si la console série montre le noyau mais jamais le menu, cette porte est fermée pour vous : passez directement au mode de secours. C'est une raison de plus de le vérifier à froid, avant la panne.
Panne 1 : un fstab qui référence un disque absent
C'est la panne de sig-outils. Vendredi, Camille a ajouté un volume Block Storage, l'a formaté, et a ajouté cette ligne à /etc/fstab :
UUID=3f1c9a7e-2b4d-4c8a-9e51-7d2f6a0b8c34 /srv/sauvegardes ext4 defaults 0 2Puis le volume a été détaché pour être recréé plus grand, et le nouveau a reçu un autre UUID (mkfs en génère un à chaque formatage). Au redémarrage, systemd attend un périphérique qui n'existera jamais. La console montre, ligne après ligne :
[ *** ] A start job is running for /dev/disk/by-uuid/3f1c9a7e-2b4d-4c8a-9e51-7d2f6a0b8c34 (47s / 1min 30s)
[ TIME ] Timed out waiting for device /dev/disk/by-uuid/3f1c9a7e-2b4d-4c8a-9e51-7d2f6a0b8c34.
[DEPEND] Dependency failed for /srv/sauvegardes.
[DEPEND] Dependency failed for Local File Systems.
You are in emergency mode. After logging in, type "journalctl -xb" to view
system logs, "systemctl reboot" to reboot, or "exit"
to continue bootup.
Cannot open access to console, the root account is locked.
See sulogin(8) man page for more details.
Press Enter to continue.Chaque ligne a un sens précis. Le décompte (47s / 1min 30s) vient de la temporisation par défaut d'attente d'un périphérique, 90 secondes. Timed out waiting for device est le message d'échec propre aux unités de périphérique. Dependency failed for /srv/sauvegardes dit que l'unité de montage, qui requiert le périphérique, échoue à son tour, et Dependency failed for Local File Systems que local-fs.target, qui requiert tous les montages de fstab sans nofail, échoue aussi. Or local-fs.target déclare OnFailure=emergency.target : d'où le mode emergency, et le refus de sulogin puisque root est verrouillé.
La réparation par la console. Redémarrez depuis l'interface Scaleway, affichez le menu GRUB, éditez l'entrée et ajoutez systemd.unit=emergency.target SYSTEMD_SULOGIN_FORCE=1. Vous obtenez un shell root. Puis :
# journalctl -xb -p err --no-pager | head -30
# findmnt /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda1 ext4 ro,relatime
# mount -o remount,rw /
# lsblk -f
# nano /etc/fstab
journalctl -xbaffiche le journal du démarrage en cours ;-xajoute les explications du catalogue de systemd,-p errne garde que les erreurs. Le journal confirme la cause avant que vous ne touchiez à quoi que ce soit.findmnt /montre comment la racine est montée. En mode emergency, elle peut l'être en lecture seule (ro) ;mount -o remount,rw /la passe en écriture sans la démonter.lsblk -fliste les disques avec leur système de fichiers, leur étiquette et leur UUID : vous y trouvez le nouvel UUID du volume, s'il est attaché.
Dans fstab, corrigez l'UUID, ou commentez la ligne, et ajoutez dans tous les cas l'option nofail aux volumes qui ne sont pas indispensables au démarrage :
UUID=8a2d4e61-0c3b-4f7a-b5d9-1e6c8f3a2b70 /srv/sauvegardes ext4 defaults,nofail,x-systemd.device-timeout=10s 0 2La page systemd.mount(5) est explicite sur nofail : le montage n'est plus que voulu, et non requis, par local-fs.target, et n'est plus ordonné avant elle ; le démarrage continue sans l'attendre et quel que soit son résultat. x-systemd.device-timeout=10s raccourcit l'attente du périphérique à 10 secondes au lieu de 90. Ensuite :
# findmnt --verify
# systemctl daemon-reload
# mount -a
# systemctl default
findmnt --verify analyse fstab sans rien monter (voir plus bas). systemctl daemon-reload est indispensable : systemd ne lit pas fstab directement, il en a tiré des unités .mount au démarrage, et il faut les régénérer. mount -a monte tout ce qui est déclaré et non encore monté ; s'il échoue, vous le savez maintenant et non au prochain redémarrage. systemctl default reprend le démarrage vers la cible par défaut, comme le suggère le message (« exit to continue bootup »).
Panne 2 : passer par le mode de secours Scaleway
Si le menu GRUB est inaccessible, ou si la panne est en amont de systemd, il faut démarrer sur un autre système. Le mode de secours de Scaleway, d'après sa documentation, redémarre l'instance « via le réseau sur un système d'exploitation minimal » qui tourne en mémoire vive ; les disques de l'instance restent attachés et accessibles. Avec la CLI scw (outil présenté sur sa fiche) :
$ scw instance server list zone=fr-par-1 name=sig-outils
$ scw instance server update 11111111-2222-3333-4444-555555555555 boot-type=rescue zone=fr-par-1
$ scw instance server reboot 11111111-2222-3333-4444-555555555555 zone=fr-par-1
server listdonne l'identifiant de l'instance (la colonneID), nécessaire aux commandes suivantes.boot-type=rescuechange le mode de démarrage ; les valeurs possibles sontlocal(le défaut, le disque de l'instance),rescueetbootscript(historique).zone=doit correspondre à la zone de l'instance ; sans lui, la CLI utilise la zone par défaut de sa configuration.
Dans la console web, le même réglage se trouve dans Advanced settings, section Boot mode, instance éteinte. Connectez-vous ensuite en SSH, avec vos clés du projet, à l'adresse habituelle. Le système de secours ayant sa propre clé d'hôte, SSH vous alertera :
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Ici, c'est attendu. Ne supprimez pas pour autant la clé connue de sig-outils : connectez-vous au système de secours sans l'enregistrer, et vous retrouverez la vraie clé au retour.
$ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=accept-new root@<adresse-ip>
Monter le système et entrer dans un chroot
Dans le système de secours, identifiez les partitions. La documentation Scaleway montre une disposition typique d'image cloud : sda1 pour la racine, sda14 (partition d'amorçage BIOS) et sda15 pour la partition système EFI (ESP).
# lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1 ext4 1.0 cloudimg-rootfs 0b6f8c2e-5d0a-4f8e-9a63-2a7c1d9e4b10
├─sda14
└─sda15 vfat FAT32 UEFI 7A3C-1F9E
sdb ext4 1.0 8a2d4e61-0c3b-4f7a-b5d9-1e6c8f3a2b70
Ne vous fiez pas aux noms (sda, sdb) mais au contenu : la racine est celle qui contient /etc/os-release. Montez-la, puis les systèmes de fichiers virtuels dont les outils auront besoin :
# mount /dev/sda1 /mnt
# mount /dev/sda15 /mnt/boot/efi
# for d in dev proc sys run; do mount --rbind "/$d" "/mnt/$d"; mount --make-rslave "/mnt/$d"; done
# chroot /mnt /bin/bash
mount --rbindmonte récursivement :/devvient avec/dev/pts,/sysavec/sys/firmware/efi/efivars, dontgrub-installa besoin sur une machine UEFI.mount --make-rslavecoupe la propagation dans le sens chroot vers hôte : sans lui, le démontage récursif final peut démonter aussi les/dev/ptsdu système de secours.chroot /mnt /bin/bashlance un shell dont la racine apparente est/mnt. Vous êtes « dans »sig-outils:apt,update-grub,update-initramfs,passwdagissent sur son disque.
Avant toute réparation, lisez ce qui s'est passé. Depuis le système de secours (hors du chroot), journalctl sait lire un journal qui n'est pas le sien :
# journalctl --root=/mnt --list-boots --no-pager | tail -3
# journalctl --root=/mnt -b -0 -p warning --no-pager
# journalctl --root=/mnt -b -1 -n 50 --no-pager
--root=/mnt fait chercher les fichiers sous /mnt/var/log/journal/ (et /mnt/run/journal/). -D /mnt/var/log/journal/<identifiant de machine> est l'équivalent pour un répertoire précis. Attention à l'option -b : d'après journalctl(1), -0 désigne le dernier démarrage trouvé dans les fichiers et -1 l'avant-dernier ; avec un journal étranger, le démarrage « courant » n'est pas le dernier, d'où l'intérêt d'écrire -b -0 explicitement. Si la panne s'est produite dans l'initramfs, avant que la racine ne soit montée en écriture, ce démarrage n'apparaîtra tout simplement pas.
Une fois la réparation faite, sortez proprement :
# exit
# umount -R /mnt
# sync
Puis repassez en démarrage local, sans quoi l'instance redémarrera encore sur le système de secours :
$ scw instance server update 11111111-2222-3333-4444-555555555555 boot-type=local zone=fr-par-1
$ scw instance server reboot 11111111-2222-3333-4444-555555555555 zone=fr-par-1
Panne 3 : le nouveau noyau ne démarre pas
Après une mise à jour du noyau (leçon 4), sig-app-2 affiche par exemple :
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)unknown-block(0,0) signifie que le noyau n'a trouvé aucun périphérique : typiquement, l'initramfs de ce noyau est absent ou incomplet, souvent parce que sa génération a échoué pendant la mise à jour. Les distributions gardent l'ancien noyau précisément pour ce cas. Dans le menu GRUB, ouvrez Advanced options for Ubuntu (ou Advanced options for Debian GNU/Linux) et choisissez la version précédente. Si elle démarre, la machine est rétablie ; il reste à comprendre pourquoi la nouvelle échoue.
Si le menu est inaccessible, la procédure Scaleway pour un noyau défaillant passe par le mode de secours et GRUB_DEFAULT : dans le chroot, éditez /etc/default/grub et remplacez GRUB_DEFAULT=0 par GRUB_DEFAULT="1>2", puis lancez update-grub. La syntaxe 1>2 désigne, en comptant à partir de zéro, la troisième entrée (2) du deuxième élément du menu (1, le sous-menu « Advanced options »). La numérotation dépend du nombre de noyaux installés et de la présence d'entrées « recovery mode » : vérifiez dans /boot/grub/grub.cfg l'ordre des menuentry du sous-menu avant de choisir. N'oubliez pas de remettre GRUB_DEFAULT=0 une fois le noyau réparé, sinon la machine restera épinglée sur un noyau qui ne recevra plus de correctifs.
Pour tester un noyau sans risque, grub-reboot choisit l'entrée du seul prochain démarrage ; il exige GRUB_DEFAULT=saved. Si le test échoue, un simple redémarrage revient à l'entrée habituelle.
Panne 4 : l'initramfs ne trouve pas la racine
Autre symptôme possible après une mise à jour, ou après qu'un administrateur a « optimisé » l'initramfs :
Gave up waiting for root file system device. Common problems:
- Boot args (cat /proc/cmdline)
- Check rootdelay= (did the system wait long enough?)
- Check root= (did the system wait for the right device?)
- Missing modules (cat /proc/modules; ls /dev)
ALERT! UUID=0b6f8c2e-5d0a-4f8e-9a63-2a7c1d9e4b10 does not exist. Dropping to a shell!
BusyBox v1.36.1 (Ubuntu 1:1.36.1-6ubuntu3.1) built-in shell (ash)
Enter 'help' for a list of built-in commands.
(initramfs)Ce texte vient du script scripts/local d'initramfs-tools : il a attendu la racine pendant 30 secondes (ou la valeur de rootdelay= si elle est plus grande), puis abandonne et ouvre un shell BusyBox dont l'invite est (initramfs). Ses trois pistes sont les bonnes, dans l'ordre :
(initramfs) cat /proc/cmdline
(initramfs) ls /dev/disk/by-uuid/
(initramfs) blkid
(initramfs) cat /proc/modules | head- Si
/dev/disk/by-uuid/contient l'UUID attendu, le disque est là mais a mis trop de temps :exitrelance la recherche, etrootdelay=sur la ligne du noyau est un contournement. - Si un autre UUID est présent, la ligne
root=est fausse (racine reformatée, image clonée) : corrigez-la dans GRUB pour ce démarrage, puis durablement avecupdate-grub. - Si aucun disque n'apparaît, il manque le pilote du contrôleur dans l'initramfs.
Ce dernier cas a une cause fréquente : le réglage MODULES de /etc/initramfs-tools/initramfs.conf. Sa valeur par défaut est most, qui embarque la plupart des pilotes de stockage. Quelqu'un l'a passé à dep, qui n'embarque que les pilotes utilisés au moment de la génération : l'initramfs est plus petit, mais il ne démarre plus si le matériel virtuel change, par exemple après un changement de type d'instance. La réparation se fait depuis le chroot du mode de secours :
# grep '^MODULES' /etc/initramfs-tools/initramfs.conf
MODULES=dep
# sed -i 's/^MODULES=dep/MODULES=most/' /etc/initramfs-tools/initramfs.conf
# update-initramfs -u -k all
# lsinitramfs /boot/initrd.img-6.8.0-85-generic | grep -E 'virtio_scsi|nvme' | head
update-initramfs -u -k all régénère (-u, update) l'initramfs de tous les noyaux installés (-k all). lsinitramfs liste le contenu de l'image, ce qui permet de vérifier la présence du pilote avant de redémarrer. Sur Red Hat, l'équivalent est dracut -f --regenerate-all.
Le même shell (initramfs) apparaît avec un autre message quand la vérification de la racine échoue : The root filesystem on /dev/sda1 requires a manual fsck. Là, fsck -y /dev/sda1 depuis l'invite, puis exit, suffit en général ; -y répond oui à toutes les corrections, ce qui est le seul choix réaliste sur une console, mais lisez ce que fsck a corrigé.
Panne 5 : GRUB ne trouve plus ses fichiers
Si la console s'arrête sur :
error: no such partition.
Entering rescue mode...
grub rescue>GRUB a démarré (son premier étage était lisible) mais ne trouve pas la partition qui contient ses modules et grub.cfg : table de partitions modifiée, racine déplacée, disque remplacé. L'invite grub rescue> ne connaît qu'une poignée de commandes (ls, set, insmod). Une variante est l'invite grub> précédée de « Minimal BASH-like line editing is supported » : GRUB est complet mais n'a pas trouvé sa configuration. Dans les deux cas, on peut parfois démarrer à la main :
grub rescue> ls
(hd0) (hd0,gpt1) (hd0,gpt14) (hd0,gpt15)
grub rescue> ls (hd0,gpt1)/boot/grub
grub rescue> set root=(hd0,gpt1)
grub rescue> set prefix=(hd0,gpt1)/boot/grub
grub rescue> insmod normal
grub rescue> normalls liste les disques et partitions vus par GRUB ; on cherche celle qui contient /boot/grub. set prefix= indique à GRUB où sont ses modules, insmod normal charge le mode normal, et normal affiche le menu. Mais ce n'est qu'un démarrage ponctuel : la vraie réparation consiste à réinstaller GRUB depuis le système démarré ou depuis le chroot du mode de secours.
# [ -d /sys/firmware/efi ] && echo UEFI || echo BIOS
# grub-install /dev/sda # démarrage BIOS
# grub-install --target=x86_64-efi --efi-directory=/boot/efi # démarrage UEFI
# update-grub
Le test sur /sys/firmware/efi indique comment la machine a démarré ; dans un chroot, il reflète le mode du système de secours, qui démarre de la même manière que l'instance. grub-install réécrit les fichiers du chargeur (sur le disque pour le BIOS, dans l'ESP pour l'UEFI), update-grub régénère /boot/grub/grub.cfg à partir de /etc/default/grub et de /etc/grub.d/. Sur Ubuntu avec démarrage sécurisé, le plus sûr est de réinstaller les paquets signés (apt install --reinstall shim-signed grub-efi-amd64-signed), qui replacent shim et le GRUB signé dans l'ESP ; sur Debian, les paquets s'appellent shim-signed et grub-efi-amd64-signed également. Le message error: symbol 'grub_...' not found au démarrage trahit une autre variante : le premier étage et les modules ne sont plus de la même version, après une mise à jour interrompue. Le remède est le même : réinstaller.
Panne 6 : le disque est plein
Un disque racine plein empêche rarement le noyau de démarrer, mais il casse tout ce qui doit écrire au démarrage : un service qui crée son fichier de PID ou sa socket échoue, PostgreSQL refuse de démarrer, et le journal ne persiste plus rien. Sur une image cloud, /boot est en général sur la racine : un disque plein pendant une mise à jour du noyau produit le message update-initramfs: failed for /boot/initrd.img-6.8.0-85-generic with 1., puis un initramfs tronqué, et au redémarrage la panique Unable to mount root fs de la panne 3. Les deux pannes sont souvent la même.
Depuis la console ou le chroot :
# df -h / ; df -i /
# du -xh --max-depth=1 / 2>/dev/null | sort -h | tail
# journalctl --vacuum-size=200M
# apt clean
df -i vérifie les inodes, qui peuvent s'épuiser alors qu'il reste de la place (des millions de petits fichiers). du -x reste sur le système de fichiers de la racine, sans descendre dans les autres montages. Libérez de quoi travailler (cache d'APT, journal, archives de journaux), régénérez l'initramfs, et traitez la cause : la leçon 6 revient sur la surveillance de l'espace et l'agrandissement d'un volume Scaleway à chaud.
Panne 7 : plus aucun accès administrateur
Le compte qui avait sudo a été supprimé avec le départ de Camille, ou son mot de passe est inconnu et la console l'exige. Trois chemins, du plus propre au plus brutal.
Depuis le chroot du mode de secours. C'est le plus sûr : passwd adminsig (le compte d'administration de votre équipe), ou usermod -aG sudo adminsig, ou l'ajout d'une clé dans son ~/.ssh/authorized_keys. Sur Scaleway, la documentation prévient que le fichier authorized_keys de l'utilisateur par défaut est réécrit à chaque démarrage à partir des clés du projet : ajoutez plutôt la clé au projet dans la console, et réservez la modification manuelle à un autre compte.
SYSTEMD_SULOGIN_FORCE=1 avec emergency.target, comme dans la panne 1, si le menu GRUB est accessible. Vous avez un vrai systemd, ce qui permet d'activer les unités pas à pas.
init=/bin/bash. Le noyau lance Bash au lieu de systemd. L'initramfs a déjà monté la racine, en lecture seule à cause de ro, et déplacé /dev, /proc, /sys et /run. Il n'y a ni systemd, ni journal, ni réseau, ni services :
bash-5.2# mount -o remount,rw /
bash-5.2# passwd adminsig
bash-5.2# sync
bash-5.2# mount -o remount,ro /
bash-5.2# echo b > /proc/sysrq-trigger
systemctl reboot ne fonctionne pas, puisque systemd ne tourne pas. On écrit donc sur disque (sync), on repasse la racine en lecture seule pour qu'elle soit propre, et on demande au noyau un redémarrage immédiat par la touche SysRq (la documentation du noyau précise que l'écriture dans /proc/sysrq-trigger par un administrateur est toujours permise, quel que soit le réglage kernel.sysrq, qui ne concerne que le clavier). Surtout, ne tapez pas exit : Bash est le PID 1, et le noyau ne survit pas à la mort de son PID 1 (voir « Sous le capot »).
Sur Red Hat et ses dérivés, la procédure documentée utilise rd.break : dracut s'arrête juste avant de passer la main au système, la racine est montée en lecture seule sous /sysroot, et l'on fait mount -o remount,rw /sysroot, chroot /sysroot, passwd, puis touch /.autorelabel pour que SELinux réétiquette les fichiers au démarrage suivant. Oublier cette dernière étape donne un système où plus personne ne peut se connecter. initramfs-tools offre un équivalent, break=premount (ou break=mount, break=bottom...), documenté dans initramfs-tools(7), mais le chroot du mode de secours est plus confortable.
Panne 8 : une unité bloque le démarrage
Dernier classique : la machine démarre, mais très lentement, ou reste suspendue sur une ligne du type :
[ *** ] A start job is running for Wait for Network to be Configured (1min 12s / no limit)Une unité attend une condition qui ne viendra pas : un réseau privé mal configuré, un montage NFS, un service maison qui ne signale jamais qu'il est prêt. Deux outils, sur la ligne de commande du noyau :
systemd.mask=systemd-networkd-wait-online.service systemd.debug_shell=ttyS0systemd.mask= retire l'unité de ce démarrage seulement, comme un systemctl mask temporaire ; systemd.debug_shell=ttyS0 vous donne en parallèle un shell root sur la console série, depuis lequel systemctl list-jobs montre les tâches en attente et ce qui bloque :
# systemctl list-jobs
JOB UNIT TYPE STATE
98 systemd-networkd-wait-online.service start running
1 multi-user.target start waiting
...
Une fois la machine démarrée, systemd-analyze blame et systemd-analyze critical-chain (leçon 2) disent qui a pris le temps, et journalctl -b -u <unité> pourquoi.
Sous le capot
Comment un paramètre de GRUB devient une décision de systemd. GRUB charge le noyau et l'initramfs en mémoire, et leur passe une chaîne de caractères : la ligne linux que vous avez éditée, moins le chemin du noyau. Le noyau prend les paramètres qu'il connaît (root=, ro, console=, init=, panic=) et laisse les autres accessibles dans /proc/cmdline. L'initramfs y lit root=, rootdelay=, break=. Une fois la racine montée, systemd y lit les siens. C'est pour cela que la modification est sans danger : elle ne vit que dans la mémoire de ce démarrage.
D'où viennent les unités .mount. systemd ne monte pas fstab ligne par ligne comme le faisaient les scripts d'init. Très tôt, il exécute des générateurs (generators), de petits programmes qui traduisent des configurations héritées en unités. systemd-fstab-generator crée, pour chaque ligne de fstab, une unité srv-sauvegardes.mount qui requiert le périphérique dev-disk-by\x2duuid-....device et qui est requise par local-fs.target, sauf avec nofail où elle n'est que voulue. Ces unités sont écrites dans /run/systemd/generator/ : allez les lire avec systemctl cat srv-sauvegardes.mount. C'est aussi pourquoi mount vous prévient après une modification de fstab non suivie d'un rechargement : « mount: (hint) your fstab has been modified, but systemd still uses the old version; use 'systemctl daemon-reload' to reload. »
Pourquoi l'échec d'un montage mène au mode emergency. Le périphérique ne se montrant pas, sa tâche de démarrage expire au bout de DefaultDeviceTimeoutSec (90 secondes par défaut) ; la tâche du montage échoue avec le résultat dependency, affiché [DEPEND] ; la tâche de local-fs.target échoue de même ; et local-fs.target porte OnFailure=emergency.target avec OnFailureJobMode=replace-irreversibly. systemd remplace alors tout le démarrage par l'isolement de emergency.target, dont l'unique service, emergency.service, lance systemd-sulogin-shell emergency. Ce programme affiche « You are in emergency mode... », puis exécute sulogin, qui consulte le mot de passe de root dans /etc/shadow. Un champ commençant par ! ou * signifie compte verrouillé, d'où le refus.
Ce que fait vraiment le shell (initramfs). Le script init d'initramfs-tools est un script shell exécuté par BusyBox comme PID 1 de l'initramfs. Quand il ne trouve pas la racine, il appelle sa fonction panic, qui, sauf si panic= est passé au noyau, lance un shell interactif sur la console avec l'invite (initramfs). Quand vous tapez exit, le script reprend sa boucle d'attente. Si la racine apparaît, il la monte sous /root, y déplace /run, /sys et /proc (mount -o move), puis passe la main à /sbin/init du vrai système, qui hérite du PID 1.
Pourquoi exit dans init=/bin/bash provoque une panique. Le PID 1 a un statut particulier : il adopte les orphelins, et le noyau ne sait pas continuer sans lui. Si Bash, devenu PID 1, se termine, le noyau s'arrête avec Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000, sans avoir écrit les tampons en attente sur le disque. D'où le sync et la remise en lecture seule avant le redémarrage par SysRq.
Ce qu'un chroot change, et ce qu'il ne change pas. chroot ne change qu'une chose : la racine apparente du processus et de ses enfants. Le noyau reste celui du système de secours, /proc et /sys décrivent la machine réelle, et les périphériques sont ceux de /dev. C'est pour cela qu'il faut les y monter : grub-install lit /proc/mounts et les périphériques de /dev pour savoir où écrire, update-initramfs interroge /sys pour savoir quels modules embarquer. Sans eux, les outils échouent avec des messages qui ont l'air graves et ne le sont pas.
Pièges courants
grub-probe: error: cannot find a device for / (is /dev mounted?). Vous avez lancé update-grub ou grub-install dans un chroot sans les montages de /dev, /proc et /sys. Sortez, faites les mount --rbind, recommencez.
Lancer la réparation hors du chroot. update-grub ou update-initramfs exécutés dans le système de secours lui-même modifient... le système de secours, en mémoire, et rien sur le disque de l'instance. Vérifiez votre invite, ou cat /etc/os-release, avant chaque commande de réparation.
Temporary failure resolving 'archive.ubuntu.com' dans le chroot. Sur Ubuntu, /etc/resolv.conf est un lien vers /run/systemd/resolve/stub-resolv.conf, qui n'existe pas dans le système de secours. Évitez si possible d'avoir besoin du réseau dans le chroot. Sinon, renommez temporairement le lien, copiez le resolv.conf du système de secours, et restaurez le lien avant de sortir.
Oublier de repasser en démarrage local. L'instance redémarre sur le système de secours, en mémoire, et toute modification faite à la racine de celui-ci est perdue. Le disque de l'instance, lui, a bien été modifié, mais vous croirez que la réparation n'a pas pris.
Éditer /boot/grub/grub.cfg à la main. Le fichier est régénéré à chaque mise à jour du noyau par update-grub. Modifiez /etc/default/grub ou /etc/grub.d/, puis régénérez.
Laisser GRUB_DEFAULT="1>2" en place. La machine reste sur l'ancien noyau, qui ne reçoit plus de correctifs, et la numérotation change à la prochaine installation de noyau : la machine finit par démarrer sur une entrée que personne n'a choisie.
exit dans un shell init=/bin/bash. Panique du noyau, et éventuellement des écritures perdues. sync, remontage en lecture seule, puis SysRq.
Le clavier de GRUB. GRUB ne connaît pas votre disposition de clavier. Sur une console qui transmet des touches (console graphique, IPMI), un clavier AZERTY tape systemd;unit)rescue;target ; repérez = et . sur la disposition QWERTY. Une console série web transmet en général des caractères, et le problème ne se pose pas.
Corriger fstab sans daemon-reload. En mode emergency, systemd utilise toujours l'unité générée à partir de l'ancienne ligne ; systemctl default échouera de la même façon.
nofail sur un montage indispensable. Si Signalements écrit ses pièces jointes dans un volume monté avec nofail et que ce volume est absent, le service démarre et écrit... dans le répertoire vide de la racine, qu'il remplit. Pour un montage dont un service dépend vraiment, gardez le montage requis, ou ajoutez à l'unité du service RequiresMountsFor=/chemin, pour que ce soit le service, et non la machine, qui refuse de démarrer.
Supprimer la clé d'hôte connue pour faire taire SSH. Après le retour en démarrage local, la vraie clé de sig-outils sera de nouveau présentée, et vous aurez pris l'habitude d'accepter n'importe quelle clé. Utilisez un fichier known_hosts jetable pour le système de secours.
Sécurité
Un accès à la console équivaut à un accès root. Tout ce que vous venez d'apprendre est à la portée de quiconque peut afficher le menu GRUB, ou démarrer l'instance sur un système de secours. Sur une machine physique, c'est l'accès au local ; chez Scaleway, ce sont les permissions IAM : un utilisateur ou une clé d'API qui peut modifier le boot-type d'une instance et la redémarrer peut lire et modifier tout son disque, clés privées et données personnelles comprises. Traitez ces permissions comme un accès root à toutes les machines du projet, et révisez qui les détient lors du départ d'une personne, exactement comme vous révisez les comptes sudo.
Le mot de passe du chargeur de démarrage. Le guide BP-028 de l'ANSSI recommande, dès le niveau minimal (recommandation R5), de configurer un mot de passe empêchant de modifier les options du chargeur de démarrage. Avec GRUB, on génère une empreinte avec grub-mkpasswd-pbkdf2, puis on déclare dans un fichier de /etc/grub.d/ (par exemple 40_custom) les lignes set superusers="admin" et password_pbkdf2 admin grub.pbkdf2.sha512.... Piège majeur : dès qu'un superutilisateur est défini, GRUB exige le mot de passe pour démarrer toute entrée qui n'est pas marquée --unrestricted, et les scripts de génération de Debian et d'Ubuntu ne posent pas cette option par défaut. Un serveur ainsi configuré attend un mot de passe à chaque redémarrage automatique. Vérifiez dans grub.cfg que les entrées normales portent --unrestricted, et testez sur une VM. Notez enfin que ce mot de passe ne protège pas contre le mode de secours de l'hébergeur, qui ne passe pas par GRUB.
Le chiffrement du disque. Seul le chiffrement protège contre la lecture du disque depuis un système de secours ou un instantané. Il a un coût de dépannage : une racine chiffrée par LUKS doit être déverrouillée au démarrage, ce qui demande une saisie sur la console ou un mécanisme automatique (clé dans une puce TPM, serveur Tang avec Clevis) ; et en mode de secours, il faut la clé pour ouvrir le volume avant de le monter. C'est un arbitrage à faire en connaissance de cause, en fonction de la sensibilité des données et de la confiance accordée à l'hébergeur, que le cours sur le chiffrement des données approfondira.
Les raccourcis de dépannage ne doivent pas survivre. SYSTEMD_SULOGIN_FORCE=1, systemd.debug_shell, init=/bin/bash sont sans mot de passe par construction. Ils ne sont acceptables que pour un démarrage, sur la ligne de commande éditée dans GRUB. Ne les ajoutez jamais dans GRUB_CMDLINE_LINUX, et n'activez jamais debug-shell.service de façon permanente : vous laisseriez un shell root ouvert sur un terminal.
Les instantanés et le journal contiennent tout. L'instantané pris avant une réparation, comme le journal que vous lisez en mode de secours, contient les secrets de la machine (/etc/signalements/env, clés SSH d'hôte) et des données personnelles (adresses IP des citoyens dans les journaux reçus par sig-outils). Supprimez les instantanés de dépannage une fois la machine rétablie, conformément à votre politique de conservation au titre du RGPD.
En production
Prévenir plutôt que dépanner. La plupart des pannes de cette leçon sont introduites par une modification qui n'a pas été vérifiée avant le redémarrage. Après chaque modification de fstab :
$ sudo findmnt --verify
/srv/sauvegardes
[E] unreachable on boot required source: UUID=3f1c9a7e-2b4d-4c8a-9e51-7d2f6a0b8c34
0 parse errors, 1 error, 0 warnings
$ sudo systemctl daemon-reload
$ sudo mount -a
D'après son code source, findmnt --verify signale en erreur ([E]) une source introuvable dès que la ligne n'est pas en noauto, et affiche « Success, no errors or warnings detected » quand tout va bien ; -v détaille chaque vérification. Après une mise à jour du noyau, vérifiez que l'initramfs a été généré (ls -l /boot/initrd.img-*) et que update-grub n'a rien signalé. Après une modification de GRUB, relisez la section de grub.cfg produite.
Préparer la porte d'entrée à froid. Au moment de la prise en charge, et non pendant la panne :
- vérifiez que la console série affiche le démarrage et le menu GRUB, et réglez un
GRUB_TIMEOUTcourt mais non nul (quelques secondes) dans un fichier de/etc/default/grub.d/; - définissez un compte de secours avec un mot de passe long, connu de l'équipe et conservé dans le gestionnaire de secrets, utilisable sur la console mais interdit en SSH (en ne le mettant pas dans le groupe autorisé par
AllowGroups, voir la leçon 14) ; - vérifiez que la CLI
scwest configurée sur au moins deux postes de l'équipe, avec les droits nécessaires au mode de secours ; - gardez au moins deux noyaux installés (comportement par défaut d'APT, voir leçon 4).
Un instantané avant toute modification risquée. Avant de toucher à fstab, à GRUB, ou de changer de noyau à la main, un instantané du volume racine coûte quelques secondes et transforme une panne en retour arrière :
$ scw block snapshot create volume-id=<id-du-volume> name=sig-outils-avant-fstab zone=fr-par-1
Réparer ou reconstruire. Sur sig-app-1 et sig-app-2, qui ne portent pas de données et sont décrites par l'automatisation, la question se pose franchement : si la réparation dépasse le temps de recréer l'instance à partir de son image et de sa configuration, recréez-la. C'est le sens de la distinction entre animaux et bétail et de l'infrastructure immuable. Pendant ce temps, l'autre instance assure le service derrière le répartiteur. sig-outils, qui porte un état, se répare ; c'est un argument pour réduire cet état (journaux expédiés, sauvegardes dans Object Storage) jusqu'à ce qu'elle devienne, elle aussi, remplaçable. Dans tous les cas, fixez-vous une limite de temps avant de changer de stratégie.
Écrire le runbook. La procédure de mode de secours, avec les identifiants d'instance, les zones et les partitions, tient sur une page de votre documentation (un runbook). Écrite à froid et testée une fois sur une VM, elle fait gagner la première demi-heure d'un incident nocturne.
Après l'incident. Une panne de démarrage révèle presque toujours une modification non tracée. Notez-la dans le journal des changements de la fiche de serveur, avec la cause et la correction, et cherchez ce qui l'aurait évitée : une vérification automatique de fstab dans l'outil d'automatisation (cours Ansible : les fondamentaux), une alerte de la supervision sur une machine qui ne revient pas après un redémarrage, un redémarrage de test dans la fenêtre de maintenance après chaque modification du démarrage.
Exercices
1. Lire une console (niveau 100). Pour chacun des messages suivants, indiquez l'étape du démarrage en cause et la première porte d'entrée que vous utiliseriez : (a) grub rescue> ; (b) Dependency failed for Local File Systems. ; (c) (initramfs) précédé de ALERT! UUID=... does not exist. ; (d) Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) juste après une mise à jour du noyau.
Solution
(a) GRUB : il ne trouve pas sa partition. Commandes ls, set prefix, insmod normal, normal pour démarrer une fois, puis réinstallation de GRUB depuis le système démarré ou le mode de secours.
(b) systemd : un montage requis de fstab a échoué. Mode emergency (avec SYSTEMD_SULOGIN_FORCE=1 si root est verrouillé), correction de fstab, daemon-reload, systemctl default.
(c) initramfs : la racine n'est pas trouvée. Au shell (initramfs), cat /proc/cmdline, ls /dev/disk/by-uuid/, blkid pour distinguer une lenteur, une mauvaise ligne root= ou un pilote manquant ; ce dernier se répare depuis le mode de secours par update-initramfs.
(d) noyau : aucun périphérique, initramfs probablement absent ou incomplet. Menu GRUB, « Advanced options », ancien noyau ; puis diagnostic de la génération de l'initramfs (souvent un disque plein pendant la mise à jour).
2. Le fstab de sig-outils (niveau 200). Reprenez la panne 1 sur votre VM Debian 13 de test : ajoutez à fstab une ligne avec un UUID inventé, sans nofail, et redémarrez. Récupérez la machine sans mode de secours, puis écrivez la ligne qui aurait évité la panne, et la vérification à faire avant tout redémarrage.
Solution
Au redémarrage : attente de 90 secondes, Timed out waiting for device, Dependency failed, mode emergency, et sur Debian cloud Cannot open access to console, the root account is locked. Redémarrer, afficher le menu GRUB (Échap), e, ajouter systemd.unit=emergency.target SYSTEMD_SULOGIN_FORCE=1 à la ligne linux, Ctrl-x. Dans le shell : mount -o remount,rw /, corriger ou commenter la ligne, systemctl daemon-reload, systemctl default.
Ligne correcte pour un volume non indispensable :
UUID=<uuid réel> /srv/sauvegardes ext4 defaults,nofail,x-systemd.device-timeout=10s 0 2
avec l'UUID lu par lsblk -f ou blkid. Vérification : findmnt --verify (aucune erreur), systemctl daemon-reload, mount -a (aucune erreur), et findmnt /srv/sauvegardes.
3. Lire le journal d'une machine morte (niveau 200). sig-outils est démarrée en mode de secours et sa racine est montée sur /mnt. Écrivez les commandes qui affichent la liste de ses démarrages, puis les erreurs du dernier démarrage, puis les cent dernières lignes de l'avant-dernier. Pourquoi faut-il écrire -b -0 et non -b ?
Solution
# journalctl --root=/mnt --list-boots --no-pager
# journalctl --root=/mnt -b -0 -p err --no-pager
# journalctl --root=/mnt -b -1 -n 100 --no-pager
-b sans valeur désigne le démarrage courant, c'est-à-dire celui du système de secours, absent de ces fichiers. La page journalctl(1) précise que -0 est le dernier démarrage trouvé dans le journal, et qu'un -b vide n'équivaut à -0 que si le démarrage courant est le dernier, ce qui n'est pas le cas quand on lit le journal d'une autre machine. Si aucun démarrage récent n'apparaît, la panne s'est produite avant que la racine ne soit écrite (initramfs) ou le journal n'est pas persistant.
4. Un GRUB détruit (niveau 300). Sur une VM de test UEFI Ubuntu 24.04, un collègue a supprimé par erreur le contenu de /boot/efi/EFI/. La machine ne démarre plus. Décrivez la procédure complète de réparation depuis un système de secours, montages compris, en précisant pour chaque commande ce qui se passerait si on l'oubliait.
Solution
- Démarrer sur le système de secours (sur Scaleway :
boot-type=rescue, redémarrage, SSH avec unknown_hostsjetable). lsblk -fpour repérer la racine (ext4, contient/etc/os-release) et l'ESP (vfat).mount /dev/sda1 /mnt, puismount /dev/sda15 /mnt/boot/efi. Sans l'ESP montée,grub-installécrirait dans le répertoire vide/mnt/boot/efide la racine, et le firmware ne verrait rien.for d in dev proc sys run; do mount --rbind /$d /mnt/$d; mount --make-rslave /mnt/$d; done. Sans/devet/proc:cannot find a device for / (is /dev mounted?). Sans/sys(etefivars) :grub-installne peut pas créer l'entrée de démarrage dans la NVRAM.chroot /mnt /bin/bash, vérifiercat /etc/os-release.apt install --reinstall shim-signed grub-efi-amd64-signed(ou, sans démarrage sécurisé,grub-install --target=x86_64-efi --efi-directory=/boot/efi), puisupdate-grub. Si APT doit télécharger, gérer la résolution DNS du chroot et restaurer le lien deresolv.confensuite.ls /boot/efi/EFI/ubuntu/pour vérifiershimx64.efietgrubx64.efi, etefibootmgr -vpour l'entrée de démarrage.exit,umount -R /mnt,sync, retour enboot-type=local, redémarrage, et suivi sur la console série. Oublier le retour en démarrage local redémarre sur le système de secours.
Récapitulatif
- Une panne de démarrage se situe d'après le premier message d'erreur :
grub rescue>(GRUB),Kernel panic(noyau),(initramfs)(racine introuvable),Dependency failedetemergency mode(systemd). - Trois portes quand SSH est fermé : la console série (qui exige un mot de passe défini à l'avance), la ligne de commande du noyau éditée dans GRUB (
e, puisCtrl-x), et le mode de secours de l'hébergeur avec montage etchroot. emergency.targetne monte rien d'autre que la racine,rescue.targetmonte tout ; avec root verrouillé (Ubuntu, images cloud Debian),suloginrefuse, saufSYSTEMD_SULOGIN_FORCE=1pour ce démarrage.systemd.mask=etsystemd.debug_shell=ttyS0contournent et observent une unité bloquante.- Un chroot utile demande
/dev,/proc,/sys,/run(et l'ESP sur/boot/efi) ;journalctl --root=/mnt -b -0lit le journal de la machine en panne. - Réparations types :
nofailetdaemon-reloadpourfstab; ancien noyau dans « Advanced options » ;MODULES=mostetupdate-initramfs -u -k all;grub-installetupdate-grub; place libérée puis initramfs régénéré. - Accès console ou mode de secours = accès root : IAM, mot de passe GRUB (ANSSI R5, attention à
--unrestricted), chiffrement si les données l'exigent. - La meilleure réparation est celle qu'on n'a pas à faire :
findmnt --verify,mount -a, instantané avant modification, console préparée à froid, runbook testé.
Pour aller plus loin
- Les pages
systemd.special(7),kernel-command-line(7)etsystemd-debug-generator(8)sur freedesktop.org, pour tous les paramètres de démarrage de systemd. - La page
initramfs-tools(7)sur manpages.debian.org, pour les paramètresbreak=,rootdelay=etpanic=de l'initramfs de Debian et Ubuntu, etdracut.cmdline(7)pour son équivalent sur Red Hat. - Le manuel de GRUB, chapitres sur la configuration simple et sur la protection par mot de passe.
- Les guides Scaleway sur les modes de démarrage, la console série et le noyau défaillant.
- Le cours systemd en profondeur, pour les générateurs, les dépendances et les cibles.
- La leçon suivante, Disques et systèmes de fichiers au quotidien, qui ajoute proprement le volume de sauvegarde de
sig-outils.
Sources
- systemd, page de manuel kernel-command-line(7)
- systemd, page de manuel systemd.special(7) : emergency.target et rescue.target
- systemd, page de manuel systemd-debug-generator(8)
- systemd, page de manuel systemd.mount(5) : nofail et x-systemd.device-timeout
- systemd, page de manuel journalctl(1) : --root, --directory et --boot
- systemd v255, code source de systemd-sulogin-shell
- systemd v255, code source des messages de tâches (job.c)
- util-linux, code source de sulogin
- util-linux, code source de findmnt --verify
- initramfs-tools pour Ubuntu 24.04, scripts init, scripts/local et scripts/functions
- Debian, page de manuel initramfs-tools(7) : paramètre break=
- GNU GRUB Manual, Simple configuration handling
- GNU GRUB, code source du mode rescue (rescue_reader.c)
- Documentation du noyau Linux, Linux Magic System Request Key Hacks
- Documentation du noyau Linux, The kernel's command-line parameters
- Scaleway, How to use boot modes on Instances
- Scaleway, Troubleshooting issues with faulty kernel installations
- Scaleway, How to use the serial console to connect to an Instance
- Scaleway CLI, commandes instance et block
- ANSSI, Recommandations de configuration d'un système GNU/Linux (BP-028 v2.0), R5
- Red Hat, RHEL 9 : Resetting the root password (rd.break)