Come un limite di connessioni al database ha quasi riavviato i Mac dei miei clienti
Gestiamo una piccola flotta di Mac mini per i clienti. Un daemon su un hub interroga ogni macchina via SSH, invia la telemetria a un control plane e fa escalation quando una macchina tace. Prima aspetta. Poi spegne e riaccende la macchina tramite una presa smart. Poi chiama una persona.
La settimana scorsa il control plane ha iniziato a restituire errori 500. Tredici minuti dopo il daemon aveva concluso che tutti e quattro i Mac erano morti, e aveva registrato un power cycle per ciascuno. Due erano di clienti paganti. Un terzo era stato venduto quella mattina.
Cosa si è rotto davvero
Un pool di connessioni al database. Il control plane gira su funzioni serverless collegate a un pooler Postgres con un limite di quindici connessioni per tutto il progetto. Poche funzioni già calde le hanno occupate tutte, e ogni route API che usava il database ha iniziato a fallire. I dettagli sono in un articolo a parte.
I Mac stavano bene. SSH funzionava. Ogni sessione grafica era attiva. Il cliente che stava compilando su uno di essi non si è accorto di nulla. L’unica cosa rotta era il sistema che doveva sapere se i Mac erano rotti.
Come una flotta sana è sembrata morta
Il daemon teneva un timestamp per macchina: l’ultima volta in cui un poll era riuscito. La logica di escalation lo confrontava con l’ora attuale. Il poll, giustamente, iniziava scaricando l’elenco delle macchine dal control plane. Se quella richiesta falliva, terminava subito.
Quindi durante il guasto nessun poll è partito, nessun timestamp è avanzato, e tutti gli intervalli sono cresciuti insieme. La logica di escalation non sapeva che il daemon non ci aveva mai provato. Ha visto tredici minuti di silenzio da quattro macchine e ha fatto ciò per cui era stata costruita.
ladder: Unit 02 unreachable 12m51s → power cycle ladder: Unit 03 unreachable 12m51s → power cycle ladder: Unit 04 unreachable 12m51s → power cycle ladder: Unit 05 unreachable 12m43s → power cycle
Perché nulla si è riavviato
Non c’era nessuna presa smart configurata. Il passaggio del power cycle ha cercato una presa, non l’ha trovata ed è andato avanti. Dopo, le quattro macchine mostravano un uptime di sei giorni, sei giorni, un giorno e circa un’ora. Nessuna era stata toccata.
È stata fortuna, non progettazione. Le prese smart sono previste per il prossimo lotto di macchine. Se fossero state installate, un problema di connessioni al database avrebbe tolto la corrente a tre Mac di clienti. Uno forse era a metà di una build. Nessuno aveva fatto niente di sbagliato.
La soluzione
Ora il daemon registra l’ultima volta in cui è riuscito a scaricare l’elenco delle unità e a contattare davvero le macchine. La logica di escalation si rifiuta di agire se non è successo di recente, e scrive nel log il motivo: il guasto è nel control plane, non nelle unità.
ladder: skipped, no successful unit poll in 14m02s (control plane, not the units)
Quella riga dice esattamente cosa si rifiuta di fare e perché. È quello che la vecchia avrebbe dovuto dire fin dalla prima volta.
La regola di fondo è semplice. Una remediation deve richiedere la prova che il controllo sia stato eseguito. "Abbiamo provato a raggiungerlo e non ci siamo riusciti" è una prova. "Non ne abbiamo notizie" non lo è, perché è anche l’aspetto di un guasto di chi ascolta.
Cosa testare nella tua automazione
Avevamo testato cosa succede quando un Mac muore. Non avevamo mai testato cosa succede quando muore il sistema che osserva i Mac. Non sono lo stesso test, ed è il secondo quello che allunga la mano verso l’interruttore.
Domande
- Le azioni di recupero come il power cycle dovrebbero mai essere automatiche?
- Sì, ma solo con una prova concreta che sia il target stesso a essersi guastato. Un’azione che scatta per mancanza di informazioni scatterà durante qualsiasi guasto del sistema che raccoglie quelle informazioni.
- Come lo testi senza rompere la produzione?
- Spegni l’osservatore, non i nodi. Impedisci al daemon di raggiungere il suo control plane e guarda cosa decide la remediation. Se fa escalation, sta ragionando sul silenzio.
- Qual è la soglia giusta per considerare un nodo irraggiungibile?
- Più lunga di qualsiasi breve interruzione prevista del control plane. E deve iniziare a contare solo dopo un tentativo fallito di raggiungere il nodo, mai dall’ultima volta in cui il nodo è stato visto per caso.
Fai i tuoi conti con il calcolatore oppure noleggia un runner.