🛠 Outils IT
🛠 78 outils 📚 32 docs
🤖 Assistant

Systemd - Gestion des Services Linux

1. Introduction a systemd

1.1 Qu'est-ce que systemd ?

systemd est le systeme d'initialisation (init system) utilise par la majorite des distributions Linux modernes (Debian, Ubuntu, CentOS/RHEL, Fedora, Arch, etc.). Il est le premier processus lance par le noyau au demarrage du systeme et porte toujours le PID 1.

systemd remplace l'ancien systeme SysVinit (scripts dans /etc/init.d/) et apporte de nombreuses ameliorations :

  • Demarrage parallele : les services sont lances en parallele, ce qui accelere considerablement le boot
  • Gestion des dependances : systemd resout automatiquement les dependances entre services
  • Activation a la demande : les services peuvent etre demarres uniquement lorsqu'ils sont sollicites (socket activation)
  • Journalisation centralisee : les logs de tous les services sont centralises via journald
  • Supervision des processus : redemarrage automatique des services en cas de crash (via cgroups)
  • Interface unifiee : une seule commande (systemctl) pour gerer tous les services

1.2 Concepts fondamentaux

systemd s'articule autour de la notion d'unites (units). Chaque unite represente une ressource que systemd sait gerer :

  • .service : un service / daemon (ex: nginx.service, sshd.service)
  • .socket : un socket reseau ou IPC pour l'activation a la demande
  • .timer : un minuteur planifie (alternative a cron)
  • .target : un groupe d'unites (equivalent des runlevels SysVinit)
  • .mount : un point de montage
  • .path : surveillance d'un chemin dans le systeme de fichiers
  • .slice : gestion des ressources via cgroups
  • .device : un peripherique detecte par udev

1.3 Arborescence des fichiers

Les fichiers d'unites systemd se trouvent dans plusieurs repertoires, par ordre de priorite :

# Fichiers fournis par les paquets (ne PAS modifier)
/usr/lib/systemd/system/

# Fichiers personnalises par l'administrateur (priorite la plus haute)
/etc/systemd/system/

# Fichiers generes dynamiquement au runtime
/run/systemd/system/
Astuce : Placez toujours vos services personnalises dans /etc/systemd/system/. Ce repertoire a la priorite la plus elevee et ne sera pas ecrase par les mises a jour de paquets.
Attention : Ne modifiez jamais directement les fichiers dans /usr/lib/systemd/system/. Utilisez plutot systemctl edit pour creer un override propre dans /etc/systemd/system/.

2. systemctl - Commandes essentielles

systemctl est la commande principale pour interagir avec systemd. Elle permet de controler l'etat des services et du systeme.

2.1 Demarrer / Arreter / Redemarrer un service

# Demarrer un service
sudo systemctl start nginx

# Arreter un service
sudo systemctl stop nginx

# Redemarrer un service (arret + demarrage)
sudo systemctl restart nginx

# Recharger la configuration du service (sans interruption)
sudo systemctl reload nginx

# Recharger si possible, sinon redemarrer
sudo systemctl reload-or-restart nginx
Astuce : Preferez reload a restart quand c'est possible (ex: Apache, Nginx, PHP-FPM). Le reload applique la nouvelle configuration sans couper les connexions existantes.

2.2 Activer / Desactiver au demarrage

# Activer un service au demarrage (cree un lien symbolique)
sudo systemctl enable nginx

# Activer ET demarrer immediatement
sudo systemctl enable --now nginx

# Desactiver un service au demarrage (supprime le lien symbolique)
sudo systemctl disable nginx

# Desactiver ET arreter immediatement
sudo systemctl disable --now nginx
Astuce : L'option --now combine l'activation/desactivation avec le demarrage/arret en une seule commande. Tres pratique au quotidien.

2.3 Verifier l'etat d'un service

# Afficher l'etat complet d'un service (PID, memoire, logs recents...)
systemctl status nginx

# Verifier si un service est actif (running)
systemctl is-active nginx

