Table des matières

, , , , , ,

systemd : configuration des services

systemd est à la fois un système d'initialisation et un gestionnaire pour les services système. Il est utilisé par de nombreuses distributions GNU/Linux et a finit par s'imposer comme un standard.

systemctl est le CLI permettant d'interagir avec systemd. Il permet de gérer les services, vérifier leur état, modifier l'état du système ou encore modifier les fichiers de configuration.

Notons que même si systemd est devenu le système d'initialisation par défaut pour de nombreuses distributions, il n'est pas forcément implémenté totalement sur celles-ci. Un message du type bash: systemctl is not installed peut être retrourné lors de l'usage d' une fonctionnalité non disponible sur votre distribution

Gestion des services

Le but d'un système d'initialisation est d'initialiser (paramétrer) les composant devant être démarrés après le chargement (boot) du noyau Linux (traditionnellement désignés composants utilisateur “userland components”). Le système d' initialisation à également pour rôle la gestion/supervision des services (daemons).

Dans systemd la cible de la plupart des actions sont les “unités” (units) qui sont des ressources que systemd sait gérer. Les unités sont catégorisées par type de ressource et sont définies dans des fichiers d'unité (unit files). Le type d'une unité peut être déduit par le suffixe sur son fichier d'unité.

Pour les taches de gestion des services, l' unité cible sera de type unité de service (service units) et le fichier d'unité aura le suffixe .service. Cependant pour de nombreuses commandes de gestion de services le suffixe peut être omis, systemd étant capable de le compléter dans la plupart des cas.

Démarrage et arrêt d'un service

Pour démarrer un service systemd et exécuter les instruction de son fichier d'unité, utiliser la commande start:

# Démarrage de l'environnent graphique
systemctl start lightdm.service
 
# pour les commandes de gestion de service telle que start
# systemd consulte tous les fichiers unités *.service
# le suffixe peut être omis
systemctl start lightdm

Pour arrêter un service, on utilise sans surprise la commande stop:

systemctl stop lightdm.service

Redémarrage et rechargement

Pour redémarrer un service en cours d'exécution, utiliser restart

systemctl restart isc-dhcp-server.service

Certains services sont capables de recharger à chaud leurs fichiers de configuration sans redémarrage dans ce cas on peut utiliser la commande reload:

systemctl reload nfs-server.service

Activer/désactiver des services

Les commandes précédentes sont utiles pour gérer les services pendant la session en cours. Pour indiquer à systemd de démarrer automatiquement un service au prochain démarrage, il faut l'activer via la commande enable

systemctl enable isc-dhcp-server.service

Pour qu'un service ne soit plus démarré automatiquement lors du démarrage du système, utiliser la commande disable:

systemctl disable isc-dhcp-server.service

Vérifier l'état d'un service

Pour vérifier l'état d'un service, on utilise la commande status:

systemctl status isc-dhcp-server.service 

La commande retournera l'état du service, la hiérarchie des cgroups et les premières traces de journalisation.

La commande d'exemple précédente a produit la sortie ci-dessous:

