Paquets Linux : stratégie de mise à niveau sûre sans casser la production

Cet article vous a aidé ?

Les mises à jour de paquets sont l’endroit où les bonnes intentions se font confronter à la réalité. Une minute vous êtes « juste en train d’appliquer des correctifs de sécurité », la suivante vous expliquez pourquoi SSH n’accepte plus les clés et pourquoi le load balancer se trémousse.

La solution n’est pas « ne jamais mettre à jour ». La solution, c’est une stratégie qui considère les mises à jour comme de la gestion du changement pour un système vivant : observer, prédire, limiter le rayon d’action, prévoir un rollback, puis exécuter. Si ça ressemble à du jargon SRE, tant mieux. La production ne se préoccupe pas de vos sentiments ; elle se préoccupe de votre plan de retour arrière.

Ce qui casse réellement lors des mises à jour de paquets

La plupart des échecs de mise à jour ne sont pas dus au « gestionnaire de paquets qui est mauvais ». Ce sont des effets secondaires prévisibles du fonctionnement des systèmes Linux en production : les services redémarrent, les dépendances changent, la sémantique des configurations évolue, et les anciennes hypothèses meurent bruyamment.

Mode de rupture n°1 : redémarrages implicites

Beaucoup de paquets incluent des scripts de maintenance qui redémarrent des services (unités systemd, scripts init, hooks postinst). C’est pratique sur un portable. Sur un primaire de base de données, c’est une conversation de carrière.

Et « redémarrer » n’est pas toujours explicite. Certaines mises à jour font une rotation des logs, touchent des fichiers surveillés par systemd, déclenchent l’activation par socket, ou modifient des définitions d’unités. Votre service peut rebondir sans qu’un humain ait jamais tapé systemctl restart.

Mode de rupture n°2 : réalité ABI et libc

Certaines mises à jour se gèrent socialement par un reboot. Mises à jour du noyau. mises à jour de glibc. mises à jour d’OpenSSL, selon la façon dont votre processus le charge. Ce n’est pas du « hot patch et oublier » à moins d’avoir bâti toute une stratégie autour.

Quand libc change, les processus de longue durée peuvent conserver d’anciennes mappages et fonctionner… jusqu’à ce qu’ils forkent, fassent un dlopen, ou empruntent un chemin de code qui attend maintenant une autre version de symbole. C’est le type de panne qui attend le pic de trafic pour se manifester déguisée en mystère.

Mode de rupture n°3 : fusions de config et hypothèses sans surveillance

Les invites de type Debian concernant les changements dans /etc existent pour une raison. Si vous acceptez automatiquement les valeurs du mainteneur, vous pouvez écraser vos réglages. Si vous conservez toujours la configuration locale, vous pouvez manquer de nouvelles directives requises et dégrader silencieusement la sécurité ou la fonctionnalité.

Mode de rupture n°4 : les dépendances qui « vous aident »

Les gestionnaires de paquets sont des solveurs de dépendances. Ils peuvent aussi être des démolisseurs de dépendances. Vous avez demandé une nouvelle version de python3-foo ; il a décidé que cela signifie supprimer une librairie dont un agent de monitoring a besoin, parce qu’on papier rien n’en dépend plus. Sur le papier. Pas dans votre zoo de production.

Mode de rupture n°5 : dérive des dépôts

Incohérences des miroirs, dépôts mixtes, caches obsolètes, versions épinglées, et dépôts tiers avec un empaquetage créatif sont des tueurs silencieux. Vous pensez appliquer « les derniers correctifs de sécurité », mais vous faites en réalité une mise à jour partielle à travers des ensembles incompatibles.

Blague n°1 : Une mise à jour partielle, c’est comme faire la moitié d’un canal radiculaire — techniquement vous avez commencé, mais vous n’aimerez pas la fin.

Mode de rupture n°6 : surprises du système de fichiers et du stockage

Les mises à jour écrivent sur le disque. Beaucoup. Si votre système de fichiers racine est presque plein, vous échouerez en milieu de transaction et vous vous retrouverez dans un purgatoire à moitié configuré. Si vous êtes sur un stockage thin-provisionné, les snapshots peuvent remplir les pools. Si votre IO est déjà serré, les scripts dpkg/rpm deviennent le nouveau vilain de latence.

En tant qu’ingénieur stockage, je le dis franchement : beaucoup d’« échecs de paquets » sont en réalité des « nous avons épuisé notre budget IO » déguisés.

