Nachdem ich feststellen musst, dass immer noch der ein oder andere mit Systemd und den Unitfiles auf Kriegsfuß steht und mit tieferem Wissen manches Problem zu vermeiden wäre, will ich mit ein paar kurzen Erklärungen Abhilfe schaffen.
Systemd hat als Ersatz für init bereits 2010 angefangen in die verschiedenen Distributionen Einzug zu halten und ist mittlerweile Standard. Somit haben auch die alten init-Skripte ausgedient und wurde durch Unitfiles ersetzt. Auf den ersten Blick lassen diese weniger Optionen zu, aber sobald man sich etwas weiter mit den Einstellmöglichkeiten auseinandersetzt, wird man wohl nichts an Funktionalität vermissen.
Für die Erläuterungen möchte ich ein Beispiel nehmen, dass vielleicht der ein oder andere schon kennt, und habe mich darum für Icinga 2 entschieden. Dieses findet sich in /usr/lib/systemd/system
als icinga2.service
und sieht folgendermaßen aus:
[Unit] Description=Icinga host/service/network monitoring system After=syslog.target network-online.target postgresql.service mariadb.service carbon-cache.service carbon-relay.service [Service] Type=forking EnvironmentFile=/etc/sysconfig/icinga2 ExecStartPre=/usr/lib/icinga2/prepare-dirs /etc/sysconfig/icinga2 ExecStart=/usr/sbin/icinga2 daemon -d -e ${ICINGA2_ERROR_LOG} PIDFile=/run/icinga2/icinga2.pid ExecReload=/usr/lib/icinga2/safe-reload /etc/sysconfig/icinga2 TimeoutStartSec=30m [Install] WantedBy=multi-user.target
Als erstes möchte ich auf den Pfad selbst eingehen. Diese muss per Konvention heißen wie der Service, der über sie gesteuert wird, und auf .service
enden, damit sie von anderen Units unterscheidbar ist. Andere Units wären beispielsweise Sockets für die socketbasierende Aktivierung oder Targets als Gruppierung von Services und Ersatz für die Runlevel. Der Pfad /usr/lib/systemd/system
ist hierbei der Ablageort für Package-Maintainer und kann mit Dateien in /run/systemd/system
oder /etc/systemd/system
überschrieben werden, wobei letzteres für den Administrator gedacht ist.
Die Datei selbst ist dann im Ini-Format, heißt es gibt verschiedene Sektion wie [Unit]
und Key-Value-Paare, die in der entsprechenden Sektion sein müssen. In der Sektion [Unit]
finden sich somit allgemeine Einstellungen die bei jedem Unit-Typen vorkommen können, in diesem Fall die Beschreibung und mit After
eine Liste von Units, die wenn vorhanden vor Icinga 2 gestartet sein sollen. Die Manpage systemd.unit
gibt hierüber detailliert Auskunft.
In der für den Unit-Typ spezifischen Sektion in unserem Fall [Service]
werden dann weitere Einstellungen vorgenommen. Hier wird Systemd gesagt wie das Startverhalten des Dienstes ist denn standardmäßig möchte Systemd Dienste im Vordergrund starten im Gegensatz zum Standardverhalten von init bei dem sich der Dienst in den Hintergrund forkt. Über EnvironmentFile
, zusätzliche Skripte in ExecStartPre
oder ExecStartPost
und den eigentlich Aufruf des zu startenden Dienst mittels ExecStart
wird das frühere init-Skript abgelöst. In Fall von Icinga2 wird im Pre-Skript sichergestellt, dass benötigte Verzeichnisse existieren und entsprechend berechtigt sind. Zusätzlich wird der Reload-Mechanismus durch ein Skript ersetzt, damit die Konfiguration validiert wird bevor gegebenenfalls der Dienst neugestartet wird. TimeoutStartSec
ist prinzipiell selbsterklärend denk ich, nimmt im Gegensatz zu den Sekunden im Namen aber auch andere Einheiten an wie hier 30m
für 30 Minuten. Hierbei bitte aufpassen, dass nur der Start-Timeout und nicht der allgemeine Timeout hochgesetzt wird, da letzterer auch für den Shutdown des Systems gilt. Mehr Details liefert die Manpage systemd.service
.
Die letzte Sektion gibt an in welches Target der Dienst “installiert” werden soll, wenn systemctl enable
ausgeführt wird.
Die Datei unter /usr/lib/systemd/system
sollte nicht angepasst werden, da diese beim nächsten Update überschrieben wird. Kopiert man es aber nach /etc/systemd/system
muss man die komplette Pflege übernehmen, da es das aus dem Paket gelieferte komplett ersetzt. Hierfür gibt es den Mechanismus der Drop-Ins. Diese müssen in ein Verzeichnis mit dem Namen der Unit abgelegt werden, in unserem Fall /etc/systemd/system/icinga2.service.d
und auf .conf
enden. Der Name ist hierbei prinzipiell egal, sollte aber sprechend gewählt werden und da sich Eigenschaften überschreiben bietet sich eine Priorität als Präfix an. Beim Inhalt nicht die Sektionsheader vergessen! Auch hierfür ein Beispiel aus Icinga 2:
# Icinga 2 sets some default values to extend OS defaults # # Please refer to our troubleshooting documentations for details # and reasons on these values. [Service] TasksMax=infinity # May also cause problems, uncomment if you have any #LimitNPROC=62883
Mit dem Kommando systemctl property
kann man genau diesen Mechanismus nutzen ohne sich um die Dateistruktur kümmern zu müssen, aber leider funktioniert dies nicht für alle Optionen. Kernel-Parameter, Posix-Limits und vieles mehr lassen sich hier einstellen, welche sich in systemd.exec
finden, und Einstellungen für die Kontrolle über Ressourcen, welche Systemd mittels Cgroups umsetzt, finden sich in systemd.resource-control
. Die Defaults hierfür finden sich übrigens in /etc/systemd/system.conf
und müssen nicht immer gleich heißen, beispielsweise DefaultTasksMax und TasksMax. Die eingebundenen Drop-Ins zeigt systemctl status
sehr schön an und die aktuellen Werte für alle Einstellungen eines Services inklusive Defaults liefert systemctl show
.
Und abschließend nicht vergessen Systemd die vorgenommenen Änderungen mit systemctl daemon-reload
auch mitzuteilen.
Ich hoffe diese kleine Erläuterung hilft dem ein oder anderen Unitfiles besser zu verstehen und er weiß nun wo er hin langen muss wenn Stellschrauben anzupassen sind.
0 Comments