systemd : Gestion des services

systemd : Gestion des services

systemd est une suite logicielle qui fournit un ensemble de composants pour les systèmes basés sur Linux. Son principal composant est le système d’initialisation qui s’occupe entre autre de la gestion des services, leur démarrage, de les charger en parallèle et ce sans devoir faire appel à des scripts shell. Il fournit en outre toute une série de services tels que la gestion du réseau, la synchronisation du temps etc.

Dans cet article nous nous concentrerons sur sa fonctionnalité principale: la gestion des services. Nous verrons comment démarrer, arrêter, recharger, activer, désactiver et bien évidemment lister les services mais aussi comment créer un service personnalisé.

Introduction

De nos jours la grande majorité des distributions Linux ont adopté systemd en tant qu’initialiseur du système parmi les plus courantes nous avons:

Cette liste n’est bien évidemment pas exhaustive mais permet de déjà se faire une idée de l’intérêt de gérer systemd sachant que toutes les distributions dérivées de cette liste sont concernées également.

Gestion des services avec « systemd »

L’interaction avec systemd se fait par l’intermédiaire de la commande systemctl qui vu son utilité requiert des droits privilégiés.

Structure général de la commande systemctl
systemctl [OPTIONS...] COMMAND ...

Lister les services

Tout élément géré par systemd (un service, un socket, un timer, …) est appelé unité et possède un type. Nous pouvons donc lister les unités de systemd de type « service ».

Lister les services de systemd
sudo systemctl list-units -t service
Exemple de liste de services
steve@just-sudo-it:~$ sudo systemctl list-units -t service
  UNIT                                                                                      LOAD   ACTIVE SUB     DESCRIPTION
  dbus.service                                                                              loaded active running D-Bus System Message Bus
  getty@tty1.service                                                                        loaded active running Getty on tty1
  kmod-static-nodes.service                                                                 loaded active exited  Create List of Static Device Nodes
  ldconfig.service                                                                          loaded active exited  Rebuild Dynamic Linker Cache
  NetworkManager.service                                                                    loaded active running Network Manager
  sshd.service                                                                              loaded active running OpenSSH Daemon
  systemd-fsck@dev-disk-by\x2duuid-b0569943\x2dea7f\x2d4fcc\x2db1ac\x2d65c983a76d76.service loaded active exited  File System Check on /dev/disk/by-uuid/b0569943-ea7f-4fcc-b1ac-65c983a76d76
  systemd-journal-catalog-update.service                                                    loaded active exited  Rebuild Journal Catalog
  systemd-journal-flush.service                                                             loaded active exited  Flush Journal to Persistent Storage
  systemd-journald.service                                                                  loaded active running Journal Service
  systemd-logind.service                                                                    loaded active running User Login Management
  systemd-modules-load.service                                                              loaded active exited  Load Kernel Modules
  systemd-random-seed.service                                                               loaded active exited  Load/Save OS Random Seed
  systemd-remount-fs.service                                                                loaded active exited  Remount Root and Kernel File Systems
  systemd-sysctl.service                                                                    loaded active exited  Apply Kernel Variables
  systemd-sysusers.service                                                                  loaded active exited  Create System Users
  systemd-timesyncd.service                                                                 loaded active running Network Time Synchronization
  systemd-tmpfiles-setup-dev.service                                                        loaded active exited  Create Static Device Nodes in /dev

...

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.
28 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
steve@just-sudo-it:~$

A chaque service correspond une série d’états:

  • Le service est-il chargé ou non
  • Le service est-il actif ou non
  • Le service est-il en cours de fonctionnement ou non
  • La description du service

Lister les services dans un état donné

Nous pouvons aussi n’afficher que les services qui sont dans un état donné:

Lister les services dans un état spécifique
 sudo systemctl list-units -t service --state <etat>

Voici par exemple la liste des services en cours de fonctionnement (« running »).

Liste des services en cours d’exécution
steve@just-sudo-it:~$ sudo systemctl list-units -t service --state running
  UNIT                      LOAD   ACTIVE SUB     DESCRIPTION
  dbus.service              loaded active running D-Bus System Message Bus
  getty@tty1.service        loaded active running Getty on tty1
  NetworkManager.service    loaded active running Network Manager
  sshd.service              loaded active running OpenSSH Daemon
  systemd-journald.service  loaded active running Journal Service
  systemd-logind.service    loaded active running User Login Management
  systemd-timesyncd.service loaded active running Network Time Synchronization
  systemd-udevd.service     loaded active running Rule-based Manager for Device Events and Files
  user@1000.service         loaded active running User Manager for UID 1000

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.
9 loaded units listed.
steve@just-sudo-it:~$

Afficher le statut d’un service