Faits et contexte intéressants (parce que l’histoire se répète)

  • Fait 1 : dpkg de Debian précède apt. apt est devenu le résolveur convivial ; dpkg est resté l’instrument brutal qui désarchive et exécute les scripts des mainteneurs.
  • Fait 2 : Les transactions RPM ont été conçues pour être cohérentes, mais les scriptlets (pre/post install) sont du code arbitraire. Les transactions sont atomiques à peu près ; les scriptlets sont « bonne chance ».
  • Fait 3 : L’idée de séparer « mises à jour de sécurité » et « mises à jour de fonctionnalités » a façonné les modèles de distributions d’entreprise ; c’est pourquoi existent les branches de release stable et les workflows d’errata.
  • Fait 4 : Le live patching du noyau existe (kpatch/kGraft/livepatch), mais il n’élimine pas les reboots pour toujours — les changements complexes, les pilotes et l’espace utilisateur demandent encore un rythme de redémarrage contrôlé.
  • Fait 5 : Systemd a changé la sensation opérationnelle des mises à jour : fichiers d’unités, drop-ins, daemon-reload et activation par socket ont introduit de nouvelles façons pour « rien n’a changé » de changer.
  • Fait 6 : Le mème « pets vs cattle » est devenu populaire parce que les mises à jour manuelles ne montent pas en échelle ; les mises à niveau sûres pour une flotte sont un problème d’orchestration, pas un problème de héros.
  • Fait 7 : La pratique des déploiements canaris vient de l’ingénierie de fiabilité au sens large, mais elle s’applique parfaitement aux mises à jour de paquets : validez sur un sous-ensemble représentatif avant de toaster la flotte.
  • Fait 8 : Le rollback basé sur snapshots est devenu courant en ops non pas parce que les snapshots sont sexy, mais parce qu’ils transforment le « debug en panique » en « revenir en arrière et enquêter ». Btrfs, ZFS et LVM jouent tous ce jeu différemment.

Une idée paraphrasée à garder sur un post-it : les échecs ne sont pas une surprise ; les surprises sont un échec de préparation (paraphrase de Gene Kranz, opérations de mission).

Principes non négociables pour des mises à jour sûres

1) Traitez les mises à jour comme des déploiements

Si votre organisation a du CI/CD pour le code applicatif mais « YOLO update » pour l’OS, vous avez un trou de fiabilité de la taille d’un datacenter. L’OS fait partie du produit.

Rendez les mises à jour observables, étagées et réversibles. Si vous ne pouvez pas revenir en arrière, vous n’effectuez pas une mise à jour — vous jouez au hasard.

2) Définissez l’intention de la mise à jour : sécurité, correction ou fonctionnalité

« Lancer les mises à jour » n’est pas une intention. L’intention, c’est : appliquer des correctifs de sécurité critiques sans sauts de version majeurs, ou passer d’une version mineure X à Y, ou standardiser une série de noyau.

L’intention détermine le choix des dépôts, l’épinglage, la politique de reboot et le niveau de tests requis. La sécurité-seulement peut toujours redémarrer des services. Les mises à jour de fonctionnalités peuvent changer la sémantique des configs. Planifiez en conséquence.

3) Contraignez le rayon d’action avec des canaris et des vagues

Choisissez des canaris représentatifs : même rôle, même forme de trafic, mêmes dépendances critiques, même agent bizarre que tout le monde oublie. Puis déployez en vagues dimensionnées selon votre tolérance à la douleur.

4) Séparez « installer » et « activer »

Installer des paquets, c’est une chose. Les activer (redémarrage de service, reload, reboot) en est une autre. Votre stratégie doit découpler ces étapes autant que possible :

  • Installer pendant les heures ouvrables si nécessaire, mais redémarrer pendant une fenêtre contrôlée.
  • Permettre aux paquets noyau d’atterrir, mais ne redémarrer que quand vous le décidez.
  • Utiliser un ordonnancement de redémarrage de processus pour les bibliothèques qui l’exigent.

5) Ayez toujours une histoire de rollback qui correspond à votre réalité de stockage

Le rollback n’est pas une technique unique. C’est un menu :

  • Rollback par snapshot de système de fichiers (snapshots de sous-vol Btrfs, snapshots ZFS, snapshots LVM) pour un « undo » rapide.
  • Downgrade au niveau paquet en utilisant des paquets en cache ou des versions épinglées.
  • Rollback au niveau image (images immuables, AMI golden, reconstruction d’hôte conteneur).

Choisissez celui que vous pouvez réellement exécuter à 03:00 avec les mains qui tremblent.

6) Ne laissez pas votre gestionnaire de paquets improviser

Épinglez des versions quand vous avez besoin de stabilité. Verrouillez les paquets critiques. Geler les dépôts tiers sauf si vous avez une pipeline de test pour eux. Le contrôle est tout le but.

7) Mesurez l’impact : ce n’est pas « est-ce que ça s’est installé », c’est « est-ce que ça a fait du mal »

Après les mises à jour, validez la santé : réactivité des services, taux d’erreur, saturation, latence, décalage de réplication, messages noyau. Les logs d’installation peuvent être propres alors que vos systèmes se dégradent en silence.

Blague n°2 : La seule chose pire qu’une mise à jour ratée, c’est une mise à jour réussie qui casse la production lentement — comme un film d’horreur avec de meilleurs graphes d’uptime.

Playbook de diagnostic rapide (premier/deuxième/troisième)

Ceci est le playbook pour le cas « nous avons mis à jour des paquets » et maintenant quelque chose ne va pas. Vous n’avez pas de temps pour le debugging philosophique. Il faut trouver le goulot vite.

Premier : confirmez ce qui a changé et si ça a redémarré

  • Identifiez les paquets récemment mis à jour, la version du noyau et si des services ont redémarré.
  • Vérifiez les logs de transaction dpkg/rpm pour des échecs et des invites.
  • Confirmez la corrélation temporelle : « le problème a commencé juste après la mise à jour » est utile, mais seulement si les horodatages correspondent.