# Verifier si un service est active au demarrage
systemctl is-enabled nginx

# Verifier si un service est en echec
systemctl is-failed nginx

Exemple de sortie de systemctl status :

$ systemctl status nginx
● 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 Mon 2025-01-20 09:15:32 CET; 2 days ago
       Docs: man:nginx(8)
   Main PID: 1234 (nginx)
      Tasks: 5 (limit: 4915)
     Memory: 12.3M
        CPU: 1.542s
     CGroup: /system.slice/nginx.service
             ├─1234 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─1235 "nginx: worker process"

Jan 20 09:15:32 srv01 systemd[1]: Starting A high performance web server...
Jan 20 09:15:32 srv01 systemd[1]: Started A high performance web server.

2.4 Commandes systeme

# Redemarrer le serveur
sudo systemctl reboot

# Eteindre le serveur
sudo systemctl poweroff

# Mettre en veille
sudo systemctl suspend

# Hiberner
sudo systemctl hibernate

3. Gestion des services

3.1 Lister les services

# Lister toutes les unites chargees (services, timers, sockets, etc.)
systemctl list-units

# Lister uniquement les services
systemctl list-units --type=service

# Lister les services actifs uniquement
systemctl list-units --type=service --state=active

# Lister les services en echec
systemctl list-units --type=service --state=failed

# Lister tous les fichiers d'unites installes (actives et inactives)
systemctl list-unit-files

# Lister les fichiers d'unites de type service
systemctl list-unit-files --type=service

# Filtrer les services actives au demarrage
systemctl list-unit-files --type=service --state=enabled
Astuce : Pour une vue rapide des services en erreur : systemctl --failed. C'est la premiere commande a lancer en cas de probleme.

3.2 Masquer / Demasquer un service

Le masquage est plus fort que la desactivation : il empeche completement un service d'etre demarre, meme manuellement.

# Masquer un service (cree un lien symbolique vers /dev/null)
sudo systemctl mask nginx

# Demasquer un service
sudo systemctl unmask nginx
Attention : Un service masque ne peut pas etre demarre, meme manuellement avec systemctl start. Utilisez cette fonctionnalite avec precaution. Elle est utile pour empecher un service dangereux ou conflictuel de demarrer accidentellement.

3.3 Afficher les proprietes d'un service

# Afficher toutes les proprietes d'un service
systemctl show nginx

# Afficher une propriete specifique
systemctl show nginx --property=MainPID
systemctl show nginx --property=ActiveState
systemctl show nginx --property=MemoryCurrent

# Voir le fichier d'unite complet
systemctl cat nginx

3.4 Dependances

# Voir les dependances d'un service (arborescence)
systemctl list-dependencies nginx

# Voir les dependances inversees (qui depend de ce service)
systemctl list-dependencies nginx --reverse

3.5 Recharger la configuration de systemd

# Apres toute modification d'un fichier .service, recharger systemd
sudo systemctl daemon-reload
Attention : Apres chaque modification d'un fichier d'unite (.service, .timer, etc.), vous DEVEZ executer daemon-reload pour que systemd prenne en compte les changements. Sans cela, l'ancienne version du fichier reste en memoire.

4. Creer un service personnalise

4.1 Structure d'un fichier .service

Un fichier d'unite .service se compose de trois sections principales :

[Unit]
# Metadonnees et dependances
Description=Description du service
Documentation=https://example.com/docs
After=network.target          # Demarre apres le reseau
Wants=network-online.target   # Souhaite que le reseau soit en ligne
Requires=mysql.service        # Necessite MySQL (arret si MySQL s'arrete)

[Service]
# Configuration du service lui-meme
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/monapp
ExecStartPre=/opt/monapp/pre-start.sh
ExecStart=/opt/monapp/start.sh
ExecStartPost=/opt/monapp/post-start.sh
ExecStop=/opt/monapp/stop.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=monapp

[Install]
# Quand activer ce service
WantedBy=multi-user.target