Pour obtenir plus d’information sur l’état d’un service nous pouvons invoquer la commande suivante:

Afficher le statut détaillé d’un service
sudo systemctl status <service>

Voci par exemple les informations relatives à l’unité sshd.service.

Statut du service sshd
steve@just-sudo-it:~$ sudo systemctl status sshd
● sshd.service - OpenSSH Daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: disabled)
     Active: active (running) since Wed 2023-08-16 20:01:09 CEST; 16min ago
   Main PID: 322 (sshd)
      Tasks: 1 (limit: 9496)
     Memory: 7.7M
        CPU: 77ms
     CGroup: /system.slice/sshd.service
             └─322 "sshd: /usr/bin/sshd -D [listener] 0 of 10-100 startups"

aoû 16 20:01:09 just-sudo-it systemd[1]: Started OpenSSH Daemon.
aoû 16 20:01:09 just-sudo-it sshd[322]: Server listening on 0.0.0.0 port 22.
aoû 16 20:01:09 just-sudo-it sshd[322]: Server listening on :: port 22.
aoû 16 20:01:16 just-sudo-it sshd[338]: Accepted password for steve from 192.168.56.1 port 59445 ssh2
aoû 16 20:01:16 just-sudo-it sshd[338]: pam_unix(sshd:session): session opened for user steve(uid=1000) by steve(uid=0)
steve@just-sudo-it:~$

Vous retrouvez ici des informations détaillés sur l’état du service (chargé ou non, actif ou non, en cours ou non, ..) mais aussi les derniers logs système relatifs à cette unité.

Arrêter, démarrer ou redémarrer un service.

L’arrêt et le démarrage de service sont bien évidemment les actions principales. Le redémarrage n’est rien de plus qu’un stop-start.

Arrêter un service
sudo systemctl stop <service>
Démarrer un service
sudo systemctl start <service>
Arrêter et redémarrer un service
sudo systemctl restart <service>

Notez que si vous essayez de redémarrer un service déjà à l’arrêt, la commande effectuera bel et bien le démarrage.

Recharger un service.

Recharger un service est une opération un peu moins barbare qu’un redémarrage, le but étant de ne pas arrêter le processus mais de lui faire uniquement recharger sa configuration. Toutefois toutes les unités de service ne disposent pas de cette action, mais systemctl dispose d’une commande permettant de contourner le problème.

Recharger la configuration du service
sudo systemctl reload <service>

Si vous n’êtes pas certain que le service puisse simplement recharger sa configuration sans redémarrer, vous pouvez utiliser la commande suvante:

Recharge la config si le service en est capable sinon le redémarre
sudo systemctl reload-or-restart <service>

Démarrer un service automatiquement au démarrage

Les commandes start, stop, restart, reload, etc. permettent d’interagir en temps réel avec un service. Toutefois il est souvent nécessaire qu’un service soit lancé automatiquement lors du démarrage du système.

Activer le lancement automatique du service
sudo systemctl enable <service> [--now]

L’option --now provoque le démarrage immédiat du service en plus de son activation automatique.

Désactiver le lancement automatique du service
sudo systemctl disable <service> [--now]

Ici l’option --now provoque l’arrêt immédiat du service en plus de désactiver son lancement automatique.

Masquer ou révéler un service

Un service arrêté peut toujours être démarré, soit manuellement soit par un autre service qui l’utilise comme dépendance. Pour empêcher qu’un service ne puisse être exécuté il faut le masquer, ce qui rend son exécution impossible.

Empêcher l’exécution d’un service
sudo systemctl mask <service>
Permettre à nouveau l’exécution d’un service
sudo systemctl unmask <service>

Quelques commandes bonus

Outre ces fonctions principales, systemctl dispose d’une série de commande permettant d’obtenir des informations spécifiques comme la vérification de l’état d’un service.

Vérifier si un service est actif
sudo systemctl is-active <service>
Vérifier si le service SSHD est actif
steve@just-sudo-it:~$ sudo systemctl is-active sshd
active
steve@just-sudo-it:~$

Comme vous pouvez le constater cette commande retourne un simple mot, ce qui la rend très pratique si nous devons utiliser cette information dans un script.

Dans la même logique nous pouvons aussi vérifié sir l’exécution à échoué ou si le service est chargé au démarrage du système.

Vérifier si l’exécution d’un service à échoué.
sudo systemctl is-failed <service>
Vérifier si un service est chargé au démarrage.
sudo systemctl is-enabled <service>

Créer un service personnalisé

Maintenant que nous avons vu comment manipuler les services, intéressons nous à la création de service personnalisés.

Création d’un exécutable d’une application fictive

Commençons par créer un application fictive que nous exécuterons comme un service (cette étape n’est là que pour permettre l’illustrer la définition du service sans introduire d’autres concepts ou technologies). Pour ce faire nous pouvons créer un script Bash basique:

