101 Series: Kubernetes Probes
Warum werden Probes benötigt?
Innerhalb eines Kubernetes Clusters hat man typischerweise viele Applikationen gleichzeitig laufen. Alle diese Anwendungen sind meist über HTTP(S)-Traffic von außerhalb des Clusters erreichbar oder verbinden sich untereinander. Als Beispiel für internen Traffic sei an dieser Stelle die Kommunikation zwischen einem Backend und einer Datenbank genannt.
Bei all diesen Applikationen ist es wichtig, dass diese immer korrekt funktionieren. Sollte es einen Fehler geben, so sollte diese Applikation automatisiert neu gestartet werden.
Auch gibt es Anwendungsfälle, bei denen eine Applikation zwar schon läuft, aber noch nicht bereit ist, externen Traffic zu empfangen. Stellt euch hier z. B. eine Datenbank vor, die gerade intern ein Update durchführt. Während dieser Zeit läuft zwar unser Datenbankserver, aber jede Anfrage an diesen würde zu einem Fehler führen.
Für all diese Anwendungsfälle gibt es innerhalb von Kubernetes sogenannte Probes.
Was sind Probes?
Grundlegend handelt es sich bei Probes um eine regelmäßige Überprüfung der entsprechenden Applikation, um zu entscheiden, ob diese korrekt funktioniert oder nicht.
Beispielsweise kann ich damit meine Applikation alle 10 Sekunden überwachen lassen. Sobald dabei ein Fehler festgestellt wird, wird die Applikation neu gestartet.
Innerhalb von Kubernetes unterscheiden wir zwischen drei verschiedenen Probes:
LivenessProbe - Läuft der Container?
Diese Probe überwacht, ob eine Applikation gerade korrekt läuft. Sollte hierbei ein Fehler erkannt werden, so wird die Applikation neu gestartet.
ReadinessProbe - Kann der Container Requests empfangen?
Diese Probe sagt aus, ob eine Applikation auch tatsächlich verwendet werden kann. Nur weil der entsprechende Container läuft, heißt das ja nicht gleichzeitig, dass auch Request empfangen werden dürfen. Ein klassisches Beispiel hierfür haben wir bereits in der Einleitung dieses Beitrages erwähnt: Eine Datenbank läuft, macht intern ein Update und kann daher noch nicht (von außen betrachtet) verwendet werden.
StartupProbe - Sonderfall
Diese Probe wird ausschließlich beim Startvorgang eines Containers aktiv und ersetzt in dieser Zeit die Liveness- und ReadinessProbe. Sie ist nicht immer notwendig und wird in der Regel bei Legacy Applikationen verwendet, bei denen die anderen Probes nicht ausreichend wären.
Als Beispiel sei hier eine Applikation genannt, die unterschiedlich lange Startzeiten aufweist. In diesem Fall könnten wir die initialDelaySeconds
nicht verwenden, da wir dort eine vergleichbar hohe Zeit eintragen müssten. Mit der Verwendung der StartupProbe können wir in solch einem Fall alternativ dafür sorgen, dass die Applikation sehr schnell online gehen kann.
Die Einstellung dafür sollte dann wie folgt gesetzt werden:periodSeconds
* failureThreshold
> Maximal zu erwartende Startzeit der Applikation.
Wie werden Probes konfiguriert?
Egal, welche Probes ihr in euren Containern verwenden wollt, die Einstellungen sind bei allen Probes exakt identisch. Schauen wir uns zunächst einmal eine beispielhafte Readiness Probe an:
apiVersion: v1
kind: Pod
metadata:
name: probe-example
spec:
containers:
- name: probe-example
image: nginx
# Readiness Probe configuration
readinessProbe:
# probe type
httpGet:
path: /
port: 80
scheme: HTTP
# wait X seconds before first check
initialDelaySeconds: 0
# check every X seconds
periodSeconds: 5
# mark as failed after X failed checks
failureThreshold: 3
# mark as success after X checks
successThreshold: 1
# timeout for the probe requests
timeoutSeconds: 1
Die erste Einstellung, die wir für unsere Probes setzen müssen, ist der ProbeType. Hierbei haben wir drei Optionen:
HTTP Probes (httpGet
)
Dieser Typ einer Probe wird mit Abstand am häufigsten eingesetzt. Hierbei führt Kubernetes einen HTTP-Request an die Applikation aus. Der entsprechende Response wird bei HTTP-Status Code >= 200 und < 400 als erfolgreich gewertet.
httpGet:
path: /
port: 80
scheme: HTTP
TCP Probes (tcpSocket
)
Applikationen, die keinen Webtraffic unterstützen, können alternativ mit der TCP Socket Action überwacht werden. Hierbei wird ein TCP-Check gegen den angegebenen Port durchgeführt. Achtung: Dieser Typ sollte nicht bei Webapplikationen verwendet werden. Hierbei könnte es z. B. passieren, dass der Port 80 zwar offen ist, jeder Request an den Webserver aber mit einem HTTP-Status 500 antwortet. In diesem Fall würde unsere Probe keinen Fehler feststellen, da der Port ja offen ist.
tcpSocket:
port: 80
Command Probes (exec
)
Bei diesem Typ wird ein Command (z. B. ein Bash-Script) innerhalb des Containers ausgeführt. Kubernetes wertet diesen als erfolgreich aus, wenn der Exit-Code des Commands 0 ist. Jeder andere Code wird als Fehler gewertet. Diese Probes ist besonders dann sinnvoll, wenn die zu überprüfende Applikation keinen Port geöffnet hat.
exec:
command: /healthcheck.sh
Alle weiteren Einstellungen sind Optional und können bei Bedarf angepasst werden:
initialDelaySeconds (Standard 0) Mit dieser Einstellung kann die Zeit definiert werden, die Kubernetes nach dem Starten des Containers wartet, bis der erste Probe Durchlauf startet. Diese Einstellung ist besonders dann sinnvoll, wenn die Applikation z. B. immer 30 Sekunden zum Starten benötigt.
periodSeconds (Standard 10) In welchem Intervall soll die Probe ausgeführt werden.
failureThreshold (Standard 3) Wie oft darf die Probe fehlschlagen, bis der gesamte Durchlauf als Fehlschlag gewertet werden.
successThreshold (Standard 1) Wie oft muss diese Probe erfolgreich durchlaufen, bis der gesamte Durchlauf als Erfolg gewertet wird
timeoutSeconds (Standard 1) Definiert den Timeout für einen einzelnen Probe Request
Auslesen des Status einer Probe
Um den aktuellen Status der Probes einzusehen, gibt es verschiedene Wege. Für die ReadinessProbe
finden wir den Status direkt bei der Auflistung unserer Pods. In diesem Beispiel sehen wir drei Pods, wobei ein Pod aktuell noch nicht Ready ist:
$ kubectl get po -n probes
NAME READY STATUS RESTARTS AGE
probe-example-6485dcb89d-gj8j2 1/1 Running 0 28s
probe-example-6485dcb89d-kgqlc 1/1 Running 0 28s
probe-example-6485dcb89d-kr8pz 0/1 Running 0 28s
Eine weitere Möglichkeit, den Status der Probes auszulesen, haben wir, indem wir einen Describe auf den gewünschten Pod ausführen. Dabei sehen wir zum einen die aktuelle Konfiguration der Probes, zum anderen – im Fehlerfall – entsprechende Nachrichten in den Events:
$ kubectl describe po -n probes
Name: probe-example-6485dcb89d-gj8j2
Namespace: probes
[ . . . ]
Liveness: http-get http://:80/healthz delay=0s timeout=1s period=5s #success=1 #failure=1
Readiness: http-get http://:80/readiness delay=0s timeout=1s period=5s #success=1 #failure=1
[ . . . ]
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 1s (x5 over 8s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404
Im Falle der LivenessProbe
wird unser Pod entsprechend neu gestartet. Dieses ist auch hier wieder über das Auflisten der Pods (RESTARTS > 0) sowie über die Events sichtbar:
$ kubectl get po -n probes
NAME READY STATUS RESTARTS AGE
probe-example-7bc764c4fb-c2g8h 0/1 CrashLoopBackOff 3 (8s ago) 23s
$ kubectl describe po -n probes probe-example-7bc764c4fb-c2g8h
Name: probe-example-7bc764c4fb-c2g8h
Namespace: probes
[ . . . ]
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 2m44s (x3 over 2m54s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 404
Normal Killing 2m49s (x2 over 2m54s) kubelet Container nginx failed liveness probe, will be restarted
Container Probes - Best Practices
Das Wichtigste bei der Verwendung von Probes ist eine optimale Konfiguration der Applikation. Dazu hat sich ein Standard etabliert, der verwendet werden sollte. Typischerweise verwendet man für die LivenessProbe und die ReadinessProbe eigens implementierte httpGet
Funktionen in der Applikation.
LivenessProbe: /livez
ReadinessProbe: /readyz
Zusätzlich sollten die Einstellungen der Probes auf failureThreshold: 1
geändert sein, sodass Kubernetes unsere Applikation direkt nach dem ersten erkannten Fehler neu startet.
Die Einstellung der initialDelaySeconds
sowie die startupProbe
sollten, wenn möglich, nicht verwendet werden.
Habt ihr noch Fragen oder Feedback zum Thema Probes? Weitere Informationen findet ihr in unserer Kubernetes Einführungsschulung! Ansonsten wendet euch gerne an uns und schreibt uns eine kurze Nachricht oder nutzt den Chat auf unserer Website. Wir freuen uns auf eure Nachrichten.