Jak skonfigurować systemd, aby zabijał i restartował demona przy przeładowaniu?

12

Mam demona oldschoolowego, który chcę kontrolować za pomocą systemd. Kiedy zmienia się jego plik konfiguracyjny, należy go zabić i uruchomić ponownie. Innymi słowy, po edycji pliku konfiguracyjnego systemctl reload MYSERVICEnależy zakończyć proces i uruchomić go ponownie.

Próba 1: Wypróbuj ustawienia domyślne. Mówi to systemd jak uruchomić demona, ale nie jak go ponownie załadować.

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

W rezultacie starti restartdziała, ale reloaddaje ten błąd:

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

Próba 2: Powiedz, jak zabić proces. To zabija proces, ale systemd nie uruchamia go ponownie dla mnie.

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

...śledzony przez...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... zabija proces, ale nie jest restartowany automatycznie.

Próba 3: Użyj ExecReload, aby zrestartować proces. Nie udaje się to z kilku powodów:

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

... pojawia się komunikat o błędzie ...:

# 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.

Spodziewałbym się, że będzie ReloadType = kill_and_restart lub coś takiego, ale bez takiego szczęścia.

Jak powiedzieć systemd, aby zabił i zrestartował demona podczas przeładowywania?

TomOnTime
źródło
Czy to naprawdę trzeba przeładować , aby nie do końca pasowało? Czy nie możesz sprawić, by demon zachowywał się rozsądnie?
Michael Hampton
Dzięki @MichaelHampton, ale to nie jest sytuacja, w której mogę przepisać program. Doceniam twoją pomocną sugestię. To powiedziawszy, jestem pewien, że jest to częsty przypadek użycia systemu, a kanoniczna odpowiedź może pomóc wielu ludziom.
TomOnTime,
1
Jestem pewien, że odpowiedź może komuś pomóc, więc głosowałem za tym pytaniem. Po prostu nie jestem pewien, czy jest to częsty przypadek użycia. Używając systemd od około pięciu lat, prawie od dnia, w którym został on wypuszczony na świat, po raz pierwszy przypominam sobie, że ktoś próbował tego rodzaju scenariusz. Możliwe, że coś źle zrozumiałem z powodu brakujących szczegółów.
Michael Hampton

Odpowiedzi:

17

Odpowiedź brzmi „nie”! Ale mamy dobre wieści.

Filozofią systemd jest to, że przeładowanie jest opcjonalne i powinno pozostać niezdefiniowane, jeśli nie ma prawdziwej funkcji przeładowania. Zdefiniowałbym „prawdziwą funkcjonalność przeładowania” jako przeładowanie, które nie zabija i nie uruchamia ponownie usługi lub nie zmienia usługi PID. Innymi słowy, systemd chce tylko odzwierciedlić istniejące funkcje.

Zamiast tego powinieneś użyć, systemctl reload-or-restartktóry przeładuje, jeśli istnieje, i uruchom ponownie, jeśli nie istnieje.

Ze strony podręcznika ...

   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.

Dlatego: (1) pozostaw ExecReload puste, (2) użyj systemctl reload-or-restart MYSERVICEi, (3) wszystko powinno być ustawione.

Jeśli spróbujesz użyć narzędzia ExecReload do zdefiniowania sposobu zabicia i ponownego uruchomienia usługi, będzie ona miała nowy PID i systemd byłby zdezorientowany.

TomOnTime
źródło
3

Filozofia systemd reloadjest opcjonalna i użytkownik systemd powinien wiedzieć dla każdej usługi, czy powinien zadzwonić, reloadczy sfałszować ją przez połączenie restart.

Dlatego odpowiedź na twoje pytanie brzmi: „To nie działa i nie powinno. Rozwiąż to na następnej wyższej warstwie”.

Innymi słowy, systemd chce, abyś wdrożył „ przeładowanie ” tylko wtedy, gdy usługa bazowa obsługuje prawdziwą funkcję przeładowania ... tj. Przeładowanie, które nie zabija i nie uruchamia ponownie usługi lub powoduje, że usługa zmienia swój PID. Innymi słowy, systemd chce tylko odzwierciedlić istniejące funkcje.

Być może zastanawiasz się: Ale czy nie byłoby łatwiej, gdybym mógł wdrożyć „fałszywe” przeładowanie, umożliwiając ExecReloadzabicie i ponowne uruchomienie usługi? Wtedy mógłbym korzystać systemctl reload FOOze wszystkich moich usług i nie musiałbym pamiętać, które z nich obsługują, a które nie?

Tak, byłoby to łatwiejsze, ale nie byłoby to w porządku systemowym. Systemd chce, aby osoba dzwoniąca wiedziała, czy reloadistnieje dla usługi. Systemd chce być wspólnym interfejsem do istniejących funkcji, nie chce być odpowiedzialny za wypełnianie luk.

Na przykład marionetka zakłada, że ​​usługa sterowana systemowo nie ma reloadi domyślnie zabija i ponownie uruchamia proces . Jeśli typ Service [] dodał sposób określania, że ​​przeładowanie istnieje i że należy go użyć po powiadomieniu, będzie musiał dowiedzieć się, które usługi mają lub nie mają przeładowania natywnego. Szef kuchni i wszystkie inne systemy również musiałyby nauczyć się tego samego, ponieważ systemd chce, aby rozwiązano to na tej warstwie. (MiniRant: do uruchomienia procesu systemd wydaje się być wszechwiedzącym, wszechstronnym, dostosowującym się do przestrzeni nazw systemem i-do-all-at-my-layer. Dlatego nie mogę powiedzieć, dlaczego tak nie jest rozciągnij tę filozofię na przeładowywanie. Może jeden z autorów może tu dzwonić.)

TomOnTime
źródło
1
Jest taki systemctl reload-or-restart, który przeładuje usługę, jeśli obsługuje, i uruchom ją ponownie, jeśli nie. Nie mam pojęcia, dlaczego Puppet przyjmuje takie założenie.
Michael Hampton