4.2 Directives importantes de [Unit]

  • Description : texte descriptif affiche dans systemctl status
  • After : ordonne le demarrage apres les unites listees (ordre uniquement, pas de dependance)
  • Before : ordonne le demarrage avant les unites listees
  • Requires : dependance forte - si l'unite requise echoue, ce service est arrete aussi
  • Wants : dependance faible - si l'unite souhaitee echoue, ce service continue
  • BindsTo : comme Requires, mais encore plus strict (arret si l'unite liee s'arrete)
  • Conflicts : les unites listees seront arretees quand ce service demarre

4.3 Directives importantes de [Service]

  • Type : type de service (voir section 5)
  • User / Group : utilisateur et groupe sous lesquels le service s'execute
  • WorkingDirectory : repertoire de travail du processus
  • ExecStart : commande de demarrage (obligatoire)
  • ExecStop : commande d'arret (par defaut : SIGTERM)
  • ExecReload : commande de rechargement de la configuration
  • Restart : politique de redemarrage (no, on-success, on-failure, on-abnormal, on-abort, always)
  • RestartSec : delai avant redemarrage (en secondes)
  • TimeoutStartSec : timeout pour le demarrage
  • TimeoutStopSec : timeout pour l'arret
  • Environment : variables d'environnement (Environment=KEY=value)
  • EnvironmentFile : fichier contenant les variables d'environnement

4.4 Exemple complet : application Node.js

# /etc/systemd/system/monapp-node.service
[Unit]
Description=Mon Application Node.js
Documentation=https://wiki.interne/monapp
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=nodeapp
Group=nodeapp
WorkingDirectory=/opt/monapp
ExecStart=/usr/bin/node /opt/monapp/server.js
Restart=on-failure
RestartSec=10
StartLimitIntervalSec=60
StartLimitBurst=3

# Variables d'environnement
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/opt/monapp/.env

# Securite
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/monapp/data /var/log/monapp
PrivateTmp=true

# Logs
StandardOutput=journal
StandardError=journal
SyslogIdentifier=monapp-node

[Install]
WantedBy=multi-user.target

4.5 Exemple complet : script de backup

# /etc/systemd/system/backup-quotidien.service
[Unit]
Description=Sauvegarde quotidienne des donnees
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=root
ExecStart=/opt/scripts/backup.sh
StandardOutput=journal
StandardError=journal
SyslogIdentifier=backup-quotidien

# Timeout genereux pour les sauvegardes
TimeoutStartSec=3600

[Install]
WantedBy=multi-user.target

4.6 Deployer un service personnalise

# 1. Creer le fichier d'unite
sudo nano /etc/systemd/system/monapp.service

# 2. Recharger la configuration de systemd
sudo systemctl daemon-reload

# 3. Activer le service au demarrage
sudo systemctl enable monapp

# 4. Demarrer le service
sudo systemctl start monapp

# 5. Verifier l'etat
systemctl status monapp

4.7 Modifier un service existant (override)

Pour modifier un service fourni par un paquet sans toucher au fichier original :

# Cree un fichier override dans /etc/systemd/system/nginx.service.d/override.conf
sudo systemctl edit nginx

Exemple d'override pour augmenter les limites de fichiers ouverts :

# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
# Pour editer le fichier complet (copie integrale)
sudo systemctl edit --full nginx

# Apres modification, recharger
sudo systemctl daemon-reload
sudo systemctl restart nginx
Astuce : Utilisez toujours systemctl edit plutot que d'editer manuellement les fichiers. Cela cree proprement les repertoires d'override et lance automatiquement daemon-reload a la sauvegarde.

5. Types de services

Le parametre Type= dans la section [Service] definit comment systemd interprete le cycle de vie du processus.

5.1 Type=simple (par defaut)

Le processus lance par ExecStart est le processus principal du service. systemd considere le service comme demarre immediatement apres le fork.

[Service]
Type=simple
ExecStart=/usr/bin/monapp --foreground

Utilisation : applications qui restent au premier plan (Node.js, Python, Go, etc.)

5.2 Type=forking