Deuxième : vérifiez les signaux de santé système (CPU, mémoire, disque, réseau)

  • Vol CPU pris, file d’exécution, saturation.
  • Pression mémoire et kills OOM.
  • Disque plein, exhaustion d’inodes, IO wait, santé RAID/ZFS pool.
  • Erreurs réseau, problèmes DNS, règles de pare-feu modifiées par des paquets.

Troisième : isolez le composant en panne et décidez rollback vs correction en avant

  • Est-ce un service ou beaucoup ? Un hôte ou la flotte ?
  • Le rollback est-il sûr et rapide ? Si oui, revenez en arrière et stabilisez. Puis analysez.
  • Si le rollback est risqué, atténuez : désactivez la nouvelle fonctionnalité, épinglez la version, redémarrez dans une séquence contrôlée, basculez.

Règle de décision que j’aime

Si l’impact client est actif et que vous avez un chemin de rollback connu-bon qui s’exécute en minutes, vous revenez en arrière d’abord et vous debuggez ensuite. Le debugging de héros pendant un incident, c’est comment on gagne une réputation et on perd du sommeil.

Tâches pratiques avec commandes : ce que vous voyez, ce que ça signifie, ce que vous décidez

Voici les vraies actions. Pas de la théorie. Chaque tâche inclut une commande, un exemple de sortie, ce que ça signifie et la décision à prendre.

Tâche 1 : Identifier ce qui a changé récemment (Debian/Ubuntu)

cr0x@server:~$ grep -E " upgrade | install " /var/log/dpkg.log | tail -n 8
2026-02-04 01:10:22 upgrade openssl:amd64 3.0.2-0ubuntu1.12 3.0.2-0ubuntu1.13
2026-02-04 01:10:24 upgrade libssl3:amd64 3.0.2-0ubuntu1.12 3.0.2-0ubuntu1.13
2026-02-04 01:10:31 upgrade nginx-core:amd64 1.24.0-1ubuntu0.2 1.24.0-1ubuntu0.3
2026-02-04 01:10:32 upgrade nginx:amd64 1.24.0-1ubuntu0.2 1.24.0-1ubuntu0.3
2026-02-04 01:10:41 upgrade systemd 255.4-1ubuntu8.2 255.4-1ubuntu8.3

Ce que ça signifie : Vous avez une timeline des mises à jour. Notez les changements de bibliothèques (libssl3) et de paquets de service (nginx), plus les modifications du gestionnaire système (systemd).

Décision : Si l’incident s’aligne avec une mise à jour de bibliothèque ou de systemd, priorisez les processus utilisant cette bibliothèque et vérifiez les redémarrages/reloads.

Tâche 2 : Identifier ce qui a changé récemment (RHEL/Rocky/Alma/Fedora)

cr0x@server:~$ sudo dnf history list | head
ID     | Command line             | Date and time    | Action(s)      | Altered
--------------------------------------------------------------------------------
42     | upgrade -y               | 2026-02-04 01:05 | Upgrade        | 18
41     | install tcpdump -y       | 2026-01-20 10:12 | Install        | 1

Ce que ça signifie : Un ID de transaction existe. Vous pouvez l’inspecter ou l’annuler.

Décision : Si la mise à jour corrèle, inspectez la transaction 42 et préparez-vous à rollback de paquets spécifiques ou de la transaction complète.

Tâche 3 : Inspecter une transaction DNF pour voir exactement ce qui a bougé

cr0x@server:~$ sudo dnf history info 42
Transaction ID : 42
Begin time     : 2026-02-04 01:05:11
End time       : 2026-02-04 01:06:02
Packages Altered:
  Upgraded openssl-libs-3.0.7-30.el9_3.x86_64 @baseos
           to openssl-libs-3.0.7-31.el9_3.x86_64 @baseos
  Upgraded nginx-1:1.22.1-5.el9.x86_64 @appstream
           to nginx-1:1.22.1-6.el9.x86_64 @appstream

Ce que ça signifie : Les bibliothèques crypto et nginx ont changé. Ce sont des changements à fort rayon d’action car beaucoup de choses lient OpenSSL.

Décision : Planifiez un redémarrage contrôlé des services utilisant OpenSSL (ou planifiez un reboot si la politique l’exige), et vérifiez la compatibilité de la config nginx.

Tâche 4 : Prédire les mises à jour avant de les lancer (APT)

cr0x@server:~$ sudo apt-get -s dist-upgrade
Reading package lists... Done
Building dependency tree... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libc6 libssl3 nginx nginx-core openssl systemd
5 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Ce que ça signifie : libc6 et systemd font partie de la liste. Ce n’est pas « patch rapide », c’est « prévoir des redémarrages et peut-être un reboot ».

Décision : Si c’est un hôte critique, soit (a) vous différerez, (b) vous ferez un staging sur canaris, soit (c) vous planifierez une fenêtre de maintenance.

Tâche 5 : Prédire les mises à jour avant de les lancer (DNF)

cr0x@server:~$ sudo dnf upgrade --assumeno
Last metadata expiration check: 0:12:41 ago on 2026-02-04T00:52:21Z.
Dependencies resolved.
================================================================================
 Package        Arch   Version                Repository             Size
