Outils pour utilisateurs

Outils du site


blog

SystemD service - exemples

Diagnostic d'un service

Source : https://wiki.archlinux.org/title/Systemd_(Fran%C3%A7ais)#Diagnostic_d'un_service

Si un service systemd se comporte mal ou si vous souhaitez obtenir plus d'informations sur ce qui se passe, définissez la SYSTEMD_LOG_LEVEL {[variable d'environnement]] à SYSTEMD_LOG_LEVEL. [à debug. Par exemple, pour exécuter le daemon systemd-networkd en mode débogage :

Ajoutez un Fichiers de substitution pour le service en ajoutant les deux lignes :

[Service]
Environment=SYSTEMD_LOG_LEVEL=debug

Ou comme équivalent, définissez la variable d'environnement manuellement :

# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd

puis redémarrer systemd-networkd et regarder le journal du service avec l'option -f/--follow.

Exemple conf

Exemple conf proxy

/etc/systemd/system/docker.service.d/http-proxy.conf

[Service]
# Environment="HTTP_PROXY=http://192.168.56.1:3128/" "HTTPS_PROXY=http://192.168.56.1:3128/" "NO_PROXY=localhost,127.0.0.0/8,192.168.0.0/16,docker-1"
Environment="ALL_PROXY=http://192.168.56.1:3128/" "NO_PROXY=localhost,127.0.0.0/8,192.168.0.0/16,docker-1"
systemctl daemon-reload
systemctl show --property=Environment docker
systemctl restart docker
Désactiver un service si un fichier est présent

/lib/systemd/system/systemd-timesyncd.service.d/disable-with-time-daemon.conf

[Unit]
# don t run timesyncd if we have another NTP daemon installed
#ConditionFileIsExecutable=!/usr/sbin/VBoxService
Arguments utiles
Environment=NODE_ENV=production
Command systemd-run

https://blog.octo.com/5-services-que-systemd-ma-deja-rendu/

#systemd-run --user
systemd-run --on-active=10 /bin/bash -c "echo 'Bip!' >>'/var/log/spoutnik.log'

https://wiki.archlinux.org/index.php/Systemd/Timers

systemd-run --on-active="12h 30m" --unit someunit.service

https://www.systutorials.com/docs/linux/man/1-systemd-run/

systemd-run -p BlockIOWeight=10 updatedb
systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo

Exemple

Exemple 1

Source : https://confluence.atlassian.com/confkb/run-confluence-as-a-systemd-service-on-linux-937177781.html

touch /lib/systemd/system/confluence.service
chmod 664 /lib/systemd/system/confluence.service
vi /lib/systemd/system/confluence.service

/lib/systemd/system/confluence.service

[Unit]
Description=Confluence
After=network.target
 
[Service]
Type=forking
User=confluence
PIDFile=/opt/atlassian/confluence/work/catalina.pid
ExecStart=/opt/atlassian/confluence/bin/start-confluence.sh
ExecStop=/opt/atlassian/confluence/bin/stop-confluence.sh
TimeoutSec=200
LimitNOFILE=2048
LimitNPROC=2048
 
[Install]
WantedBy=multi-user.target

Vérif syntax

systemd-analyze verify /lib/systemd/system/confluence.service
systemctl daemon-reload
systemctl enable confluence.service
systemctl start confluence.service
systemctl status confluence.service
Exemple 2

https://wiki.archlinux.org/index.php/Advanced_Format

/etc/systemd/system/lcc_fix.service

[Unit]
Description=WDIDLE3
 
[Service]
Type=oneshot
ExecStart=/usr/bin/hdparm -J 300 --please-destroy-my-drive /dev/sdX
TimeoutSec=0
StandardInput=tty
RemainAfterExit=yes
UMask=006
 
[Install]
WantedBy=multi-user.target
Exemple 3

Source : https://fabianlee.org/2017/05/21/golang-running-a-go-binary-as-a-systemd-service-on-ubuntu-16-04/

/lib/systemd/system/sleepservice.service

[Unit]
Description=Sleep service
ConditionPathExists=/home/ubuntu/work/src/sleepservice/sleepservice
After=network.target
 
[Service]
Type=simple
User=sleepservice
Group=sleepservice
LimitNOFILE=1024
 
Restart=on-failure
RestartSec=10
startLimitIntervalSec=60
 
WorkingDirectory=/home/ubuntu/work/src/sleepservice
ExecStart=/home/ubuntu/work/src/sleepservice/sleepservice --name=foo
 
# make sure log directory exists and owned by syslog
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /var/log/sleepservice
ExecStartPre=/bin/chown syslog:adm /var/log/sleepservice
ExecStartPre=/bin/chmod 755 /var/log/sleepservice
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=sleepservice
 
[Install]
WantedBy=multi-user.target
Exemple 4 - SystemD appelant un script sysV init

Exemple avec SonarQube

/etc/systemd/system/sonar.service

[Unit]
Description=Sonar 6
After=network.target network-online.target
Wants=network-online.target
 
[Service]
ExecStart=/home/sonar/sonarqube-6.7.1/bin/linux-x86-64/sonar.sh start
ExecStop=/home/sonar/sonarqube-6.7.1/bin/linux-x86-64/sonar.sh stop
ExecReload=/home/sonar/sonarqube-6.7.1/bin/linux-x86-64/sonar.sh restart
PIDFile=/home/sonar/sonarqube-6.7.1/bin/linux-x86-64/./SonarQube.pid
Type=forking
User=sonar
 
[Install]
WantedBy=multi-user.target
Exemple Jenkins slave agent

Jenkins-agent.service

[Unit]
Description=Jenkins Service
Wants=network.target
After=network.target
 
[Service]
ExecStart=/usr/bin/java -jar /home/user1/slave2.jar -jnlpUrl http://jenkins:8080/computer/SERVER01/slave-agent.jnlp
User=user1
Restart=always
 
[Install]
WantedBy=multi-user.target
Exemple Postgres

/usr/local/lib/systemd/system/postgres_plop_rct.service

[Unit]
Description=postgresql_plop_rct_service
After=network.target
AssertPathExists=!/etc/noprod
 
[Service]
Type=forking
User=postgres
 
#Disable OOM kill on postmaster
OOMScoreAdjust=-1000
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=0
 
WorkingDirectory=/tools/list/postgres/script/bin
ExecStart=/tools/list/postgres/script/bin/rc_postgres.ksh start plop_rct
ExecStop=/tools/list/postgres/script/bin/rc_postgres.ksh stop plop_rct
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-abort
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0
 
[Install]
WantedBy=multi-user.target
Exemple AAP - Tirer des dépendances seulement

/etc/systemd/system/automation-controller.service

[Unit]
Description=Automation Controller service
After=network.target redis.service  nginx.service supervisord.service receptor.service
Wants=redis.service  nginx.service supervisord.service receptor.service
 
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
 
[Install]
WantedBy=multi-user.target
Exemple iptables-service de RedHat

/usr/lib/systemd/system/iptables.service

[Unit]
Description=IPv4 firewall with iptables
After=syslog.target
AssertPathExists=/etc/sysconfig/iptables
 
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/iptables/iptables.init start
ExecReload=/usr/libexec/iptables/iptables.init reload
ExecStop=/usr/libexec/iptables/iptables.init stop
Environment=BOOTUP=serial
Environment=CONSOLETYPE=serial
StandardOutput=syslog
StandardError=syslog
 
[Install]
WantedBy=basic.target

/usr/libexec/iptables/iptables.init

#!/bin/bash
#
# iptables      Start iptables firewall
#
# chkconfig: 2345 08 92
# description:  Starts, stops and saves iptables firewall
#
# config: /etc/sysconfig/iptables
# config: /etc/sysconfig/iptables-config
#
### BEGIN INIT INFO
# Provides: iptables
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop iptables firewall
# Description: Start, stop and save iptables firewall
### END INIT INFO
 
# Source function library.
. /etc/init.d/functions
 
#------------------------------------------------
 
case "$1" in
    start)
        [ -f "$VAR_SUBSYS_IPTABLES" ] && exit 0
        start
        RETVAL=$?
        ;;
    stop)
        [ "x$IPTABLES_SAVE_ON_STOP" = "xyes" ] && save
        stop
        RETVAL=$?
        ;;
    restart|force-reload)
        restart
        RETVAL=$?
        ;;
    reload)
        [ -e "$VAR_SUBSYS_IPTABLES" ] && reload
        RETVAL=$?
        ;;
    condrestart|try-restart)
        [ ! -e "$VAR_SUBSYS_IPTABLES" ] && exit 0
        restart
        restart
        RETVAL=$?
        ;;
    status)
        status
        RETVAL=$?
        ;;
    panic)
        set_policy DROP
        RETVAL=$?
        ;;
    save)
        save
        RETVAL=$?
        ;;
    *)
        echo $"Usage: ${IPTABLES} {start|stop|reload|restart|condrestart|status|panic|save}"
        RETVAL=2
        ;;