Le processus lance par ExecStart fork un processus enfant puis se termine. Le processus enfant devient le processus principal. systemd utilise le PIDFile pour suivre le processus.

[Service]
Type=forking
PIDFile=/var/run/monapp.pid
ExecStart=/usr/sbin/monapp -d

Utilisation : daemons traditionnels qui se detachent du terminal (Apache httpd en mode prefork, MySQL classique, etc.)

Astuce : Si possible, preferez Type=simple avec l'option foreground de votre application. C'est plus fiable et plus simple que Type=forking.

5.3 Type=oneshot

Le processus s'execute et se termine. systemd attend la fin de l'execution avant de considerer le service comme actif. Ideal pour les scripts ponctuels.

[Service]
Type=oneshot
ExecStart=/opt/scripts/initialisation.sh
RemainAfterExit=yes

Utilisation : scripts d'initialisation, taches ponctuelles, commandes de configuration. L'option RemainAfterExit=yes permet au service d'apparaitre comme "active" meme apres la fin du script.

5.4 Type=notify

Similaire a simple, mais le processus envoie une notification a systemd (via sd_notify()) quand il est pret. Cela permet a systemd de savoir exactement quand le service est operationnel.

[Service]
Type=notify
ExecStart=/usr/sbin/monapp
NotifyAccess=main

Utilisation : applications compatibles avec le protocole sd_notify (certaines versions de Nginx, PostgreSQL, etc.)

5.5 Type=exec

Similaire a simple, mais systemd attend que le binaire soit effectivement execute (apres le exec()) avant de considerer le service comme demarre.

[Service]
Type=exec
ExecStart=/usr/bin/monapp

5.6 Tableau recapitulatif

Type Comportement Cas d'usage
simple Le processus ExecStart EST le service Apps en foreground (Node, Python, Go)
forking Le processus fork puis se termine Daemons classiques (Apache, MySQL)
oneshot Execute puis se termine Scripts, taches ponctuelles
notify Notifie systemd quand pret Apps compatibles sd_notify
exec Pret apres exec() reussi Alternative plus precise a simple

6. journalctl - Gestion des logs

journalctl est l'outil de consultation des logs du journal systemd (systemd-journald). Il centralise les logs de tous les services, du noyau et des messages syslog.

6.1 Commandes de base

# Voir tous les logs (du plus ancien au plus recent)
journalctl

# Voir les logs en temps reel (comme tail -f)
journalctl -f

# Voir les N derniers messages
journalctl -n 50

# Afficher les logs sans pagination (utile pour les scripts)
journalctl --no-pager

# Afficher les logs en format court avec horodatage precis
journalctl -o short-precise

6.2 Filtrer par service

# Logs d'un service specifique
journalctl -u nginx

# Logs d'un service en temps reel
journalctl -u nginx -f

# Les 100 derniers logs d'un service
journalctl -u nginx -n 100

# Logs de plusieurs services
journalctl -u nginx -u php-fpm

# Logs d'un service depuis le dernier demarrage
journalctl -u nginx -b

6.3 Filtrer par date et heure

# Logs depuis une date specifique
journalctl --since "2025-01-15"

# Logs entre deux dates
journalctl --since "2025-01-15 08:00:00" --until "2025-01-15 18:00:00"

# Logs de la derniere heure
journalctl --since "1 hour ago"

# Logs des 30 dernieres minutes
journalctl --since "30 min ago"

# Logs d'aujourd'hui
journalctl --since today

# Logs d'hier
journalctl --since yesterday --until today

6.4 Filtrer par priorite (severite)

Les niveaux de priorite suivent la norme syslog :

# 0 = emerg   : systeme inutilisable
# 1 = alert   : action immediate requise
# 2 = crit    : conditions critiques
# 3 = err     : erreurs
# 4 = warning : avertissements
# 5 = notice  : normal mais significatif
# 6 = info    : informationnel
# 7 = debug   : debug

# Afficher uniquement les erreurs et plus grave
journalctl -p err

