In che modo le priorità dei pod in Kubernetes hanno causato tempi di inattività presso Grafana Labs

Nota. trad.: Presentiamo alla vostra attenzione i dettagli tecnici sui motivi del recente periodo di inattività del servizio cloud gestito dai creatori di Grafana. Questo è un classico esempio di come una funzionalità nuova e apparentemente estremamente utile, progettata per migliorare la qualità delle infrastrutture... può causare danni se non si tengono conto delle numerose sfumature della sua applicazione nelle realtà produttive. È fantastico quando compaiono materiali come questo che ti permettono di imparare non solo dai tuoi errori. I dettagli sono nella traduzione di questo testo del vicepresidente del prodotto di Grafana Labs.

In che modo le priorità dei pod in Kubernetes hanno causato tempi di inattività presso Grafana Labs

Venerdì 19 luglio il servizio Hosted Prometheus in Grafana Cloud ha smesso di funzionare per circa 30 minuti. Mi scuso con tutti i clienti colpiti dall'interruzione. Il nostro compito è fornire gli strumenti di monitoraggio di cui hai bisogno e comprendiamo che non averli a disposizione può renderti la vita più difficile. Prendiamo questo incidente estremamente sul serio. Questa nota spiega cosa è successo, come abbiamo reagito e cosa stiamo facendo per garantire che non accada di nuovo.

Sfondo

Il servizio Grafana Cloud Hosted Prometheus è basato su Corteccia — Progetto CNCF per creare un servizio Prometheus multi-tenant scalabile orizzontalmente, altamente disponibile. L'architettura Cortex è costituita da un insieme di singoli microservizi, ognuno dei quali svolge la propria funzione: replica, archiviazione, query, ecc. Cortex è in fase di sviluppo attivo e aggiunge costantemente nuove funzionalità e migliora le prestazioni. Distribuiamo regolarmente nuove versioni di Cortex ai cluster in modo che i clienti possano sfruttare queste funzionalità: fortunatamente Cortex può essere aggiornato senza tempi di inattività.

Per aggiornamenti senza interruzioni, il servizio Ingester Cortex richiede una replica Ingester aggiuntiva durante il processo di aggiornamento. (Nota. trad.: Ingerire - la componente base della corteccia. Il suo compito è raccogliere un flusso costante di campioni, raggrupparli in blocchi Prometheus e archiviarli in un database come DynamoDB, BigTable o Cassandra.) Ciò consente ai vecchi Ingester di inoltrare i dati correnti ai nuovi Ingester. Vale la pena notare che gli Ingesters richiedono risorse. Affinché funzionino, è necessario disporre di 4 core e 15 GB di memoria per pod, ovvero Nel caso dei nostri cluster Kubernetes, il 25% della potenza di elaborazione e della memoria della macchina base. In generale, di solito abbiamo molte più risorse inutilizzate nel cluster rispetto a 4 core e 15 GB di memoria, quindi possiamo facilmente attivare questi ingester aggiuntivi durante gli aggiornamenti.

Tuttavia, accade spesso che durante il normale funzionamento nessuna macchina disponga di questo 25% di risorse inutilizzate. Sì, non ci sforziamo nemmeno: CPU e memoria saranno sempre utili per altri processi. Per risolvere questo problema, abbiamo deciso di utilizzare Priorità dei pod Kubernetes. L'idea è quella di dare agli Ingesters una priorità più alta rispetto ad altri microservizi (senza stato). Quando dobbiamo eseguire un Ingester aggiuntivo (N+1), sostituiamo temporaneamente altri pod più piccoli. Questi pod vengono trasferiti in risorse gratuite su altre macchine, lasciando un “buco” abbastanza grande per eseguire un Ingester aggiuntivo.

Giovedì 18 luglio abbiamo introdotto quattro nuovi livelli di priorità nei nostri cluster: critico, alto, media и basso. Sono stati testati su un cluster interno senza traffico client per circa una settimana. Per impostazione predefinita, vengono ricevuti i pod senza una priorità specificata media priorità, la classe è stata impostata per gli Ingesters con alto priorità. Critico era riservato al monitoraggio (Prometheus, Alertmanager, node-exporter, kube-state-metrics, ecc.). La nostra configurazione è aperta e puoi visualizzare il PR qui.

Авария

Venerdì 19 luglio uno degli ingegneri ha lanciato un nuovo cluster Cortex dedicato per un grande cliente. La configurazione per questo cluster non includeva nuove priorità dei pod, quindi a tutti i nuovi pod è stata assegnata una priorità predefinita: media.