esac
 
exit $RETVAL
Exemple Nagios

nagios4.service

[Unit]
Description=nagios4
Documentation=man:nagios4
 
[Service]
Environment=NAGIOSCFG="/etc/nagios4/nagios.cfg"
EnvironmentFile=/etc/default/nagios4
ExecStartPre=sh -c 'nagiospipe=$$(sed -n "s/^command_file=\\(.*\\)/\\1/p" ${NAGIOSCFG}); [ -z "$${nagiospipe}" -o ! -e "$${nagiospipe}" ] || rm -f "$${nagiospipe}"'
ExecStart=/usr/sbin/nagios4 ${NAGIOSCFG}
ExecStopPost=sh -c 'nagiospipe=$$(sed -n "s/^command_file=\\(.*\\)/\\1/p" ${NAGIOSCFG}); [ -z "$${nagiospipe}" -o ! -e "$${nagiospipe}" ] || rm -f "$${nagiospipe}"'
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
PIDFile=/run/nagios4/nagios.pid
 
[Install]
WantedBy=multi-user.target
Exemple Podman

/etc/systemd/user/podman.service

[Unit]
Description=Podman API Service
Requires=podman.socket
After=podman.socket
Documentation=man:podman-system-service(1)
StartLimitIntervalSec=0
 
