Таймеры SystemD

2 мин

Сегодня решил написать заметку по таймерам в SystemD, этакой альтернативе нашему все - cron’у. Погнали!

В качестве иллюстрации, я буду использовать свой небольшой проект, который прячет сертификаты Let’s Encrypt в Hashicorp Vault - Let’s Hide!. Это Bash скрипт, который запускается раз в сутки, проверяет дату изменения сертификата Let’s Encrypt и если она, дата, меньше суток, то обновляет сертификаты в хранилище.

Вот мы и настроим запуск нашего скрипта раз в сутки через SystemD.

Сначала нужно создать юнит-файл нашего демона.

tee /etc/systemd/system/letshide.service <<EOF
[Unit]
Description=Let's Hide!

[Service]
Type=oneshot
EnvironmentFile=/etc/default/letshide
ExecStart=/usr/local/bin/letshide
EOF

Теперь нужно создать конфигурацию таймера. Имя сервис-файла должно совпадать с таймером, т.е. если у нас letshide.service, то будет letshide.timer.

tee /etc/systemd/system/letshide.timer <<EOF
[Unit]
Description=Run letshide daily

[Timer]
OnCalendar=*-*-* 00:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

Вот этим OnCalendar= мы и задаем наш таймер “реального времени” (Realtime timer). Формат значения:

DayOfWeek Year-Month-Day Hour:Minute:Second

Можно использовать перечисление и диапазоны, например следующая задача будет запускаться с первого по третье число каждого месяца, но только в воскресенье и пятницу:

OnCalendar=Sun,Fri *-*-01..03 12:00:00

Так же вы можете использовать временную зону в конце строки:

OnCalendar=*-*-* 00:00:00 Europe/Madrid
Совет
Зоны всегда можно подсмотреть через `timedatectl list-timezones`

Можно использовать привычные многим daily, weekly. Только учитывайте, что такие таймеры будут запускать одновременно и здесь вам может помочь директива RandomizedDelaySec в этом же разделе [Timer].

Совет
Проверить формат вы можете с помощью утилиты `systemd-analyze`, 
например `systemd-analyze calendar weekly` 
или `systemd-analyze calendar "Sun,Fri *-*-01..03 12:00:00"`,
а ключ `--iterations=N` позволит вывести несколько циклов

Так же упомяну, что существуют “монотонные” таймеры (Monotonic timers). Эти таймеры, вместо OnCalendar, используют директиву вида OnTypeSec=, например OnBootSec или OnUnitActiveSec. Следующая задача выполнится через 15 минут после загрузки, а затем будет повторятся каждую неделю:

OnBootSec=15min
OnUnitActiveSec=1w

После того, как вы создали таймер, его нужно включить и запустить, как любой демон, только обязательно указать .timer:

systemctl daemon-reload
systemctl enable letshide.timer
systemctl start letshide.timer
Совет
Отобразить все таймеры можно с помощью команды `systemctl list-timers`

А на сегодня все, до новых встреч :)