● isc-dhcp-server.service - LSB: DHCP server
     Loaded: loaded (/etc/init.d/isc-dhcp-server; generated)
     Active: active (running) since Sun 2022-01-02 11:29:22 CET; 1h 10min ago
       Docs: man:systemd-sysv-generator(8)
    Process: 1137 ExecStart=/etc/init.d/isc-dhcp-server start (code=exited, status=0/SUCCE>
      Tasks: 4 (limit: 9399)
     Memory: 4.8M
        CPU: 50ms
     CGroup: /system.slice/isc-dhcp-server.service
             └─1225 /usr/sbin/dhcpd -4 -q -cf /etc/dhcp/dhcpd.conf ap

janv. 02 11:29:20 nucleus dhcpd[1225]: Wrote 0 deleted host decls to leases file.
janv. 02 11:29:20 nucleus dhcpd[1225]: Wrote 0 new dynamic host decls to leases file.
janv. 02 11:29:20 nucleus dhcpd[1225]: Wrote 0 leases to leases file.
janv. 02 11:29:20 nucleus dhcpd[1225]: Server starting service.
janv. 02 11:29:22 nucleus isc-dhcp-server[1137]: Starting ISC DHCPv4 server: dhcpd.
janv. 02 11:29:22 nucleus systemd[1]: Started LSB: DHCP server.
janv. 02 11:37:34 nucleus dhcpd[1225]: DHCPREQUEST for 192.168.33.10 from 34:cf:f6:b2:09:8>
janv. 02 11:37:34 nucleus dhcpd[1225]: DHCPACK on 192.168.33.10 to 34:cf:f6:b2:09:8a via ap
janv. 02 11:37:34 nucleus dhcpd[1225]: DHCPREQUEST for 192.168.33.10 from 34:cf:f6:b2:09:8>
janv. 02 11:37:34 nucleus dhcpd[1225]: DHCPACK on 192.168.33.10 to 34:cf:f6:b2:09:8a via ap

Pour les scripts automatisés, on pourra préférer la commande is-active, moins verbeuse et retournant 0 si le service passé en argument est actif:

systemctl is-active isc-dhcp-server.service 
active
 
echo $?
0

Gestion du système

Les commandes précédentes sont dédiées à la gestion des services mais ne sont pas adaptées si l'on souhaite connaître l'état global du système. systemctl prévoit des commandes à cet effet.

Lister les unités

Pour lister les unités actives dont systemd a connaissance, on peut utiliser la commandes list-units:

systemctl list-units
 
# équivalent: appel de systemctl sans argument
systemctl

La sortie de la commande comporte plusieurs colonnes:

Pour lister l'ensemble des unités que systemd a chargé ou tenté de charger:

# lister toutes les unités
systemctl list-units --all
 
# filtrer les unités non actives
systemctl list-units --all --state=inactive

Pour diverses raison, certaines unités peuvent passer à l'état inactif après exécution ou ne pas être présentes sur le disque.

Un autre usage fréquent est l'utilisation du filtrage des unités par type:

systemctl list-units --type=service

Lister les fichiers unité

La commande list-units affiche les unités que systemd est en mesure d'évaluer et de charger en mémoire. Cela n'inclus pas nécessairement toutes les unités disponibles sur le système. Pour lister tous les fichiers unités disponibles et présents dans les chemins de systemd (systemd paths):

systemctl list-unit-files

Les unités sont des ressources dont à connaissance systemd. Comme systemd n'a pas nécessairement lu toutes les définitions incluses dans les fichiers unités, la vue présente les informations à propos des fichiers eux-même.

static dans ce contexte indique que le fichier unité ne contient pas de section install ( l'unité ne peut donc pas être activée). Généralement cela signifie que l'unité a une action on/off ou qu'elle est utilisée comme dépendance pour une autre unité et ne devrait pas être exécutée directement.

# Liste les fichiers unités des services désactivés ou masqués
systemctl list-unit-files  --type=service --state=disabled,masked

Gestion des unités

Certaines commandes ont été prévues pour afficher des informations plus précises sur les unités et les fichiers unités.

Afficher un fichier unité

Pour afficher le fichier unité que systemd à chargé, on peut utiliser la commande cat:

systemctl cat isc-dhcp-server.service

La sortie obtenue est une fichier unité connu du processus systemd en cours d’exécution. Cette précision est importante lorsque un fichier unité a été modifié récemment ou si certaines options ont été redéfinies dans un fichier unité fragmenté.

Afficher les dépendances

Pour visualiser l'arbre des dépendances on utilise la commande list-dependencies:

systemctl list-dependencies sshd.service

En sortie on obtient les dépendances nécessaires pour le démarrage du service.

On peut également utiliser des dépendances inversées (retrouver les services qui dépendent du service passé en argument) avec l'option --reverse. Les options --before et --after sont également souvent utilisées et permettent d'identifier les unités ayant un lien avec l'unité passée en argument et devant être démarrées avant ou après.

systemctl list-dependencies --before sshd.service

Vérifier les propriétés d'une unité

Pour visualiser les propriétés d'une unité on peut utiliser la commande show. Sans options la commande liste l'ensemble des propriété définies pour l'unité, on peut cibler une propriété en spécifiant l'option -p:

# Liste l'ensemble des propriétés de l'unité hostapd.service
systemctl show hostapd.service
 
# Affiche la valeur de la propriété ExecStart pour l'unité hostapd.service
systemctl show hostapd.service -p ExecStart
 
# syntaxe avec option longue
systemctl show hostapd.service --property PIDFile 

La commande show permet notamment de retourner les prérequis nécessaires à la bonne exécution d'une unité:

# Affiche les unités nécessaires à l’exécution de graphical.target 
systemctl show -p Wants -p Requires graphical.target

Masquer/démasquer une unité

La section gestion des services aborde comment arrêter/désactiver un service. systemd propose également définir un service comme totalement non activable (automatiquement ou manuellement) en redirigeant les appels vers le périphérique spécial /dev/null, ce comportement est désigné masquer(cahcer) un service:

systemctl mask nginx.service

Ceci permettra de s'assurer que le service Nginx ne sera pas démarré (automatiquement ou manuellement) aussi longtemps qu'il restera caché/maqué:

systemctl list-unit-files
 
. . .
messagebus.service                     static  
nginx.service                          masked
rescue.service                         static
. . .

Toute tentative de démarrage d'un service masqué retournera un message du type:

Failed to start nginx.service: Unit nginx.service is masked.

Pour démasquer un service:

systemctl unmask nginx.service

Modifier un fichier unité

systemd intègre une commande pour assister la modification des fichiers unité afin ajuster les comportement des unités aux besoins: c'est la commande edit:

Modifications temporaires

Il est possible de modifier puis de charger un fichier unité non persistant:

systemctl edit --runtime some.service

Cette proposition permet d'expérimenter un changement tout en assurant de retrouver un état fonctionnel après redémarrage dans le cas d'un imprévu.

snippet ou fragment/extrait

Utilisée sans option la commande edit produit un fichier de configuration complémentaire pour l'unité:

systemctl edit nginx.service

C'est un fichier texte vide utilisé pour redéfinir les valeurs par défaut ou ajouter de nouvelles directives pour la définition de l'unité. Un dossier sera créé dans le répertoire /etc/systemd/system. Il sera nommé en fonction de l'unité puis terminé par le suffixe .d. Dans celui-ci un fragment (extrait ou snippet) de fichier de configuration sera enregistré avec le nom override.conf. Quand l'unité sera chargée, les valeurs présentes dans ce fichier seront prioritaires.

Dans le cas ou l'on souhaite charger l'ensemble des valeurs du fichier unité par défaut, il faut utiliser l'option --full:

systemctl edit --full nginx.service

La commande charge la totalité des valeurs du fichier unité courant dans l'éditeur de texte. Les modifications sont écrites dans le répertoire /etc/systemd/system qui est prioritaire sur les définitions des unités du système (/lib/systemd/system)

Identifier les modifications

Pour identifier les modifications apportées sur l'ensemble de la configuration des unités de systemd:

systemd-delta

Supprimer les altérations

Pour supprimer les ajustements, on peut supprimer le dossier contenant les fragments de configuration liés à l'unité ou le fichier unité présent dans le dossier /etc/systemd/system

# Supprime les extraits de configuration défini pour l'unité nginx.service
rm -r /etc/systemd/system/nginx.service.d
 
# Supprime le fichier de configuration défini pour l'unité nginx.service
rm /etc/systemd/system/nginx.service

Après suppression des fichiers de configuration, recharger systemd:

systemctl daemon-reload

Restaurer la configuration système

Pour restaurer la configuration proposée dans les paquets de la distribution:

systemctl revert some.service

targets et runlevel

Définition

Les cibles (targets) sont des fichiers unités spéciaux pouvant décrire un état système souhaité ou un point de synchronisation. Comme les autres unités, les fichiers définissant les cibles sont identifiés par leur suffixe en .target. Les cibles n'ont pas directement d'actions en elles-même mais sont utilisées pour regrouper des unités.

Les cibles peuvent être utilisées pour conduire le système dans un état donné, ce que d'autres systèmes init désignent par runlevels. Les cibles permettent de spécifié un état voulu plutot qu'une liste d'unités nécessaire pour produire cet état.

Pour exemple, il existe une cible swap.target utilisée pour indiquer que la mémoire swap est prête à l' utilisation. Les unités qui participent au processus de mise en service de la swap peuvent se synchroniser avec cette cible en définissant dans leur fichier de configuration respectif les directives WantedBy= (voulues) ou RequiredBy= (nécessaires).

Les unités qui ont besoin de mémoire swap pourront spécifier cette condition en utilisant les directives Wants=, Requires=, ou After= pour définir la nature de cette relation de dépendance.

Obtenir ou définir la cible par défaut

Le processus systemd aboutit à une cible par défaut (default target). Pour l'afficher:

systemctl get-default

Pour lister les cibles existantes sur le système:

systemctl list-unit-files --type=target

Contrairement aux runlevels, de multiples cibles peuvent être actives en même temps. Une cible active indique que systemd a tenté de démarrer l'ensemble des unités liées à la cible et qu' aucune procédure d’arrêt n'est en cours.

Pour visualser les cibles actives:

systemctl list-units --type=target

Si on souhaite définir une autre cible par défaut, on utilise la commande set-default

systemctl set-default multi-user.target
systemctl set-default graphical.target

Isolation d'une cible

Il est possible de démarrer l'ensemble des unités associées à un cible et de stopper toutes les unités qui ne font pas parti de l'arbre des dépendances: on parle d' isolation (isolate). C'est similaire au changement de niveau d'exécution système (runlevel).

Par exemple si le système opère avec un environnement graphique par défaut via la cible graphical.target, vous pouvez l'arreter et basculer le système en mode multi-utilisateur en isolant la cible multi-user.target.

On peut vérifier la liste des dépendances du mode console multi-utilisateur avant de l'activer. Pour vérifier qu'aucun service vital n'est omis:

systemctl list-dependencies multi-user.target

Si les services deumerant actifs sont satisfaisants, on peut isoler la cible multi-user.target:

systemctl isolate multi-user.target

Utiliser des raccourcis pour les événements importants

Certaines cibles sont définies sur des événements systèmes importants comme la mise sous tension ou le redémarrage. systemctl propose certains raccourcis pour ces événements particuliers.

Pour placer le système en mode restauration (rescue ou single-user):

systemctl rescue
 
# équivalent de
systemctl isolate rescue.taget

Pour les arrets / redémarrages

systemctl halt
 
# Arret complet du système
systemctl poweroff
 
# redémarrage
systemctl reboot

Ces commandes préviennent les utilisateurs avec des sessions en cours que le système est arrêté, ce que ne feront pas les commandes d'isolation.

Analyser la phase de démarrage

systemd intègre un outils d'analyse du temps de démarrage:

systemd-analyse time

Pour détailler le temps de démarrage par unité:

systemd-analyse blame

Pour conclure

Ce wiki a présenté les commandes de bases permettant d'interagir avec systemd. L'utilitaire systemctl est le CLI prévut à cet effet permettant la gestion des services et de l'état du système.

D' autres composants existent dans l'écosystème de systemd. Des fonctionnalités telles que la gestion de la journalisation, des sessions utilisateurs sont controlées par des utilitaire différents respectivement journald/journalctl et logind/loginctl.

Références