Créer le script bash
sudo vim /usr/local/bin/justsudoit.sh
Contenu de /usr/local/bin/justsudoit.sh
#!/bin/bash
echo "Just-Sudo-It.be service ... DEMARRAGE"
sleep 5
echo "Just-Sudo-It.be service ... TERMINE"

Ce script affichera la première phrase à son démarrage, attendra ensuite 5 secondes et ensuite affichera la deuxième et se terminera normalement.

Nous devons maintenant rendre ce script exécutable.

Bash
sudo chmod +x /usr/local/bin/justsudoit.sh

Nous pouvons d’ailleurs tester l’exécution de ce script…

Test d’exéction du script.
steve@just-sudo-it:~$ myservice.sh
Just-Sudo-It.be service ... DEMARRAGE
Just-Sudo-It.be service ... TERMINE
steve@just-sudo-it:~$

Création de la définition de l’unité de « systemd »

Comme précisé en tout début d’article, un service est un type d’unité d’un point de vue de systemd. Toutes les unités sont définies par un fichier moyennant une structure propre à systemd.

Voici une définition minimale pour notre service que nous nommerons justsudoit.service (le nom du fichier doit terminer par .service) et que nous placerons dans /etc/systemd/system/, dossierdans lequel systemd recherchera par défaut des définitions d’unités.

Création de la définition du service
sudo vim /etc/systemd/system/justsudoit.service
/etc/systemd/system/justsudoit.service
[Unit]
Description=Just-Sudo-It.be service

[Service]
ExecStart=/usr/local/bin/justsudoit.sh

[Install]
WantedBy=multi-user.target

Comme vous le remarquerez, ce fichier est composé de plusieurs section:

  • [Unit] : La description du service
  • [Service] : Les informations d’éxécution du service
  • [Install] : Comment le service doit être installé.

La clé ExecStart défini le chemin vers l’exécutable à lancer au démarrage du service et WantedBy permet de définir dans quel contexte le service doit être démarré. Par exemple multi-user.target correspond à l’état du système quand il a démarré normalement. Une autre option aurait été graphical.target qui correspond au système quand une interface graphique est chargée.

Nous avons ici une structure minimaliste pour la définition du service, pour en savoir plus repportez vous au man systemd.unit.

Recharger le gestionnaire de configuration de « systemd »

Quand des modifications sont apportées aux services, sockets ou tout autre unité de systemd, il faut impérativement demander un rechargement du gestionnaire de configuration, sans quoi les changements apportés ne seront pas pris en compte.

Recharger le gestionnaire de configuration de systemd
sudo systemctl daemon-reload

Vérification et lancement du service

Nous pouvons vérifier si systemd a bel et bien chargé la configuration de notre service:

Vérification de l’état du service
steve@just-sudo-it:~$ sudo systemctl status justsudoit.service
○ justsudoit.service - Just-Sudo-It.be service
     Loaded: loaded (/etc/systemd/system/justsudoit.service; disabled; preset: disabled)
     Active: inactive (dead)
steve@just-sudo-it:~$

Si le service est chargé, il ne nous reste plus qu’à le lancer.

Démarrage de notre service
sudo systemctl start justsudoit.service

Après quelques secondes nous pouvons vérifier l’état et nous devrions voir l’effet de notre script directement dans les messages de logs affichés:

Vérification de l’état du service
steve@just-sudo-it:~$ sudo systemctl status justsudoit.service
○ justsudoit.service - Just-Sudo-It.be service
     Loaded: loaded (/etc/systemd/system/justsudoit.service; disabled; preset: disabled)
     Active: inactive (dead)

aoû 16 21:35:05 just-sudo-it systemd[1]: Started Just-Sudo-It.be service.
aoû 16 21:35:05 just-sudo-it justdusoit.sh[367]: Just-Sudo-It.be service ... DEMARRAGE
aoû 16 21:35:10 just-sudo-it justdusoit.sh[367]: Just-Sudo-It.be service ... TERMINE
aoû 16 21:35:10 just-sudo-it systemd[1]: justsudoit.service: Deactivated successfully.
steve@just-sudo-it:~$

Comme prévu notre service a démarré, a lancé l’exécution de notre application fictive et s’est terminé normalement.

Conclusion

Comme nous l’avons vu, la gestion des services de systemd est relativement simple et surtout standardisée. Les services et autres unités de systemd que nous créons pour nos propres besoins s’intègrent aussi parfaitement au système.

Les définitions d’unités peuvent être bien plus complexe, ici nous n’avons fait que découvrir le principe de fonctionnement. Le reste, ce sera pour un futur article!

0 Comments on “systemd : Gestion des services

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.