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

12

У меня есть демон старой школы, которым я хочу управлять с помощью systemd. Когда его конфигурационный файл изменяется, его нужно убить и перезапустить. Другими словами, после редактирования файла конфигурации, systemctl reload MYSERVICEследует завершить процесс и перезапустить его.

Попытка 1: попробуйте значения по умолчанию. Это сообщает systemd, как запустить демон, а не как его перезагрузить.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

В результате startи restartработает, но reloadвыдает эту ошибку:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Попытка 2: Расскажите, как убить процесс. Это убивает процесс, но systemd не перезапускает его для меня.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...с последующим...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... убивает процесс, но он не перезапускается автоматически.

Попытка 3: используйте ExecReload, чтобы перезапустить процесс тоже. Это терпит неудачу по нескольким причинам:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... сообщение об ошибке я получаю ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Я ожидаю, что там будет ReloadType = kill_and_restart или что-то, но не такая удача.

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

TomOnTime
источник
Действительно ли это необходимо включить в перезагрузку , где это не совсем подходит? Разве вы не можете заставить демона вести себя разумно?
Майкл Хэмптон
Спасибо @MichaelHampton, но это не та ситуация, когда я могу переписать программу. Я ценю ваше полезное предложение. Тем не менее, я уверен, что это общий системный вариант использования, и канонический ответ может помочь многим людям.
TomOnTime
1
Я уверен, что ответ может кому-то помочь, поэтому я поднял вопрос. Я просто не уверен, что это общий случай использования. Пользуясь systemd в течение пяти лет или около того, почти с того дня, как он был выпущен в мир, я впервые могу вспомнить, что слышал о ком-либо, кто предпринимал попытки такого сценария. Возможно, я что-то неправильно понимаю из-за отсутствия деталей.
Майкл Хэмптон

Ответы:

16

Ответ: «Ты не»! Но у нас есть хорошие новости.

Философия systemd заключается в том, что перезагрузка является необязательной, и ее следует оставить неопределенной, если нет реальной функции перезагрузки. Я бы определил «истинную функциональность перезагрузки» как перезагрузку, которая не убивает и не перезапускает службу, или заставляет службу изменять свой PID. Другими словами, systemd хочет только отразить, какие функции существуют.

Вместо этого вы должны использовать, systemctl reload-or-restartкоторый выполнит перезагрузку, если она существует, и перезагрузку, если она не существует.

Со страницы руководства ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Поэтому: (1) оставьте ExecReload пустым, (2) используйте systemctl reload-or-restart MYSERVICEи (3) вы должны быть полностью настроены.

Если вы попытаетесь использовать ExecReload для определения способа уничтожения и перезапуска службы, у нее будет новый PID, и systemd будет сбит с толку.

TomOnTime
источник
3

Философия systemd заключается в том, что reloadона необязательна, и пользователь systemd должен знать для каждой службы, следует ли ей вызывать reloadили подделывать ее, вызывая restart.

Поэтому ответ на ваш вопрос: «Это не работает, и это не должно. Пожалуйста, решите это на следующем более высоком уровне».

Другими словами, systemd хочет, чтобы вы реализовали « перезагрузку » только в том случае, если базовый сервис поддерживает истинную функциональность перезагрузки ... т.е. перезагрузку, которая не уничтожает и не перезапускает службу, или не заставляет службу изменять свой PID. Другими словами, systemd хочет только отразить, какие функции существуют.

Вы можете спросить себя: а не проще ли было бы реализовать «фальшивую» перезагрузку, позволив ExecReloadубить и перезапустить службу? Тогда я мог бы использовать systemctl reload FOOвсе свои услуги, и мне не пришлось бы вспоминать, какие из них поддерживают, а какие нет?

Да, это было бы проще, но это не было бы способом systemd. Systemd хочет, чтобы вызывающий был тем, кто знает, reloadсуществует ли для службы. Systemd хочет быть общим интерфейсом с существующими функциями, не хочет отвечать за заполнение пробелов.

Например, puppet предполагает, что служба, управляемая systemd, не имеет reloadи по умолчанию убивает и перезапускает процесс . Если в типе Service [] добавлен способ указать, что перезагрузка существует и что ее следует использовать при уведомлении, необходимо узнать, какие службы имеют или не имеют встроенной перезагрузки. Chef и всем остальным системам также придется учиться тому же, потому что systemd хочет, чтобы это было решено на этом уровне. (MiniRant: для запуска процесса systemd представляется всезнающей, универсальной, настраивающей все пространство имен системой i-do-everything-at-my-layer. Поэтому я не могу сказать вам, почему это не так. расширить эту философию до перезагрузки. Может быть, один из авторов может быть здесь.)

TomOnTime
источник
1
Существует systemctl reload-or-restart, который перезагрузит сервис, если он его поддерживает, и перезапустит, если это не так. Понятия не имею, почему Puppet делает это предположение.
Майкл Хэмптон