[Service]
Type=exec
KillMode=process
Environment=LOGGING="--log-level=info"
ExecStart=/usr/bin/podman $LOGGING system service --time=1800
 
[Install]
WantedBy=multi-user.target
systemctl --user daemon-reload
systemctl restart --user podman.socket

Source : https://buildpacks.io/docs/for-app-developers/how-to/special-cases/build-on-podman/

2025/03/24 15:06

SystemD mount relancer un unit failed avec un Timer

Voir : https://github.com/SSSD/sssd/issues/5074

At boot SystemD type “mount” failed for CIFS when uid is ldap account, because sssd not ready (be started)

Erreur

bad option uid="jean"

Problème avec mount.cifs avec l'option uid= quand le uid n'est pas un uid mais un username. Le username est sur LDAP et le service sssd n'est pas prêt.

Nous faisons un montage réseau CIFS avec pour options : uid=jean. Hors jean est un compte LDAP. Il est préférable d'utiliser les UID, mais dans mon cas j'ai une contrainte d'entreprise.

Le problème se produit au boot. L'Unit SystemD mnt-plop.mount est bien lancée, mais presque en même temps que sssd.service et le LDAP n'est pas encore fonctionnel.

Et donc le montage réseau échoue.

# journalctl -u mnt-plop.mount -u sssd -b
-- Logs begin at Sat 2023-02-18 14:07:02 CET, end at Wed 2023-03-08 19:46:26 CET. --
Mar 08 19:45:55 srv01 systemd[1]: Starting System Security Services Daemon...
Mar 08 19:45:55 srv01 sssd[1367]: Starting up
Mar 08 19:45:55 srv01 sssd_be[1439]: Starting up
Mar 08 19:45:56 srv01 sssd_sudo[1501]: Starting up
Mar 08 19:45:56 srv01 sssd_nss[1499]: Starting up
Mar 08 19:45:56 srv01 sssd_pam[1500]: Starting up
Mar 08 19:45:56 srv01 systemd[1]: Started System Security Services Daemon.
Mar 08 19:45:56 srv01 systemd[1]: Mounting Partage...
Mar 08 19:45:56 srv01 mount[1606]: bad option uid="jean"
Mar 08 19:45:56 srv01 systemd[1]: mnt-plop.mount: Mount process exited, code=exited status=1
Mar 08 19:45:56 srv01 systemd[1]: mnt-plop.mount: Failed with result 'exit-code'.
Mar 08 19:45:56 srv01 systemd[1]: Failed to mount Partage.
Mar 08 19:45:57 srv01 sssd_be[1439]: Backend is online

Pour les montages NAS je préconise de faire systématiquement un Unit automount, mais autre contrainte d'entreprise, je dois trouver une solution sans automount.

