Onze watchdog heeft de services opnieuw gestart die we bewust hadden gestopt
Ops
Eén van onze watchdogs start elke service die is ingeschakeld maar niet draait. Twee keer in oktober startte hij services die we bewust hadden gestopt. De tweede keer kregen bezoekers van een van onze sites ongeveer 45 minuten lang fouten te zien.
Waarom die watchdog bestaat
Een service die netjes afsluit bij SIGTERM, bijvoorbeeld omdat iets hem bij naam heeft afgesloten, wordt door systemd niet als "failed" gemarkeerd. Restart=on-failure start hem niet opnieuw op, en systemctl --failed toont hem niet. Hij blijft down totdat iemand het toevallig merkt. De watchdog zoekt daarom naar services die zijn ingeschakeld maar niet draaien, en start ze.
Het probleem is dat een service die je handmatig hebt gestopt er precies hetzelfde uitziet.
De eerste keer
Op 7 oktober stopten we een video-worker met systemctl stop om 12:47 om zijn wachtrij te bewerken. Om 12:55 draaide hij weer: de watchdog had hem gestart.
De tweede keer
Op 21 oktober hadden we het geheugen nodig van de machine die ook twee van onze sites bedient voor een modeltest. Een script stopte de webapps van de sites, een sync-job en een databasecontainer, opnieuw met systemctl stop. Ongeveer vijf minuten later bracht een timer die de sites bewaakt, en om 19:14 de watchdog, de tunnel en de webapps weer terug.
De tunnel nam weer verkeer over, maar de webapps konden niet antwoorden: het geteste model hield 114 GiB van het geheugen van de machine vast. Van ongeveer 19:14 tot 20:00 kregen sommige bezoekers 502-fouten. Om 20:00 schakelden we de tunnel, de webapps en de sync-job uit, en stopten we de bewaaktimer.
De regel die we nu gebruiken
- Pauzeer een service door hem uit te schakelen:
sudo systemctl disable --now <unit>. Start hem weer metsudo systemctl enable --now <unit>. Onze watchdog kijkt alleen naar ingeschakelde services, dus een uitgeschakelde service laat hij met rust. - Pauzeer alles wat hem terug kan brengen: de tunnel ervoor en elke timer die hem bewaakt.
- Een korte stop is een race. Als je alleen
stopgebruikt, wees dan klaar vóór de volgende controle, die op onze machines binnen enkele minuten plaatsvindt.
Twee extra systemd-valkuilen uit dezelfde maanden
systemctl mask --runtimedoet niets voor een unit-bestand in /etc/systemd/system. Units in /etc hebben voorrang op de runtime-mask in /run, dus het commando slaagt en de service start nog steeds. Om een service tegen te houden, gebruiken we een drop-in metConditionPathExists=!/etc/<name>.hold: zolang dat bestand bestaat, start de service niet, noch bij het opstarten noch handmatig.systemctl is-activenoemt een draaiende oneshot-service inactive. Terwijl eenType=oneshot-service draait, is de status "activating", dusis-activetoont dat en geeft 3 terug. Een lus zoalswhile systemctl is-active --quiet job.service; do sleep 60; done, bedoeld om te wachten op een nachtelijke taak, stopt meteen. Lees in plaats daarvan de status: active, activating, reloading of deactivating betekenen allemaal dat de service nog steeds draait.
Factory Floor houdt ingeschakelde services bij die niet draaien. Standaard meldt het ze alleen, en start het ze alleen als je dat inschakelt. Sinds versie 1.0.3 vermeldt de melding ook hoe je een service bewust pauzeert, en het runbook zegt hetzelfde.