ITSkillsCenter
Blog

Maîtriser systemd : units, timers et targets sur RHEL 10

11 min de lecture

📍 Article principal : RHCSA EX200 v10 : la voie d’entrée Linux entreprise

systemd reste le gestionnaire d’init de Red Hat Enterprise Linux 10, et la maîtrise de ses concepts pèse lourd dans l’examen RHCSA. Au-delà des commandes start et stop apprises en première semaine, le candidat doit savoir écrire une unité personnalisée, planifier une tâche avec un timer plutôt qu’avec cron, basculer la cible par défaut entre mode console et mode graphique, lire un journal filtré par priorité et masquer un service problématique. Ce tutoriel parcourt ces sujets dans l’ordre où ils s’enchaînent en production.

Prérequis avant de commencer

  • Un système RHEL 10, Rocky Linux 10 ou AlmaLinux 10 fonctionnel.
  • Un accès sudo ou root.
  • Un éditeur de texte ligne de commande maîtrisé.
  • Niveau attendu : intermédiaire. Temps estimé : 90 minutes pour parcourir l’ensemble.

Étape 1 — Lister et inspecter les unités

Avant de manipuler quoi que ce soit, il faut savoir interroger l’état actuel du système. systemd expose une vue uniforme de tous les services, sockets, timers, mounts et autres ressources sous forme d’unités. Quelques commandes donnent immédiatement l’image complète.

systemctl                                # Liste toutes les unités chargées
systemctl --type=service --state=running # Filtre les services en cours
systemctl status sshd
systemctl cat sshd                       # Affiche le fichier d'unité réel

La commande systemctl sans argument affiche la totalité, ce qui sature vite la console — l’usage en filtre --type et --state est plus utile au quotidien. La commande systemctl status retourne l’état de l’unité, son PID principal, l’utilisation mémoire, les dix dernières lignes du journal et l’horodatage du dernier démarrage. C’est la commande de diagnostic numéro un. La commande systemctl cat sshd affiche le fichier .service avec les éventuels drop-ins dans /etc/systemd/system/sshd.service.d/ empilés visuellement, ce qui clarifie immédiatement la configuration finale appliquée.

Étape 2 — Cycle de vie d’un service

Les opérations de base sur un service répondent à une logique cohérente. Le verbe d’action est aussi explicite que possible.

sudo systemctl start httpd               # Démarre le service maintenant
sudo systemctl stop httpd                # L'arrête
sudo systemctl restart httpd             # Stop puis start
sudo systemctl reload httpd              # Recharge la conf sans redémarrer
sudo systemctl is-active httpd           # Retourne active/inactive/failed

La distinction restart versus reload n’est pas anecdotique. reload envoie un signal SIGHUP au processus principal et lui demande de relire sa configuration sans interrompre les connexions en cours, ce qui est essentiel pour Apache, Nginx ou OpenSSH en production. restart coupe brutalement le service. Tous les services ne supportent pas reload ; quand ce n’est pas le cas, systemctl reload retourne une erreur et il faut basculer sur restart.

Étape 3 — Activer au démarrage et masking

Un service démarré aujourd’hui ne sera pas automatiquement relancé après reboot s’il n’est pas enabled. La commande systemctl enable crée un lien symbolique dans /etc/systemd/system/ qui force systemd à inclure l’unité dans la cible appropriée.

sudo systemctl enable httpd              # Active au démarrage
sudo systemctl enable --now httpd        # Active et démarre maintenant
sudo systemctl disable httpd             # Désactive au démarrage
sudo systemctl mask httpd                # Empêche tout démarrage manuel ou auto
sudo systemctl unmask httpd              # Annule le mask

Le drapeau --now couplé à enable évite la double commande enable + start en une seule frappe. La commande mask est un cran plus puissant que disable : elle remplace le fichier d’unité par un lien vers /dev/null, ce qui rend impossible tout démarrage, y compris par dépendance. C’est l’outil pour neutraliser définitivement un service sur lequel un autre tente de s’appuyer. Sur RHCSA, savoir distinguer disable et mask est explicitement attendu.

Étape 4 — Lire les journaux avec journalctl

systemd centralise l’ensemble des journaux dans le binaire journald. La commande journalctl remplace en pratique les anciens tail -f /var/log/messages. Elle permet de filtrer par unité, par priorité, par horodatage, en lecture continue.