================================================================================
Upgrading:
 nginx          x86_64 1:1.22.1-6.el9         appstream             40 k
 openssl-libs   x86_64 1:3.0.7-31.el9_3       baseos               1.5 M

Transaction Summary
================================================================================
Upgrade  2 Packages

Total download size: 1.6 M
Is this ok [y/N]: N

Ce que ça signifie : Liste claire de ce qui va changer et depuis quel dépôt.

Décision : Si vous voyez des dépôts inattendus (comme EPEL ou un dépôt fournisseur) qui pilotent des paquets cœur, arrêtez et corrigez la politique des dépôts d’abord.

Tâche 6 : Voir quels services ont été redémarrés récemment (journal systemd)

cr0x@server:~$ sudo journalctl --since "2026-02-04 00:55" -u nginx -u ssh -u postgresql --no-pager | tail -n 12
Feb 04 01:10:33 server systemd[1]: Stopping nginx - high performance web server...
Feb 04 01:10:33 server systemd[1]: nginx.service: Deactivated successfully.
Feb 04 01:10:33 server systemd[1]: Started nginx - high performance web server.
Feb 04 01:10:42 server systemd[1]: Reloading OpenBSD Secure Shell server daemon...
Feb 04 01:10:42 server sshd[1240]: Received SIGHUP; restarting.

Ce que ça signifie : nginx a été redémarré (pas juste rechargé), sshd a été rechargé. Cela peut couper des connexions, changer les suites de chiffrement, ou révéler des incompatibilités de configuration.

Décision : Si cet hôte fait partie d’un pool, le drainer avant les mises à jour ; s’il est unique, vous avez besoin d’une politique de redémarrage plus stricte (ou d’une fenêtre de maintenance).

Tâche 7 : Vérifier les décisions de fichiers de configuration en attente (famille Debian)

cr0x@server:~$ sudo dpkg --audit
The following packages have been unpacked but not yet configured:
  nginx
The following packages have been configured but have not had their triggers run:
  libc-bin

Ce que ça signifie : Vous êtes en pleine mise à jour. Le système est dans un état incohérent jusqu’à la fin de la configuration/des triggers.

Décision : Terminez la transaction avant de déboguer les symptômes applicatifs. Exécutez sudo dpkg --configure -a et résolvez les invites volontairement.

Tâche 8 : Compléter un run dpkg cassé en toute sécurité

cr0x@server:~$ sudo dpkg --configure -a
Setting up nginx (1.24.0-1ubuntu0.3) ...
Installing new version of config file /etc/nginx/nginx.conf ...
Processing triggers for libc-bin (2.39-0ubuntu8.3) ...

Ce que ça signifie : Le fichier de config a été remplacé ou fusionné, les triggers libc se sont exécutés. Cela peut changer le comportement à l’exécution.

Décision : Diff immediatement votre ancienne config nginx (depuis les sauvegardes ou la gestion de configuration) et validez la syntaxe nginx avant de remettre le trafic.

Tâche 9 : Valider la config d’un service avant de redémarrer

cr0x@server:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Ce que ça signifie : La config nginx se parse et les contrôles basiques passent. Ce n’est pas un test d’intégration complet, mais cela évite la panne la plus bête.

Décision : Si ça échoue, ne redémarrez pas. Corrigez la config ou revenez en arrière paquet/config avant de toucher le processus en cours d’exécution.

Tâche 10 : Vérifier si un reboot est requis (famille Debian)

cr0x@server:~$ test -f /var/run/reboot-required && echo "reboot required" || echo "no reboot flag"
reboot required

Ce que ça signifie : Le noyau ou des composants userland critiques ont changé. Vous êtes maintenant dans l’état « nouveaux bits sur disque, anciens bits en RAM ».

Décision : Planifiez le reboot dans la prochaine fenêtre de maintenance, ou basculez d’abord si cet hôte est critique.

Tâche 11 : Confirmer quel noyau vous exécutez vs celui installé

cr0x@server:~$ uname -r
6.5.0-21-generic
cr0x@server:~$ dpkg -l | awk '/linux-image-[0-9]/{print $2, $3}' | tail -n 3
linux-image-6.5.0-21-generic 6.5.0-21.21
linux-image-6.5.0-22-generic 6.5.0-22.22
linux-image-generic 6.5.0.22.22

Ce que ça signifie : Vous exécutez 6.5.0-21 mais 6.5.0-22 est installé. Le reboot est en attente.

Décision : Si vous avez besoin de conformité sécurité, vous redémarrez. Si vous avez besoin d’uptime, redémarrez après avoir drainé/basculé. Choisissez honnêtement.

Tâche 12 : Mettre en hold/épingler des paquets critiques pour éviter des sauts majeurs surprises (APT)

cr0x@server:~$ sudo apt-mark hold nginx nginx-core
nginx set on hold.
nginx-core set on hold.

Ce que ça signifie : Ces paquets ne seront pas mis à jour sauf si on les retire de l’hold explicitement.

Décision : Utilisez les holds pour des services critiques en bordure quand vous devez étager les mises à jour. Ne laissez pas en hold pour toujours ; vous reportez le risque, pas le supprimez.

Tâche 13 : Verrouiller une version de paquet (DNF versionlock)

