Il nostro watchdog ha riavviato i servizi che avevamo fermato di proposito
Ops
Uno dei nostri watchdog avvia qualsiasi nostro servizio abilitato ma non in esecuzione. A ottobre, per due volte, ha avviato servizi che avevamo fermato di proposito. La seconda volta, i visitatori di uno dei nostri siti hanno ricevuto errori per circa 45 minuti.
Perché esiste quel watchdog
Un servizio che esce correttamente quando riceve SIGTERM, ad esempio perché qualcosa lo ha terminato per nome, non risulta "failed" per systemd. Restart=on-failure non lo riavvia e systemctl --failed non lo elenca. Resta fermo finché qualcuno non se ne accorge per caso. Quindi il watchdog cerca i servizi abilitati ma non in esecuzione e li avvia.
Il problema è che un servizio fermato manualmente sembra esattamente uguale.
La prima volta
Il 7 ottobre abbiamo fermato un worker video con systemctl stop alle 12:47 per modificare la sua coda di lavoro. Alle 12:55 era di nuovo in esecuzione: il watchdog lo aveva avviato.
La seconda volta
Il 21 ottobre avevamo bisogno della memoria della macchina che serve anche due dei nostri siti per un test di modello. Uno script ha fermato le web app dei siti, un job di sincronizzazione e un container del database, sempre con systemctl stop. Circa cinque minuti dopo un timer che sorveglia i siti, e alle 19:14 il watchdog, hanno riavviato il tunnel e le web app.
Il tunnel ha ripreso a ricevere traffico, ma le web app non rispondevano: il modello in test occupava 114 GiB della memoria della macchina. Dalle 19:14 alle 20:00 circa, alcuni visitatori hanno ricevuto errori 502. Alle 20:00 abbiamo disabilitato il tunnel, le web app e il job di sincronizzazione, e fermato il timer di sorveglianza.
La regola che usiamo ora
- Metti in pausa un servizio disabilitandolo:
sudo systemctl disable --now <unit>. Riportalo in vita consudo systemctl enable --now <unit>. Il nostro watchdog controlla solo i servizi abilitati, quindi lascia stare quelli disabilitati. - Metti in pausa tutto ciò che può riavviarlo: il tunnel davanti ad esso e qualsiasi timer che lo sorveglia.
- Una fermata breve è una corsa contro il tempo. Se usi solo
stop, finisci prima del prossimo controllo, che sulle nostre macchine arriva entro pochi minuti.
Altre due insidie di systemd degli stessi mesi
systemctl mask --runtimenon fa nulla per un file di unit in /etc/systemd/system. Le unit in /etc hanno priorità sul mask runtime in /run, quindi il comando ha successo ma il servizio si avvia comunque. Per bloccare un servizio, usiamo un drop-in conConditionPathExists=!/etc/<name>.hold: finché quel file esiste, il servizio non si avvia, né all'avvio né manualmente.systemctl is-activeconsidera inattivo un servizio oneshot in esecuzione. Mentre un servizioType=oneshotè in esecuzione, il suo stato è "activating", quindiis-activestampa quel valore e restituisce 3. Un ciclo comewhile systemctl is-active --quiet job.service; do sleep 60; done, pensato per attendere un job notturno, esce subito. Leggi invece lo stato: active, activating, reloading o deactivating indicano tutti che è ancora in esecuzione.
Factory Floor sorveglia i servizi abilitati che non sono in esecuzione. Per impostazione predefinita li segnala soltanto, e li avvia solo se attivi questa opzione. Dalla versione 1.0.3 il suo avviso indica anche come mettere in pausa un servizio intenzionalmente, e il suo runbook dice lo stesso.