sudo journalctl -u sshd                  # Tous les logs de sshd
sudo journalctl -u sshd --since "1 hour ago"
sudo journalctl -p err -b                # Erreurs depuis ce boot
sudo journalctl -f                       # Suivi en temps réel
sudo journalctl --disk-usage             # Espace utilisé par les journaux

Les niveaux de priorité suivent la convention syslog : emerg, alert, crit, err, warning, notice, info, debug. Le filtrage avec -p err retourne tout ce qui est de niveau err ou plus grave. La sortie de journalctl --disk-usage indique combien d’espace les journaux occupent ; sur RHEL 10, la valeur par défaut SystemMaxUse dans /etc/systemd/journald.conf permet à journald d’occuper jusqu’à 10 % de la partition /var/log. Pour rendre les journaux persistants entre reboots, il suffit de créer le répertoire /var/log/journal avec sudo mkdir -p /var/log/journal et de redémarrer journald.

Étape 5 — Comprendre les targets

Les targets remplacent les anciens niveaux d’exécution SysV. Une target est une unité spéciale qui agrège un ensemble d’autres unités à activer pour atteindre un état système. Les targets standard sur RHEL 10 incluent multi-user.target (équivalent runlevel 3, multi-utilisateur sans interface graphique), graphical.target (équivalent runlevel 5, avec interface graphique), rescue.target (mode mono-utilisateur), et emergency.target (système minimal de dépannage).

systemctl get-default                    # Cible courante
sudo systemctl set-default multi-user.target
sudo systemctl isolate multi-user.target # Bascule sans reboot

La commande set-default modifie un lien symbolique dans /etc/systemd/system/default.target qui pointe vers la cible voulue. La commande isolate bascule la cible immédiatement, sans reboot, ce qui revient à arrêter tous les services qui ne sont pas dans la cible visée et à démarrer ceux qui doivent l’être. Sur un poste utilisé en SSH, basculer en graphical.target sans clavier-écran physique installerait quand même GNOME mais ne couperait pas SSH ; basculer en rescue.target coupe par contre toutes les connexions actives.

Étape 6 — Écrire un service personnalisé

Le candidat RHCSA doit savoir créer une unité .service de zéro pour démarrer un script ou un binaire personnalisé. Le fichier va sous /etc/systemd/system/ et suit un schéma simple en trois sections.

sudo vim /etc/systemd/system/audit-disk.service
[Unit]
Description=Surveillance espace disque - rapport quotidien
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/audit-disk.sh
User=root
StandardOutput=journal

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now audit-disk.service
sudo systemctl status audit-disk.service

La section [Unit] décrit l’unité et ses dépendances. After ordonne le démarrage : ne lancer cette unité qu’après network-online.target. La section [Service] indique le type d’exécution : oneshot convient à un script qui s’exécute, fait son travail et se termine ; simple conviendrait à un démon qui tourne en permanence ; forking à un démon classique qui se détache. La section [Install] précise dans quelle target installer l’unité quand on l’active. La commande daemon-reload est obligatoire après chaque modification d’un fichier d’unité — sans elle, systemd ignore les changements.

Étape 7 — Créer un timer pour remplacer cron

Les timers systemd remplacent avantageusement cron dans la majorité des cas modernes : ils héritent de la journalisation centralisée, des dépendances et de la gestion des erreurs. Un timer associe une planification à un service à déclencher.

sudo vim /etc/systemd/system/audit-disk.timer
[Unit]
Description=Lance audit-disk.service tous les jours à 03h00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
Unit=audit-disk.service

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now audit-disk.timer
systemctl list-timers --all | grep audit-disk

L’expression OnCalendar suit la syntaxe systemd décrite dans man systemd.time ; la commande systemd-analyze calendar "Mon..Fri 09:00:00" permet de tester une expression calendrier sans planifier réellement. La directive Persistent=true garantit que si le système était éteint au moment d’une exécution prévue, le service sera lancé au prochain démarrage. La commande list-timers donne l’horodatage de la prochaine exécution et le délai depuis la dernière, ce qui sert à vérifier qu’un timer est bien armé.

Étape 8 — Définir un mount avec systemd

Plutôt que d’éditer /etc/fstab, on peut définir un point de montage en unité systemd. C’est la méthode propre quand le montage dépend d’un service réseau qui doit être actif au préalable.

sudo vim /etc/systemd/system/srv-data.mount
[Unit]
Description=Montage du volume data
Requires=network-online.target
After=network-online.target

[Mount]
What=192.168.10.100:/data
Where=/srv/data
Type=nfs
Options=defaults,_netdev

[Install]
WantedBy=multi-user.target