cr0x@server:~$ sudo dnf install -y 'dnf-command(versionlock)'
Last metadata expiration check: 0:03:19 ago on 2026-02-04T01:02:11Z.
Dependencies resolved.
Installed:
  python3-dnf-plugins-core-4.3.0-13.el9.noarch

Complete!
cr0x@server:~$ sudo dnf versionlock add nginx
Adding versionlock on: nginx-1:1.22.1-6.el9.*

Ce que ça signifie : nginx est verrouillé sur le pattern NEVRA courant.

Décision : Verrouillez en production quand vous n’êtes pas prêt à accepter des changements de comportement. Déverrouillez seulement après la validation canari.

Tâche 14 : Revenir en arrière une transaction DNF (quand c’est possible)

cr0x@server:~$ sudo dnf history undo 42
Dependencies resolved.
================================================================================
 Package        Arch   Version                Repository             Size
================================================================================
Downgrading:
 nginx          x86_64 1:1.22.1-5.el9         @appstream             1.9 M
 openssl-libs   x86_64 1:3.0.7-30.el9_3       @baseos                1.5 M

Transaction Summary
================================================================================
Downgrade  2 Packages

Is this ok [y/N]: y
Complete!

Ce que ça signifie : Vous avez inversé la transaction. C’est un des rares rollbacks qui « fonctionnent simplement » dans le monde Linux, quand les dépôts contiennent encore les versions plus anciennes.

Décision : Si le rollback restaure rapidement le service, stoppez le déploiement, épinglez les versions et debuggez en staging.

Tâche 15 : Snapshot avant mise à jour (exemple LVM)

cr0x@server:~$ sudo lvs
  LV   VG   Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root vg0  -wi-ao----  80.00g
cr0x@server:~$ sudo lvcreate -s -n root_preupgrade -L 8G /dev/vg0/root
  Logical volume "root_preupgrade" created.

Ce que ça signifie : Vous avez créé un snapshot avec 8G d’espace COW. Si les écritures le dépassent, le snapshot devient invalide.

Décision : Assurez-vous que l’espace snapshot correspond au volume d’écritures attendu (caches de paquets, logs, churn base de données). Sur des hôtes très occupés, les snapshots LVM peuvent être fragiles — préférez rollback image ou bascule.

Tâche 16 : Snapshot avant mise à jour (exemple ZFS)

cr0x@server:~$ sudo zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
rpool/ROOT      12G   220G    96K   /rpool/ROOT
rpool/ROOT/ubuntu  12G  220G   11G   /
cr0x@server:~$ sudo zfs snapshot rpool/ROOT/ubuntu@preupgrade-2026-02-04

Ce que ça signifie : Le snapshot est instantané. Le rollback est aussi rapide, mais attention aux services qui écrivent constamment.

Décision : Pour les mises à jour OS, les snapshots ZFS sont de l’or. Pour les volumes de données à forte écriture, coordonnez et surveillez l’espace du pool.

Tâche 17 : Vérifier l’espace disque et l’exhaustion d’inodes avant mises à jour

cr0x@server:~$ df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/mapper/vg0-root   80G   74G  2.1G  98% /
cr0x@server:~$ df -i /
Filesystem       Inodes   IUsed   IFree IUse% Mounted on
/dev/mapper/vg0-root 5242880 5241002   1878  100% /

Ce que ça signifie : Vous êtes à court d’inodes. Même si des octets restent, la création de fichiers échouera. dpkg/rpm s’effondrera en milieu de mise à jour.

Décision : Arrêtez. Nettoyez (anciens logs, cache, tmp), puis mettez à jour. Si vous mettez à jour maintenant, vous finirez en mode récupération.

Tâche 18 : Identifier les paquets qui ont modifié des unit files et nécessitent un daemon-reload

cr0x@server:~$ systemctl status nginx | sed -n '1,8p'
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2026-02-04 01:10:33 UTC; 2min ago
       Docs: man:nginx(8)

Ce que ça signifie : Vous voyez où vit le fichier d’unité et si le service est actif. Si des fichiers d’unité ont changé, systemd peut nécessiter un daemon-reload, et des redémarrages ont pu se produire.

Décision : Après des mises à jour touchant des unités systemd, exécutez systemctl daemon-reload pendant une fenêtre contrôlée, et validez que les drop-ins s’appliquent toujours.

Trois mini-récits d’entreprise venus des tranchées

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Ils ont supposé que « les mises à jour de sécurité ne changeront pas le comportement ». Cette hypothèse est une couverture chaude jusqu’à ce qu’elle prenne feu.

Une équipe infra a déployé des mises à jour OpenSSL sur un ensemble de gateways API pendant un jour ouvrable. Ils l’avaient déjà fait. Ils avaient l’automatisation. Ils avaient des graphes. Ils n’avaient pas de règle qui disait « les mises à jour crypto impliquent des redémarrages coordonnés et une validation pour la terminaison TLS ».

La mise à jour du paquet elle-même s’est bien passée. Puis le service a redémarré (scripts post-install, comportement standard), et un sous-ensemble de clients a commencé à échouer les handshakes TLS. Le symptôme immédiat ressemblait à un flapping réseau : échecs intermittents, pas de motif régional clair. Le support a escaladé. L’astreinte a lancé des captures de paquets. C’était moche.

