wiki/HowtoSystemd.md

375 lines
9.4 KiB
Markdown
Raw Normal View History

2016-12-14 16:14:44 +01:00
---
2016-12-14 16:15:13 +01:00
categories: system sysadmin
2016-12-14 16:14:44 +01:00
title: Howto systemd
...
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
* Manpages : <https://www.freedesktop.org/software/systemd/man/index.html>
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
[systemd](https://www.freedesktop.org/wiki/Software/systemd/) est un gestionnaire de services (le fameux démon avec le PID 1) en alternative au System V. Il est installé par défaut depuis Debian 8. Son utilisation a suscitée des débats au sein de l'équipe, mais nous l'utilisons sur tous nos serveurs en Debian 8.
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
# Utilisation de base
2017-01-06 14:27:50 +01:00
## Statut systemd
2016-12-14 16:07:01 +01:00
2017-01-06 14:27:50 +01:00
Afficher le statut :
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:13:33 +01:00
# systemctl status
2016-12-14 16:07:01 +01:00
~~~
Lister les unités qui tournent :
~~~
2016-12-14 16:13:33 +01:00
# systemctl
# systemctl list-units
2016-12-14 16:07:01 +01:00
~~~
Lister les unités en échecs :
~~~
2016-12-14 16:13:33 +01:00
# systemctl --failed
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:18:01 +01:00
Lister les unités installées :
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:13:33 +01:00
# systemctl list-unit-files
2016-12-14 16:07:01 +01:00
~~~
2017-01-06 14:29:25 +01:00
> **Note** : Les unités sont dans `/usr/lib/systemd/system/` (emplacement par défaut) et `/etc/systemd/system/` (géré par l'administrateur).
2016-12-14 16:07:01 +01:00
2017-01-06 14:27:50 +01:00
## Gestion des unités
<https://www.freedesktop.org/software/systemd/man/systemd.unit.html>
2016-12-14 16:07:01 +01:00
Démarrer une unité :
~~~
2017-01-06 14:27:50 +01:00
# systemctl start <unité>
2016-12-14 16:07:01 +01:00
~~~
Arrêter une unité :
~~~
2017-01-06 14:27:50 +01:00
# systemctl stop <unité>
2016-12-14 16:07:01 +01:00
~~~
Redémarrer une unité :
~~~
2017-01-06 14:27:50 +01:00
# systemctl restart <unité>
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:18:01 +01:00
Recharger la configuration d'une unité :
2016-12-14 16:07:01 +01:00
~~~
2017-01-06 14:27:50 +01:00
# systemctl reload <unité>
2016-12-14 16:07:01 +01:00
~~~
2017-01-06 14:27:50 +01:00
Afficher le statut d'une unité :
2016-12-14 16:07:01 +01:00
~~~
2017-01-06 14:27:50 +01:00
# systemctl status <unité>
# systemctl status <unité> -l
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:18:01 +01:00
Savoir si une unité est activée ou non :
2016-12-14 16:07:01 +01:00
~~~
2017-01-06 14:27:50 +01:00
# systemctl is-enabled <unité>
2016-12-14 16:07:01 +01:00
~~~
> **Note** : Attention, si l'unité est en fait un script d'init dans `/etc/init.d/`, `is-enabled` ne fonctionne pas.
Activer une unité au boot :
~~~
2017-01-06 14:27:50 +01:00
# systemctl enable <unité>
2016-12-14 16:07:01 +01:00
~~~
Désactiver une unité au boot :
~~~
2017-01-06 14:27:50 +01:00
# systemctl disable <unité>
2016-12-14 16:07:01 +01:00
~~~
Masquer une unité, rendant impossible tout stop/start/… :
~~~
2017-01-06 14:27:50 +01:00
# systemctl mask <unité>
2016-12-14 16:07:01 +01:00
~~~
Démasquer une unité :
~~~
2017-01-06 14:27:50 +01:00
# systemctl unmask <unité>
2016-12-14 16:07:01 +01:00
~~~
Afficher la man page correspondante au service de l'unité :
~~~
2017-01-06 14:27:50 +01:00
# systemctl help <unité>
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:18:01 +01:00
Recharger systemd pour prendre en compte les unités modifiées :
2016-12-14 16:07:01 +01:00
~~~
# systemctl daemon-reload
~~~
2017-01-06 14:27:50 +01:00
2016-12-14 16:07:01 +01:00
## Gestion de l'alimentation
Éteindre et redémarrer la machine :
~~~
# systemctl reboot
~~~
Éteindre et couper l'alimentation de la machine :
~~~
# systemctl poweroff
~~~
2017-01-06 14:27:50 +01:00
# Écriture des unités
2016-12-14 16:07:01 +01:00
2017-01-06 14:27:50 +01:00
<https://www.freedesktop.org/software/systemd/man/systemd.service.html>
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
## Modifier une unité
2016-12-14 16:07:01 +01:00
~~~
# cp -a /lib/systemd/system/<service>.service /etc/systemd/system/
# vim /etc/systemd/system/<service>.service
# systemctl daemon-reload
~~~
2016-12-14 15:09:19 +01:00
Exemple avec ssh.service sous Debian 8 :
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 16:07:31 +01:00
[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
Alias=sshd.service
2016-12-14 16:07:01 +01:00
~~~
2016-12-14 15:09:19 +01:00
2016-12-14 16:31:11 +01:00
> **Note** : Chaque fois qu'une unité est modifiée, il est nécessaire de recharger systemd avec `systemctl daemon-reload`.
2016-12-14 16:07:01 +01:00
2017-01-06 14:27:50 +01:00
## Modifier partiellement une unité
2016-12-14 16:07:01 +01:00
On peut « override » une partie de l'unité en créant un fichier dans `/etc/systemd/system/unit.d/` qui précisera les modifications à faire.
2017-01-06 14:27:50 +01:00
Exemple avec l'unité de _varnish_ :
2016-12-14 16:07:01 +01:00
2016-12-14 16:28:38 +01:00
Dossier `/etc/systemd/system/varnish.service.d`, fichier `/etc/systemd/system/varnish.service.d/varnish.service` :
~~~
[Service]
2016-12-14 16:28:58 +01:00
ExecStart=/usr/sbin/varnishd -a 0.0.0.0:80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,16G -p thread_pools=8 -p thread_pool_add_delay=2 -p thread_pool_min=500 -p thread_pool_max=5000
ExecReload=/etc/varnish/reload-vcl.sh
2016-12-14 16:28:38 +01:00
~~~
2016-12-14 16:07:01 +01:00
# Utiliser les templates d'unités
2017-01-06 14:27:50 +01:00
On peut créer/utiliser des templates d'unités. Cela permet de gérer à la volée des instances de services. Par exemple pour _redis_ via `/etc/systemd/system/redis@.service`.
2016-12-14 16:07:01 +01:00
~~~
[Unit]
Description=Advanced key-value store instance %i
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/%i.conf
ExecStartPost=/bin/chgrp %i /var/run/redis/%i.sock
ExecStop=/usr/bin/redis-cli shutdown
Restart=always
User=redis
Group=%i
[Install]
WantedBy=multi-user.target
~~~
`%i` correspond au nom d'instance après le `@`.
On pourra ensuite démarrer l'instance foo et bar avec :
~~~
# systemctl start redis@foo redis@bar
~~~
2017-01-06 14:27:50 +01:00
2016-12-14 16:07:01 +01:00
# systemd par utilisateur
2017-01-06 14:27:50 +01:00
systemd fonctionne avec le PID 1. Mais il est aussi possible de lancer des instances par utilisateur avec le paramètre `--user`. C'est très pratique pour donner les droits à un utilisateur de gérer lui-même ses services (instances _Tomcat_ par exemple).
Il faut avoir le paquet `libpam-systemd` installé : une session systemd est lancée quand on est connecté à la machine :
~~~
$ systemctl --user status
● bar
State: running
Jobs: 0 queued
Failed: 0 units
Since: ven. 2016-12-23 21:15:33 CET; 1 weeks 6 days ago
CGroup: /user.slice/user-1001.slice/user@1001.service
├─1758 /lib/systemd/systemd --user
└─1760 (sd-pam)
~~~
Attention, si l'on veut une session permanente pour un utilisateur, il faut l'activer avec `loginctl` (si l'on ne fait pas cela, les services lancés via `systemctl --user` seront coupés à la déconnexion). Par exemple pour l'utilisateur _foo_ :
2016-12-14 16:07:01 +01:00
~~~
# loginctl enable-linger foo
~~~
2017-01-06 14:27:50 +01:00
Exemple d'unité utilisateur pour _Tomcat_ :
2016-12-14 16:07:01 +01:00
`/etc/systemd/user/tomcat.service`
2016-12-14 16:11:37 +01:00
2016-12-14 16:07:01 +01:00
~~~
[Unit]
Description=Tomcat %u.
After=network.target
[Service]
WorkingDirectory=/home/%u
Environment="CATALINA_BASE=/home/%u/tomcat"
EnvironmentFile=/home/%u/tomcat/conf/env
UMask=0002
ExecStart=/usr/share/tomcat7/bin/startup.sh
ExecStop=/usr/share/tomcat7/bin/shutdown.sh
ExecStopPost=/bin/sh -c date | /usr/bin/mail -s "%H/%u : Shutdown instance" foo@bar.com
Type=forking
[Install]
WantedBy=default.target
~~~
2017-01-06 14:27:50 +01:00
L'utilisateur pourra ainsi gérer lui-même le service :
2016-12-14 16:12:36 +01:00
2016-12-14 16:07:01 +01:00
~~~
$ systemctl --user enable tomcat
$ systemctl --user start tomcat
$ systemctl --user status -l tomcat
$ systemctl --user restart tomcat
$ systemctl --user stop tomcat
~~~
2017-01-06 14:27:50 +01:00
*Note* : pour pouvoir gérer `systemctl --user` via `sudo -iu foo`, on conseille de mettre dans `/etc/profile.d/systemd.sh` :
~~~
export XDG_RUNTIME_DIR="/run/user/$UID"
~~~
2016-12-14 16:07:01 +01:00
# Utilisation avancée
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
## Debug
2016-12-14 15:09:19 +01:00
2016-12-14 16:18:01 +01:00
Afficher plein d'informations sur l'unité :
2016-12-14 16:11:37 +01:00
~~~
# systemctl show <service>
~~~
2017-01-06 14:27:50 +01:00
_Debug_ au démarrage accessible sur _tty9_ :
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
~~~
# systemctl enable debug-shell
~~~
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
Débug d'une unité :
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
~~~
# systemctl stop unit
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/unit
~~~
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
Analyser ce qui prend du temps au démarrage :
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
~~~
# systemd-analyze
Startup finished in 5.019s (firmware) + 6.128s (loader) + 5min 35.864s (kernel) + 20min 3.148s (userspace) = 25min 50.160s
# systemd-analyze blame | head -3
2.029s systemd-udev-settle.service
1.400s docker.service
1.215s uml-utilities.service
2016-12-14 16:12:23 +01:00
~~~
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
# Migrer de sysvinit à systemd
Cette action est souvent requise lorsque l'on migre de Debian Wheezy à Jessie.
~~~
# apt install systemd-sysv
The following packages will be REMOVED:
sysvinit-core
# reboot
~~~
Vérifier que GRUB ne se lance pas avec l'option `init=/lib/sysvinit/init`.
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
2016-12-14 16:07:01 +01:00
# FAQ
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
## Bind9
2016-12-14 15:09:19 +01:00
2016-12-14 16:34:42 +01:00
Sous Debian 8, l'unité par défaut ne gère par les options dans `/etc/default/bind`.
2016-12-14 15:09:19 +01:00
2016-12-14 16:11:37 +01:00
Voir <http://trac.evolix.net/infogerance/wiki/HowtoDebian/MigrationWheezyJessie#Bind>
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
## strace Apache impossible
2016-12-14 15:09:19 +01:00
2016-12-14 16:34:42 +01:00
Une astuce efficace pour stracer un serveur de type Apache était : `strace -s65535 -ff /etc/init.d/apache2 restart`. Ensuite on joue la requête et on des infos (impossible à faire en prod bien sûr!).
Avec systemd, le strace ne suit pas les forks malgré `-ff`. À voir pourquoi systemd empêche ça…
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
## networking
2016-12-14 15:09:19 +01:00
Sous Debian 8, le démarrage du système se bloque complètement (dead lock) si l'initialisation de process dépendant du réseau (comme NFS, NTP, firewalling…) se fait avant que le réseau soit démarré.
2016-12-14 16:34:42 +01:00
Notamment quand ils sont démarrés via des hooks dans `/etc/network/if-*/`… Cela n'était pas bloquant avec SysV, cf https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754218#30
2016-12-14 15:09:19 +01:00
2016-12-14 16:34:42 +01:00
Astuces « bourrin » : ajouter `exit 0` dans `/etc/init.d/networking` et voir le souci via `systemctl status networking -l` ; modifier `JobTimeoutUSer` => `systemctl show networking -p JobTimeoutUSer`
2016-12-14 15:09:19 +01:00
2016-12-14 16:07:01 +01:00
## Failed to get D-Bus connection: Unknown error -1
2016-12-14 15:09:19 +01:00
2016-12-14 16:34:42 +01:00
Si en utilisant `systemctl` vous obtenez une erreur "Failed to get D-Bus connection: Unknown error -1" vérifiez si vous êtes bien passé à systemd et n'êtes resté à sysvinit !
2016-12-14 15:09:19 +01:00
2017-01-06 14:27:50 +01:00
## systemd-fsck : Dependency failed
Vous obtenez _systemd-fsck : Dependency failed for File System Check on /dev/disk/foo_ ?
2016-12-14 15:09:19 +01:00
2016-12-14 16:34:42 +01:00
Par défaut, `systemd-fsck` attend 1m30 l'accès à chaque device disque. Pour diverses raisons (accès à un SAN externe, etc.) cela peut échouer, vous aurez alors :
2016-12-14 15:09:19 +01:00
2016-12-14 16:11:37 +01:00
~~~
systemd[1]: Job dev-disk-by\x2dlabel-foo.device/start timed out.
systemd[1]: Timed out waiting for device dev-disk-by\x2dlabel-foo.device.
systemd[1]: Dependency failed for /backup.
systemd[1]: Dependency failed for Local File Systems.
systemd[1]: Triggering OnFailure= dependencies of local-fs.target.
systemd[1]: Dependency failed for File System Check on /dev/disk/by-label/foo.
~~~
2016-12-14 15:09:19 +01:00
Vous pouvez alors ajouter différentes options via le fstab, du type :
2016-12-14 16:11:37 +01:00
~~~
LABEL=foo /foo ext4 defaults,nofail,x-systemd.device-timeout=120 0 0
~~~
2016-12-14 15:09:19 +01:00
2016-12-14 16:11:37 +01:00
Notamment `nofail` pour éviter que cela fasse échouer votre séquence de boot !
2017-01-06 14:27:50 +01:00
## systemd VS systemD VS SystemD
**systemd** ne prend aucune majuscule. Ce n'est pas SystemD ou systemD.