Vous vous demandez comment gérer les services en arrière-plan ou au démarrage ?

Le mécanisme de gestion et de démarrage des processus au démarrage a été modifié. Jusqu’à RHEL/CentOS 6.x, vous deviez créer un script dans /etc/init.d/ et l’activer à l’aide de chkconfig, mais les choses sont différentes avec RHEL 7.

Il a été remplacé par systemd et comme il s’agit plus ou moins du gestionnaire de processus par défaut sur les principales versions de Linux, les administrateurs système versés dans d’autres saveurs se sentiront comme chez eux. Dans cet article, nous allons explorer ce qu’est systemd, quelles sont les raisons de ce changement et comment utiliser systemd pour configurer, exécuter et gérer les processus d’arrière-plan.

Qu’est-ce que systemd ?

Puisque tous les processus de Linux sont visibles de manière transparente, voyons où se cache systemd. Sur mon système, j’obtiens ce qui suit :

 ~$ ps -ef | grep systemd
root 1 0 0 Nov11 ?        00:01:02 /lib/systemd/systemd --system --deserialize 22
message 768 1 0 Nov11 ?        00:05:46 /usr/bin/dbus-daemon --system --address=systemd : --nofork --nopidfile --systemd-activation --syslog-only
root 805 1 0 Nov11 ?        00:10:22 /lib/systemd/systemd-logind
ankush 1132 1 0 Nov11 ?        00:00:00 /lib/systemd/systemd --user
ankush 1176 1132 0 Nov11 ?        00:04:50 /usr/bin/dbus-daemon --session --adresse=systemd : --nofork --nopidfile --systemd-activation --syslog-only
ankush 9772 20029 0 21:11 pts/6 00:00:00 grep --color=auto systemd
systemd 17298 1 0 Nov19 ? 00:00:12 /lib/systemd/systemd-resolved
systemd 17303 1 0 Nov19 ? 00:00:00 /lib/systemd/systemd-timesyncd
root 17307 1 0 Nov19 ? 00:00:02 /lib/systemd/systemd-journald
root 18182 1 0 Nov19 ? 00:00:00 /lib/systemd/systemd-udevd

Je parie que vous l’avez remarqué immédiatement. Le premier processus de la liste a été lancé en tant qu’utilisateur root, et a le pid 1.

En effet, il s’agit du premier processus lancé par le système au démarrage. Dites bonjour à systemd🙂

Donc, tout simplement, systemd est le processus “mère” qui lance, gère et termine les autres processus du système, en plus de fournir des informations sur leur journalisation, l’état du système de fichiers, etc.

Une remarque sur le nom, cependant. Le nom est bien systemd et non System D ou autre. Le “d” signifie daemon, un processus Linux standard qui travaille (se cache ?) en arrière-plan et n’est rattaché à aucune session de terminal.

Pourquoi RHEL a-t-il adopté systemd ?

Comme nous l’avons déjà mentionné, systemd est un gestionnaire de systèmes et de processus qui, dans RHEL 7, remplace le programme bien connu Upstart. Pourquoi RHEL a-t-il pris cette décision ? Il y a de très bonnes raisons à cela, alors jetons un coup d’œil rapide.

Initialisation parallèle des services

Contrairement au programme init de SysV, systemd est capable de lancer des services en parallèle. Le programme init, en revanche, les lance un par un. À une époque où même les appareils mobiles sont dotés de processeurs multicœurs, l’absence d’initialisation parallèle est un gros inconvénient.

Gestion dynamique des services (à chaud)

Si vous avez remarqué que les lecteurs USB doivent être explicitement montés sur les anciens systèmes Fedora alors qu’ils s’ouvrent automatiquement sur Ubuntu et les distributions similaires, la raison en est systemd. Il est capable de détecter les modifications matérielles en temps réel et d’arrêter ou de lancer des services si nécessaire. Certains diront qu’il n’est pas nécessaire, mais pour beaucoup, tout ce qui réduit la charge cognitive est le bienvenu.

Lancement de service différé