# Afficher les warnings et plus grave
journalctl -p warning

# Erreurs d'un service specifique
journalctl -u nginx -p err

# Combiner avec une periode
journalctl -p err --since "1 hour ago"

6.5 Filtrer par boot

# Logs du boot actuel
journalctl -b

# Logs du boot precedent
journalctl -b -1

# Logs de l'avant-dernier boot
journalctl -b -2

# Lister tous les boots enregistres
journalctl --list-boots

6.6 Filtrer par PID / UID / executable

# Logs d'un PID specifique
journalctl _PID=1234

# Logs d'un utilisateur specifique
journalctl _UID=1000

# Logs d'un executable specifique
journalctl /usr/sbin/sshd

# Logs du noyau (equivalent de dmesg)
journalctl -k

6.7 Formats de sortie

# Format JSON (une ligne par entree)
journalctl -u nginx -o json

# Format JSON lisible (indente)
journalctl -u nginx -o json-pretty

# Format verbose (tous les champs)
journalctl -u nginx -o verbose

# Format court avec microsecondes
journalctl -u nginx -o short-precise

# Format catalogue (avec explications si disponibles)
journalctl -u nginx -o cat

6.8 Gestion de l'espace disque

# Voir l'espace occupe par le journal
journalctl --disk-usage

# Nettoyer les logs de plus de 7 jours
sudo journalctl --vacuum-time=7d

# Limiter la taille totale du journal a 500 Mo
sudo journalctl --vacuum-size=500M

# Garder uniquement les 3 derniers fichiers de journal
sudo journalctl --vacuum-files=3
Astuce : Pour configurer la taille maximale du journal de facon permanente, editez /etc/systemd/journald.conf et definissez SystemMaxUse=500M. Puis rechargez avec sudo systemctl restart systemd-journald.
Astuce : Combinaison utile au quotidien pour diagnostiquer un probleme : journalctl -u monservice -p err --since "1 hour ago" -n 50 affiche les 50 dernieres erreurs du service dans la derniere heure.

7. Timers systemd (alternative a cron)

Les timers systemd sont une alternative moderne aux taches cron. Ils offrent une meilleure integration avec le journal, la gestion des dependances et un controle plus fin de l'execution.

7.1 Avantages des timers par rapport a cron

  • Logs integres : automatiquement dans le journal systemd
  • Dependances : possibilite de definir des conditions d'execution
  • Rattrapage : option Persistent=true pour rattraper les executions manquees
  • Precision : precision a la seconde (cron = minute minimum)
  • Controle des ressources : limites CPU, memoire via cgroups
  • Pas de conflit d'execution : systemd ne lance pas une nouvelle instance si la precedente est encore en cours

7.2 Structure : fichier .timer + fichier .service

Un timer necessite deux fichiers : le .timer qui definit la planification, et le .service associe qui definit la tache a executer.

Fichier .timer

# /etc/systemd/system/backup-quotidien.timer
[Unit]
Description=Timer pour la sauvegarde quotidienne

[Timer]
# Execution tous les jours a 02h30
OnCalendar=*-*-* 02:30:00

# Rattraper les executions manquees (ex: si le serveur etait eteint)
Persistent=true

# Ajouter un delai aleatoire de 0 a 5 min pour eviter les pics de charge
RandomizedDelaySec=300

# Precision (defaut: 1min, reduire si besoin d'exactitude)
AccuracySec=1s

[Install]
WantedBy=timers.target

Fichier .service associe

# /etc/systemd/system/backup-quotidien.service
[Unit]
Description=Sauvegarde quotidienne des donnees

[Service]
Type=oneshot
User=root
ExecStart=/opt/scripts/backup.sh
StandardOutput=journal
StandardError=journal
SyslogIdentifier=backup-quotidien

7.3 Syntaxe OnCalendar

La syntaxe OnCalendar est tres flexible :

# Format general : DayOfWeek Year-Month-Day Hour:Minute:Second

# Tous les jours a minuit
OnCalendar=daily
# equivalent a :
OnCalendar=*-*-* 00:00:00

