{{tag>sysadmin linux systemd unit services config configuration}} ====== 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: * UNIT: la désignation de l'unité; * LOAD: indique si le fichier unité a bien été évalué par systemd. Le fichier unité est gardé en mémoire; * ACTIVE: résumé de l'état de l'unité. Permet d'identifier de façon élémentaire si un service a bien démarré. * SUB: état de l'unité de plus bas niveau apportant de plus amples informations. Les valeurs retournés dépendent du type d'unité, de l'état etc; * DESCRIPTION: description textuelle sommaire 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 ===== * https://blog.thewatertower.org/2019/04/24/modifying-systemd-unit-files/ * https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units * [[https://www.baeldung.com/linux/systemctl-list-enabled-services|systemd : lister les services actifs (baeldung.com)]]