Liveness-Probes in Kubernetes können gefährlich sein.

Hinweis.: Der Lead Engineer von Zalando, Henning Jacobs, hat immer wieder Probleme bei Benutzern von Kubernetes festgestellt, die das Konzept von Liveness- (und Readiness-) Probes und deren richtige Anwendung nicht verstehen. Daher hat er seine Gedanken in dieser prägnanten Notiz zusammengefasst, die im Laufe der Zeit Teil der K8s-Dokumentation werden wird.

Liveness-Probes in Kubernetes können gefährlich sein.

Zustandsprüfungen, die in Kubernetes als liveness probes bezeichnet werden (d.h. wörtlich „Lebensfähigkeitstests“ — Anmerkung des Übersetzers),können sehr gefährlich sein. Ich empfehle, sie, wo immer möglich, zu vermeiden: Ausnahmen sind nur Fälle, in denen sie tatsächlich notwendig sind und Sie sich der Spezifik und der Konsequenzen ihrer Nutzung vollständig bewusst sind. In diesem Beitrag geht es um Liveness- und Readiness-Prüfungen sowie darum, in welchen Fällen steht und wo es nicht ratsam ist, sie anzuwenden.

Mein Kollege Sandor hat kürzlich auf Twitter die häufigsten Fehler geteilt, die er sieht, einschließlich derjenigen, die mit der Verwendung von Readiness/Liveness Probes verbunden sind:

Liveness-Probes in Kubernetes können gefährlich sein.

Eine falsch konfigurierte livenessProbe kann die Situation bei hoher Last (lawinenartige Ausfälle + potenziell langsamer Container-/Anwendungsstart) verschärfen und zu weiteren negativen Folgen wie dem Absturz von Abhängigkeiten führen. (siehe auch meinen kürzlich veröffentlichten Artikel über die Begrenzung der Anfragen in der Kombination K3s+ACME). Es wird noch schlimmer, wenn die Liveness-Probe mit einem Health Check kombiniert wird, für den eine externe Datenbank zuständig ist: ein einziger DB-Ausfall wird alle Ihre Container neu starten!

Die Hauptaussage „Verwenden Sie keine Liveness-Probes“ hilft in diesem Fall wenig, deshalb schauen wir uns an, wofür Readiness- und Liveness-Checks gedacht sind.

Hinweis: Der Großteil des folgenden Tests war ursprünglich Teil der internen Dokumentation für Entwickler von Zalando.

Readiness- und Liveness-Checks

Kubernetes bietet zwei wichtige Mechanismen, die genannt werden Liveness-Probes und Readiness-Probes. Sie führen regelmäßig eine bestimmte Aktion aus – beispielsweise senden sie eine HTTP-Anfrage, öffnen eine TCP-Verbindung oder führen einen Befehl im Container aus –, um zu bestätigen, dass die Anwendung ordnungsgemäß funktioniert.

Kubernetes nutzt ein Readiness-Probes, um zu verstehen, wann der Container bereit ist, Verkehr zu empfangen. Ein Pod wird als betriebsbereit angesehen, wenn alle seine Container bereit sind. Eine der Anwendungen dieses Mechanismus besteht darin, zu steuern, welche Pods als Backends für Kubernetes-Dienste (insbesondere Ingress) verwendet werden.

Lebenszeichenprüfungen helfen Kubernetes zu erkennen, wann es Zeit ist, den Container neu zu starten. Eine solche Prüfung kann einen Deadlock abfangen, wenn die Anwendung an einer Stelle „feststeckt“. Der Neustart des Containers in einem solchen Zustand hilft, die Anwendung trotz der Fehler in Bewegung zu bringen, kann jedoch auch zu kaskadierenden Fehlern führen (siehe unten).

Wenn Sie versuchen, ein Update der Anwendung bereitzustellen, das die Lebenszeichen-/Bereitschaftsprüfungen nicht besteht, wird die Bereitstellung stoppt, da Kubernetes auf den Status Bereit aller Pods wartet.

Beispiel

Hier ist ein Beispiel für eine Bereitschaftsprüfung, die den Pfad /health über HTTP mit den Standardeinstellungen überprüft (interval: 10 Sekunden, timeout: 1 Sekunde, Erfolgsschwelle: 1, Fehlschlagschwelle: 3):

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

