Intro
La mise à niveau de systemd est courante sur les Linux modernes, mais elle touche PID 1, la supervision des services, la journalisation et l'ordre de démarrage. Une modification mal préparée peut laisser un hôte en mode d'urgence ou casser des services critiques. Ce guide présente un parcours pratique, sans drame, pour upgrader ou migrer vers des versions plus récentes de systemd, valider le comportement et récupérer rapidement en cas de problème. Vous obtiendrez un workflow clair, un pilote local sûr, des commandes concrètes et des exemples pour services et timers.
Workflow Overview
Suivez ces étapes pour rendre les upgrades prévisibles :
- Évaluer : inventorier services, timers, drop-ins et scripts personnalisés. Repérer tout élément non standard.
- Préparer la sécurité : capturer les infos OS et paquets, activer les journaux persistants, préparer snapshots et commandes de rollback.
- Piloter : exécuter une petite tâche d'upgrade mesurable sur un hôte ou VM non critique.
- Stager et upgrader : mettre à jour les paquets systemd et bibliothèques associées, puis planifier une fenêtre de redémarrage contrôlée.
- Valider : confirmer les cibles de démarrage, services, timers et le timing de la chaîne critique. Inspecter les logs pour détecter les régressions.
- Migrer les unités : convertir les scripts legacy ou affiner les types d'unités et le sandboxing avec les exemples ci‑dessous.
- Observer : surveiller pendant 24‑72 heures. Revenir en arrière rapidement si des régressions apparaissent.
Preparation Checklist
Exécutez les commandes sur un hôte de test d'abord, puis en production pendant une fenêtre avec accès console.
Baseline et inventaire
- Enregistrer les versions actuelles :
systemctl --version
cat /etc/os-release
- Lister les unités activées et les overrides :
systemctl list-unit-files --type=service --state=enabled
systemd-delta
- Inventorier timers et jobs cron :
systemctl list-timers --all
crontab -l
sudo ls -1 /etc/cron.*
Journaux et journalisation
- Assurer la journalisation persistante pour lire les logs après redémarrage :
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
Console et accès
- S'assurer d'un accès out‑of‑band (série/IPMI/tty) au cas où SSH ne remonterait pas.
- Garder un shell root ouvert sur la console ou une session tmux ; éviter de se déconnecter en plein upgrade.
Snapshots et chemin de downgrade
- Snapshot système de fichiers recommandé :
- LVM :
sudo lvcreate -s -n root-pre-sd -L 10G /dev/vg/root - Btrfs :
sudo btrfs subvolume snapshot -r / @ /@snapshots/@pre-systemd - Préparation rollback paquets :
- Debian/Ubuntu :
sudo apt-cache policy systemd; noter la version candidate et celle installée. Optionnelapt download systemd systemd-sysv libsystemd0 - RHEL/Fedora :
sudo dnf history list systemd; noter le dernier NVR connu bon
Fenêtre de changement
- Planifier une fenêtre de redémarrage même si non strictement requis. Les redémarrages révèlent les problèmes d'ordre à valider.
Local Pilot Plan
Commencez avec un hôte ou VM unique et un objectif mesurable. Exemple de pilote : upgrader systemd, convertir un cron en timer, vérifier le démarrage et la santé des services.
Périmètre du pilote
- Hôte : VM non critique qui reflète les unités de production.
- Changement 1 : upgrader systemd vers la version cible.
- Changement 2 : convertir un petit job cron quotidien en timer systemd.
- Critères de succès :
- Hôte redémarre proprement vers la cible par défaut.
- 0 unités en échec (
systemctl --failed). - Timer se déclenche et se termine une fois avec code de sortie 0.
- Aucune nouvelle erreur de priorité
errou supérieure dansjournalctl -b -p err..alert.
Commandes du pilote
- Valider la baseline :
systemctl --version
systemctl list-units --failed
journalctl -b -p warning..alert --no-pager | tail -n +1
- Après upgrade et redémarrage, relancer les mêmes vérifications et comparer.
Upgrade Execution
Debian/Ubuntu (apt)
- Mettre à jour les méta‑données et revoir les versions :
sudo apt-get update
apt-cache policy systemd
- Upgrader seulement systemd d'abord pour limiter le blast radius :
sudo apt-get install --yes systemd libsystemd0
- Planifier une fenêtre de redémarrage contrôlée :
sudo systemctl reboot
RHEL/CentOS/Alma/Rocky/Fedora (dnf)
- Rafraîchir les méta‑données et revoir les versions :
sudo dnf --refresh info systemd
- Upgrader systemd et bibliothèques :
sudo dnf upgrade -y systemd systemd-libs
- Redémarrer pendant la fenêtre de changement :
sudo systemctl reboot
Hygiène post‑upgrade
- Recharger les fichiers d'unité pour prendre en compte les changements d'empaquetage :
sudo systemctl daemon-reload
- Nettoyer tout état d'unité obsolète si nécessaire :
sudo systemctl reset-failed
Validation
Démarrage et cibles
- Confirmer la cible par défaut et l'accessibilité :
systemctl get-default
systemctl is-system-running
- Inspecter la chaîne critique pour services lents ou bloqués :
systemd-analyze critical-chain
Services et sockets
- Rechercher échecs et état dégradé :
systemctl --failed
- Valider services clés (exemple nginx) :
systemctl status nginx
sudo journalctl -u nginx -b --no-pager | tail -50
Journaux et erreurs
- Scanner les messages haute priorité depuis le boot :
journalctl -b -p err..alert --no-pager
Timers et tâches
- Lister et vérifier timers :
systemctl list-timers
- Déclencher un timer à l'avance pour test :
sudo systemctl start mybackup.timer
sudo systemctl status mybackup.service
Vérification d'unités
- Vérifier statiquement les fichiers d'unité pour problèmes courants :
sudo systemd-analyze verify /etc/systemd/system/*.service
Réseau et accès distant
- Confirmer la cible network-online et l'accessibilité multi‑user :
systemctl status NetworkManager.service | head -20
systemctl status systemd-networkd.service | head -20
Si quelque chose semble anormal, capturer les logs et passer au rollback ou à la remédiation avant d'élargir le déploiement.
Migration Examples
Example A : Convertir une application SysV en service natif
Supposons /etc/init.d/myapp gérait un binaire simple. Le remplacer par une unité native à /etc/systemd/system/myapp.service :
[Unit]
Description=MyApp REST API
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=-/etc/myapp/env
ExecStart=/opt/myapp/bin/myapp --port=8080
Restart=on-failure
RestartSec=2s
# Durcissement ressources et sécurité
LimitNOFILE=65536
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
NoNewPrivileges=true
AmbientCapabilities=
[Install]
WantedBy=multi-user.target
Activer et démarrer :
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
Valider :
systemctl status myapp
journalctl -u myapp -b --no-pager | tail -100
Example B : Ajouter un drop-in pour tuner un service existant (nginx)
Créer un drop-in pour augmenter la limite de descripteurs sans modifier l'unité fournie :
sudo systemctl edit nginx
Cela crée /etc/systemd/system/nginx.service.d/override.conf avec :
[Service]
LimitNOFILE=131072
Appliquer et valider :
sudo systemctl daemon-reload
sudo systemctl restart nginx
systemctl show nginx -p LimitNOFILE
Example C : Convertir un job cron en timer
Cron original (quotidien à 02:15) : sauvegarde /srv vers /backups.
Créer service /etc/systemd/system/backup.service :
[Unit]
Description=Sauvegarde nocturne
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/backup.sh /srv /backups
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=6
Créer timer /etc/systemd/system/backup.timer :
[Unit]
Description=Lancer la sauvegarde nocturne à 02:15
[Timer]
OnCalendar=*-*-* 02:15:00
RandomizedDelaySec=5m
Persistent=true
[Install]
WantedBy=timers.target
Activer et tester :
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers | grep backup
sudo systemctl start backup.service
systemctl status backup.service
Example D : Vérifier et durcir les unités après upgrade
- Chercher deltas et directives dépréciées :
systemd-delta
sudo systemd-analyze verify /etc/systemd/system/*.service
- Envisager
Type=notifypour services signalant leur prêts, ou ajouterExecStartPrepour échouer vite.
Rollback and Recovery
Décisions de rollback rapides
- Si l'hôte démarre mais services clés échouent : downgrader les paquets et rétablir les changements d'unités.
- Si l'hôte n'atteint pas multi‑user : démarrer en rescue, restaurer depuis snapshot ou downgrader systemd.
Démarrer en rescue ou emergency
Au chargeur de démarrage, éditer la ligne de commande kernel pour inclure :
systemd.unit=rescue.targetsystemd.unit=emergency.target
Une fois dans le shell rescue, inspecter les logs :
journalctl -xb --no-pager | less
Downgrade de paquets
Debian/Ubuntu :
apt-cache madison systemd
sudo apt-get install systemd=VERSION libsystemd0=VERSION
sudo apt-mark hold systemd libsystemd0 # optionnel
RHEL/Fedora :
sudo dnf history systemd
sudo dnf downgrade -y systemd systemd-libs
Restauration de snapshot
LVM :
sudo lvconvert --merge /dev/vg/root-pre-sd
sudo reboot
Btrfs :
- Monter le snapshot et restaurer ou utiliser une stratégie de rollback de sous‑volume adaptée à votre layout.
Rollback des changements d'unités
- Supprimer ou renommer les drop-ins sous
/etc/systemd/system/*.d - Restaurer les fichiers d'unité précédents depuis la sauvegarde, puis :
sudo systemctl daemon-reload
sudo systemctl restart affected.service
Post‑rollback
Documenter la cause racine et ajuster la checklist de validation avant la prochaine tentative.
Conclusion
Traitez les upgrades et migrations systemd comme un changement incrémental et testable, pas comme un saut dans l'inconnu. Inventoriez d'abord, préparez un rollback, lancez un pilote étroit, puis upgrader, valider et surveiller avant déploiement large. Utilisez des unités et timers natifs avec drop-ins pour placer vos services personnalisés sous supervision fiable. Gardez vos chemins de rescue et downgrade documentés et testés. Prochaines étapes : exécuter le pilote sur un hôte non critique cette semaine, convertir un job cron en timer, et rédiger un runbook court pour votre fenêtre de changement production.