# Toutes les heures
OnCalendar=hourly

# Toutes les semaines (lundi a minuit)
OnCalendar=weekly

# Tous les mois (1er du mois a minuit)
OnCalendar=monthly

# Tous les jours a 6h et 18h
OnCalendar=*-*-* 06,18:00:00

# Du lundi au vendredi a 8h
OnCalendar=Mon..Fri *-*-* 08:00:00

# Le premier et le 15 de chaque mois
OnCalendar=*-*-01,15 00:00:00

# Toutes les 15 minutes
OnCalendar=*:0/15

# Toutes les 2 heures
OnCalendar=0/2:00:00

# Le dimanche a 3h
OnCalendar=Sun *-*-* 03:00:00
Astuce : Utilisez systemd-analyze calendar "Mon..Fri *-*-* 08:00:00" pour verifier et tester vos expressions OnCalendar. La commande affiche les prochaines occurrences.

7.4 Timers monotoniques (relatifs au demarrage)

[Timer]
# 5 minutes apres le demarrage du systeme
OnBootSec=5min

# 10 minutes apres l'activation du timer
OnActiveSec=10min

# Toutes les heures apres la derniere execution du service
OnUnitActiveSec=1h

# Toutes les 30 minutes apres la derniere desactivation du service
OnUnitInactiveSec=30min

7.5 Deployer et gerer les timers

# Recharger systemd apres creation des fichiers
sudo systemctl daemon-reload

# Activer et demarrer le timer
sudo systemctl enable --now backup-quotidien.timer

# Verifier l'etat du timer
systemctl status backup-quotidien.timer

# Lister tous les timers actifs et leur prochaine execution
systemctl list-timers

# Lister tous les timers (y compris inactifs)
systemctl list-timers --all

# Declencher manuellement le service associe (test)
sudo systemctl start backup-quotidien.service

# Voir les logs de la derniere execution
journalctl -u backup-quotidien.service -n 50

7.6 Exemple complet : nettoyage des fichiers temporaires

# /etc/systemd/system/nettoyage-tmp.timer
[Unit]
Description=Nettoyage des fichiers temporaires toutes les 6 heures

[Timer]
OnCalendar=0/6:00:00
Persistent=true

[Install]
WantedBy=timers.target
# /etc/systemd/system/nettoyage-tmp.service
[Unit]
Description=Supprimer les fichiers temporaires de plus de 7 jours

[Service]
Type=oneshot
ExecStart=/usr/bin/find /tmp -type f -mtime +7 -delete
ExecStart=/usr/bin/find /var/tmp -type f -mtime +30 -delete
Attention : Contrairement a cron, les timers doivent etre explicitement actives avec systemctl enable --now. Creer les fichiers ne suffit pas.

