Systemd im Userspace: Unterschied zwischen den Versionen
(einfache Service-Unit) |
Tim (Diskussion | Beiträge) |
||
(41 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
'' | == Über systemd == | ||
''systemd'' ist seit einigen Jahren das Init-System aller gängigen Linux-Distributionen. Der ''init''-Prozess ist im laufenden System der Prozess mit der Nummer "1", der alle anderen Prozesse als Kind-Prozesse verwaltet. | |||
Auch ein normaler Account ohne besondere Privilegien kann | Auch ein normaler Account ohne besondere Privilegien kann systemd nutzen, um Prozesse im Userspace zu starten und zu kontrollieren. Auf der Hostsharing Managed Plattform hat jeder Account mit einer gültigen Login-Shell die Möglichkeit Dienste unter Kontrolle von systemd zu starten. In einem Webspace im Shared Hosting ist es zwingend systemd als Prozessmonitor für eigene Serverdienste zu nutzen; auf einem Managed Server ist es die empfohlene Vorgehensweise ("Best practice"). | ||
== | == Eigene Serverdienste mit systemd == | ||
In diesem Wiki finden sich viele Beispiele für systemd-Units zur Kontrolle eines Serverdienstes. An dieser Stelle folgen Erläuterungen für die wichtigsten Einstellungen. | |||
In diesem Wiki | |||
Voraussetzung: In ''HSAdmin'' wird ein Service-User zur Rechtetrennung dieses Dienstes von anderen Anwendungen angelegt. In diesem Artikel soll der Beispiel-User ''xyz00-service'' im Webspace ''xyz00'' sein. Dieser User bekommt bei der Einrichtung eine gültige Shell zugewiesen, so dass man sich per ''ssh'' oder vom Paketadmin mit einem Befehl ''sudo -i -u xyz00-service'' anmelden kann. Die Umgebungsvariable ''XDG_RUNTIME_DIR'' sollte im Environment des Users gesetzt sein, wenn man erfolgreich angemeldet ist. Das testet man mit | Voraussetzung: In ''HSAdmin'' wird ein Service-User zur Rechtetrennung dieses Dienstes von anderen Anwendungen angelegt. In diesem Artikel soll der Beispiel-User ''xyz00-service'' im Webspace ''xyz00'' sein. Dieser User bekommt bei der Einrichtung eine gültige Shell zugewiesen, so dass man sich per ''ssh'' oder vom Paketadmin mit einem Befehl ''sudo -i -u xyz00-service'' anmelden kann. Die Umgebungsvariable ''XDG_RUNTIME_DIR'' sollte im Environment des Users gesetzt sein, wenn man erfolgreich angemeldet ist. Das testet man mit | ||
Zeile 43: | Zeile 24: | ||
Dabei wird statt ''112345'' eine andere Zahl erscheinen. Diese Zahl ist die numerische User-Id des Users ''xyz00-service'' im System. | Dabei wird statt ''112345'' eine andere Zahl erscheinen. Diese Zahl ist die numerische User-Id des Users ''xyz00-service'' im System. | ||
Die | === systemd Unit === | ||
Die systemd-Units für einen User werden im Verzeichnis ''$HOME/.config/systemd/user/'' verwaltet. Dieser Pfad ist fest vorgegeben. Für einen neuen User legt man also zuerst dieses Verzeichnis an: | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Zeile 49: | Zeile 32: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
In diesem Verzeichnis wird für jeden Service eine Datei mit der Endung ''.service'' angelegt. Ich verwende hier | In diesem Verzeichnis wird für jeden Service eine Datei mit der Endung ''.service'' angelegt. Ich verwende hier eine Beispielkonfiguration für eine GotoSocial-Instanz. GotoSocial ist ein einfaches Binärprogramm, das in der Programmiersprache ''Go'' programmiert ist. | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="ini" line> | ||
[Unit] | [Unit] | ||
Description=GotoSocial Service | Description=GotoSocial Service | ||
#After=my-redis.service | |||
[Service] | [Service] | ||
Zeile 64: | Zeile 48: | ||
Restart=always | Restart=always | ||
PrivateTmp=true | PrivateTmp=true | ||
[Install] | [Install] | ||
WantedBy=default.target | WantedBy=default.target | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Die meisten Eigenschaften sind selbsterklärend. Folgende Eigenschaften sind einstellbar: | |||
; After: Hier kann eingestellt werden, welcher Dienst vorher starten muss, bevor dieser Dienst gestartet wird. Wenn GotoSocial eine Redis Instanz benötigt, könnte das entsprechend eingestellt werden. | |||
; Type=simple : ''simple'' ist die Voreinstellung und kann weggelassen werden. Evtl. braucht man auch ''forking'', wenn ein Dienst als Daemon im Hintergrund startet. Wenn man die Wahl hat, sollte man den Dienst immer im Vordergrund starten und nicht forken. | |||
; WorkingDirectory : ist das Verzeichnis, in dem der Dienst gestartet wird. %h ist in dieser Datei eine Abkürzung für das Home-Verzeichnis des Users. | |||
; Environment : Hier wird die Variable ''PATH'' definiert. Man kann mehrere Einträge des Namens ''Environment'' eintragen und bei Bedarf eine beliebige Anzahl von Environment-Variablen definieren. | |||
; ExecStart : Das Programm, das als Dienst ausgeführt wird. Man kann eine komplette Kommandozeile angeben. | |||
; StandardOutput : Eine Log-Datei in die die Standardausgabe des laufenden Dienstes geschrieben wird. | |||
; StandardError : Entsprechend zu ''StandardOutput''. Mit ''inherit'' wird der die Datei von ''StandardOutput'' geerbt. | |||
; Restart=always : Der Dienst soll grundsätzlich neu gestartet werden, wenn der Prozess unerwartet beendet wird. | |||
; PrivateTmp=true : ''/tmp'' und ''/var/tmp'' werden temporär im Namespace gemountet, so dass sie nicht mit anderen Prozessen geteilt werden. | |||
; WantedBy : sollte im Usermodus von systemd meistens ''default.target'' sein. Andere Targets sind z.B. ''base.target'' oder ''timers.target''. Für eine komplette Liste: <code>systemctl list-units --user --type=target</code> | |||
==== RAM- und CPU-Limits ==== | |||
Auf Wunsch kann man die RAM- und CPU-Ressourcen für den Dienst begrenzen. Dazu trägt man weitere Eigenschaften im Abschnitt ''Service'' ein: | |||
<syntaxhighlight lang="ini" line> | |||
[Service] | |||
... | |||
MemoryAccounting=true | |||
CPUAccounting=true | |||
MemoryHigh=512M | |||
MemoryMax=768M | |||
CPUQuota=50% | |||
</syntaxhighlight> | |||
; MemoryHigh : Weiches RAM-Limit, das ggf. überschritten werden kann, wenn es unvermeidlich ist. | |||
; MemoryMax : Hartes, absolutes RAM-Limit. | |||
; CPUQuota : Maximale Belegung eines CPU-Threads in Prozent. Werte über 100% sind sinnvoll, wenn mehr als ein CPU-Thread verfügbar ist. | |||
==== Ausführliche Dokumentation der Direktiven ==== | |||
Eine ausführliche Dokumentation der Direktiven findet sich hier: | |||
https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html | |||
=== systemd Unit starten und stoppen === | |||
Nachdem die systemd-Unit definiert ist, soll der Dienst gestartet werden. | |||
Für die Verwaltung des Dienstes stehen die folgenden Kommandos zur Verfügung: | |||
==== Reload ==== | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user daemon-reload | |||
</syntaxhighlight> | |||
Die Konfigurationsdateien im Verzeichnis ''$HOME/.config/systemd/user/'' werden neu eingelesen. Dieses Kommando ist nach jeder Änderung einer ''.service''-Datei nötig. | |||
==== Start und Stopp ==== | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user start gotosocial.service | |||
</syntaxhighlight> | |||
bzw. | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user stop gotosocial.service | |||
</syntaxhighlight> | |||
sind die Kommandos zum Starten und Beenden des Dienstes. | |||
==== Enable und Disable ==== | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user enable gotosocial.service | |||
</syntaxhighlight> | |||
bzw. | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user disable gotosocial.service | |||
</syntaxhighlight> | |||
sind die Kommandos, die den Dienst für einen Reboot des Servers aktivieren bzw. deaktivieren. | |||
==== Status ==== | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user status | |||
</syntaxhighlight> | |||
oder | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user status gotosocial.service | |||
</syntaxhighlight> | |||
zeigen den Status aller Dienste des Users bzw. eines bestimmten Dienstes an. | |||
== Zeitgesteuerte Ausführung mit systemd == | |||
Bisher wurden meistens cronjobs eingesetzt, um wiederkehrende Aufgaben zu erledigen. | |||
Auch Cronjobs können durch systemd ersetzt werden. Ergänzend zu einem »service-file« wird eine weitere Unit, nämlich ein »timer-file« mit der Endung ».timer« angelegt und aktiviert. | |||
=== Einrichten des »service-files« === | |||
<syntaxhighlight lang=bash> | |||
$ cat $HOME/.config/systemd/user/my-cleanup.service | |||
[Unit] | |||
Description=My Cleanup Service | |||
[Service] | |||
Type=oneshot | |||
ExecStart=%h/bin/cleanup-script | |||
</syntaxhighlight> | |||
=== Testen === | |||
<syntaxhighlight lang=bash> | |||
$ systemctl --user start my-cleanup.service | |||
</syntaxhighlight> | |||
=== Einrichten des »timer-files« === | |||
<syntaxhighlight lang=bash> | |||
$ cat $HOME/.config/systemd/user/my-cleanup.timer | |||
[Unit] | |||
Description=Daily My Cleanup Timer | |||
[Timer] | |||
OnCalendar=daily | |||
[Install] | |||
WantedBy=timers.target | |||
</syntaxhighlight> | |||
Eine ausführliche Dokumentation der Direktiven findet sich hier: | |||
https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html | |||
=== Aktivieren der zeitgesteuerten Ausführung === | |||
<syntaxhighlight lang=bash> | |||
$ systemctl --user enable my-cleanup.timer | |||
</syntaxhighlight> | |||
== RAM Kontingent eines Webspace == | |||
Den aktuell belegten RAM eines Webspace ''xyz00'' kann man sich mit dem Befehl | |||
<syntaxhighlight lang="bash"> | |||
systemctl status pacs-xyz00.slice | |||
</syntaxhighlight> | |||
ansehen. | |||
Etwa in der fünften Zeile der Ausgabe findet man eine Angabe der Form: | |||
<syntaxhighlight lang="bash"> | |||
Memory: 58.4M (max: 14.8G available: 14.8G) | |||
</syntaxhighlight> | |||
Hier sind aktuell 58,4 Megabyte RAM genutzt, es sind 14,8 Gigabyte RAM für den Webspace verfügbar. Der verfügbare RAM ist das gebuchte Kontingent. Das gebuchte Kontigent wird im Shared Hosting deutlich kleiner sein. | |||
Das RAM Kontingent wird in Schritten von jeweils 128 Ḿegabyte gebucht. Änderungen des RAM Kontingents für einen Webspace nimmt der Service unter [mailto:service@hostsharing.net service@hostsharing.net] entgegen, wie es bei anderen Paketoptionen die Vorgehensweise ist. | |||
= weiterführende Links = | |||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html | |||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html | |||
---- | |||
[[Kategorie:systemd]] | |||
[[Kategorie:Eigene Daemons]] |
Aktuelle Version vom 21. November 2024, 08:34 Uhr
Über systemd
systemd ist seit einigen Jahren das Init-System aller gängigen Linux-Distributionen. Der init-Prozess ist im laufenden System der Prozess mit der Nummer "1", der alle anderen Prozesse als Kind-Prozesse verwaltet.
Auch ein normaler Account ohne besondere Privilegien kann systemd nutzen, um Prozesse im Userspace zu starten und zu kontrollieren. Auf der Hostsharing Managed Plattform hat jeder Account mit einer gültigen Login-Shell die Möglichkeit Dienste unter Kontrolle von systemd zu starten. In einem Webspace im Shared Hosting ist es zwingend systemd als Prozessmonitor für eigene Serverdienste zu nutzen; auf einem Managed Server ist es die empfohlene Vorgehensweise ("Best practice").
Eigene Serverdienste mit systemd
In diesem Wiki finden sich viele Beispiele für systemd-Units zur Kontrolle eines Serverdienstes. An dieser Stelle folgen Erläuterungen für die wichtigsten Einstellungen.
Voraussetzung: In HSAdmin wird ein Service-User zur Rechtetrennung dieses Dienstes von anderen Anwendungen angelegt. In diesem Artikel soll der Beispiel-User xyz00-service im Webspace xyz00 sein. Dieser User bekommt bei der Einrichtung eine gültige Shell zugewiesen, so dass man sich per ssh oder vom Paketadmin mit einem Befehl sudo -i -u xyz00-service anmelden kann. Die Umgebungsvariable XDG_RUNTIME_DIR sollte im Environment des Users gesetzt sein, wenn man erfolgreich angemeldet ist. Das testet man mit
echo $XDG_RUNTIME_DIR
Die Ausgabe sollte sein:
xyz00-service@h01:~$ echo $XDG_RUNTIME_DIR
/run/user/112345
xyz00-service@h01:~$
Dabei wird statt 112345 eine andere Zahl erscheinen. Diese Zahl ist die numerische User-Id des Users xyz00-service im System.
systemd Unit
Die systemd-Units für einen User werden im Verzeichnis $HOME/.config/systemd/user/ verwaltet. Dieser Pfad ist fest vorgegeben. Für einen neuen User legt man also zuerst dieses Verzeichnis an:
mkdir -p $HOME/.config/systemd/user
In diesem Verzeichnis wird für jeden Service eine Datei mit der Endung .service angelegt. Ich verwende hier eine Beispielkonfiguration für eine GotoSocial-Instanz. GotoSocial ist ein einfaches Binärprogramm, das in der Programmiersprache Go programmiert ist.
[Unit]
Description=GotoSocial Service
#After=my-redis.service
[Service]
Type=simple
WorkingDirectory=%h/gotosocial
Environment="PATH=/usr/local/bin:/usr/bin:/bin"
ExecStart=%h/gotosocial/gotosocial --config-path %h/gotosocial/config.yaml server start
StandardOutput=file:%h/var/gotosocial.log
StandardError=inherit
Restart=always
PrivateTmp=true
[Install]
WantedBy=default.target
Die meisten Eigenschaften sind selbsterklärend. Folgende Eigenschaften sind einstellbar:
- After
- Hier kann eingestellt werden, welcher Dienst vorher starten muss, bevor dieser Dienst gestartet wird. Wenn GotoSocial eine Redis Instanz benötigt, könnte das entsprechend eingestellt werden.
- Type=simple
- simple ist die Voreinstellung und kann weggelassen werden. Evtl. braucht man auch forking, wenn ein Dienst als Daemon im Hintergrund startet. Wenn man die Wahl hat, sollte man den Dienst immer im Vordergrund starten und nicht forken.
- WorkingDirectory
- ist das Verzeichnis, in dem der Dienst gestartet wird. %h ist in dieser Datei eine Abkürzung für das Home-Verzeichnis des Users.
- Environment
- Hier wird die Variable PATH definiert. Man kann mehrere Einträge des Namens Environment eintragen und bei Bedarf eine beliebige Anzahl von Environment-Variablen definieren.
- ExecStart
- Das Programm, das als Dienst ausgeführt wird. Man kann eine komplette Kommandozeile angeben.
- StandardOutput
- Eine Log-Datei in die die Standardausgabe des laufenden Dienstes geschrieben wird.
- StandardError
- Entsprechend zu StandardOutput. Mit inherit wird der die Datei von StandardOutput geerbt.
- Restart=always
- Der Dienst soll grundsätzlich neu gestartet werden, wenn der Prozess unerwartet beendet wird.
- PrivateTmp=true
- /tmp und /var/tmp werden temporär im Namespace gemountet, so dass sie nicht mit anderen Prozessen geteilt werden.
- WantedBy
- sollte im Usermodus von systemd meistens default.target sein. Andere Targets sind z.B. base.target oder timers.target. Für eine komplette Liste:
systemctl list-units --user --type=target
RAM- und CPU-Limits
Auf Wunsch kann man die RAM- und CPU-Ressourcen für den Dienst begrenzen. Dazu trägt man weitere Eigenschaften im Abschnitt Service ein:
[Service]
...
MemoryAccounting=true
CPUAccounting=true
MemoryHigh=512M
MemoryMax=768M
CPUQuota=50%
- MemoryHigh
- Weiches RAM-Limit, das ggf. überschritten werden kann, wenn es unvermeidlich ist.
- MemoryMax
- Hartes, absolutes RAM-Limit.
- CPUQuota
- Maximale Belegung eines CPU-Threads in Prozent. Werte über 100% sind sinnvoll, wenn mehr als ein CPU-Thread verfügbar ist.
Ausführliche Dokumentation der Direktiven
Eine ausführliche Dokumentation der Direktiven findet sich hier:
https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html
systemd Unit starten und stoppen
Nachdem die systemd-Unit definiert ist, soll der Dienst gestartet werden. Für die Verwaltung des Dienstes stehen die folgenden Kommandos zur Verfügung:
Reload
systemctl --user daemon-reload
Die Konfigurationsdateien im Verzeichnis $HOME/.config/systemd/user/ werden neu eingelesen. Dieses Kommando ist nach jeder Änderung einer .service-Datei nötig.
Start und Stopp
systemctl --user start gotosocial.service
bzw.
systemctl --user stop gotosocial.service
sind die Kommandos zum Starten und Beenden des Dienstes.
Enable und Disable
systemctl --user enable gotosocial.service
bzw.
systemctl --user disable gotosocial.service
sind die Kommandos, die den Dienst für einen Reboot des Servers aktivieren bzw. deaktivieren.
Status
systemctl --user status
oder
systemctl --user status gotosocial.service
zeigen den Status aller Dienste des Users bzw. eines bestimmten Dienstes an.
Zeitgesteuerte Ausführung mit systemd
Bisher wurden meistens cronjobs eingesetzt, um wiederkehrende Aufgaben zu erledigen.
Auch Cronjobs können durch systemd ersetzt werden. Ergänzend zu einem »service-file« wird eine weitere Unit, nämlich ein »timer-file« mit der Endung ».timer« angelegt und aktiviert.
Einrichten des »service-files«
$ cat $HOME/.config/systemd/user/my-cleanup.service
[Unit]
Description=My Cleanup Service
[Service]
Type=oneshot
ExecStart=%h/bin/cleanup-script
Testen
$ systemctl --user start my-cleanup.service
Einrichten des »timer-files«
$ cat $HOME/.config/systemd/user/my-cleanup.timer
[Unit]
Description=Daily My Cleanup Timer
[Timer]
OnCalendar=daily
[Install]
WantedBy=timers.target
Eine ausführliche Dokumentation der Direktiven findet sich hier:
https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html
Aktivieren der zeitgesteuerten Ausführung
$ systemctl --user enable my-cleanup.timer
RAM Kontingent eines Webspace
Den aktuell belegten RAM eines Webspace xyz00 kann man sich mit dem Befehl
systemctl status pacs-xyz00.slice
ansehen.
Etwa in der fünften Zeile der Ausgabe findet man eine Angabe der Form:
Memory: 58.4M (max: 14.8G available: 14.8G)
Hier sind aktuell 58,4 Megabyte RAM genutzt, es sind 14,8 Gigabyte RAM für den Webspace verfügbar. Der verfügbare RAM ist das gebuchte Kontingent. Das gebuchte Kontigent wird im Shared Hosting deutlich kleiner sein.
Das RAM Kontingent wird in Schritten von jeweils 128 Ḿegabyte gebucht. Änderungen des RAM Kontingents für einen Webspace nimmt der Service unter service@hostsharing.net entgegen, wie es bei anderen Paketoptionen die Vorgehensweise ist.
weiterführende Links
- https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html
- https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html