Nota traducătorului.: Liderul inginer din compania Zalando — Henning Jacobs — a observat de nenumărate ori că utilizatorii Kubernetes au probleme în a înțelege scopul probes-urilor liveness (și readiness) și aplicarea corectă a acestora. Prin urmare, el și-a adunat gândurile în această notă concisă, care în timp va deveni parte a documentației K8s.

Probe-urile de stare, cunoscute în Kubernetes ca liveness probes (adică, literal, „teste de viabilitate” — nt. trad.), pot fi destul de periculoase. Recomand să le evitați pe cât posibil: excepțiile sunt doar cazurile în care acestea sunt cu adevărat necesare și sunteți pe deplin conștienți de specificul și consecințele utilizării lor. În această publicație vom discuta despre probes-urile liveness și readiness, precum și despre când merită sau nu merită să fie aplicate.
Colegul meu Sandor a împărtășit recent pe Twitter cele mai frecvente greșeli cu care se confruntă, inclusiv cele legate de utilizarea probes-urilor readiness/liveness:
O probe de liveness configurată incorect livenessProbe poate agrava situațiile cu sarcină mare (deconectare în aval + repornire potențial îndelungată a containerului/aplicației) și poate duce la alte consecințe negative precum căderi de dependențe (vezi și despre limitarea numărului de solicitări în combinație K3s+ACME). Și mai rău este când liveness probe se combină cu verificarea sănătății unei dependențe (health check) reprezentată de o bază de date externă: o singură defecțiune a BAZEI DE DATI va reporni toate containerele dvs.!
Mesajul general „Nu folosiți liveness probes” în acest caz ajută puțin, așa că să vedem pentru ce sunt menite probe-urile readiness și liveness.
Notă: cea mai mare parte a testului de mai jos a fost inclusă inițial în documentația internă pentru dezvoltatorii Zalando.
Probe-urile Readiness și Liveness
Kubernetes oferă două mecanisme importante, numite . Acestea efectuează periodic o anumită acțiune — de exemplu, trimit un request HTTP, deschid o conexiune TCP sau execută o comandă în container — pentru a confirma că aplicația funcționează corect.
Kubernetes utilizează readiness probes, pentru a înțelege când containerul este pregătit să primească trafic. Un pod este considerat gata de lucru dacă toate containerele sale sunt gata. O utilizare a acestui mecanism este de a controla care poduri sunt folosite ca back-end pentru serviciile Kubernetes (în special Ingress).
Probe de liveness ajută Kubernetes să înțeleagă când este momentul să repornească un container. De exemplu, o astfel de verificare permite interceptarea deadlock-ului, atunci când aplicația „se blochează” într-un loc. Repornirea containerului într-o astfel de stare ajută la deblocarea aplicației, în ciuda erorilor, însă poate duce și la eșecuri în cascadă (vezi mai jos).
Dacă încercați să desfășurați o actualizare a aplicației care eșuează verificările de liveness/readiness, desfășurarea va fi oprită, deoarece Kubernetes va aștepta statutul Gata de la toate pod-urile.
Exemplu
Iată un exemplu de readiness probe, care verifică calea /health prin HTTP cu setările implicit (interval: 10 secunde, timeout: 1 secundă, threshold de succes: 1, threshold de eșec: 3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080Recomandări
- Pentru microservicii cu endpoint HTTP (REST etc.) definiți întotdeauna readiness probe, care verifică dacă aplicația (pod) este gata să primească trafic.
- Asigurați-vă că readiness probe acoperă pregătirea portului efectiv al serverului web:
- utilizând porturi pentru nevoi administrative, denumite „admin” sau „management” (de exemplu, 9090), pentru
readinessProbe, asigurați-vă că endpoint-ul returnează OK doar dacă portul HTTP principal (de exemplu, 8080) este gata să primească trafic*;* Știu de cel puțin un caz din Zalando, când acest lucru nu s-a întâmplat, adică
readinessProbea verificat portul „management”, dar serverul nu a început să funcționeze din cauza problemelor cu încărcarea cache-ului. - aplicarea readiness probe pe un port separat poate duce la faptul că supraîncărcarea pe portul principal nu va fi reflectată în health check (adică pool-ul de fire pe server este plin, totuși health check-ul arată că totul este OK).
- utilizând porturi pentru nevoi administrative, denumite „admin” sau „management” (de exemplu, 9090), pentru
- Asigurați-vă că readiness probe include inițializarea/migrarea bazei de date;
- cel mai simplu mod de a realiza acest lucru este să apelați la serverul HTTP doar după finalizarea inițializării (de exemplu, migrarea DB cu etc.); adică în loc să schimbați statutul health check-ului, pur și simplu nu porniți serverul web până la finalizarea migrației DB*.
* De asemenea, puteți rula migrarea DB din containerele init externe pod-ului. Rămân un susținător al aplicațiilor autonome, adică acelea în care containerul aplicației știe fără coordonare externă cum să aducă baza de date în stare corespunzătoare.
- cel mai simplu mod de a realiza acest lucru este să apelați la serverul HTTP doar după finalizarea inițializării (de exemplu, migrarea DB cu etc.); adică în loc să schimbați statutul health check-ului, pur și simplu nu porniți serverul web până la finalizarea migrației DB*.
- Windows VPS pentru lucru la distanță
httpGetpentru verificările de readiness prin punctele de verificare tipice (de exemplu,/health). - Înțelegeți parametrii de verificare setați implicit (
interval: 10s,timeout: 1s,successThreshold: 1,failureThreshold: 3):- parametrii implicați în mod implicit înseamnă că pod-ul va deveni not-ready în aproximativ 30 de secunde (3 verificări eșuate ale stării de funcționare).
- Utilizați un port separat pentru «admin» sau «management», dacă tehnologia stack-ului (de exemplu, Java/Spring) permite acest lucru, pentru a separa gestionarea «sănătății» și metricilor de traficul obișnuit:
- dar nu uitați de punctul 2.
- Dacă este necesar, readiness probe poate fi folosit pentru a încălzi/încărca cache-ul și returna codul de stare 503, până când containerul nu se «încălzește»:
- de asemenea, recomand să vă familiarizați cu noua verificare
startupProbe, (am scris despre ea în română — nota trad.).
- de asemenea, recomand să vă familiarizați cu noua verificare
Atenționări
- Nu vă bazați pe dependențe externe (cum ar fi stocările de date) în timpul testelor de readiness/liveness — acest lucru poate duce la eșecuri în cascadă:
- ca exemplu, să luăm un serviciu stateful REST cu 10 pod-uri care depind de o singură bază de date Postgres: când verificarea depinde de o conexiune funcțională la baza de date, toate cele 10 pod-uri pot cădea dacă apare o întârziere în rețea/sistemul de bază de date — de obicei, totul se termină mai rău decât ar putea;
- rețineți că Spring Data verifică de obicei conexiunea cu baza de date*;
* Aceasta este comportamentul implicit al Spring Data Redis (cel puțin așa a fost atunci când am verificat ultima oară), ceea ce a dus la o prăbușire «catastrofală»: când Redis a fost temporar inaccesibil, toate pod-urile „au căzut”.
- «extern» în acest sens poate însemna și alte pod-uri ale aceleași aplicații, adică ideal, verificarea nu ar trebui să depindă de starea altor pod-uri din același cluster pentru a preveni căderile în cascadă:
- rezultatele pot varia pentru aplicații cu stări distribuite (de exemplu, caching în memorie în pod-uri).
- Nu utilizați liveness probe pentru pod-uri (excepțiile sunt cazurile în care sunt cu adevărat necesare și sunteți complet conștient de specificul și consecințele aplicării lor):
- Probe-ul de liveness poate ajuta la recuperarea containerelor «blocate», dar, deoarece aveți control complet asupra aplicației dvs., lucruri precum procesele «blocate» și deadlock-urile, în ideal, nu ar trebui să se întâmple: cea mai bună alternativă este o prăbușire intenționată a aplicației și returnarea acesteia la un stadiu anterior stabil;
- Un eșec al probei de liveness va duce la repornirea containerului, ceea ce ar putea agrava consecințele erorilor legate de încărcare: repornirea containerului va provoca un timp de nefuncționare (cel puțin, timp de pornire a aplicației, să spunem, peste 30 de secunde), provocând noi erori, crescând sarcina asupra altor containere și sporind probabilitatea ca acestea să eșueze, etc.;
- Probe-urile de liveness combinate cu o dependență externă reprezintă cea mai proastă combinație posibilă, riscând eșecuri în cascadă: o întârziere minoră pe partea bazei de date va duce la repornirea tuturor containerelor dvs.!
- Parametrii probelor de liveness și readiness trebuie să fie diferiți:
- poate fi utilizată o probă de liveness cu aceeași verificare de sănătate, dar cu un prag de declanșare mai ridicat (
failureThreshold), de exemplu, atribuirea unui status not-ready după 3 încercări și considerarea că proba de liveness a eșuat după 10 încercări;
- poate fi utilizată o probă de liveness cu aceeași verificare de sănătate, dar cu un prag de declanșare mai ridicat (
- Nu utilizați verificări exec, deoarece acestea sunt legate de probleme cunoscute care duc la apariția proceselor zombie:
- detalii: vezi .
Rezumat
- Utilizați probele de readiness pentru a determina când un pod este pregătit să primească trafic.
- Utilizați probele de liveness doar atunci când sunt cu adevărat necesare.
- Utilizarea incorectă a probelor de readiness/liveness poate duce la o disponibilitate scăzută și la eșecuri în cascada.
Materiale suplimentare pe tema
- ;
- ;
- (vorbește și despre livenessProbe).
Actualizare Nr. 1 din 2019-09-29
: a fost adăugată o notă de subsol.
despre PDB: una dintre problemele probelor de liveness este lipsa coordonării între pod-uri. În Kubernetes există pentru a limita numărul de eșecuri paralele pe care aplicația le poate experimenta, dar verificările nu iau în considerare PDB. În ideal, putem ordona K8s: «Reporneste un pod, dacă verificarea sa eșuează, dar nu le reporni pe toate, pentru a nu agrava situația».
: „Folosțiți sondarea de liveness atunci când știți exact că cel mai bine ar fi să „omorâți” aplicația„(de asemenea, nu vă lăsați dus de val).
Actualizare nr. 2 din 2019-09-29
: am creat o solicitare corespunzătoare () pentru a completa documentația despre sondările de liveness.
P.S. de la traducător
Citiți și în blogul nostru:
- «»;
- «»;
- «».
Sursa: habr.com
