Liveness-sondes in Kubernetes kunnen gevaarlijk zijn

Opmerking. vert.: Hoofdingenieur van Zalando, Henning Jacobs, heeft herhaaldelijk problemen opgemerkt onder Kubernetes-gebruikers bij het begrijpen van het doel van liveness (en readiness) probes en het juiste gebruik ervan. Daarom verzamelde hij zijn gedachten in deze ruime notitie, die uiteindelijk onderdeel zal worden van de K8s-documentatie.

Liveness-sondes in Kubernetes kunnen gevaarlijk zijn

Healthchecks, in Kubernetes bekend als levendigheidssondes (d.w.z. letterlijk ‘levensvatbaarheidstests’ - ca. vert.), kan behoorlijk gevaarlijk zijn. Ik raad aan om ze indien mogelijk te vermijden: de enige uitzonderingen zijn wanneer ze echt nodig zijn en je je volledig bewust bent van de details en gevolgen van het gebruik ervan. In deze publicatie wordt gesproken over liveness- en paraatheidscontroles, en wordt ook aangegeven in welke gevallen is en je mag ze niet gebruiken.

Mijn collega Sandor deelde onlangs op Twitter de meest voorkomende fouten die hij tegenkomt, inclusief fouten die verband houden met het gebruik van gereedheids-/levendigheidssondes:

Liveness-sondes in Kubernetes kunnen gevaarlijk zijn

Verkeerd geconfigureerd livenessProbe kan situaties met hoge belasting verergeren (sneeuwbaluitschakeling + mogelijk lange opstarttijd van container/applicatie) en tot andere negatieve gevolgen leiden, zoals afname van de afhankelijkheid (zie ook mijn recente artikel over het beperken van het aantal verzoeken in de combinatie K3s+ACME). Het is zelfs nog erger als de liveness-sonde wordt gecombineerd met een gezondheidscontrole, wat een externe database is: een enkele DB-fout zal al uw containers opnieuw opstarten!

Algemeen bericht "Gebruik geen liveness-sondes" in dit geval helpt het niet veel, dus laten we eens kijken waar de gereedheids- en liveheidscontroles voor dienen.

Opmerking: het grootste deel van de onderstaande test was oorspronkelijk opgenomen in de interne ontwikkelaarsdocumentatie van Zalando.

Gereedheids- en liveheidscontroles

Kubernetes biedt twee belangrijke mechanismen genaamd liveness-sondes en gereedheidssondes. Ze voeren periodiek een bepaalde actie uit, zoals het verzenden van een HTTP-verzoek, het openen van een TCP-verbinding of het uitvoeren van een opdracht in de container, om te bevestigen dat de applicatie werkt zoals verwacht.

Kubernetes gebruikt gereedheidssondesom te begrijpen wanneer de container klaar is om verkeer te accepteren. Een pod wordt als gereed voor gebruik beschouwd als alle containers gereed zijn. Eén gebruik van dit mechanisme is om te bepalen welke pods worden gebruikt als backends voor Kubernetes-services (en vooral Ingress).

Levendigheidssondes help Kubernetes te begrijpen wanneer het tijd is om de container opnieuw op te starten. Met zo’n controle kun je bijvoorbeeld een impasse onderscheppen wanneer een applicatie op één plek vastloopt. Het opnieuw opstarten van de container in deze status helpt de applicatie ondanks fouten van de grond te krijgen, maar kan ook leiden tot opeenvolgende fouten (zie hieronder).

Als u probeert een applicatie-update te implementeren die de liveness/gereedheidscontroles niet doorstaat, wordt de uitrol ervan stopgezet terwijl Kubernetes wacht op de status Ready uit alle peulen.

Voorbeeld

Hier is een voorbeeld van een gereedheidstest die een pad controleert /health via HTTP met standaardinstellingen (interval: 10 seconden, time-out: 1 seconde, succesdrempel: 1, drempel voor falen: 3):

