Náš hlídač restartoval služby, které jsme záměrně zastavili
Provoz
Jeden z našich hlídačů spustí kteroukoli z našich služeb, která je povolená, ale neběží. Dvakrát v říjnu spustil služby, které jsme záměrně zastavili. Podruhé se návštěvníci jednoho z našich webů setkávali s chybami přibližně 45 minut.
Proč tento hlídač existuje
Služba, která čistě skončí po přijetí SIGTERM, například protože ji něco ukončilo podle názvu, není z pohledu systemd „selhaná“. Restart=on-failure ji neobnoví a systemctl --failed ji nevylistuje. Zůstane vypnutá, dokud si toho někdo náhodou nevšimne. Hlídač tedy hledá služby, které jsou povolené, ale neběží, a spustí je.
Problém je v tom, že služba, kterou jste zastavili ručně, vypadá úplně stejně.
Poprvé
Dne 7. října jsme ve 12:47 zastavili video worker příkazem systemctl stop, abychom upravili jeho frontu úloh. V 12:55 opět běžel: spustil ho hlídač.
Podruhé
Dne 21. října jsme potřebovali paměť stroje, který obsluhuje také dva z našich webů, pro test modelu. Skript zastavil webové aplikace webů, synchronizační úlohu a kontejner databáze, opět příkazem systemctl stop. Přibližně o pět minut později časovač, který hlídá weby, a v 19:14 hlídač, znovu spustily tunel a webové aplikace.
Tunel opět přijímal provoz, ale webové aplikace nedokázaly odpovídat: testovaný model zabíral 114 GiB paměti stroje. Od přibližně 19:14 do 20:00 se někteří návštěvníci setkávali s chybami 502. V 20:00 jsme zakázali tunel, webové aplikace a synchronizační úlohu a zastavili časovač hlídání.
Pravidlo, které nyní používáme
- Pozastavte službu jejím zakázáním:
sudo systemctl disable --now <unit>. Obnovte ji příkazemsudo systemctl enable --now <unit>. Náš hlídač se dívá pouze na povolené služby, takže zakázanou nechá být. - Pozastavte vše, co ji může obnovit: tunel před ní a jakýkoli časovač, který ji hlídá.
- Krátké zastavení je závod s časem. Pokud použijete pouze
stop, dokončete práci před další kontrolou, která na našich strojích probíhá v řádu minut.
Další dvě pasti systemd ze stejných měsíců
systemctl mask --runtimeu souboru unitu v /etc/systemd/system nic neudělá. Unitové soubory v /etc mají přednost před maskou v /run, takže příkaz proběhne úspěšně a služba se přesto spustí. K pozastavení služby používáme drop-in sConditionPathExists=!/etc/<name>.hold: dokud tento soubor existuje, služba nespustí, ani při startu systému, ani ručně.systemctl is-activeoznačuje běžící oneshot službu za neaktivní. Zatímco službaType=oneshotběží, její stav je „activating“, takžeis-activevypíše tento stav a vrátí 3. Smyčka jakowhile systemctl is-active --quiet job.service; do sleep 60; done, která má čekat na noční úlohu, okamžitě skončí. Místo toho čtěte stav: active, activating, reloading nebo deactivating všechna znamenají, že služba stále běží.
Factory Floor sleduje povolené služby, které neběží. Ve výchozím nastavení je pouze hlásí a spouští je, pouze pokud to zapnete. Od verze 1.0.3 jeho upozornění také uvádí, jak službu záměrně pozastavit, a jeho runbook říká totéž.