La cause racine n’était pas « OpenSSL a cassé TLS ». La cause racine était une dérive de configuration combinée à des valeurs par défaut plus strictes : un côté s’était reposé sur des chiffrements legacy ; la pile mise à jour a cessé de les tolérer. L’ancien comportement existait parce que la config du gateway avait discrètement divergé entre clusters sur des mois.

La correction n’a pas été un debugging héroïque. La correction a été de revenir en arrière sur le groupe canari affecté, normaliser la config TLS via la gestion de configuration, puis redéployer avec validation. La vraie leçon : si « sécurité seulement » touche l’authentification, la crypto ou l’identité, traitez-la comme un changement de fonctionnalité avec un chapeau sécurité.

Mini-récit 2 : L’optimisation qui s’est retournée

Une équipe plateforme voulait que les mises à jour soient plus rapides. Ils faisaient des cycles de patch fréquents sur des centaines de VMs. Quelqu’un a remarqué que les caches de paquets étaient gros et a pensé : « on va nettoyer agressivement pour gagner de l’espace et accélérer. »

Ils ont ajouté un job nocturne qui purgeait les caches : archives APT, caches DNF, anciens noyaux, tout. L’usage disque avait l’air super. Les dashboards sont devenus plus verts. Tout le monde s’est félicité en silence, parce que personne n’aime célébrer un nettoyage disque publiquement.

Deux semaines plus tard, une mauvaise mise à jour a atterri dans un dépôt tiers et a fait planter en boucle un agent cœur. Le rollback aurait dû être simple : downgrader le paquet et passer à autre chose. Sauf que les anciens fichiers de paquets avaient disparu, et le dépôt avait déjà déplacé la build précédente, et le miroir qu’ils utilisaient ne conservait pas la build antérieure.

Le rollback a exigé de chercher un ancien RPM/DEB, de le tirer d’un store d’artefacts qui ne l’avait pas parfaitement, et de le distribuer manuellement sous pression. Ils ont finalement stabilisé en épinglant et en remplaçant le dépôt, mais le rayon d’action avait déjà coûté cher.

Ils n’ont pas arrêté de nettoyer les caches. Ils ont arrêté de le faire sans réflexion. Ils ont gardé un cache borné des dernières versions connues-bonnes et ont miroiré les dépôts critiques en interne. L’optimisation est géniale quand elle ne retire pas vos sorties d’urgence.

Mini-récit 3 : La pratique ennuyeuse qui a sauvé la mise

Une entreprise de finance avait une politique rébarbative : chaque vague de mise à jour OS exigeait un snapshot (ou image) plus une période de soak canari. Aucune exception. Les ingénieurs se plaignaient. Produit se plaignait. C’était, franchement, peu glamour.

Une nuit, une mise à jour routinière incluait un changement subtil dans une librairie cliente de base de données utilisée par un système batch interne. Le système batch n’était pas fortement monitoré car il « ne s’exécute que la nuit ». Vous voyez venir la suite.

Les hôtes canaris ont exécuté le batch en premier et ont montré des taux d’erreur élevés envers le cluster de base de données. Pas une panne complète, mais suffisamment pour sentir mauvais. Comme le canari était strictement isolé, seule une tranche de jobs a échoué. Le rollback a été immédiat : revert snapshot, épingler la librairie, relancer.

Pendant ce temps, la flotte principale n’avait pas encore mis à jour. La paie n’a pas manqué sa fenêtre. Personne n’a dû écrire un mail d’excuses. La pratique ne semblait pas intelligente ; elle semblait bureaucratique. Et puis elle a sauvé la mise en étant ennuyeuse et correcte.

Checklists / plan étape par étape

Plan A : Mise à jour standard sûre pour une flotte de services (recommandé)

  1. Classifiez le changement. Sécurité uniquement dans une release stable ? Noyau ? libc ? systemd ? Dépôt tiers impliqué ?
  2. Choisissez un ensemble canari. Même rôle, même config, trafic réel. Si vous ne pouvez pas router du vrai trafic, rejouez-le.
  3. Vérifications pré-vol. Espace disque + inodes, santé du pool, décalage de réplication, et baseline de taux d’erreur.
  4. Créez un point de retour. Snapshot ou référence d’image immuable. Vérifiez que vous pouvez réellement revenir.
  5. Simulez la mise à jour. Utilisez -s sur APT ou --assumeno sur DNF. Inspectez les dépôts et les sauts de version.
  6. Installez les paquets. Gardez les redémarrages de services contrôlés. Drain du nœud du load balancer d’abord si applicable.
  7. Activez intentionnellement. Redémarrez les services dans le bon ordre. Rebootez si la politique noyau/libc l’exige.
  8. Validez. Checks synthétiques plus métriques réelles : latence, erreurs, saturation, profondeur de file, handshakes TLS, DNS.
  9. Soak. Laissez-le sous charge réelle un moment. Certaines pannes sont des bombes à retardement (fuites, renégociations, cron).
  10. Déployez en vagues. Étendez à 5 %, 25 %, 50 %, puis le reste. Arrêtez au premier anomalie qui sent le systémique.
  11. Clôturez la boucle. Enregistrez ce qui a changé, ce que vous avez observé, et quels paquets ont déclenché des redémarrages.

