systemd : dépendances, cibles et sockets
Comprendre comment systemd enchaîne les unités permet de démarrer les services dans le bon ordre. Les exemples utilisent des noms génériques.
Dépendance et ordre : deux notions différentes
Section intitulée « Dépendance et ordre : deux notions différentes »| Notion | Directives | Effet |
|---|---|---|
| Dépendance (quoi lancer) | Wants=, Requires=, BindsTo=, PartOf= |
Si A dépend de B, démarrer A démarre aussi B |
| Ordre (dans quel ordre) | After=, Before= |
A démarre après B (mais ne le lance pas) |
Les deux sont indépendantes : Requires= seul ne garantit pas l’ordre. Pour « B doit être lancé et prêt avant A », il faut les deux.
[Unit]Description=Application monappRequires=postgresql.serviceAfter=postgresql.serviceForce des dépendances
Section intitulée « Force des dépendances »| Directive | Si la dépendance échoue ou s’arrête |
|---|---|
Wants= |
L’unité démarre quand même (dépendance faible, recommandée) |
Requires= |
L’unité n’est pas démarrée (dépendance forte) ; arrêtée si la dépendance s’arrête |
Requisite= |
Comme Requires, mais échoue tout de suite si la dépendance n’est pas déjà active |
BindsTo= |
Comme Requires, et s’arrête aussitôt si la dépendance disparaît |
PartOf= |
Les arrêts et redémarrages de la dépendance sont propagés à l’unité |
Conflicts= |
Les deux unités ne peuvent pas tourner ensemble |
Pour un service qui a besoin de sa base de données mais qui doit survivre à son redémarrage : Wants= + After=.
Attendre le réseau
Section intitulée « Attendre le réseau »After=network.target signifie seulement que la pile réseau est initialisée, pas que le réseau est en ligne (adresse obtenue). Pour un service qui contacte un serveur au démarrage :
[Unit]After=network-online.targetWants=network-online.targetnetwork-online.target est atteint quand la configuration réseau est terminée, grâce à systemd-networkd-wait-online ou NetworkManager-wait-online, selon le gestionnaire réseau en place (Netplan avec networkd sur Ubuntu Server).
Les cibles (.target)
Section intitulée « Les cibles (.target) »Une cible regroupe des unités pour représenter un état de la machine :
| Cible | Équivalent (anciens niveaux d’exécution) |
|---|---|
poweroff.target, reboot.target |
Arrêt, redémarrage |
rescue.target |
Mode de secours (mono-utilisateur) |
multi-user.target |
Serveur sans interface graphique (niveau 3) : cible par défaut d’un serveur |
graphical.target |
Avec interface graphique (niveau 5) |
network-online.target |
Réseau configuré |
timers.target, sockets.target |
Regroupent les timers, les sockets |
systemctl get-defaultsudo systemctl set-default multi-user.targetsudo systemctl isolate rescue.target # bascule (arrête les services hors de cette cible)systemctl list-dependencies multi-user.target --no-pager | head -20WantedBy=multi-user.target dans la section [Install] d’un service signifie « démarrer avec la machine, en mode normal ».
Analyser le démarrage
Section intitulée « Analyser le démarrage »systemd-analyze # durée du démarragesystemd-analyze blame --no-pager | head # unités les plus lentessystemd-analyze critical-chain --no-pager # chaîne d'unités qui détermine la durée totalesystemd-analyze critical-chain monapp.service # chaîne d'un servicesystemd-analyze plot > demarrage.svg # diagramme (ouvrir dans un navigateur)Activation par socket
Section intitulée « Activation par socket »Une unité .socket écoute un port et lance le service à la première connexion : économie de ressources et démarrage différé. (C’est le fonctionnement de ssh.socket sur Ubuntu : voir SSH : installation.)
/etc/systemd/system/echo.socket :
[Socket]ListenStream=127.0.0.1:7777Accept=yes
[Install]WantedBy=sockets.target/etc/systemd/system/echo@.service :
[Service]ExecStart=/bin/catStandardInput=socketsudo systemctl daemon-reloadsudo systemctl enable --now echo.socketecho "bonjour" | nc 127.0.0.1 7777 # renvoie « bonjour » : un service echo@ est lancé pour la connexionsystemctl list-socketsAvec Accept=yes, systemd lance un service par connexion (nom d’unité avec @). Avec Accept=no (défaut), un seul service reçoit le socket et gère toutes les connexions.
Unités .path : réagir à un fichier
Section intitulée « Unités .path : réagir à un fichier »[Path]PathExists=/srv/depot/nouveau.txtUnit=traitement.service
[Install]WantedBy=multi-user.targetAutres déclencheurs : PathChanged= (fichier modifié), PathModified=, DirectoryNotEmpty= (un dossier reçoit un fichier).
Unités modèles (@)
Section intitulée « Unités modèles (@) »Un service modèle s’instancie avec un paramètre :
# /etc/systemd/system/salut@.service[Service]Type=oneshotExecStart=/bin/sh -c 'echo "salut %i"'sudo systemctl start salut@alice.service # %i vaut « alice »sudo systemctl start salut@bob.servicejournalctl -u 'salut@*' --no-pager | tail -4Utile pour des instances multiples d’un même programme (un par port, par utilisateur, par site). %n est le nom complet de l’unité, %i l’instance.
Montages et automontage
Section intitulée « Montages et automontage »# /etc/systemd/system/srv-donnees.mount (le nom correspond au chemin : /srv/donnees)[Unit]Description=Disque de données
[Mount]What=/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxWhere=/srv/donneesType=ext4Options=defaults,noatime
[Install]WantedBy=multi-user.targetUn service qui a besoin de ce disque : RequiresMountsFor=/srv/donnees. Les montages courants restent dans /etc/fstab (systemd en génère les unités).
Ordre de démarrage : repérer les problèmes
Section intitulée « Ordre de démarrage : repérer les problèmes »systemctl list-dependencies monapp --after # unités démarrées avantsystemctl list-dependencies monapp --before # unités démarrées aprèssystemctl list-jobs # tâches en cours (démarrage bloqué ?)journalctl -b -u monapp --no-pager | headDépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
| Le service démarre avant sa base de données | Ajouter After= (en plus de Wants=/Requires=) |
Dependency failed for … |
La dépendance (Requires=) a échoué : systemctl status de celle-ci |
| Un service démarre trop tôt, réseau indisponible | After=network-online.target et Wants=network-online.target |
Job … ordering cycle / Found ordering cycle |
Boucle de dépendances : journalctl -b | grep -i cycle, retirer un After= |
| Le démarrage est lent | systemd-analyze blame et critical-chain |
| Le socket ne lance pas le service | Nom du service différent (echo.socket ↔ echo@.service avec Accept=yes), Service= pour le désigner |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Les directives de cette page sont identiques sur systemd 255 et 259. Sur Ubuntu 26.04, la prise en charge des scripts System V est annoncée comme dernière version : les services sous /etc/init.d doivent être convertis (voir Bases et systemctl).
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Manuel :
man systemd.unit,man systemd.socket,man systemd.target - Suite : Durcissement d’un service