8. Targets (niveaux d'execution)

Les targets sont des groupes d'unites qui representent un etat du systeme. Elles remplacent les anciens runlevels de SysVinit.

8.1 Correspondance runlevels / targets

Runlevel SysVinit Target systemd Description
0 poweroff.target Arret du systeme
1 rescue.target Mode mono-utilisateur (rescue)
2, 3, 4 multi-user.target Multi-utilisateur en ligne de commande
5 graphical.target Multi-utilisateur avec interface graphique
6 reboot.target Redemarrage

8.2 Gerer les targets

# Voir la target par defaut
systemctl get-default

# Changer la target par defaut (permanent)
sudo systemctl set-default multi-user.target
sudo systemctl set-default graphical.target

# Basculer vers une target immediatement (non permanent)
sudo systemctl isolate multi-user.target
sudo systemctl isolate rescue.target
sudo systemctl isolate graphical.target

# Lister toutes les targets actives
systemctl list-units --type=target

# Lister toutes les targets disponibles
systemctl list-units --type=target --all

8.3 Targets utiles pour les serveurs

  • multi-user.target : la target par defaut recommandee pour les serveurs (pas d'interface graphique)
  • graphical.target : inclut multi-user + interface graphique (rarement utile sur un serveur)
  • rescue.target : mode depannage, seul root peut se connecter, services minimaux
  • emergency.target : mode urgence, systeme de fichiers en lecture seule, shell root uniquement
  • network-online.target : indique que le reseau est completement operationnel
Astuce : Pour passer en mode rescue depuis GRUB (si vous n'avez pas acces au systeme), ajoutez systemd.unit=rescue.target a la ligne de boot du noyau.
Attention : systemctl isolate arrete tous les services qui ne font pas partie de la target cible. Utilisez-le avec precaution, surtout si vous etes connecte en SSH (une bascule vers rescue.target coupera le reseau).

9. Analyse du boot

systemd-analyze permet d'analyser en detail le temps de demarrage du systeme et d'identifier les services qui ralentissent le boot.

9.1 Temps de boot global

# Afficher le temps de boot total
systemd-analyze

# Exemple de sortie :
# Startup finished in 3.456s (kernel) + 12.789s (userspace) = 16.245s
# graphical.target reached after 12.654s in userspace

9.2 blame - Services les plus lents

# Lister les services par temps de demarrage (du plus lent au plus rapide)
systemd-analyze blame

# Exemple de sortie :
#  8.123s NetworkManager-wait-online.service
#  3.456s dev-sda1.device
#  2.345s docker.service
#  1.234s nginx.service
#  0.987s ssh.service
#  ...

9.3 critical-chain - Chaine critique

# Afficher la chaine critique du boot (chemin le plus long)
systemd-analyze critical-chain

# Chaine critique pour une target specifique
systemd-analyze critical-chain multi-user.target

# Exemple de sortie :
# multi-user.target @12.654s
# └─docker.service @9.198s +3.456s
#   └─network-online.target @9.197s
#     └─NetworkManager-wait-online.service @1.074s +8.123s
#       └─NetworkManager.service @0.987s +0.087s
#         └─dbus.service @0.876s +0.021s

9.4 Generez un graphique SVG du boot

# Generer un graphique SVG du boot (visualisation des services paralleles)
systemd-analyze plot > boot-chart.svg

# Ouvrir le graphique dans un navigateur
firefox boot-chart.svg

9.5 Verifier la configuration des unites

# Verifier la syntaxe d'un fichier d'unite (detecte les erreurs)
systemd-analyze verify /etc/systemd/system/monapp.service

# Verifier la securite d'un service (score de hardening)
systemd-analyze security nginx

# Verifier la securite de tous les services
systemd-analyze security
Astuce : systemd-analyze security attribue un score de 0 a 10 (10 = le moins securise) a chaque service. C'est un excellent outil pour identifier les services qui ont besoin de durcissement (sandboxing, capabilities, etc.).

9.6 Optimisation du boot

Strategies pour accelerer le demarrage :

  • Desactiver les services inutiles : sudo systemctl disable service-inutile
  • Masquer les services vraiment inutiles : sudo systemctl mask service-inutile
  • NetworkManager-wait-online : souvent le plus lent, le desactiver si le reseau n'est pas critique au boot
  • Utiliser socket activation : les services sont demarres uniquement quand ils sont sollicites
  • Verifier les timeouts : un service avec un long TimeoutStartSec peut bloquer le boot
# Identifier les services lents
systemd-analyze blame | head -20

# Desactiver le service le plus courant coupable : wait-online
sudo systemctl disable NetworkManager-wait-online.service

# Ou pour systemd-networkd
sudo systemctl disable systemd-networkd-wait-online.service

10. Depannage

10.1 Un service ne demarre pas

Procedure de diagnostic :

# Etape 1 : Verifier l'etat du service
systemctl status monservice

# Etape 2 : Lire les logs detailles
journalctl -u monservice -n 100 --no-pager

# Etape 3 : Verifier la syntaxe du fichier d'unite
systemd-analyze verify /etc/systemd/system/monservice.service

# Etape 4 : Verifier que daemon-reload a ete fait
sudo systemctl daemon-reload

# Etape 5 : Essayer de demarrer manuellement et observer
sudo systemctl start monservice
systemctl status monservice

10.2 Services en echec (failed)

# Lister tous les services en echec
systemctl --failed

# Reinitialiser l'etat d'echec d'un service
sudo systemctl reset-failed monservice

# Reinitialiser l'etat de tous les services en echec
sudo systemctl reset-failed

10.3 Problemes courants et solutions

Erreur : "Failed to start - Unit is masked"

# Le service est masque, il faut le demasquer
sudo systemctl unmask monservice
sudo systemctl start monservice

Erreur : "Main process exited, code=exited, status=203/EXEC"

# Le binaire specifie dans ExecStart n'existe pas ou n'est pas executable
# Verifier le chemin
which monapp
ls -la /chemin/vers/monapp

# Verifier les permissions
chmod +x /chemin/vers/monapp

Erreur : "Main process exited, code=exited, status=217/USER"

# L'utilisateur specifie dans User= n'existe pas
# Verifier l'utilisateur
id monuser

# Creer l'utilisateur si necessaire
sudo useradd -r -s /usr/sbin/nologin monuser

Erreur : "Start request repeated too quickly"

# Le service crash en boucle et atteint la limite de redemarrage
# Verifier les logs pour comprendre le crash
journalctl -u monservice -b -p err

# Ajuster les limites dans le fichier .service
# [Service]
# StartLimitIntervalSec=60
# StartLimitBurst=5
# RestartSec=10

Erreur : "Service hold-off time over, scheduling restart"

# Le service redemarrage en boucle. Diagnostic :
journalctl -u monservice -f

# Verifier le code de sortie
systemctl show monservice --property=ExecMainStatus
systemctl show monservice --property=Result

10.4 Daemon-reload oublie

Symptome : vous modifiez un fichier .service mais les changements ne sont pas pris en compte.

# systemd affiche souvent un avertissement si reload est necessaire :
# Warning: The unit file, source configuration file or drop-ins of
# monservice.service changed on disk. Run 'systemctl daemon-reload'
# to reload units.

sudo systemctl daemon-reload
sudo systemctl restart monservice

10.5 Debugger un service en detail

# Augmenter le niveau de log temporairement
sudo systemctl service-log-level monservice debug

# Voir les variables d'environnement du service
systemctl show monservice --property=Environment

# Voir le fichier d'unite effectif (avec les overrides)
systemctl cat monservice

# Voir les chemins du fichier et ses overrides
systemctl show monservice --property=FragmentPath
systemctl show monservice --property=DropInPaths

10.6 Problemes de dependances

# Voir pourquoi un service ne demarre pas (dependances manquantes)
systemctl list-dependencies monservice

# Verifier l'ordre de demarrage
systemd-analyze critical-chain monservice

# Verifier les conditions d'un service
systemctl show monservice --property=ConditionResult
systemctl show monservice --property=AssertResult

10.7 Commandes de secours

# Si systemd est completement bloque, forcer le rechargement
sudo systemctl daemon-reexec

# Redemarrer le journal en cas de probleme de logs
sudo systemctl restart systemd-journald

# Mode emergency (depuis GRUB) : ajouter a la ligne de boot
systemd.unit=emergency.target

# Mode rescue (depuis GRUB) : ajouter a la ligne de boot
systemd.unit=rescue.target

# Debug complet du boot (depuis GRUB) : ajouter a la ligne de boot
systemd.log_level=debug systemd.log_target=console
Astuce : Creez un alias dans votre .bashrc pour le diagnostic rapide :
# Alias pratiques pour systemd
alias scs='systemctl status'
alias scr='sudo systemctl restart'
alias sce='sudo systemctl enable --now'
alias scl='journalctl -u'
alias scf='systemctl --failed'
Attention : La commande daemon-reexec re-execute le processus PID 1 de systemd. Utilisez-la uniquement en dernier recours car elle peut avoir des effets inattendus sur les services en cours d'execution.