systemd raccourcit les temps de démarrage car il est capable de différer le lancement des services jusqu’à ce qu’ils soient réellement nécessaires. Un exemple simple est celui des services liés au système de fichiers réseau. S’il n’y a pas de disque réseau disponible, il n’est pas utile de lancer un service.

Communication plus rapide des processus

Les capacités parallèles de systemd s ‘étendent à la communication inter-processus. systemd est capable d’offrir un accès parallèle aux sockets et au bus système, ce qui réduit considérablement les temps d’attente des processus pour les ressources de communication.

Redémarrage automatique

Si un service tombe en panne, systemd peut le détecter et tenter de le redémarrer. La plupart du temps, un simple redémarrage suffit pour qu’une application recommence à fonctionner, à moins qu’il n’y ait des problèmes plus fondamentaux.

Quoi qu’il en soit, systemd facilite la vie de l’administrateur système.

systemd dans RHEL7 – Quels sont les changements pour les administrateurs système ?

Si vous avez le sentiment tenace que systemd ne va pas être tout en cloches et en sifflets, vous avez raison. Il y a quelques incompatibilités significatives qui peuvent prendre les administrateurs système RHEL par surprise. Jetons un coup d’œil rapide.

Prise en charge limitée des niveaux d’exécution

systemd a une reconnaissance et une prise en charge assez médiocre des niveaux d’exécution. Tous les niveaux d’exécution ne sont pas supportés, et pour certaines cibles, il peut même n’y en avoir aucun. Dans de tels cas, systemd renvoie “N” en réponse aux commandes runlevel, ce qui signifie qu’il n’y a pas de runlevel correspondant à cette cible. Dans l’ensemble, Red Hat nous conseille de ne pas utiliser ( !) les commandes runlevel.

Pas de commandes personnalisées

Celle-ci va faire mal. L’un des grands avantages de SysV était la possibilité de définir des commandes personnalisées afin de fournir une meilleure fonctionnalité pour la gestion des processus. Avec systemd, il n’y a pas de telles options et vous devez vous contenter de start, stop, status, restart, etc.

Familial et non interactif

systemd (bien sûr) garde une trace des processus qu’il a lancés et stocke leur PID. Le problème, cependant, est que systemd ne peut pas gérer les processus qu’il n’a pas lancés. De plus, il n’est pas possible pour un utilisateur d’interagir avec un processus lancé par systemd. Toutes les sorties sont envoyées vers /dev/null, ce qui met un terme aux espoirs que vous auriez pu avoir de capturer les sorties.

Pas de contexte

Contrairement aux services init, ceux lancés par systemd n’héritent d’aucun environnement de la part des utilisateurs du système. En d’autres termes, des informations comme PATH et d’autres variables système ne sont pas disponibles, et chaque nouveau processus est lancé dans un contexte vide.

Si cette liste de limitations vous fait pleurer, sachez que vous n’êtes pas seul. systemd a été une force polarisante dans le monde Linux, et en cherchant “systemd sucks” sur Google, vous trouverez de nombreuses lectures 😉

Comment démarrer un service automatiquement lorsqu’il est arrêté ?

Voici un cas d’utilisation assez courant dans les déploiements. Nous avons besoin de démoniser un programme dans un langage qui n’a pas de processus de longue durée : PHP ! Supposons que j’écrive un script PHP pour gérer les connexions websocket entrantes (nous avons construit une application de chat, après tout !) et que le script soit placé dans /home/ankush/chat_server/index.php.

Comme les connexions websocket peuvent atteindre le serveur à tout moment, ce processus doit être actif en permanence et surveiller les connexions entrantes. Nous ne pouvons pas avoir le cycle de vie traditionnel de PHP ici parce que les WebSockets sont des connexions avec état, et si le script meurt, la connexion est une liste. Quoi qu’il en soit, assez parlé de websockets ; voyons comment nous allons procéder pour démoniser ce script via systemd.

Tous les services systemd résident dans /etc/systemd/system, créons donc un fichier pour décrire notre script de serveur websocket. En supposant que vous êtes connecté en tant qu’utilisateur root.

# vi /etc/systemd/system/chat_server.service