Plan B : Hôte unique critique (la réalité douloureuse)

  1. Décidez votre « budget de coupure maximale ». Si c’est proche de zéro, votre vraie solution est la redondance, pas des mises à jour astucieuses.
  2. Prenez un snapshot et une sauvegarde. Snapshot n’est pas une sauvegarde. Faites les deux si vous pouvez.
  3. Arrêtez les mises à jour non supervisées. Vous voulez un changement à la fois, par des humains, avec une horloge et un plan.
  4. Mettez à jour uniquement ce qui est nécessaire. Préférez des correctifs de sécurité ciblés plutôt que des dist-upgrades larges.
  5. Redémarrez un service à la fois. Validez après chaque étape. Si vous rebootez, faites-le une fois, pas cinq fois.

Plan C : Hôtes quasi immuables (meilleur quand c’est possible)

  1. Construisez une nouvelle image avec les paquets mis à jour dans le CI.
  2. Exécutez la suite de tests + smoke tests.
  3. Déployez des instances canaris depuis la nouvelle image.
  4. Basculez le trafic progressivement.
  5. Rollback en terminant les canaris et en renvoyant le trafic, pas en downgrading in-place.

Politiques opérationnelles par défaut que j’appliquerais

  • Les dépôts critiques sont mirrorés en interne, ou au moins mis en cache avec rétention.
  • Les mises à jour noyau atterrissent à tout moment ; les reboots sont planifiés et suivis.
  • Les paquets qui affectent auth/crypto/ssh/dns sont traités comme à haut risque.
  • Chaque vague de mise à jour a une condition de succès mesurable (pas « pas de pages »).
  • Chaque flotte a un anneau canari et un mécanisme de rollback testé trimestriellement.

Erreurs courantes : symptôme → cause racine → correction

1) Symptom : « apt upgrade » bloque sur une invite dans l’automatisation

Cause racine : dpkg attend une décision interactive concernant un fichier de config ou la politique de redémarrage d’un service.

Correction : Ne supprimez pas les invites aveuglément. Préseed les décisions ou utilisez une politique : gérez les configs via la gestion de configuration ; utilisez le mode non interactif avec des options dpkg explicites seulement quand vous comprenez les conséquences.

2) Symptom : les sessions SSH se coupent pendant le patching

Cause racine : reload/restart de sshd déclenché par des scripts de paquets, ou une mise à jour de dépendance entraînant systemd à redémarrer des unités.

Correction : Utilisez un accès console/série pour les mises à jour. Drainer les hôtes d’abord. Envisagez needrestart (Debian/Ubuntu) pour gérer la visibilité des redémarrages, et planifiez les redémarrages volontairement.

3) Symptom : le service ne démarre pas après la mise à jour ; la config semble « inchangée »

Cause racine : Le schéma de config du service a changé, ou les valeurs par défaut ont changé ; votre ancienne config échoue maintenant la validation.

Correction : Lancez les commandes natives de test de config (nginx -t, sshd -t, named-checkconf, etc.) avant le redémarrage. Comparez les changements de config packagés. Revenez en arrière si nécessaire.

4) Symptom : segfaults aléatoires après une mise à jour libc/OpenSSL, mais seulement plus tard

Cause racine : Les processus longue durée conservent d’anciennes mappings ; les problèmes apparaissent lors d’un fork/dlopen ou sur des chemins rares.

Correction : Planifiez des redémarrages coordonnés pour les daemons affectés, ou faites un reboot. Suivez « processes using deleted libraries » et redémarrez-les.

5) Symptom : Le gestionnaire de paquets indique « no space left on device » en milieu de mise à jour

Cause racine : Système de fichiers racine plein, exhaustion d’inodes, ou espace COW de snapshot épuisé.

Correction : Libérez de l’espace et des inodes d’abord ; augmentez l’espace snapshot ou supprimez-le ; puis relancez la configuration (dpkg --configure -a / retentez la transaction). Évitez des marges minces sur les partitions root.

6) Symptom : DNF/YUM veut supprimer la moitié du monde

Cause racine : Dépôts mixtes, mismatch de streams modulaires, ou dépendances obsolètes provenant d’un dépôt désactivé.

Correction : Arrêtez et corrigez la cohérence des dépôts. Verrouillez les streams. Mirror les dépôts. N’acceptez pas une transaction qui supprime des paquets runtime critiques.

7) Symptom : Après la mise à jour, le CPU va bien mais la latence explose

Cause racine : IO wait causé par des scripts de paquets, rotation de logs, triggers de maintenance de base de données, ou problèmes de filesystem révélés par un nouveau comportement.

Correction : Regardez les stats IO et la santé du stockage. Déplacez les mises à jour vers des fenêtres à faible IO, limitez-les, ou éloignez le trafic pendant les mises à jour.

8) Symptom : « Tout est à jour » mais les scanners de vulnérabilités se plaignent encore

Cause racine : Le noyau en cours d’exécution est ancien ; reboot en attente. Ou les scanners se basent sur des chaînes de versions brutes ignorant les backports.

