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 poursystemd
. Dans le jargon desystemd
, 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.