et que vous avez besoin de ce qui suit.

 [Unit]
Description=Service de serveur de chat
After=network.target

[Service]
Type=simple
Utilisateur=ankush
ExecStart=php /home/ankush/chat_server/index.php
Restart=on-abort


[Installer]
WantedBy=multi-user.target

Sauvegardez le fichier et l’étape suivante consiste à recharger le démon systemd

 # systemctl daemon-reload

et de démarrer le service que nous venons de créer :

 # systemctl start chat_server

Si vous ne voyez pas d’erreur, c’est terminé !

Jetons également un coup d’œil rapide à la signification des différentes directives du fichier :

  • La partie [Unit] définit une nouvelle unité de service pour systemd. Dans le jargon de systemd, tous les services sont connus sous le nom d’unités de service.
  • La directive After (comme on peut s’y attendre) indique à systemd de ne lancer ce service qu’après le lancement des services de réseau (sinon, qui s’occupera de la gestion de bas niveau des connexions de sockets ?)
  • La directive Type=simple indique à systemd que ce service n’est pas censé se forker lui-même. En d’autres termes, une seule instance fonctionnera à tout moment.
  • User=ankush signifie que ce service s’exécutera sous l’utilisateur “ankush”. Nous pourrions changer cela en “root”, mais c’est fortement déconseillé du point de vue de la sécurité.
  • ExecStart, comme vous pouvez le voir, est la commande à exécuter.
  • Restart=on-abort signifie que le service doit être redémarré lorsqu’il s’arrête. En PHP, les processus qui tournent longtemps laissent échapper de la mémoire et finissent par exploser, c’est donc nécessaire.
  • La directive WantedBy= indique à systemd à quelle cible (pensez aux groupes) ce service appartient. Il en résulte que des liens symboliques sont créés à l’intérieur de cette cible pour pointer vers le service.

En général, cela est suffisant pour exécuter des processus d’arrière-plan à l’aide de systemd dans RHEL 7.

Plus d’options pour la logique de redémarrage

Dans l’exemple ci-dessus, j’ai configuré Restart=on-abort mais ce n’est pas la seule option. Il en existe d’autres et vous pouvez les choisir en fonction de vos besoins.

  • on-failure – sera redémarré si le code de sortie ou le signal n’est pas correct
  • always – redémarrage en cas de panne, de signal propre ou impur
  • on-abnormal – signal anormal, chien de garde ou délai d’attente
  • on-success – uniquement lorsqu’il a été arrêté par un signal ou un code de sortie propre

Configurer le service pour qu’il démarre au démarrage

Une fois que vous êtes satisfait du script et que vous vous êtes assuré qu’il fonctionne, vous devez le configurer pour qu’il se déclenche au démarrage et qu’il démarre.

Allez dans /etc/systemd/system et exécutez la commande enable ci-dessous (n’oubliez pas de changer le nom du fichier .service avec celui que vous avez)

 # systemctl enable chat_server.service

Vous verrez une confirmation de la création d’un lien symbolique.

 Création d'un lien symbolique de /etc/systemd/system/multi-user.target.wants/chat_server.service vers /etc/systemd/system/chat_server.service.

Redémarrez votre serveur et vous devriez voir le service démarrer au boot.

C’était facile ! N’est-ce pas ?

Aidez-nous ! J’ai investi massivement dans Upstart 🙁

Je comprends que vous me fassiez confiance, votre cas est la norme plutôt que l’exception. RHEL utilise Upstart depuis si longtemps que le changement ressemble presque à une trahison. Mais bon, les systèmes continuent de changer et nous ne devrions pas nous disputer pour des broutilles. Red Hat reconnaît que de nombreuses personnes sont bloquées avec des versions plus anciennes, et a créé un guide de migration auquel vous devriez absolument vous référer.

Un point positif dans tout cela est que systemd est compatible avec les scripts d’initialisation SysV, donc pour la plupart, vous n’aurez qu’à déplacer vos fichiers et à faire fonctionner les mêmes services.

Vous souhaitez en savoir plus sur l’administration et le dépannage de Linux ? Consultez ce cours en ligne.