Как настроить несколько служб systemd для использования одного таймера?

Я заметил некоторые существенные различия в подходах к документации systemd и документам с инструкциями о том, как настроить один или несколько сервисов для использования одного и того же таймера.

Насколько мне удалось собрать воедино (хотя я могу ошибаться), это описало бы, какие параметры WantedBy и Unit в файле Service и Timer должны быть установлены (без использования реальных примеров кода здесь - чтобы уменьшить количество сообщений). длина) для одной услуги и наоборот для конфигурации нескольких услуг с использованием одного таймера:

Таймер для одной услуги

My.Service1 'WantedBy' Param: N/A (1)
My.Timer 'Unit' Param: My.Service1 (2)
My.Timer 'WantedBy' Param: MultiUser/Basic.Target (3) 

(1) Служебному файлу не нужен раздел [Install] с параметром WantedBy.

(2) В разделе [Timer] таймера параметр Unit должен указывать на служебный файл My.Service1.

(3) Файл таймера имеет параметр WantedBy, который указывает на какую-то специальную системную цель, которая будет использоваться для ее запуска.

Таймер для нескольких услуг

My.Service1 'WantedBy' Param: Timer.Target (1)
My.Service2 'WantedBy' Param: Timer.Target (1)
My.Service3 'WantedBy' Param: Timer.Target (1)
Timer 'Unit' Param: Timer.Target (2)
Timer 'WantedBy' Param: ???

(1) Все службы должны подключаться к одной и той же определенной цели с использованием параметра WantedBy.

(2) Параметр [Таймер] должен также указывать на цель.

Для примера последней конфигурации см. Это с практическими рекомендациями. Я буду считать это как Пример 1. Однако я нашел другие примеры с практическими рекомендациями, которые отклоняются от этого (см. Ниже).

Пример 2 и Пример 3 говорят, что он должен быть настроен так:

My.Service1 WantedBy: Timer.Target
My.Service2 WantedBy: Timer.Target
My.Service3 WantedBy: Timer.Target
Timer 'Unit' Param: My.Service1 (1)
Timer 'WantedBy' Param: MultiUser/Basic.Target

(1) Это должно быть упущением в документации, потому что если вы оставите устройство, указывающее только на одну из ваших многочисленных служб, другие службы не смогут использовать таймер. Возможно, это произошло из-за подхода "см. Выше", который использовался для возврата читателя к конфигурации единого сервиса без фактического упоминания (что важно) того, что необходимо изменить.

Затем в примере 4 его конфигурация выглядит так, как будто он действительно будет работать, но он связан с подключением служб к цели другим способом, создавая файлы служб непосредственно в подкаталоге /etc/systemd/system/Timer.Target.wants/ и исключает любые параметры WantedBy в служебных файлах. Таким образом:

My.Service1 'WantedBy' Param: N/A
My.Service2 'WantedBy' Param: N/A
My.Service3 'WantedBy' Param: N/A
Timer 'Unit' Param: Timer.Target
Timer 'WantedBy' Param: MultiUser/Basic.Target

Гибридный подход между примерами 1 и 4, который я видел, состоит в том, чтобы создать служебные файлы в каталоге / etc / systemd / system / (расположение по умолчанию) и создать символическую ссылку на эти служебные файлы в / etc / systemd /system/Timer.Target.wants и исключить параметр WantedBy в файле службы (который функционально эквивалентен примеру 4), в то время как другая конфигурация использует метод символьной ссылки, но дополнительно включает параметр WantedBy в файл службы (который кажется лишнее и ненужное).

Мой вопрос заключается в следующем: хотя для примера 4 и гибридных подходов: зачем вообще нужно помещать что-либо в каталог *.wants, если объявление параметра WantedBy должно указывать systemd сделать это для вас (как указано в объяснении этот параметр на этой странице)?

Может ли кто-нибудь пролить свет на лучший способ настройки нескольких служб с использованием одного и того же таймера в условиях запутанного множества подходов к этому?

2 ответа

Если вы хотите активировать несколько сервисов с одним таймером, вставьте цель между:

Блок таймера, назовем его foo.timer:

[Unit]
Description=My timer that runs saturdays, 9am and triggers foo.target

[Timer]
OnCalendar=Sat 9:00
Unit=foo.target

[Install]
WantedBy=timers.target

Целевой модуль, назовем его foo.target:

[Unit]
Description= My target unit, that groups my two services xxx.service and yyy.service
Wants=xxx.service yyy.service
After=xxx.service yyy.service

[Install]
Also=foo.timer

И затем две службы xxx.service и yyy.service:

[Unit]
Description=My service XXX

[Service]
ExecStart=/bin/echo I am XXX

[Install]
Also=foo.timer
[Unit]
Descritpion=My service YYY

[Service]
ExecStart=/bin/echo I am YYYY

[Install]
Also=foo.timer

Скопируйте эти четыре файла модуля (foo.timer, foo.target, xxx.service, yyy.service) в /etc/systemd/systemd/. Затем включите и запустите таймер, выполнив "systemctl enable --now foo.timer". Это подключит foo.timer к timers.target, которая является общей целью, которая должна включать все таймеры, определенные в системе. Обратите внимание, что вы могли бы также сделать "systemctl enable foo.target" btw, а также "systemctl enable zzz.service", так как строки Always = в этих единицах распространяют запросы включения в foo.timer.

Системный таймер всегда активирует один блок.

Если вы хотите активировать два устройства по одному расписанию, я рекомендую создать два файла таймера для ясности, которые содержат одно и то же расписание.

В противном случае вы можете создать файл "service unit", который запускает две нужные вам службы.

Я не думаю, что "WantedBy=" является особенно полезной концепцией для единиц таймера.

Другие вопросы по тегам