/etc/systemd/system/mnt-plop.mount

[Unit]
Description=Partage
 
[Mount]
What=//127.0.0.1/shared
Type=cifs
Options=noexec,nosuid,nodev,rw,port=445,uid=jean,gid=jean,file_mode=0644,dir_mode=0755,noperm,credentials=/root/.cifs_plop
Where=/mnt/plop
ForceUnmount=yes
DirectoryMode=755
 
[Install]
WantedBy=remote-fs.target
systemctl stop sssd
sss_cache -E
rm /var/lib/sss/db/* -f
reboot
# systemctl status /mnt/plop
● mnt-plop.mount - Partage
   Loaded: loaded (/etc/systemd/system/mnt-plop.mount; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Wed 2023-03-08 19:54:45 CET; 36s ago
    Where: /mnt/plop
     What: //127.0.0.1/shared

Mar 08 19:54:45 srv01 systemd[1]: Mounting Partage...
Mar 08 19:54:45 srv01 mount[1574]: bad option uid="jean"
Mar 08 19:54:45 srv01 systemd[1]: mnt-plop.mount: Mount process exited, code=exited status=1
Mar 08 19:54:45 srv01 systemd[1]: mnt-plop.mount: Failed with result 'exit-code'.
Mar 08 19:54:45 srv01 systemd[1]: Failed to mount Partage.

Solution

/etc/systemd/system/mnt-plop.timer

[Unit]
Description=Partage
Requires=sssd.service
After=sssd.service
Conflicts=mnt-plop.mount
 
[Timer]
OnBootSec=15
Unit=mnt-plop.mount
RemainAfterElapse=False
 
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable mnt-plop.timer

Avec un Timer ça fonctionne bien, mais à la condition que le Unit mnt-plop.mount soit disable. En effet si il est enable, il échoue, et le Timer SystemD n'essaie même pas de le relancer.

L'astuce consiste à l'arrêter avant !

C'est grâce à l'option :

[Unit]
Conflicts=mnt-plop.mount

En contournement nous avons le choix parmi les possibilités suivantes :

  • Utiliser des UID/GID numériques à la place des usernames/groupnames
  • Créer un Unit de type automount
  • Activer le cache sssd
  • Utiliser un Unit SystemD de type Service ou de type Timer comme illustré dans cet exemple.

NB : il existe aussi l'option sss_master_map_wait pour le paquet autofs, mais ça n'a pas d’intérêt puisque ça fonctionne très bien avec un automount SystemD classique sans paramètre particulier.

2025/03/24 15:06

SystemD mode recovery single mode linux kernel param

Parametre Kernel

  • systemd.unit=rescue.target
  • systemd.debug-shell=1
  • systemd.unit=emergency.target

pour allez dans le tty8 ou tty9

ce qui revient à

systemctl enable debug-shell.service

Avec init=/bin/bash (à l'ancienne)

Dans le grub, ligne commençant par linux

init=/bin/bash
mount -n -o remount,rw /
passwd
reboot -f

rd.break

kernel param rd.break Si SeLinux : ajouter : enforcing=0

Exemple :

rd.break enforcing=0

Puis

loadkeys fr
chroot /sysroot

Sur RedHat

rd.break
? enforcing=0

mount -o remount,rw /sysroot
chroot /sysroot
passwd
 
touch /.autorelabel 
 
# ou alors (plus rapide) : 
load_policy -i  
#puis 
restorecon -Rv /etc  
Alternative à touch /.autorelabel
  • Remove rhgb quiet using the backspace key.
  • You can change “ro” to “rw” in this grub line to avoid having to do a remount (shown below).
  • IMPORTANT Add to the kernel line: rd.break enforcing=0 NOTE: you might have to make “console=tty0” above as well depending if it's virtual or not.
  • Press Ctrl x to resume the boot process. NOTE: If you did not change “ro” to “rw” above, make sure to remount the /sysroot partition as shown below.
mount –o remount,rw /sysroot
chroot /sysroot
passwd root
  • Type exit twice to continue the boot process
  • Log in, open a terminal and enter the root account.
restorecon -v /etc/shadow
setenforce 1 ; getenforce
2025/03/24 15:06

Systemd lancer un script à l'arrêt

Source : http://unix.stackexchange.com/questions/39226/how-to-run-a-script-with-systemd-right-before-shutdown

/etc/systemd/system/jbshutdown.service

[Unit]
Description=Exec before shutdown
 
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/root/bin/shutdown.sh
 
[Install]
WantedBy=multi-user.target
chmod +x /root/bin/shutdown.sh
systemctl enable jbshutdown.service
systemctl start jbshutdown.service

Le lien symbolique suivant sera crée : /etc/systemd/system/multi-user.target.wants/jbshutdown.service

2025/03/24 15:06

Systemd journalctl journal logs

Requête sur les logs, chercher et trouver

Trouver les logs entres deux dates

Voir find_entre_deux_dates

journalctl --since "2016-10-18 06:50" --until "2016-10-18 09:00"
journalctl --since yesterday -p err

Par service et/ou par PID

journalctl -u pacemaker.service --since "2017-02-24 16:00" -p warning
journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097 + _SYSTEMD_UNIT=dbus.service

Voir aussi

ps -f -p 28097
systemctl status 28097
 
# Par PPID
ps -f --ppid 1

Erreur au boot

journalctl -b -p err

tailf

# dmesg -l warn
journalctl -f -p warning

Ouvrir un fichier spécifique

journalctl --file /tmp/plop.journal

Filtrer les logs json

journalctl -u nginx -o json-pretty  | jq '. | select(.SYSLOG_IDENTIFIER=="plop")

Les commandes sudo

# journalctl -b -t sudo -p 5 -u session-*.scope
Sep 12 08:19:01 vmdeb01 sudo[601]:    admin : TTY=pts/0 ; PWD=/root ; USER=root ; COMMAND=/bin/bash
Options sur le forme

Arguments :

  • --no-pager
  • -f : tail -f

Configuration

Rendre persistant journalctl

Source : https://geekeries.de-labrusse.fr/?p=3189

Par défaut journalctl affiche uniquement les logs du dernier boot

# journalctl --boot=-1
Failed to look up boot -1: Cannot assign requested address

Pour avoir les logs persistant :

/etc/systemd/journald.conf

[Journal]
#Storage=auto
Storage=persistent
Compress=yes
 
#SystemMaxUse=
SystemMaxUse=250M
 
#ForwardToSyslog=yes
mkdir /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald

Journalctl et container

Source : https://docs.docker.com/engine/logging/drivers/journald/

CONTAINER_ID The container ID truncated to 12 characters.
CONTAINER_ID_FULL The full 64-character container ID.
CONTAINER_NAME The container name at the time it was started. If you use docker rename to rename a container, the new name isn't reflected in the journal entries.
CONTAINER_TAG,\ SYSLOG_IDENTIFIER The container tag ( log tag option documentation).
CONTAINER_PARTIAL_MESSAGE A field that flags log integrity. Improve logging of long log lines.
IMAGE_NAME The name of the container image.
Retrieve log messages with journalctl

Use the journalctl command to retrieve log messages. You can apply filter expressions to limit the retrieved messages to those associated with a specific container:

sudo journalctl CONTAINER_NAME=webserver

You can use additional filters to further limit the messages retrieved. The -b flag only retrieves messages generated since the last system boot:

sudo journalctl -b CONTAINER_NAME=webserver

The -o flag specifies the format for the retrieved log messages. Use -o json to return the log messages in JSON format.

sudo journalctl -o json CONTAINER_NAME=webserver

View logs for a container with a TTY enabled

If TTY is enabled on a container you may see [10B blob data] in the output when retrieving log messages. The reason for that is that \r is appended to the end of the line and journalctl doesn't strip it automatically unless --all is set:

sudo journalctl -b CONTAINER_NAME=webserver --all
Journalctl container et Python

Retrieve log messages with the journal API This example uses the systemd Python module to retrieve container logs:

import systemd.journal
 
reader = systemd.journal.Reader()
reader.add_match('CONTAINER_NAME=web')
 
for msg in reader:
    print '{CONTAINER_ID_FULL}: {MESSAGE}'.format(**msg)
Autres

/etc/systemd/journald.conf

[Journal]
RateLimitInterval=10s
RateLimitBurst=6000

Pb

Pb plus de logs avec journalctl ni dans /var/log/message

/var/log/message vide ?

# journalctl                                                                                                                                                                                                    
No journal files were found.                                                                     
-- No entries --

Solution

systemctl restart systemd-journald
systemctl restart rsyslog.service
2025/03/24 15:06
blog.txt · Dernière modification : de 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki