systemd-timer, der Cron-Nachfolger
Systemd wird inzwischen von den meisten modernen Linux-Distributionen als Init-System genutzt, das für die Verwaltung aller Dienste zuständig ist. Leider werden die Möglichkeiten von systemd sehr unterschätzt, weshalb ich ein paar kleine Einblicke über die Möglichkeiten des modernen Init-Systems geben möchte. Wir starten mit der, meiner Meinung nach, nützlichsten Einsatzmöglichkeit: systemd-timer!
Timer anzeigen
Um die aktuell konfigurierten Timer anzuzeigen, kann man das kleine Tool systemctl list-timers nutzen.
root@web1: ~ # systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2017-01-23 00:00:00 CET 11h left Sun 2017-01-22 12:00:01 CET 14min ago certbot.timer certbot.service
Mon 2017-01-23 11:08:11 CET 22h left Sun 2017-01-22 11:08:11 CET 1h 6min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Wie man an der Ausgabe meines Webservers sehen kann, werden hier zwei Jobs ausgeführt: die Erneuerung meiner SSL-Zertifikate und die Entfernung nicht mehr benötigter Tempfiles durch systemd.
Timer-Unit
Um eigene Timer anzulegen genügt es, ein einfaches Text-File unter /etc/systemd/system/ zu erstellen. Der Dateiname kann frei gewählt werden, muss aber auf .timer enden. Eine einfache Timer-Unit sieht so aus:
[Unit]
Description=Run certbot twice daily
[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target
Die Optionen sind eigentlich relativ selbsterklärend, trotzdem möchte ich kurz auf den Timer-Abschnitt eingehen. Die Abschnitte Unit und Install sind identisch mit den Abschnitten der Service Units.
OnCalendar – durch die hier angegebene Option wird der Job alle 12 Stunden ausgeführt
RandomizedDelaySec – diese Option gibt an, dass systemd mit der Ausführung des Jobs zufällig bis zu 3600 Sekunden warten soll (sehr hilfreich, um Überlastungen bei z.B. Backups zu vermeiden)
Persistent – bewirkt, dass versäumte Jobs – z.B. weil der Rechner ausgeschaltet war – beim nächsten Start nachgeholt werden
Eine komplette Liste aller möglichen OnCalendar-Optionen inklusive Beispielen findet man in der systemd-Dokumentation.
Service-Unit
Jeder Timer-Unit muss eine entsprechende, gleichnamige .service-Datei beiliegen, die den auszuführenden Prozess beschreibt. Für den angelegten certbot-Timer sieht die .service-Datei so aus:
[Unit]
Description=Let's Encrypt renewal
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
Diese Datei ist, denke ich, selbsterklärend. Type gibt an, dass das Skript nur einmalig ausgeführt wird, ExecStart gibt das zu startende Skript inklusive Optionen an – in diesem Fall eben den certbot.
Timer aktivieren
Neu angelegte systemd-timer müssen, wie auch service-units erst durch systemctl enable dauerhaft aktiviert werden. Um Änderungen an bereits aktivierten Timern einzulesen, genügt es, den Timer mit systemctl reenable –now certbot.timer neu zu aktivieren.
Fazit
systemd-Timer sind nach kurzer Gewöhnung sehr einfach einzusetzen, auch wenn es etwas mehr Arbeit ist, als einen einfachen Cronjob anzulegen. Der größte Vorteil gegenüber Cron ist aber relativ eindeutig: man kann systemd-timer zeitlich viel genauer steuern, als es mit Cronjobs möglich ist.
Wichtig: systemd versendet die Ausgabe von gestarteten Timern nicht automatisch per E-Mail, wie es Cron tut. Um dies zu korrigieren, muss man die Mailfunktion bestenfalls direkt in das zu startende Skript einbauen oder eine Lösung wie die aus dem ArchWiki nutzen.