Le nom du fichier doit refléter le point de montage avec les / remplacés par des tirets : /srv/data donne srv-data.mount. systemd refuse tout autre nommage, et c’est l’erreur qui revient le plus souvent quand on découvre les mount units. La directive Type=nfs ici sert d’exemple ; pour un point de montage local, on indiquerait xfs, ext4, ou la valeur appropriée.

Étape 9 — Surveiller et déboguer une unité défaillante

Quand un service refuse de démarrer ou tombe en boucle, plusieurs commandes complètent le diagnostic.

systemctl --failed                       # Liste toutes les unités en état failed
sudo journalctl -xeu nom.service         # Journaux étendus de cette unité
systemd-analyze blame                    # Temps de démarrage par unité
systemd-analyze critical-chain           # Chaîne critique du boot

La sortie de systemctl --failed liste les unités en échec — première chose à vérifier après un boot lent ou anormal. L’option -x de journalctl ajoute des explications du catalog de systemd quand elles existent, ce qui donne souvent la cause immédiatement. Les commandes blame et critical-chain pointent les services lents au démarrage, utiles quand un boot dépasse les 30 secondes sans raison apparente.

Étape 10 — Vérifier la persistance après reboot

sudo systemctl reboot
# Au retour :
systemctl get-default
systemctl is-active httpd
systemctl is-enabled audit-disk.service
systemctl list-timers | head

Si la cible par défaut ne correspond pas à la commande set-default exécutée précédemment, c’est qu’un autre lien symbolique default.target a été créé manuellement et écrase le réglage. La commande ls -l /etc/systemd/system/default.target montre exactement vers quoi pointe le lien.

Erreurs fréquentes

Erreur Cause Solution
Modification de .service sans effet Oubli de systemctl daemon-reload Toujours daemon-reload après modification d’un fichier d’unité.
Service activé n’a pas démarré au boot Section [Install] manquante ou WantedBy incorrect Vérifier que la cible cible existe et que la section est complète.
Timer ne se déclenche jamais Timer enabled mais pas démarré Utiliser enable --now ou enchaîner enable et start.
journalctl vide pour une unité Journaux non persistants après reboot Créer /var/log/journal et redémarrer journald.
Mount unit refusé Nom du fichier ne correspond pas au point de montage Utiliser systemd-escape -p chemin pour générer le bon nom.

Adaptation aux infrastructures à budget contraint

Sur les serveurs à 2 Go de RAM, les services activés inutilement consomment vite la mémoire disponible. La commande systemctl list-unit-files --state=enabled --type=service liste tout ce qui se lancera au démarrage — un audit régulier permet de désactiver les services superflus comme cups, bluetooth ou avahi-daemon sur un serveur sans périphérique. Le gain RAM peut atteindre 100 à 200 Mo, ce qui n’est pas négligeable sur un VPS d’entrée de gamme.

Tutoriels frères

Lectures complémentaires

Questions fréquentes

Faut-il préférer un timer systemd à cron ?

Pour les nouvelles planifications, oui. Les timers offrent journalisation centralisée, gestion d’erreurs, dépendances explicites et exécution différée si le système était éteint. cron reste pertinent pour la rétrocompatibilité avec des scripts hérités et n’est pas déprécié.

Comment voir les services qui démarrent au boot ?

La commande systemctl list-unit-files --state=enabled donne la liste exhaustive. Pour ne voir que les services, ajouter --type=service.

Que faire si systemctl status dit service not found ?

L’unité n’est pas chargée. Vérifier le nom exact avec systemctl list-unit-files | grep nom. Si l’unité existe mais n’est pas chargée, exécuter systemctl daemon-reload puis réessayer.

Les timers acceptent-ils des expressions cron ?

Non. La syntaxe OnCalendar est propre à systemd et est plus expressive que cron. Le manuel man systemd.time détaille la syntaxe et donne des exemples.

Comment isoler une cible sans couper SSH ?

S’assurer que multi-user.target ou graphical.target est la cible visée. rescue.target et emergency.target coupent l’ensemble du multi-utilisateur, y compris SSH. La commande isolate est sans retour si on s’est trompé sur la cible — au pire, un reboot ramène la cible par défaut.

Comment limiter l’espace disque utilisé par journald ?

Modifier SystemMaxUse dans /etc/systemd/journald.conf ou créer un drop-in /etc/systemd/journald.conf.d/size.conf avec une valeur explicite (par exemple SystemMaxUse=200M), puis redémarrer journald avec systemctl restart systemd-journald.

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité