Anmerkung des Übersetzers.: Der leitende Ingenieur von Zalando – Henning Jacobs – hat wiederholt festgestellt, dass Nutzer von Kubernetes Schwierigkeiten haben, den Zweck von liveness (und readiness) probes und deren angemessene Anwendung zu verstehen. Daher hat er seine Gedanken in dieser knappen Notiz zusammengefasst, die im Laufe der Zeit Teil der K8s-Dokumentation werden wird.

Zustandsprüfungen, die in Kubernetes als liveness probes bezeichnet werden (d.h. wörtlich „Lebensfähigkeitstests“ – Anm. d. Übersetzers),können sehr gefährlich sein. Ich empfehle, sie nach Möglichkeit zu vermeiden: Ausnahmen sind nur Fälle, in denen sie unbedingt notwendig sind und Sie die Spezifikationen sowie die Konsequenzen ihrer Nutzung vollständig verstehen. In dieser Veröffentlichung geht es um liveness- und readiness-Prüfungen und es wird erklärt, wann man steht sie anwenden sollte und wann nicht.
Mein Kollege Sandor hat kürzlich auf Twitter die häufigsten Fehler geteilt, die ihm begegnen, darunter die Verwendung von readiness/liveness probes:
Eine falsch konfigurierte livenessProbe kann Situationen mit hoher Auslastung verschärfen (lawinenartiges Ausschalten + potenziell lange Startzeit des Containers/der Anwendung) und zu anderen negativen Folgen wie dem Ausfall von Abhängigkeiten führen (siehe auch über die Begrenzung der Anzahl von Anfragen im Zusammenspiel von K3s+ACME).Noch schlimmer ist es, wenn eine liveness probe mit einer Gesundheitsprüfung (Health Check) kombiniert wird, bei der es sich um eine externe Datenbank handelt: Ein einzelner DB-Ausfall wird all Ihre Container neu starten.!
Die allgemeine Botschaft „Verwenden Sie keine liveness probes“ hilft in diesem Fall wenig, also betrachten wir, wofür readiness- und liveness-Prüfungen gedacht sind.
Anmerkung: Der größte Teil des folgenden Tests war ursprünglich in der internen Dokumentation für Entwickler von Zalando enthalten.
Readiness- und Liveness-Prüfungen
Kubernetes bietet zwei wichtige Mechanismen, die als bezeichnet werden. Sie führen in regelmäßigen Abständen bestimmte Aktionen aus – zum Beispiel 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 verwendet readiness probes, um zu verstehen, wann der Container bereit ist, Traffic zu empfangen. Ein Pod gilt als bereit, wenn alle seine Container bereit sind. Eine der Anwendungen dieses Mechanismus besteht darin, zu kontrollieren, welche Pods als Backends für Kubernetes-Dienste (insbesondere für Ingress) verwendet werden.
Liveness-Proben helfen Kubernetes zu verstehen, wann es Zeit ist, einen Container neu zu starten. Zum Beispiel ermöglicht diese Prüfung das Abfangen eines Deadlocks, wenn die Anwendung 'feststeckt'. Ein Neustart des Containers in einem solchen Zustand hilft, die Anwendung von einem toten Punkt zu bewegen, trotz der Fehler; jedoch kann dies auch zu kaskadierenden Ausfällen führen (siehe unten).
Wenn Sie versuchen, ein Update der Anwendung bereitzustellen, das die Liveness-/Readiness-Prüfungen nicht besteht, wird die Bereitstellung gestoppt, da Kubernetes auf den Status wartet Bereit von allen Pods.
Beispiel
Hier ist ein Beispiel für eine Readiness-Probe, die den Pfad überprüft /health über HTTP mit Standardkonfigurationen (Intervall: 10 Sekunden, timeout: 1 Sekunde, Erfolgsschwelle: 1, Fehlerschwelle: 3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080Empfehlungen
- Für Mikrodienste mit einem HTTP-Endpunkt (REST usw.) definieren Sie immer eine Readiness-Probe,die überprüft, ob die Anwendung (Pod) bereit ist, Verkehr zu empfangen.
- Stellen Sie sicher, dass die Readiness-Probe die Bereitschaft des tatsächlichen Ports des Webservers abdeckt,:
- indem Sie Ports für administrative Zwecke verwenden, die als 'admin' oder 'management' bezeichnet werden (zum Beispiel 9090), für
readinessProbe, stellen Sie sicher, dass der Endpunkt 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 geschah, das heißt,
readinessProbees wurde der Port 'management' überprüft, aber der Server konnte wegen Problemen beim Laden des Caches nicht starten. - Das Anwenden einer Readiness-Probe auf einen separaten Port kann dazu führen, dass eine Überlastung am Hauptport nicht im Health Check reflektiert wird (das heißt, der Thread-Pool auf dem Server ist gefüllt, aber der Health Check zeigt immer noch, dass alles in Ordnung ist).
- indem Sie Ports für administrative Zwecke verwenden, die als 'admin' oder 'management' bezeichnet werden (zum Beispiel 9090), für
- Stellen Sie sicher, dass Die Readiness-Probe umfasst die Initialisierung/Migration der Datenbank.;
- Der einfachste Weg, dies zu erreichen, besteht darin, erst nach Abschluss der Initialisierung (zum Beispiel der Migration der DB mit usw.) an den HTTP-Server zu appellieren; das heißt, anstatt den Status des Health Checks zu ändern, starten Sie einfach den Webserver nicht, bis die DB-Migration abgeschlossen ist*.
* Migrationen der Datenbank können auch von Init-Containern außerhalb des Pods gestartet werden. Ich bleibe ein Fan von selbstständigen (self-contained) Anwendungen, das heißt solchen, in denen der Anwendung-Container ohne externe Koordination weiß, wie er die DB in den gewünschten Zustand versetzen kann.
- Der einfachste Weg, dies zu erreichen, besteht darin, erst nach Abschluss der Initialisierung (zum Beispiel der Migration der DB mit usw.) an den HTTP-Server zu appellieren; das heißt, anstatt den Status des Health Checks zu ändern, starten Sie einfach den Webserver nicht, bis die DB-Migration abgeschlossen ist*.
- Verwenden Sie
httpGetfür Readiness-Prüfungen durch typische Endpunkte der Health Checks (zum Beispiel,/health). - Machen Sie sich mit den standardmäßig festgelegten Prüfparametern vertraut. (
Intervall: 10s,Timeout: 1s,Erfolgsschwelle: 1,Fehlerschwelle: 3):- Die Standardparameter bedeuten, dass pod wird nicht bereit ungefähr in 30 Sekunden (3 fehlgeschlagene Gesundheitsprüfungen).
- Verwenden Sie einen separaten Port für „admin“ oder „management“, falls der Technologiestack (zum Beispiel Java/Spring) dies zulässt, um die Verwaltung der „Gesundheit“ und Metriken vom normalen Verkehr zu trennen:
- aber vergessen Sie nicht Punkt 2.
- Bei Bedarf kann die Readiness-Prüfung zum Aufwärmen/Laden des Caches verwendet werden und den Statuscode 503 zurückgeben, solange der Container nicht „aufgewärmt“ ist:
- Ich empfehle auch, sich mit der neuen Prüfung vertraut zu machen
startupProbe, (darüber haben wir auf Russisch geschrieben, — Anm. d. Übersetzer).
- Ich empfehle auch, sich mit der neuen Prüfung vertraut zu machen
Vorsichtsmaßnahmen
- Verlassen Sie sich nicht auf externe Abhängigkeiten (wie Datenbanken) bei der Durchführung von Tests zur Readiness/Liveness – dies kann zu kaskadierenden Ausfällen führen:
- Nehmen wir als Beispiel einen zustandsbehafteten REST-Service mit 10 Pods, die von einer einzigen Postgres-Datenbank abhängen: Wenn die Prüfung von einer funktionierenden Verbindung zur DB abhängt, können alle 10 Pods ausfallen, wenn es zu Netzwerk- oder DB-seitigen Verzögerungen kommt – normalerweise endet das alles schlimmer, als es könnte;
- beachten Sie, dass Spring Data standardmäßig die Verbindung zur DB prüft*;
* So verhält sich standardmäßig Spring Data Redis (zumindest war es so, als ich das letzte Mal überprüft habe), was zu einem „katastrophalen“ Ausfall führte: Als Redis kurzfristig nicht verfügbar war, fielen alle Pods „aus“.
- „extern“ bedeutet in diesem Sinne auch andere Pods derselben Anwendung, das heißt, im Idealfall sollte die Prüfung nicht von dem Zustand anderer Pods desselben Clusters abhängen, um kaskadierende Ausfälle zu verhindern:
- Die Ergebnisse können bei Anwendungen mit verteiltem Zustand (zum Beispiel In-Memory-Caching in Pods) variieren.
- Verwenden Sie die Liveness-Prüfung nicht für Pods (Ausnahmen sind die Fälle, in denen sie tatsächlich notwendig sind und Sie sich der Spezifika und Konsequenzen ihrer Anwendung vollständig bewusst sind):
- Die Liveness-Prüfung kann zur Wiederherstellung „eingefrorener“ Container beitragen, aber da Sie die volle Kontrolle über Ihre Anwendung haben, sollte es idealerweise nicht zu Dingen wie „eingefrorenen“ Prozessen und Deadlocks kommen: Eine bessere Alternative ist das absichtliche Abstürzen der Anwendung und das Zurücksetzen auf einen vorherigen stabilen Zustand;
- Ein fehlgeschlagener Liveness-Probe führt zum Neustart des Containers, was potenziell die Auswirkungen von Ladefehlern verschärfen kann: Der Neustart des Containers verursacht Ausfallzeiten (mindestens während der Anlaufzeit der Anwendung, sagen wir, mehr als 30 Sekunden), was zu neuen Fehlern führt, die Last auf andere Container erhöhen und die Wahrscheinlichkeit ihres Ausfalls erhöht usw.;
- Liveness-Checks in Kombination mit externen Abhängigkeiten sind die schlechteste denkbare Kombination, die das Risiko von Kaskadenausfällen birgt: Eine geringfügige Verzögerung auf der DB-Seite führt zum Neustart aller Ihrer Container!
- Die Parameter für Liveness- und Readiness-Checks sollten unterschiedlich sein:
- Man kann einen Liveness-Probe mit demselben Health-Check verwenden, jedoch mit einem höheren Auslöseschwellenwert (
failureThreshold), zum Beispiel den Status nicht bereit nach 3 Versuchen zu setzen und zu berücksichtigen, dass der Liveness-Probe nach 10 Versuchen fehlschlägt;
- Man kann einen Liveness-Probe mit demselben Health-Check verwenden, jedoch mit einem höheren Auslöseschwellenwert (
- Verwenden Sie keine Exec-Checks, da diese bekannte Probleme verursachen, die zur Entstehung von Zombie-Prozessen führen:
- Details: siehe .
Zusammenfassung
- Verwenden Sie Readiness-Probes, um festzustellen, wann ein Pod bereit ist, Traffic zu empfangen.
- Verwenden Sie Liveness-Probes nur, wenn sie wirklich notwendig sind.
- Falsche Verwendung von Readiness/Liveness-Probes kann zu einer Verringerung der Verfügbarkeit und zu Kaskadenausfällen führen.
Zusätzliche Materialien zum Thema
- ;
- ;
- (spricht auch über livenessProbe).
Update Nr. 1 vom 29.09.2019
: Fußnote hinzugefügt.
an die PDB: Ein Problem der Liveness-Checks ist das Fehlen von Koordination zwischen den Pods. In Kubernetes gibt es , um die Anzahl gleichzeitiger Ausfälle zu begrenzen, die eine Anwendung erfahren kann, jedoch berücksichtigen die Checks die PDB nicht. Ideal könnten wir K8s anweisen: 'Starte einen Pod neu, wenn seine Prüfung fehlschlägt, aber starte nicht alle neu, um es nicht schlimmer zu machen.'
: 'Verwenden Sie Liveness-Testing, wenn Sie genau wissen, dass das Beste, was Sie tun können, darin besteht, die Anwendung zu 'töten'' (denken Sie daran, nicht zu übertreiben).
Update Nr. 2 vom 29.09.2019
: Ich habe eine entsprechende Anfrage () zur Ergänzung der Dokumentation über Liveness-Probes erstellt.
P.S. vom Übersetzer
Lesen Sie auch in unserem Blog:
- «»;
- «»;
- «».
Quelle: habr.com
