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.