Umstellung von Daemon-Diensten auf systemd: Unterschied zwischen den Versionen
Tim (Diskussion | Beiträge) K (Tim verschob die Seite Umstellung von Anwendungen auf systemd nach Umstellung von Daemon-Diensten auf systemd) |
K (→Rückblick auf Bearbeitung von Cronjobs: Erklärung Übersicht Cronjobs) |
||
(19 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 14: | Zeile 14: | ||
=== cronjob === | === cronjob === | ||
==== Rückblick auf Bearbeitung von Cronjobs ==== | |||
Mit dem Befehl <code>crontab -l</code> können die eigenen Cronjobs aufgelistet werden. | |||
Mit dem Befehl <code>crontab -e</code> bearbeiten wir unsere Hintergrundjobs. | |||
Wenn am Anfang einer Zeile das Rautezeichen # eingesetzt wird, dann ist die Zeile deaktiviert. | |||
Eine Übersicht über die Cronjobs der einzelnen Benutzer eines Webpaketes xyz00 lässt sich so ausgeben, wenn in der Shell des Paket-Benutzers xyz00 folgender Befehl ausgeführt wird: | |||
<syntaxhighlight lang="bash"> | |||
cd users/; for U in *; do echo "=== $USER-$U"; sudo -u $USER-$U crontab -l | grep -v "#"; done | |||
</syntaxhighlight> | |||
Auf der Seite [[Cron]] werden weitere Einzelheiten beschrieben. | |||
==== Umstellung auf systemd Timer ==== | |||
Hier ist eine schöne Übersicht mit Beispielen: https://documentation.suse.com/smart/systems-management/html/systemd-working-with-timers/index.html#systemd-timer-catchup | |||
==== Beispiel: Nextcloud Hintergrund Job ==== | |||
Hier haben wir ein Beispiel für einen Nextcloud Hintergrund Job, der alle 5 Minuten läuft, und in der crontab eingetragen ist: | |||
<syntaxhighlight lang="crontab"> | |||
*/5 * * * * /usr/bin/php $HOME/nextcloud/cron.php | |||
</syntaxhighlight> | |||
Wir deaktivieren diesen Cronjob, in dem wir ein # vor die Zeile setzen, wie oben beschrieben. | |||
Nun muss ggfs. das Verzeichnis für systemd angelegt werden: | |||
<syntaxhighlight lang="bash"> | |||
mkdir -p $HOME/.config/systemd/user | |||
</syntaxhighlight> | |||
Nun wird die Datei für den oneshot Dienst angelegt: | |||
<syntaxhighlight lang="bash"> | |||
nano $HOME/.config/systemd/user/nextcloud-job.service | |||
</syntaxhighlight> | |||
mit diesem Inhalt: | |||
<syntaxhighlight lang="ini"> | |||
[Unit] | |||
Description=Nextcloud Hintergrundjob | |||
[Service] | |||
Type=oneshot | |||
ExecStart=/usr/bin/php %h/nextcloud/cron.php | |||
</syntaxhighlight> | |||
{{Textkasten|gelb|Beachte|Statt $HOME muss %h benutzt werden!}} | |||
Nun wird die Datei für den Timer angelegt: | |||
<syntaxhighlight lang="bash"> | |||
nano $HOME/.config/systemd/user/nextcloud-job.timer | |||
</syntaxhighlight> | |||
mit diesem Inhalt: | |||
<syntaxhighlight lang="ini"> | |||
[Unit] | |||
Description=Timer für Nextcloud Hintergrundjob | |||
[Timer] | |||
OnCalendar=*:0/5 | |||
RandomizedDelaySec=30 | |||
[Install] | |||
WantedBy=timers.target | |||
</syntaxhighlight> | |||
Nun soll der Timer noch aktiviert und gestartet werden: | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user daemon-reload | |||
systemctl --user enable nextcloud-job.timer --now | |||
</syntaxhighlight> | |||
==== Beispiel: Logrotate aufrufen ==== | |||
Hier haben wir ein Beispiel für einen Logrotate Job, der einmal in der Nacht aufgerufen wird, und in der crontab eingetragen ist: | |||
<syntaxhighlight lang="crontab"> | |||
13 1 * * * /usr/sbin/logrotate -s $HOME/.logrotate.state $HOME/.logrotate | |||
</syntaxhighlight> | |||
Wir deaktivieren diesen Cronjob, in dem wir ein # vor die Zeile setzen, wie oben beschrieben. | |||
Nun muss ggfs. das Verzeichnis für systemd angelegt werden: | |||
<syntaxhighlight lang="bash"> | |||
mkdir -p .config/systemd/user | |||
</syntaxhighlight> | |||
Nun wird die Datei für den oneshot Dienst angelegt: | |||
<syntaxhighlight lang="bash"> | |||
nano $HOME/.config/systemd/user/logrotate-job.service | |||
</syntaxhighlight> | |||
mit diesem Inhalt: | |||
<syntaxhighlight lang="ini"> | |||
[Unit] | |||
Description=Logrotate Job | |||
[Service] | |||
Type=oneshot | |||
ExecStart=/usr/sbin/logrotate -s %h/.logrotate.state %h/.logrotate | |||
</syntaxhighlight> | |||
{{Textkasten|gelb|Beachte|Statt $HOME muss %h benutzt werden!}} | |||
Nun wird die Datei für den Timer angelegt: | |||
<syntaxhighlight lang="bash"> | |||
nano $HOME/.config/systemd/user/logrotate-job.timer | |||
</syntaxhighlight> | |||
mit diesem Inhalt: | |||
<syntaxhighlight lang="ini"> | |||
[Unit] | |||
Description=Timer für Logrotate Job | |||
[Timer] | |||
OnCalendar=01:13 | |||
RandomizedDelaySec=300 | |||
Persistent=true | |||
[Install] | |||
WantedBy=timers.target | |||
</syntaxhighlight> | |||
Nun soll der Timer noch aktiviert und gestartet werden: | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user daemon-reload | |||
systemctl --user enable logrotate-job.timer --now | |||
</syntaxhighlight> | |||
=== Monit === | |||
==== Beispiel: Redis ==== | |||
Hier haben wir eine Datei <code>.monitrc</code>, mit der ein Redis Dienst betrieben wird: | |||
<syntaxhighlight lang="monit"> | |||
set daemon 60 | |||
with start delay 120 | |||
set logfile /home/pacs/xyz00/nextcloud/var/monit.log | |||
set idfile /home/pacs/xyz00/nextcloud/var/monit.id | |||
set statefile /home/pacs/xyz00/nextcloud/var/monit.state | |||
set mailserver localhost | |||
set mail-format { from: webmaster@example.org } | |||
set alert webmaster@example.org | |||
set httpd port 12345 address xyz00.hostsharing.net | |||
allow monit:topsecret | |||
check process redis with pidfile /home/pacs/xyz00/nextcloud/redis/var/redis-server.pid | |||
start program "/usr/bin/redis-server /home/pacs/xyz00/nextcloud/redis/etc/redis.conf" | |||
stop program "/bin/bash -c '/bin/kill $( cat /home/pacs/xyz00/nextcloud/redis/var/redis-server.pid )'" | |||
</syntaxhighlight> | |||
Der Start von monit nach einem Reboot des Servers wird verhindert, indem die entsprechende Zeile gelöscht wird: | |||
<syntaxhighlight lang="bash"> | |||
crontab -e | |||
entferne diese Zeile: | |||
@reboot /usr/bin/monit -c $HOME/.monitrc | |||
</syntaxhighlight> | |||
Die Dienste werden gestoppt: | |||
<syntaxhighlight lang="bash"> | |||
killall -u $USER -KILL monit | |||
killall -u $USER -KILL redis-server | |||
</syntaxhighlight> | |||
Nun muss ggfs. das Verzeichnis für systemd angelegt werden: | |||
<syntaxhighlight lang="bash"> | |||
mkdir -p .config/systemd/user | |||
</syntaxhighlight> | |||
Nun wird die Datei für den Redis Dienst angelegt: | |||
<syntaxhighlight lang="bash"> | |||
nano $HOME/.config/systemd/user/redis.service | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="ini"> | |||
[Unit] | |||
Description=Redis Service | |||
After=network-online.target | |||
[Service] | |||
WorkingDirectory=%h/redis/var | |||
ExecStart=/usr/bin/redis-server %h/redis/etc/redis.conf | |||
Restart=always | |||
PrivateTmp=true | |||
NoNewPrivileges=true | |||
StandardOutput=append:%h/var/log/redis.log | |||
StandardError=inherit | |||
[Install] | |||
WantedBy=default.target | |||
</syntaxhighlight> | |||
Es muss noch die folgende Zeile aus <code>redis/etc/redis.conf</code> entfernt werden: | |||
<syntaxhighlight lang="conf"> | |||
daemonize yes | |||
</syntaxhighlight> | |||
Nun soll der Dienst aktiviert und gestartet werden: | |||
<syntaxhighlight lang="bash"> | |||
systemctl --user enable redis.service --now | |||
</syntaxhighlight> | |||
==== Beispiel: Apache ==== | |||
Es wurden in der Vergangenheit Start- und Stoppskripte empfohlen. Die Startskripte wurden dann um verschiedene Aktionen ergänzt. | |||
Da empfehlen wir, die sonstigen Aktionen in ein eigenes Skript auszulagern, das mit der Direktive <code>ExecStartPre=</code> gestartet wird. | |||
Dann kann der eigentliche Prozess mit <code>ExecStart=</code> gestartet werden, und wird dann auch entsprechend beendet. Dann ist kein Stopp-Skript erforderlich. | |||
Es kann aber auch mit <code>ExecStop</code> ein Stopp-Skript ausgeführt werden. | |||
=== supervisor === | === supervisor === | ||
Bei supervisor wird z.B. in der Datei <code>~/supervisor/etc/supervisord.conf</code> ein Redis Dienst konfiguriert: | |||
<syntaxhighlight lang="ini"> | |||
[program:redis] | |||
command=/usr/bin/redis-server /home/pacs/xyz00/test/loomio/redis/etc/redis.conf | |||
stderr_logfile = /home/pacs/xyz00/users/test/supervisor/log/redis-stderr.log | |||
stdout_logfile = /home/pacs/xyz00/users/test/supervisor/log/redis-stdout.log | |||
</syntaxhighlight> | |||
Das muss entsprechend durch einen systemd Dienst ersetzt werden, siehe der Abschnitt bei der Umstellung von monit auf systemd. | |||
== Ermittlung und Buchung des benötigten RAM Kontingent == | == Ermittlung und Buchung des benötigten RAM Kontingent == | ||
siehe [[Prozessmanagement_mit_systemd_im_Userspace#RAM_Kontingent_eines_Webspace|RAM Kontingent eines Webspace]] | |||
---- | ---- | ||
[[Kategorie:Systemd]] | [[Kategorie:Systemd]] |
Aktuelle Version vom 3. Dezember 2024, 08:57 Uhr
Anlass dieser Anleitung
Ab November 2024 unterstützt die Managed Plattform ein RAM Kontingent pro Managed Webspace. Mitglieder buchen für ihre Webspaces jeweils ein RAM Kontingent in Schritten von jeweils 128 Megabyte. Das unterstützt uns besser bei der verursachergerechten Verteilung der Hardwarekosten, als es vorher mit einer Pauschale pro Serverdienst der Fall war. Änderungen des RAM Kontingents für einen Webspace nimmt der Service unter service@hostsharing.net entgegen, wie es bei anderen Paketoptionen die Vorgehensweise ist.
Damit die RAM Kontingente funktionieren, müssen im Managed Webspace alle Anwendungen, die im Userspace laufen, auf systemd umgestellt werden. Das betrifft Anwendungen, die bisher über z.B. cronjob, supervisor oder monit gestartet wurden.
Siehe auch unsere Systemd im Userspace Dokumentation.
Praktische Umstellung
Für eine Übergangsphase steht jedem Managed Webspace genügend RAM zur Verfügung, um eigene Serverdienste zu starten. Nach der Umstellung aller Dienste auf systemd wird dann das tatsächlich benötigte RAM-Kontingent ermittelt und gebucht.
cronjob
Rückblick auf Bearbeitung von Cronjobs
Mit dem Befehl crontab -l
können die eigenen Cronjobs aufgelistet werden.
Mit dem Befehl crontab -e
bearbeiten wir unsere Hintergrundjobs.
Wenn am Anfang einer Zeile das Rautezeichen # eingesetzt wird, dann ist die Zeile deaktiviert.
Eine Übersicht über die Cronjobs der einzelnen Benutzer eines Webpaketes xyz00 lässt sich so ausgeben, wenn in der Shell des Paket-Benutzers xyz00 folgender Befehl ausgeführt wird:
cd users/; for U in *; do echo "=== $USER-$U"; sudo -u $USER-$U crontab -l | grep -v "#"; done
Auf der Seite Cron werden weitere Einzelheiten beschrieben.
Umstellung auf systemd Timer
Hier ist eine schöne Übersicht mit Beispielen: https://documentation.suse.com/smart/systems-management/html/systemd-working-with-timers/index.html#systemd-timer-catchup
Beispiel: Nextcloud Hintergrund Job
Hier haben wir ein Beispiel für einen Nextcloud Hintergrund Job, der alle 5 Minuten läuft, und in der crontab eingetragen ist:
*/5 * * * * /usr/bin/php $HOME/nextcloud/cron.php
Wir deaktivieren diesen Cronjob, in dem wir ein # vor die Zeile setzen, wie oben beschrieben.
Nun muss ggfs. das Verzeichnis für systemd angelegt werden:
mkdir -p $HOME/.config/systemd/user
Nun wird die Datei für den oneshot Dienst angelegt:
nano $HOME/.config/systemd/user/nextcloud-job.service
mit diesem Inhalt:
[Unit]
Description=Nextcloud Hintergrundjob
[Service]
Type=oneshot
ExecStart=/usr/bin/php %h/nextcloud/cron.php
Beachte
Statt $HOME muss %h benutzt werden!
Nun wird die Datei für den Timer angelegt:
nano $HOME/.config/systemd/user/nextcloud-job.timer
mit diesem Inhalt:
[Unit]
Description=Timer für Nextcloud Hintergrundjob
[Timer]
OnCalendar=*:0/5
RandomizedDelaySec=30
[Install]
WantedBy=timers.target
Nun soll der Timer noch aktiviert und gestartet werden:
systemctl --user daemon-reload
systemctl --user enable nextcloud-job.timer --now
Beispiel: Logrotate aufrufen
Hier haben wir ein Beispiel für einen Logrotate Job, der einmal in der Nacht aufgerufen wird, und in der crontab eingetragen ist:
13 1 * * * /usr/sbin/logrotate -s $HOME/.logrotate.state $HOME/.logrotate
Wir deaktivieren diesen Cronjob, in dem wir ein # vor die Zeile setzen, wie oben beschrieben.
Nun muss ggfs. das Verzeichnis für systemd angelegt werden:
mkdir -p .config/systemd/user
Nun wird die Datei für den oneshot Dienst angelegt:
nano $HOME/.config/systemd/user/logrotate-job.service
mit diesem Inhalt:
[Unit]
Description=Logrotate Job
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate -s %h/.logrotate.state %h/.logrotate
Beachte
Statt $HOME muss %h benutzt werden!
Nun wird die Datei für den Timer angelegt:
nano $HOME/.config/systemd/user/logrotate-job.timer
mit diesem Inhalt:
[Unit]
Description=Timer für Logrotate Job
[Timer]
OnCalendar=01:13
RandomizedDelaySec=300
Persistent=true
[Install]
WantedBy=timers.target
Nun soll der Timer noch aktiviert und gestartet werden:
systemctl --user daemon-reload
systemctl --user enable logrotate-job.timer --now
Monit
Beispiel: Redis
Hier haben wir eine Datei .monitrc
, mit der ein Redis Dienst betrieben wird:
set daemon 60
with start delay 120
set logfile /home/pacs/xyz00/nextcloud/var/monit.log
set idfile /home/pacs/xyz00/nextcloud/var/monit.id
set statefile /home/pacs/xyz00/nextcloud/var/monit.state
set mailserver localhost
set mail-format { from: webmaster@example.org }
set alert webmaster@example.org
set httpd port 12345 address xyz00.hostsharing.net
allow monit:topsecret
check process redis with pidfile /home/pacs/xyz00/nextcloud/redis/var/redis-server.pid
start program "/usr/bin/redis-server /home/pacs/xyz00/nextcloud/redis/etc/redis.conf"
stop program "/bin/bash -c '/bin/kill $( cat /home/pacs/xyz00/nextcloud/redis/var/redis-server.pid )'"
Der Start von monit nach einem Reboot des Servers wird verhindert, indem die entsprechende Zeile gelöscht wird:
crontab -e
entferne diese Zeile:
@reboot /usr/bin/monit -c $HOME/.monitrc
Die Dienste werden gestoppt:
killall -u $USER -KILL monit
killall -u $USER -KILL redis-server
Nun muss ggfs. das Verzeichnis für systemd angelegt werden:
mkdir -p .config/systemd/user
Nun wird die Datei für den Redis Dienst angelegt:
nano $HOME/.config/systemd/user/redis.service
[Unit]
Description=Redis Service
After=network-online.target
[Service]
WorkingDirectory=%h/redis/var
ExecStart=/usr/bin/redis-server %h/redis/etc/redis.conf
Restart=always
PrivateTmp=true
NoNewPrivileges=true
StandardOutput=append:%h/var/log/redis.log
StandardError=inherit
[Install]
WantedBy=default.target
Es muss noch die folgende Zeile aus redis/etc/redis.conf
entfernt werden:
daemonize yes
Nun soll der Dienst aktiviert und gestartet werden:
systemctl --user enable redis.service --now
Beispiel: Apache
Es wurden in der Vergangenheit Start- und Stoppskripte empfohlen. Die Startskripte wurden dann um verschiedene Aktionen ergänzt.
Da empfehlen wir, die sonstigen Aktionen in ein eigenes Skript auszulagern, das mit der Direktive ExecStartPre=
gestartet wird.
Dann kann der eigentliche Prozess mit ExecStart=
gestartet werden, und wird dann auch entsprechend beendet. Dann ist kein Stopp-Skript erforderlich.
Es kann aber auch mit ExecStop
ein Stopp-Skript ausgeführt werden.
supervisor
Bei supervisor wird z.B. in der Datei ~/supervisor/etc/supervisord.conf
ein Redis Dienst konfiguriert:
[program:redis]
command=/usr/bin/redis-server /home/pacs/xyz00/test/loomio/redis/etc/redis.conf
stderr_logfile = /home/pacs/xyz00/users/test/supervisor/log/redis-stderr.log
stdout_logfile = /home/pacs/xyz00/users/test/supervisor/log/redis-stdout.log
Das muss entsprechend durch einen systemd Dienst ersetzt werden, siehe der Abschnitt bei der Umstellung von monit auf systemd.
Ermittlung und Buchung des benötigten RAM Kontingent
siehe RAM Kontingent eines Webspace