Correction : Confirmez les versions en cours d’exécution (uname -r). Établissez une conformité des reboots. Pour la confusion des backports, alignez la politique du scanner sur les errata du fournisseur plutôt que sur des chaînes de version brutes.

FAQ

1) Dois-je exécuter des unattended upgrades sur des serveurs de production ?

Pas sur quoi que ce soit d’étatful ou en face client sauf si vous avez conçu autour : canaris, rollbacks automatisés et contrôle sûr des redémarrages. Pour de petits pools stateless derrière un load balancer, c’est acceptable avec des garde-fous stricts.

2) « Mises à jour de sécurité seulement » est-ce vraiment plus sûr ?

Généralement plus sûr que des mises à jour larges. Mais les mises à jour touchant la crypto, l’auth, le DNS, les noyaux et les runtimes cœur peuvent toujours changer le comportement. Traitez-les comme à haut risque même si elles sont étiquetées « sécurité ».

3) Comment empêcher les services de redémarrer pendant les mises à jour de paquets ?

Vous pouvez réduire les redémarrages surprises mais pas les éliminer universellement. Sur les systèmes Debian, vous pouvez gérer le comportement de restart avec des outils de politique et des fenêtres de changement disciplinées. Opérationnellement, l’approche robuste est : drainer l’hôte, mettre à jour, puis redémarrer intentionnellement.

4) Quelle est la méthode de rollback la plus sûre ?

Pour les mises à jour in-place : le rollback par snapshot de système de fichiers est le plus rapide si votre stockage le supporte et que vous l’avez testé. Pour les flottes : remplacer des instances par une image connue-bonne est plus propre. Les downgrades de paquets fonctionnent tant que les dépôts offrent encore les anciennes builds.

5) Dois‑je redémarrer après chaque mise à jour du noyau ?

Si vous voulez que le correctif de sécurité s’applique, oui, finalement. Vous pouvez regrouper les reboots. Installez les noyaux dès qu’ils arrivent, puis redémarrez selon un calendrier après drain/basculement.

6) Comment savoir quels processus nécessitent un redémarrage après une mise à jour de bibliothèque ?

Cherchez les processus utilisant des bibliothèques supprimées ou remplacées (les outils varient selon la distro), et traitez les mises à jour glibc/OpenSSL comme un signal pour redémarrer les services clés. Si vous ne pouvez pas énumérer en toute confiance, faites un reboot dans une fenêtre.

7) Pourquoi les mises à jour cassent parfois une seule zone de disponibilité ?

Dérive des dépôts, latence des miroirs, ou dérive subtile des configurations. Si une zone a tiré une build légèrement différente ou avait une config plus ancienne, vous verrez des pannes asymétriques. Mirror en interne et appliquez la cohérence de config.

8) Quelle est la différence entre « upgrade » et « dist-upgrade » sur Debian/Ubuntu ?

upgrade est conservateur : il met à jour les paquets sans supprimer ou installer de nouvelles dépendances quand ce serait nécessaire. dist-upgrade (ou full-upgrade) peut ajouter/supprimer des paquets pour résoudre les dépendances. Le conservateur est plus sûr ; le full est parfois nécessaire.

9) À quelle fréquence devons-nous patcher ?

Assez souvent pour que chaque cycle de patch soit ennuyeux. Mensuel est courant, hebdomadaire pour des flottes internet-facing à risque élevé, et hors-cycle d’urgence pour les vulnérabilités critiques. L’objectif réel est la prévisibilité : deltas plus petits, moins de surprises.

10) Devons‑nous épingler des versions pour toujours en production ?

Non. L’épinglage est un outil de staging, pas un mode de vie. Utilisez-le pour gagner du temps de validation, puis avancez par vagues contrôlées. Les épingles permanentes deviennent des couches fossiles qui explosent lors de la prochaine migration majeure.

Conclusion : prochaines étapes que vous pouvez faire cette semaine

Si votre stratégie actuelle de mise à jour est « lancer les updates et espérer », vous n’avez pas besoin de plus d’espoir. Vous avez besoin de garde-fous.

  1. Définissez l’intention de mise à jour pour chaque environnement : sécurité-only vs complet, politique noyau, cadence des reboots.
  2. Mettez en place un anneau canari qui reçoit les mises à jour en premier et sature sous trafic réel.
  3. Implémentez le rollback : snapshots pour les systèmes in-place ou rollback image pour les flottes. Testez-le, pas seulement le documenter.
  4. Contrôlez les dépôts : supprimez les dépôts tiers surprises, ajoutez des mirrors/caches avec rétention, et verrouillez les streams de paquets critiques.
  5. Opérationnalisez la validation : tests de config, checks de santé, et une checklist post-mise à jour qui inclut « qu’est-ce qui a redémarré ? »

Faites cela, et les mises à jour cesseront d’être un rituel superstitieux. Elles redeviendront ce qu’elles auraient dû être depuis le départ : un changement de routine avec un rayon d’action connu, un résultat mesuré, et une sortie propre quand les choses deviennent étranges.

← Précédent
ZFS : la réplique que vous croyiez avoir — comment auditer la réplication pour de vrai
Suivant →
Windows dans une VM, GPU réel, performance quasi‑native : Guide de configuration IOMMU

Laisser un commentaire