Empfehlungen

  1. Für Microservices mit HTTP-Endpunkt (REST usw.) definieren Sie immer eine Bereitschaftsprüfung, die überprüft, ob die Anwendung (Pod) bereit ist, Verkehr zu empfangen.
  2. Stellen Sie sicher, dass die Bereitschaftsprüfung deckt die Verfügbarkeit des tatsächlichen Webserver-Ports ab:
    • verwendet Ports für administrative Zwecke, die als „admin“ oder „management“ bezeichnet werden (z. B. 9090), um readinessProbe, stellen Sie sicher, dass der Endpoint nur dann OK zurückgibt, wenn der Haupt-HTTP-Port (wie 8080) bereit ist, Verkehr zu empfangen*;

      * Mir ist mindestens ein Fall bei Zalando bekannt, in dem dies nicht der Fall war, nämlich readinessProbe der Port „management“ überprüft wurde, der Server jedoch aufgrund von Cache-Ladeproblemen nicht gestartet wurde.

    • Das Anbringen der Readiness-Probe an einem separaten Port kann dazu führen, dass Überlastungen am Hauptport nicht im Health Check reflektiert werden (d. h. der Thread-Pool auf dem Server ist voll, der Health Check zeigt jedoch weiterhin an, dass alles in Ordnung ist).
  3. Stellen Sie sicher, dass die Readiness-Probe die Datenbankinitialisierung/Migration umfasst;
    • der einfachste Weg, dies zu erreichen, besteht darin, den HTTP-Server nur nach Abschluss der Initialisierung anzusprechen (z. B. nach der DB-Migration mit Flyway usw.); das heißt, statt den Status des Health Checks zu ändern, starten Sie einfach den Webserver nicht, bis die DB-Migration abgeschlossen ist*.

      * Es ist auch möglich, Datenbankmigrationen von Init-Containern außerhalb des Pods zu starten. Ich bin nach wie vor ein Befürworter von selbständigen Anwendungen, d.h. solchen, bei denen der Anwendungscontainer ohne externe Koordination weiß, wie er die Datenbank in den gewünschten Zustand versetzt.

  4. Nutzen Sie httpGet für die Readiness-Checks über typische Health-Check-Endpunkte (z. B. /health).
  5. Verstehen Sie die standardmäßig festgelegten Prüfparameter (intervall: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • Die Standardparameter bedeuten, dass der Pod nicht bereit nach etwa 30 Sekunden (3 fehlgeschlagene Health-Checks).
  6. Verwenden Sie einen separaten Port für "Admin" oder "Management", wenn der Technologie-Stack (z. B. Java/Spring) dies zulässt, um das Management von "Gesundheit" und Metriken vom regulären Traffic zu trennen:
    • vergessen Sie jedoch Punkt 2 nicht.
  7. Falls erforderlich, kann die Readiness-Probe verwendet werden, um den Cache aufzuwärmen und den Statuscode 503 zurückzugeben, bis der Container "aufgewärmt" ist:

Warnungen

  1. Verlassen Sie sich nicht auf externe Abhängigkeiten. (wie etwa Datenspeicher) bei Tests zur Bereitschaft/Lebensfähigkeit – dies kann zu kaskadierenden Ausfällen führen:
    • nehmen wir als Beispiel einen stateful REST-Dienst mit 10 Pods, die von einer einzigen Postgres-Datenbank abhängen: Wenn die Prüfung von einer funktionierenden Verbindung zur Datenbank abhängt, können alle 10 Pods ausfallen, wenn es zu einer Verzögerung im Netzwerk / auf Seiten der Datenbank kommt – in der Regel endet dies schlimmer, als es könnte;
    • beachten Sie, dass Spring Data standardmäßig die Verbindung zur Datenbank überprüft*;

      * So verhält sich Spring Data Redis standardmäßig (zumindest war es so, als ich das letzte Mal überprüft habe), was zu einem „katastrophalen“ Ausfall führte: Als Redis kurzzeitig nicht verfügbar war, fielen alle Pods „aus“.

    • „extern“ kann in diesem Sinne auch andere Pods desselben Dienstes bedeuten, das heißt, idealerweise sollte die Überprüfung nicht vom Zustand anderer Pods im selben Cluster abhängen, um kaskadierende Ausfälle zu vermeiden:
      • Die Ergebnisse können für Anwendungen mit verteiltem Zustand (z. B. In-Memory-Caching in Pods) variieren.
  2. Verwenden Sie keine Liveness-Probe für Pods (außer in Fällen, in denen sie wirklich nötig sind und Sie sich der Spezifikationen und Folgen ihrer Anwendung vollständig bewusst sind):
    • Eine Liveness-Prüfung kann dazu beitragen, 'hängende' Container wiederherzustellen, aber da Sie die volle Kontrolle über Ihre Anwendung haben, sollten solche Dinge wie 'hängende' Prozesse und Deadlocks idealerweise nicht auftreten: Die bessere Alternative ist, die Anwendung absichtlich zum Absturz zu bringen und sie in einen vorherigen stabilen Zustand zurückzuführen;
    • Eine fehlgeschlagene Liveness-Prüfung führt zum Neustart des Containers, was potenziell die Konsequenzen von Fehlern im Zusammenhang mit der Last verstärkt: Der Neustart des Containers führt zu Ausfallzeiten (zumindest für die Zeit, die zum Starten der Anwendung benötigt wird, sagen wir mehr als 30 Sekunden), verursacht neue Fehler, erhöht die Last auf andere Container und steigert die Wahrscheinlichkeit ihres Ausfalls usw.;
    • Liveness-Prüfungen in Kombination mit externen Abhängigkeiten sind die schlechteste mögliche Kombination, die mit kaskadierenden Ausfällen droht: Ein kleiner Verzögerung auf der DB-Seite kann dazu führen, dass alle Ihre Container neu gestartet werden!
  3. Die Parameter für Liveness- und Readiness-Prüfungen sollten unterschiedlich sein:
    • Es ist möglich, einen Liveness-Probe mit demselben Health-Check, aber einem höheren Auslöseschwellenwert zu verwenden (failureThreshold), zum Beispiel den Status nach 3 Versuchen festzulegen und zu zählen, dass der Liveness-Probe nach 10 Versuchen fehlschlägt; nicht bereit Verwenden Sie keine Exec-Checks
  4. , da diese bekannte Probleme mit sich bringen, die zu Zombie-Prozessen führen:Details: siehe

Zusammenfassung

  • Verwenden Sie Liveness-Probes nur, wenn sie wirklich erforderlich sind.
  • Falsche Verwendung von Readiness/Liveness-Probes kann zu Verfügbarkeitsproblemen und Kaskadenschäden führen.
  • Zusätzliche Materialien zu diesem Thema

Liveness-Probes in Kubernetes können gefährlich sein.

Kubernetes-Dokumente: Liveness- und Readiness-Probes konfigurieren

Über Init-Container für die Migration der Datenbank

: eine Fußnote hinzugefügt.EJ erinnerte mich

an PDB: eines der Probleme von Liveness-Checks ist das Fehlen der Koordination zwischen Pods. In Kubernetes gibt es Pod Disruption Budgets (PDB) Pod Disruption Budgets (PDB) um die Anzahl der parallel möglichen Ausfälle, die eine Anwendung erleiden kann, zu begrenzen, jedoch berücksichtigen die Überprüfungen nicht das PDB. Idealerweise können wir K8s anweisen: „Starte einen Pod neu, wenn seine Überprüfung fehlschlägt, aber starte sie nicht alle neu, um es nicht noch schlimmer zu machen.“

Bryan hat das hervorragend formuliert: „Verwenden Sie Liveness-Probes, wenn Sie genau wissen, dass das Beste, was man tun kann, darin besteht, die Anwendung zu „töten““ (wiederum sollte man es nicht übertreiben).

Liveness-Probes in Kubernetes können gefährlich sein.

Update Nr. 2 vom 2019-09-29

Bezüglich des Lesens der Dokumentation vor der Verwendung: Ich habe eine entsprechende Anfrage erstellt (Feature-Anfrage) zur Ergänzung der Dokumentation über Liveness-Probes.

P.S. vom Übersetzer

Lesen Sie auch in unserem Blog:

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster