Nota del traduttore.: Henning Jacobs, chief engineer at Zalando, ha notato più volte che gli utenti di Kubernetes hanno difficoltà a comprendere lo scopo dei liveness (e readiness) probes e il loro corretto utilizzo. Pertanto, ha raccolto i suoi pensieri in questa concisa nota, che nel tempo diventerà parte della documentazione di K8s.

I controlli dello stato, conosciuti in Kubernetes come liveness probes (ossia, letteralmente, "test di vitalità" — nota del traduttore), possono essere molto pericolosi. Ti consiglio di evitarli se possibile: le eccezioni sono solo i casi in cui sono davvero necessari e sei pienamente consapevole delle specificità e delle conseguenze del loro utilizzo. In questo documento si parlerà dei liveness e readiness probes, e si spiegherà in quali casi è consigliabile e non è consigliabile applicarli.
Il mio collega Sandor ha recentemente condiviso su Twitter gli errori più comuni che incontra, inclusi quelli legati all'uso dei readiness/liveness probes:
Configurazione errata livenessProbe può esacerbare le situazioni di carico elevato (spegnimenti a valanga + riavvio potenzialmente lungo del container/applicazione) e portare ad altre conseguenze negative come il fallimento delle dipendenze (vedi anche sul limite del numero di richieste nella combinazione K3s+ACME). È ancora peggio quando il liveness probe è combinato con il controllo dello stato delle dipendenze (health check), rappresentato da un database esterno: un singolo guasto del database riavvierà tutti i tuoi container!
Messaggio generale "Non utilizzare i liveness probes" in questo caso non aiuta molto, quindi consideriamo a cosa servono i readiness e liveness check.
Nota: la maggior parte del test fornito di seguito era originariamente inclusa nella documentazione interna per gli sviluppatori di Zalando.
Controlli Readiness e Liveness
Kubernetes fornisce due importanti meccanismi chiamati . Eseguono periodicamente un'azione — ad esempio, inviare una richiesta HTTP, aprire una connessione TCP o eseguire un comando nel container — per confermare che l'applicazione funzioni correttamente.
Kubernetes utilizza readiness probes, per capire quando il contenitore è pronto a ricevere traffico. Un pod si considera pronto per il lavoro se tutti i suoi contenitori sono pronti. Uno degli usi di questo meccanismo è controllare quali pod vengono utilizzati come backend per i servizi Kubernetes (e in particolare per Ingress).
Liveness probes aiutano Kubernetes a capire quando è il momento di riavviare il contenitore. Ad esempio, una tale verifica può intercettare un deadlock, quando l'applicazione 'si blocca' in un punto. Riavviare il contenitore in questo stato aiuta a sbloccare l'applicazione, nonostante gli errori, ma può anche portare a guasti a cascata (vedi sotto).
Se cerchi di distribuire un aggiornamento dell'applicazione che fallisce i controlli di liveness/readiness, il rilascio si fermerà poiché Kubernetes attenderà lo stato Pronto di tutti i pod.
Esempio
Ecco un esempio di readiness probe che controlla il percorso /health via HTTP con impostazioni predefinite (interval: 10 secondi, timeout: 1 secondo, success threshold: 1, failure threshold: 3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080Raccomandazioni
- Per i microservizi con endpoint HTTP (REST, ecc.) definisci sempre una readiness probe, che verifica se l'applicazione (pod) è pronta a ricevere traffico.
- Assicurati che la readiness probe copre la disponibilità della porta effettiva del server web:
- utilizzando porte per esigenze amministrative, denominate «admin» o «management» (ad esempio, 9090), per
readinessProbe, assicurati che l'endpoint restituisca OK solo se la porta HTTP principale (come 8080) è pronta per ricevere traffico*;* Sono a conoscenza di almeno un caso in Zalando in cui ciò non è accaduto, cioè
readinessProbeho controllato la porta «management», ma il server stesso non è partito a causa di problemi di caricamento della cache. - collegare la readiness probe a una porta separata può fare in modo che il sovraccarico sulla porta principale non si rifletta nel health check (cioè il pool di thread sul server è pieno, ma l'health check continua a mostrare che tutto va bene).
- utilizzando porte per esigenze amministrative, denominate «admin» o «management» (ad esempio, 9090), per
- Assicurati che la readiness probe includa l'inizializzazione/migrazione del database;
- il modo più semplice per ottenerlo è contattare il server HTTP solo dopo il completamento dell'inizializzazione (ad esempio, la migrazione del DB con ecc.); cioè invece di modificare lo stato dell'health check, non avviare semplicemente il server web fino al completamento della migrazione del DB*.
* È possibile eseguire migrazioni del database da init-container esterni al pod. Rimango un sostenitore delle applicazioni autonome, ovvero quelle in cui il container dell'applicazione sa come portare il database nello stato desiderato senza coordinazione esterna.
- il modo più semplice per ottenerlo è contattare il server HTTP solo dopo il completamento dell'inizializzazione (ad esempio, la migrazione del DB con ecc.); cioè invece di modificare lo stato dell'health check, non avviare semplicemente il server web fino al completamento della migrazione del DB*.
- Usa
httpGetper i controlli di readiness attraverso i tipici endpoint delle health check (ad esempio,/health). - Comprendere i parametri di controllo predefiniti (
interval: 10s,timeout: 1s,successThreshold: 1,failureThreshold: 3):- i parametri predefiniti significano che il pod diventerà not-ready dopo circa 30 secondi (3 controlli di funzionalità non riusciti).
- Utilizzare una porta separata per «admin» o «management», se il stack tecnologico (ad esempio, Java/Spring) lo consente, per separare la gestione della «salute» e delle metriche dal traffico normale:
- ma non dimenticate il punto 2.
- Se necessario, la readiness probe può essere utilizzata per riscaldare/caricare la cache restituendo un codice di stato 503, finché il container non è «riscaldato»:
- consiglio anche di dare un'occhiata al nuovo controllo
startupProbe, (ne abbiamo scritto in russo — nota di traduzione).
- consiglio anche di dare un'occhiata al nuovo controllo
Avvertenze
- Non fare affidamento su dipendenze esterne (come i repository di dati) durante i test di readiness/liveness — questo può portare a guasti a cascata:
- prendiamo come esempio un servizio stateful REST con 10 pod che dipendono da un'unica base di dati Postgres: quando il controllo dipende da una connessione funzionante al DB, tutti e 10 i pod possono andare in crash se si verifica un ritardo nella rete/o dal lato del DB — di solito tutto ciò termina peggio di quanto potrebbe;
- si noti che Spring Data controlla la connessione con il DB per impostazione predefinita*;
* Questo è il comportamento predefinito di Spring Data Redis (almeno era così quando ho verificato l'ultima volta), il che ha portato a un crash 'catastrofico': quando Redis è stato temporaneamente non disponibile, tutti i pod sono 'crollati'.
- 'esterno' in questo senso può anche significare altri pod della stessa applicazione, quindi idealmente il controllo non dovrebbe dipendere dallo stato di altri pod dello stesso cluster per prevenire i crolli a cascata:
- i risultati possono variare per applicazioni con stato distribuito (ad esempio, caching in-memory nei pod).
- Non utilizzare il liveness probe per i pod (eccetto nei casi in cui siano davvero necessari e si sia pienamente consapevoli delle specifiche e delle conseguenze del loro utilizzo):
- il liveness probe può aiutare a recuperare contenitori "bloccati", ma poiché hai il pieno controllo sulla tua applicazione, situazioni come processi "bloccati" e deadlock non dovrebbero idealmente verificarsi: la migliore alternativa è il crash intenzionale dell'applicazione e il suo ritorno a uno stato stabile precedente;
- un liveness probe non riuscito porterà al riavvio del contenitore, il che potenzialmente esacerba le conseguenze di errori legati al caricamento: il riavvio del contenitore porterà a un'interruzione (almeno durante il tempo di avvio dell'applicazione, diciamo, per più di 30 secondi), causando nuovi errori, aumentando il carico su altri contenitori e aumentando la probabilità di guasti, ecc.;
- le verifiche di liveness cominate con una dipendenza esterna sono la peggiore delle combinazioni possibili, minacciando danni a cascata: un leggero ritardo da parte del database porterà al riavvio di tutti i tuoi contenitori!
- Parametri delle verifiche di liveness e readiness dovrebbero essere diversi:
- È possibile utilizzare il liveness probe con lo stesso health check, ma con una soglia di attivazione più alta (
failureThreshold), ad esempio, assegnare lo stato not-ready dopo 3 tentativi e considerare il liveness probe fallito dopo 10 tentativi;
- È possibile utilizzare il liveness probe con lo stesso health check, ma con una soglia di attivazione più alta (
- Non utilizzare controlli exec, poiché comportano noti problemi che portano alla creazione di processi zombie:
- dettagli: vedi .
Riepilogo
- Utilizzare i readiness probes per determinare quando il pod è pronto a ricevere traffico.
- Utilizzare i liveness probes solo quando sono realmente necessari.
- Un uso errato dei readiness/liveness probes può portare a una riduzione della disponibilità e a fallimenti a cascata.
Ulteriori materiali sull'argomento
- ;
- ;
- (parla anche di livenessProbe).
Aggiornamento n. 1 del 2019-09-29
: aggiunta una nota.
del PDB: una delle problematiche delle liveness checks è l'assenza di coordinazione tra i pod. In Kubernetes ci sono per limitare il numero di fallimenti paralleli che un'app può subire, tuttavia i controlli non considerano il PDB. Idealmente, possiamo ordinare a K8s: "Riavvia un pod se il suo controllo fallisce, ma non riavviare tutti, per non peggiorare la situazione".
: «Utilizza i controlli di liveness quando sei certo che la cosa migliore da fare sia «terminare» l'applicazione» (anche se non esagerare).
Aggiornamento n. 2 del 2019-09-29
: ho creato una richiesta pertinente () per aggiungere documentazione sui controlli di liveness.
P.S. dal traduttore
Leggete anche nel nostro blog:
- «»;
- «»;
- «».
Fonte: habr.com
