Probe de liveness în Kubernetes pot fi periculoase

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 de liveness în Kubernetes pot fi periculoase

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:

Probe de liveness în Kubernetes pot fi periculoase

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 articolul meu recent 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 liveness probes și readiness probes. 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: 8080

Recomandări

  1. Pentru microservicii cu endpoint HTTP (REST etc.) definiți întotdeauna readiness probe, care verifică dacă aplicația (pod) este gata să primească trafic.
  2. 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ă readinessProbe a 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).
  3. 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 Flyway 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.

  4. Windows VPS pentru lucru la distanță httpGet pentru verificările de readiness prin punctele de verificare tipice (de exemplu, /health).
  5. Î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).
  6. 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.
  7. 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, apărută în versiunea 1.16 (am scris despre ea în română aici — nota trad.).

Atenționări

  1. 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).
  2. 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.!
  3. 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;
  4. Nu utilizați verificări exec, deoarece acestea sunt legate de probleme cunoscute care duc la apariția proceselor zombie:

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.

Probe de liveness în Kubernetes pot fi periculoase

Materiale suplimentare pe tema

Actualizare Nr. 1 din 2019-09-29

Despre init-containere pentru migrarea bazelor de date: a fost adăugată o notă de subsol.

EJ mi-a amintit despre PDB: una dintre problemele probelor de liveness este lipsa coordonării între pod-uri. În Kubernetes există Pod Disruption Budgets (PDB) 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».

Bryan a formulat excelent: „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).

Probe de liveness în Kubernetes pot fi periculoase

Actualizare nr. 2 din 2019-09-29

În legătură cu citirea documentației înainte de utilizare: am creat o solicitare corespunzătoare (cererea de caracteristici) 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

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster