GNU/Linux >> Znalost Linux >  >> Cent OS

Centos – Systemd ukončí službu ihned po spuštění?

Píšu systemd jednotkové soubory pro OSSEC HIDS. Problém je v tom, že když systemd spustí služby, okamžitě je zastaví.

Když použiji následující ExecStart direktiva vše funguje dobře.

ExecStart=/var/ossec/bin/ossec-control start

Ale když po malém vylepšení udělám toto, zjistím v protokolech OSSEC, že přijímá SIG 15 po startu.

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'

Pokud provedu další malou změnu, služba obdrží SIG 15 po 20 sekundách.

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'

Takže myslím, že systemd zabije /bin/sh proces po spuštění služby a /bin/sh pak zabije OSSEC .

Jak mohu tento problém vyřešit?

Přijatá odpověď:

neshoda protokolu připravenosti

Jak naznačil Wieland, Type služby je důležité. Toto nastavení označuje protokol připravenosti systemd očekává, že služba bude mluvit. simple předpokládá se, že služba je okamžitě připravena. forking služba je považována za připravenou poté, co její počáteční proces rozdělí dítě a poté se ukončí. dbus služba je považována za připravenou, když se server objeví na sběrnici plochy. A tak dále.

Pokud nedostanete protokol připravenosti deklarovaný v servisní jednotce, aby odpovídal tomu, co služba dělá, pak se věci zvrtnou. Neshody protokolů připravenosti způsobují, že se služby nespustí správně nebo (obvykleji) jsou (nesprávně) diagnostikovány systémem systemd jako selhávající. Když je služba považována za neúspěšnou při spuštění, systemd zajistí, že každý osiřelý další proces služby která mohla zůstat spuštěna jako součást selhání (z jeho pohledu) je zabita, aby se služba správně vrátila do neaktivního stavu.

Přesně tohle děláte.

Nejprve jednoduchá věc:sh -c neodpovídá Type=simple nebo Type=forking .

V simple protokol, je počáteční proces převzat do být servisní proces. Ale ve skutečnosti sh -c wrapper spouští skutečný servisní program jako podřízený proces . Takže MAINPID se pokazí a ExecReload přestane fungovat, pro začátek. Při použití Type=simple , musíte buď použít sh -c 'exec …' nebo nepoužívat sh -c na prvním místě. To druhé je častěji správným směrem, než si někteří lidé myslí.

sh -c neodpovídá Type=forking buď. Protokol připravenosti pro forking služba je zcela specifická. Počáteční proces musí dítě rozdělit a poté ukončit. systemd aplikuje na tento protokol časový limit. Pokud se počáteční proces nerozdělí ve stanoveném čase, znamená to, že se nepodařilo připravit. Pokud se počáteční proces neukončí ve stanoveném čase, je to také selhání.

zbytečná hrůza, kterou je ossec-control

Což nás přivádí ke komplexní věci:k ossec-control skript.

Ukázalo se, že je to System 5 rc skript, který odděluje 4 až 10 procesů, které se samy rozvětvují a ukončují také. Je to jeden z těch System 5 rc skripty, které se pokoušejí spravovat celou sadu serverových procesů v jediném skriptu s for smyčky, podmínky závodu, libovolný sleep Je to pokusit se jim vyhnout, režimy selhání, které mohou udusit systém v napůl spuštěném stavu, a všechny další hrůzy, kvůli kterým lidé před dvěma desetiletími vynalezli věci jako AIX System Resource Controller a daemontools. A nezapomeňme na skrytý skript shellu v binárním adresáři, který za běhu přepisuje, aby implementoval idiosynkratické enable a disable slovesa.

Související:Debian – Jak zjistit, jak se konkrétní balíček nainstaloval?

Takže když /bin/sh -c '/var/ossec/bin/ossec-control start' stane se toto:

  1. systemd rozvětví to, co očekává jako proces služby.
  2. To je shell, který rozvětvuje ossec-control .
  3. To zase rozdělí 4 až 10 vnoučat.
  4. Všechna vnoučata se postupně rozdvojují a odcházejí.
  5. Všichni pravnuci se rozdvojují a odcházejí paralelně.
  6. ossec-control ukončí.
  7. První shell opustí.
  8. Procesy služeb byly skvělé-skvělé- vnoučata, ale protože tento způsob práce neodpovídá ani jednomu forking ani simple protokol připravenosti, systemd považuje službu jako celek za selhání a opět ji vypne.

Nic z této hrůzy vlastně není pod systemd vůbec nutné. Nic z toho.

servisní jednotka šablony systemd

Místo toho se napíše velmi jednoduchá jednotka šablony :

[Unit]
Description=The OSSEC HIDS %i server
After=network.target 

[Service]
Type=simple
ExecStartPre=/usr/bin/env /var/ossec/bin/%p-%i -t
ExecStart=/usr/bin/env /var/ossec/bin/%p-%i -f

[Install]
WantedBy=multi-user.target

Uložte to jako /etc/systemd/system/[email protected] .

Různé skutečné služby jsou instance této šablony s názvem:

  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]

Poté povolte a zakažte funkci přichází přímo ze systému správy služeb (s opravenou chybou RedHat 752774), bez potřeby skrytých skriptů shellu.

 systemctl enable [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]

Systemd navíc přímo pozná a sleduje každou skutečnou službu. Může filtrovat jejich protokoly pomocí journalctl -u . Dokáže zjistit, kdy jednotlivá služba selhala. Ví, jaké služby mají být povoleny a spuštěny.

Mimochodem:Type=simple a -f možnosti jsou zde stejně správné jako v mnoha jiných případech. Velmi málo služeb ve volné přírodě ve skutečnosti signalizuje svou připravenost pomocí exit a ani zde o takové případy nejde. Ale to je to, co forking typ znamená. Služby v divočině se většinou jen rozvětvují a opouštějí kvůli nějaké mylně přijaté představě moudrosti, že to je to, co mají démoni dělat. ve skutečnosti není. Od devadesátých let to není. Je čas to dohnat.

Další čtení

  • Jonathan de Boyne Pollard (2015). Problémy s protokolem připravenosti u unixových démonů . Často uváděné odpovědi.

Cent OS
  1. Automaticky spusťte službu OpenCA přes Systemd v CentOS 7

  2. Proč Systemd zastavuje službu ihned po jejím spuštění?

  3. Centos – Nepodařilo se spustit Apache Http Server – Httpd.service se nezdařilo?

  1. Služba Systemd nespustí Nodejs?

  2. CentOS / RHEL 7 :Jak nakonfigurovat sériové getty pomocí systemd

  3. Nelze spustit službu Nagios (CentOS/RHEL)

  1. systemd:SIGTERM ihned po startu

  2. Nelze spustit službu postgresql na CentOS 7

  3. systemctl zastaví službu Tomcat ihned po spuštění