Il cluster Kubernetes non disponeva di risorse sufficienti per il nuovo cluster Cortex e il cluster Cortex di produzione esistente non è stato aggiornato (gli ingestori sono rimasti senza высокого priorità). Poiché gli Ingester del nuovo cluster avevano per impostazione predefinita media priorità e i pod esistenti in produzione funzionavano senza priorità, gli Ingester del nuovo cluster hanno sostituito gli Ingester del cluster di produzione Cortex esistente.

ReplicaSet per l'Ingester eliminato nel cluster di produzione ha rilevato il pod eliminato e ne ha creato uno nuovo per mantenere il numero di copie specificato. Il nuovo pod è stato assegnato per impostazione predefinita media priorità, e un altro “vecchio” Ingester in produzione ha perso le sue risorse. Il risultato è stato processo di valanga, che ha portato allo spostamento di tutti i pod da Ingester per i cluster produttivi di Cortex.

Gli ingester sono stateful e archiviano i dati delle 12 ore precedenti. Ciò ci consente di comprimerli in modo più efficiente prima di scriverli nell'archiviazione a lungo termine. Per raggiungere questo obiettivo, Cortex suddivide i dati tra le serie utilizzando una tabella hash distribuita (DHT) e replica ciascuna serie su tre Ingester utilizzando la coerenza del quorum in stile Dynamo. Cortex non scrive dati sugli Ingester disabilitati. Pertanto, quando un numero elevato di Ingester lascia il DHT, Cortex non è in grado di fornire una replica sufficiente delle voci e queste si bloccano.

Rilevamento e riparazione

Nuove notifiche Prometheus basate sul “budget errore” (basato sul budget di errore — i dettagli appariranno in un prossimo articolo) ha iniziato a suonare l'allarme 4 minuti dopo l'inizio dello spegnimento. Nel corso dei successivi cinque minuti circa, abbiamo eseguito alcune operazioni di diagnostica e ampliato il cluster Kubernetes sottostante per ospitare sia i cluster di produzione nuovi che quelli esistenti.

Dopo altri cinque minuti, i vecchi Ingester hanno scritto con successo i loro dati, quelli nuovi si sono avviati e i cluster Cortex sono diventati nuovamente disponibili.

Sono stati spesi altri 10 minuti per diagnosticare e correggere gli errori di memoria insufficiente (OOM) dai proxy inversi di autenticazione situati di fronte a Cortex. Gli errori OOM sono stati causati da un aumento di dieci volte del QPS (riteniamo dovuto a richieste eccessivamente aggressive da parte dei server Prometheus del cliente).

Conseguenze

Il tempo di inattività totale è stato di 26 minuti. Nessun dato è stato perso. Gli ingestori hanno caricato correttamente tutti i dati in memoria nell'archivio a lungo termine. Durante l'arresto, il buffer dei server Prometheus del client è stato eliminato (a distanza) registrazioni utilizzando nuova API remote_write basato su WAL (scritto da Callum Styan da Grafana Labs) e ripetuto le scritture fallite dopo l'arresto anomalo.

In che modo le priorità dei pod in Kubernetes hanno causato tempi di inattività presso Grafana Labs
Operazioni di scrittura del cluster di produzione

risultati

È importante imparare da questo incidente e adottare le misure necessarie per evitare che si ripeta.

Col senno di poi, non avremmo dovuto impostare il valore predefinito media priorità fino a quando tutti gli Ingester in produzione non avranno ricevuto alto una priorità. Inoltre, era necessario prendersi cura di loro in anticipo alto priorità. Adesso è tutto sistemato. Ci auguriamo che la nostra esperienza possa aiutare altre organizzazioni a considerare l'utilizzo delle priorità dei pod in Kubernetes.

Aggiungeremo un ulteriore livello di controllo sulla distribuzione di eventuali oggetti aggiuntivi le cui configurazioni sono globali nel cluster. D'ora in poi tali modifiche verranno valutate bоpiù persone. Inoltre, la modifica che ha causato l'arresto anomalo è stata considerata troppo lieve per un documento di progetto separato: è stata discussa solo in un problema di GitHub. D'ora in poi, tutte queste modifiche alle configurazioni saranno accompagnate da un'adeguata documentazione di progetto.

Infine, automatizzeremo il ridimensionamento del proxy inverso di autenticazione per prevenire il sovraccarico OOM a cui abbiamo assistito ed esamineremo le impostazioni predefinite di Prometheus relative al fallback e al ridimensionamento per prevenire problemi simili in futuro.

Il fallimento ha avuto anche alcune conseguenze positive: avendo ricevuto le risorse necessarie, Cortex si è ripresa automaticamente senza ulteriori interventi. Abbiamo anche acquisito una preziosa esperienza lavorando con Grafa Loki - il nostro nuovo sistema di aggregazione dei log, che ha contribuito a garantire che tutti gli Ingestori si comportassero correttamente durante e dopo l'errore.

PS da traduttore

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento