|
Метка: новое перенаправление |
(не показана 41 промежуточная версия 2 участников) |
Строка 1: |
Строка 1: |
| {{span|font-size: 180%|Простая замена crontab'ов на таймеры systemd}}
| | #REDIRECT [[Таймеры systemd вместо crond]] |
| ==Предмет статьи==
| |
| Речь о периодических задачах, которые следует исполнять еже<…>но, без указания сложных конструкций из даты:времени/периодичности (сиречь, о том, чем занимаются скрипты из /etc/cron.<…>ly/, плюс не охваченные ими ежеминутные, ежеквартальные и ежесеместровые запуски).
| |
| ==Варианты==
| |
| В части руководств встречаются рекомендации пилить таймеры под каждый отдельный юнит, существуют и генераторы таймеров на основе crontab - проекты некоторых можно глянуть [https://github.com/systemd-cron здесь].
| |
| Но мне они показались несколько выморочными, излишне навороченными - ведь всё необходимое уже наличествует в systemd, и следует признать: находились таки примеры с таймерами/таргетами на отдельные периоды - часы/дни/недели и т.п.
| |
| | |
| Но посредством шаблонов можно сделать проще
| |
| ==Реализация==
| |
| ===Запилил пару шаблонов:===
| |
| | |
| <code># cat /lib/systemd/system/doit@.timer</code> (для периодических таймеров)
| |
| <source lang="ini">
| |
| [Unit]
| |
| Description = %i timer
| |
| | |
| [Timer] | |
| OnCalendar = %i
| |
| Persistent = true
| |
| Unit = doit@%i.target
| |
| | |
| [Install] | |
| WantedBy = timers.target
| |
| </source>
| |
| <code># cat /lib/systemd/system/doit@.target</code> (для их «целей»)
| |
| <source lang="ini">
| |
| [Unit]
| |
| Description = %i timer target
| |
| StopWhenUnneeded = yes
| |
| </source>
| |
| doit - мол, «делать это еже…»
| |
| <pre>
| |
| minutely …минутно,
| |
| hourly …часно,
| |
| daily …дневно,
| |
| weekly …недельно,
| |
| monhly …месячно,
| |
| quarter …квартально,
| |
| semi-annually …семестрово,
| |
| yearly …годно.
| |
| </pre>
| |
| Само собой, «doit» что в именах, что в шаблоне таймера и периодически запускаемых сервисах можно заменить на «do», «run», «cron», «timers» или что угодно иное.
| |
| | |
| ===Включил и запустил периодические таймеры:===
| |
| <source lang="bash">
| |
| for ACT in enable start; do
| |
| systemctl $ACT doit@{minute,hour,dai,week,month,quarter,semi-annual,year}ly.timer
| |
| done
| |
| </source>
| |
| ===Создал сервисы, требующие периодического исполнения, нужную периодичность указав через секцию [Install].===
| |
| Вот пример:
| |
| | |
| <code># cat /lib/systemd/system/logrotate.service</code>
| |
| <source lang="ini">
| |
| [Unit]
| |
| Description = Rotate system logs
| |
| | |
| [Service]
| |
| Nice = 19
| |
| Type = simple
| |
| IOSchedulingClass = 2
| |
| IOSchedulingPriority = 7
| |
| ExecStart = /usr/sbin/logrotate /etc/logrotate.conf
| |
| | |
| [Install]
| |
| WantedBy = doit@daily.target
| |
| </source>
| |
| | |
| ===И, наконец, включил их:===
| |
| <code># systemctl enable <список таких сервисов></code>
| |
| | |
| …напоследок проверив, что юниты нужных сервисов активированы:
| |
| | |
| <code># ls /etc/systemd/system/doit@{minute,dai,month}ly.target.wants</code>
| |
| <pre>
| |
| /etc/systemd/system/doit@daily.target.wants:
| |
| logrotate.service
| |
| | |
| /etc/systemd/system/doit@minutely.target.wants:
| |
| unbound-stats.service
| |
| | |
| /etc/systemd/system/doit@monthly.target.wants:
| |
| unbound-anchor.service
| |
| </pre>
| |
| ===Собственно, готово - работает.===
| |
| Вот:
| |
| | |
| <code># systemctl list-timers</code>
| |
| <pre>
| |
| Wed 2017-12-20 12:28:00 IRKT 22s left Wed 2017-12-20 12:27:00 IRKT 37s ago doit@minutely.timer doit@minutely.target
| |
| Wed 2017-12-20 13:00:00 IRKT 32min left Wed 2017-12-20 12:00:00 IRKT 27min ago doit@hourly.timer doit@hourly.target
| |
| Thu 2017-12-21 00:00:00 IRKT 11h left Wed 2017-12-20 00:00:18 IRKT 12h ago doit@daily.timer doit@daily.target
| |
| Thu 2017-12-21 11:12:16 IRKT 22h left Wed 2017-12-20 11:12:16 IRKT 1h 15min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
| |
| Mon 2017-12-25 00:00:00 IRKT 4 days left Mon 2017-12-18 00:00:00 IRKT 2 days ago doit@weekly.timer doit@weekly.target
| |
| Mon 2018-01-01 00:00:00 IRKT 1 weeks 4 days left Fri 2017-12-01 00:00:00 IRKT 2 weeks 5 days ago doit@monthly.timer doit@monthly.target
| |
| Mon 2018-01-01 00:00:00 IRKT 1 weeks 4 days left n/a n/a doit@quarterly.timer doit@quarterly.target
| |
| Mon 2018-01-01 00:00:00 IRKT 1 weeks 4 days left n/a n/a doit@semi-annually.timer doit@semi-annually.target
| |
| Mon 2018-01-01 00:00:00 IRKT 1 weeks 4 days left Tue 2017-10-24 18:17:11 IRKT 1 months 26 days ago doit@yearly.timer doit@yearly.target
| |
| | |
| 9 timers listed.
| |
| Pass --all to see loaded but inactive timers, too.
| |
| </pre>
| |
| | |
| Можно выключить крон:
| |
| | |
| <code># for ACT in stop disable; do systemctl $ACT crond; done</code>
| |
| | |
| И не беда, что реально работают меньше половины таймеров: один предустановленный и три добавленных, а остальные пять - пустышки. Лишние можно отключить либо рассматривать их как заготовки - вроде пустых каталогов среди /etc/cron.<…>ly/.
| |
| ==Примечание==
| |
| Само собой, для сложных конструкций в замену кронтабов из /etc/cron.d/ придётся создавать отдельные таймеры, которые, однако, справятся и там, где крон нужно подпирать костылём - вроде проверки программного RAID-массива:
| |
| | |
| <code>57 0 * * 0 root [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ] && /usr/share/mdadm/checkarray --cron --all --idle --quiet</code>
| |
| | |
| Данный пример его автор комментирует так: ''Запускать задачу следует по воскресеньям, но не позже 7-го числа - то есть, лишь в первое воскресенье каждого месяца, в каковой ситуации кронтаб беспомощен, так что приходится пользовать хак.''
| |
| | |
| И вот наипростейший пример таймера, который будет запускаться пусть не в первое, а в последнее воскресенье месяца, но без плясок с бубном из скриптов:
| |
| <source lang="ini">
| |
| [Unit]
| |
| Description = Last Monday of month timer
| |
| | |
| [Timer]
| |
| OnCalendar = Sun *~07/1
| |
| Persistent = true
| |
| | |
| [Install]
| |
| WantedBy = timers.target
| |
| </source>
| |
| [[Категория:Admin]]
| |
| {{Category navigation|title=Системному администратору|category=Admin|sortkey={{SUBPAGENAME}}}}
| |