# часть общего описания deployment'а/стека
podTemplate:
  spec:
    containers:
    - name: my-container
      # ...
      readinessProbe:
        httpGet:
          path: /health
          port: 8080

Aanbevelingen

  1. Voor microservices met HTTP-eindpunt (REST, etc.) definieer altijd een gereedheidstest, die controleert of de applicatie (pod) gereed is om verkeer te accepteren.
  2. Zorg ervoor dat de gereedheidssonde aanwezig is dekt de beschikbaarheid van de daadwerkelijke webserverpoort:
    • het gebruik van poorten voor administratieve doeleinden, genaamd "admin" of "management" (bijvoorbeeld 9090), voor readinessProbezorg ervoor dat het eindpunt alleen OK retourneert als de primaire HTTP-poort (zoals 8080) gereed is om verkeer te accepteren*;

      *Ik ben op de hoogte van minstens één geval bij Zalando waarbij dit niet gebeurde, namelijk: readinessProbe Ik controleerde de “beheer”-poort, maar de server zelf begon niet te werken vanwege problemen met het laden van de cache.

    • het aansluiten van een gereedheidstest op een afzonderlijke poort kan ertoe leiden dat overbelasting op de hoofdpoort niet tot uiting komt in de statuscontrole (dat wil zeggen dat de threadpool op de server vol is, maar de statuscontrole laat nog steeds zien dat alles in orde is ).
  3. Zeker weten dat Gereedheidstest maakt initialisatie/migratie van de database mogelijk;
    • De eenvoudigste manier om dit te bereiken is door pas contact op te nemen met de HTTP-server nadat de initialisatie is voltooid (bijvoorbeeld door een database te migreren van vliegroute enzovoort.); dat wil zeggen dat u, in plaats van de status van de statuscontrole te wijzigen, de webserver eenvoudigweg niet kunt starten totdat de databasemigratie is voltooid*.

      * U kunt ook databasemigraties uitvoeren vanuit init-containers buiten de pod. Ik ben nog steeds een fan van op zichzelf staande applicaties, dat wil zeggen applicaties waarin de applicatiecontainer weet hoe hij de database in de gewenste staat moet brengen zonder externe coördinatie.

  4. Gebruiken httpGet voor gereedheidscontroles via typische eindpunten voor gezondheidscontroles (bijvoorbeeld /health).
  5. Begrijp de standaardcontroleparameters (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • de standaardopties betekenen dat de pod wordt Niet klaar na ongeveer 30 seconden (3 mislukte sanitaire controles).
  6. Gebruik een aparte poort voor "admin" of "management" als de technologiestack (bijvoorbeeld Java/Spring) dit toestaat, om het beheer van de gezondheid en de statistieken te scheiden van het reguliere verkeer:
    • maar vergeet punt 2 niet.
  7. Indien nodig kan de gereedheidstest worden gebruikt om de cache op te warmen/laden en een 503-statuscode te retourneren totdat de container is opgewarmd:
    • Ik raad u ook aan de nieuwe cheque te lezen startupProbe, verscheen in versie 1.16 (we schreven erover in het Russisch hier — ca. vert.).

waarschuwingen

  1. Vertrouw niet op externe afhankelijkheden (zoals datawarehouses) bij het uitvoeren van gereedheids-/levendigheidstests - dit kan leiden tot opeenvolgende fouten:
    • Laten we als voorbeeld een stateful REST-service nemen met 10 pods, afhankelijk van één Postgres-database: wanneer de controle afhankelijk is van een werkende verbinding met de DB, kunnen alle 10 pods mislukken als er een vertraging is aan de netwerk-/DB-kant - meestal is dit het geval alles eindigt erger dan het zou kunnen;
    • Houd er rekening mee dat Spring Data standaard de databaseverbinding controleert*;

      * Dit is het standaardgedrag van Spring Data Redis (althans, dit was de laatste keer dat ik het controleerde), wat leidde tot een "catastrofale" fout: toen Redis een korte tijd niet beschikbaar was, "crashten" alle pods.

    • 'extern' in deze zin kan ook andere pods van dezelfde applicatie betekenen, dat wil zeggen dat de controle idealiter niet afhankelijk zou moeten zijn van de status van andere pods van hetzelfde cluster om trapsgewijze crashes te voorkomen:
      • de resultaten kunnen variëren voor toepassingen met een gedistribueerde status (bijvoorbeeld caching in het geheugen in peulen).
  2. Gebruik geen liveness-sonde voor pods (uitzonderingen zijn gevallen waarin ze echt nodig zijn en u zich volledig bewust bent van de bijzonderheden en gevolgen van het gebruik ervan):
    • Een liveness probe kan helpen vastgelopen containers te herstellen, maar aangezien u volledige controle over uw applicatie heeft, zouden zaken als vastgelopen processen en impasses idealiter niet moeten voorkomen: het beste alternatief is om de applicatie opzettelijk te laten crashen en terug te brengen naar de vorige stabiele status;
    • een mislukte liveness-sonde zal ervoor zorgen dat de container opnieuw opstart, waardoor de gevolgen van laadgerelateerde fouten mogelijk worden verergerd: het opnieuw opstarten van de container zal resulteren in downtime (tenminste voor de duur van het opstarten van de applicatie, bijvoorbeeld 30 seconden), waardoor nieuwe fouten ontstaan , het vergroten van de belasting van andere containers en het vergroten van de kans op falen ervan, enz.;
    • liveness checks in combinatie met een externe afhankelijkheid zijn de slechtst mogelijke combinatie, waardoor trapsgewijze mislukkingen dreigen: een kleine vertraging aan de databasekant zal leiden tot een herstart van al uw containers!
  3. Parameters van liveness- en gereedheidscontroles moet anders zijn:
    • u kunt een liveness-sonde gebruiken met dezelfde statuscheck, maar met een hogere responsdrempel (failureThreshold), wijs bijvoorbeeld de status toe Niet klaar na 3 pogingen en van mening zijn dat de liveness-sonde na 10 pogingen is mislukt;
  4. Gebruik geen exec-controles, omdat ze verband houden met bekende problemen die leiden tot het verschijnen van zombieprocessen:

Beknopt

  • Gebruik gereedheids tests om te bepalen wanneer een pod gereed is om verkeer te ontvangen.
  • Gebruik liveness-sondes alleen als ze echt nodig zijn.
  • Onjuist gebruik van gereedheids-/levendigheidssondes kan leiden tot verminderde beschikbaarheid en trapsgewijze fouten.

Liveness-sondes in Kubernetes kunnen gevaarlijk zijn

Aanvullende materialen over het onderwerp

Update nr. 1 van 2019-09-29

Over init-containers voor databasemigratie: Voetnoot toegevoegd.

EJ herinnerde me eraan over het VOB: een van de problemen met controles op de levendigheid is het gebrek aan coördinatie tussen de peulen. Kubernetes heeft dat wel Budgetten voor verstoring van pods (VOB) om het aantal gelijktijdige fouten die een applicatie kan ervaren te beperken, maar bij de controles wordt geen rekening gehouden met de PDB. Idealiter zouden we K8s kunnen vertellen: "Start één pod opnieuw op als de test mislukt, maar start ze niet allemaal opnieuw op om te voorkomen dat de zaken nog erger worden."

Bryan verwoordde het perfect: “Gebruik liveness-sondering als je precies weet wat het beste wat u kunt doen, is de toepassing beëindigen"(nogmaals, laat je niet meeslepen).

Liveness-sondes in Kubernetes kunnen gevaarlijk zijn

Update nr. 2 van 2019-09-29

Wat betreft het lezen van de documentatie vóór gebruik: Ik heb het bijbehorende verzoek gemaakt (functieverzoek) om documentatie over liveness-sondes toe te voegen.

PS van vertaler

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie