Einführung
Logs, Events, Exec-Befehle und Port-Forwarding helfen Ihnen bei der Untersuchung einer Anwendung. Probes ermöglichen es Kubernetes, die Anwendung kontinuierlich zu überwachen. Eine Readiness-Probe beantwortet die Frage: „Sollte dieser Pod Datenverkehr empfangen?“ Eine Liveness-Probe beantwortet die Frage: „Sollte dieser Container neu gestartet werden?“
In diesem Lab konfigurieren Sie Readiness- und Liveness-Probes separat. Zuerst erstellen Sie eine Anwendung, die erst dann als „Ready“ (bereit) gilt, wenn sie einen /ready-Endpunkt erstellt hat. Anschließend erstellen Sie eine weitere Anwendung mit einer Liveness-Probe, löschen deren Gesundheitsdatei mittels kubectl exec und beobachten, wie Kubernetes den Container neu startet.
Einen Namespace für Probe-Übungen vorbereiten
In diesem Schritt bereiten Sie einen sauberen Namespace für die Übungen mit Probes vor.
Beginnen Sie im Verzeichnis /home/labex/project. Sie werden die Manifeste für die Probes in diesem Verzeichnis speichern.
mkdir -p /home/labex/project
cd /home/labex/project
Überprüfen Sie, ob der Kubernetes API-Server erreichbar ist. Falls die VM gerade erst gestartet wurde und der Node noch nicht bereit ist, warten Sie einige Sekunden und führen Sie den Befehl erneut aus.
kubectl get nodes --request-timeout=5s
Die erwartete Ausgabe sieht in etwa so aus:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Warten Sie, bis der Cluster-Networking-Pod bereit ist. Probes und Services hängen von einem funktionierenden Pod-Netzwerk ab.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Erwartete Ausgabe:
pod/calico-node-... condition met
Erstellen Sie einen Namespace namens ckad-prep-probes und legen Sie diesen als aktuellen Namespace fest:
kubectl create namespace ckad-prep-probes
kubectl config set-context --current --namespace=ckad-prep-probes
Bestätigen Sie den aktuellen Namespace:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Erwartete Ausgabe:
ckad-prep-probes
Eine Readiness-Probe konfigurieren
In diesem Schritt konfigurieren Sie eine Readiness-Probe und beobachten, dass der Service nur bereite Pods verwendet.
Der Container startet sofort einen HTTP-Server, erstellt jedoch erst einige Sekunden später die Datei /www/ready. Die Readiness-Probe prüft GET /ready auf Port 8080. Bis dieser Pfad existiert, kann der Pod zwar den Status „Running“ haben, ist aber nicht „Ready“, und der Service sollte keinen Datenverkehr an ihn senden.
Erstellen Sie readiness-web.yaml:
cat > readiness-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: readiness-web
spec:
replicas: 2
selector:
matchLabels:
app: readiness-web
template:
metadata:
labels:
app: readiness-web
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: busybox:1.36
command:
- /bin/sh
- -c
- |
mkdir -p /www
echo readiness-ok > /www/index.html
(sleep 12; echo ready > /www/ready) &
httpd -f -p 8080 -h /www
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
failureThreshold: 1
---
apiVersion: v1
kind: Service
metadata:
name: readiness-web
spec:
selector:
app: readiness-web
ports:
- port: 80
targetPort: 8080
EOF
Wenden Sie das Manifest an und betrachten Sie die Pods kurz nach der Erstellung:
kubectl apply -f readiness-web.yaml
sleep 3
kubectl get pods -l app=readiness-web
Die erwartete Ausgabe zeigt möglicherweise Pods, die zwar „Running“, aber noch nicht „Ready“ sind:
NAME READY STATUS RESTARTS AGE
readiness-web-... 0/1 Running 0 ...
Warten Sie, bis das Deployment verfügbar ist:
kubectl rollout status deployment/readiness-web --timeout=120s
Erwartete Ausgabe:
deployment "readiness-web" successfully rolled out
Untersuchen Sie die Service-Endpunkte über EndpointSlice. Nachdem die Readiness-Probe erfolgreich war, sollte der Service zwei bereite Endpunkte haben.
kubectl get endpointslice -l kubernetes.io/service-name=readiness-web
Die erwartete Ausgabe enthält:
NAME ADDRESSTYPE PORTS ENDPOINTS
readiness-web-... IPv4 8080 ... + 1 more...
Erstellen Sie einen Client-Pod und testen Sie den Service:
kubectl run probe-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/probe-client --timeout=120s
kubectl exec probe-client -- wget -qO- http://readiness-web
Erwartete Ausgabe:
readiness-ok
Eine Liveness-Probe konfigurieren
In diesem Schritt konfigurieren Sie eine Liveness-Probe, die eine Gesundheitsdatei überprüft.
Eine Liveness-Probe entscheidet, ob Kubernetes einen Container neu starten soll. Dieses Beispiel verwendet eine exec-Probe, die test -f /tmp/healthy innerhalb des Containers ausführt. Der Container erstellt diese Datei beim Start, sodass er anfangs als gesund gilt.
Erstellen Sie liveness-web.yaml:
cat > liveness-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: liveness-web
spec:
replicas: 1
selector:
matchLabels:
app: liveness-web
template:
metadata:
labels:
app: liveness-web
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: busybox:1.36
command:
- /bin/sh
- -c
- |
touch /tmp/healthy
mkdir -p /www
echo liveness-ok > /www/index.html
httpd -f -p 8080 -h /www
ports:
- containerPort: 8080
livenessProbe:
exec:
command:
- test
- -f
- /tmp/healthy
initialDelaySeconds: 3
periodSeconds: 3
failureThreshold: 1
EOF
Wenden Sie das Manifest an und warten Sie auf das Deployment:
kubectl apply -f liveness-web.yaml
kubectl rollout status deployment/liveness-web --timeout=120s
Die erwartete Ausgabe enthält:
deployment.apps/liveness-web created
deployment "liveness-web" successfully rolled out
Speichern Sie den Pod-Namen und bestätigen Sie, dass die Gesundheitsdatei existiert:
LIVE_POD="$(kubectl get pods -l app=liveness-web -o jsonpath='{.items[0].metadata.name}')"
echo "$LIVE_POD"
kubectl exec "$LIVE_POD" -- test -f /tmp/healthy
echo "health file exists"
Die erwartete Ausgabe enthält den Pod-Namen und:
health file exists
Beschreiben Sie den Pod und suchen Sie nach der Konfiguration der Liveness-Probe:
kubectl describe pod "$LIVE_POD" | grep -A3 'Liveness:'
Die erwartete Ausgabe enthält:
Liveness: exec [test -f /tmp/healthy] delay=3s timeout=1s period=3s
Einen Liveness-Neustart auslösen
In diesem Schritt entfernen Sie die Gesundheitsdatei und beobachten, wie die Liveness-Probe den Container neu startet.
Das Pod-Objekt bleibt gleich, während der darin enthaltene Container neu startet. Deshalb beobachten wir den Neustart-Zähler (Restart Count), anstatt einen neuen Pod-Namen zu erwarten.
Speichern Sie den aktuellen Pod-Namen:
LIVE_POD="$(kubectl get pods -l app=liveness-web -o jsonpath='{.items[0].metadata.name}')"
echo "$LIVE_POD"
Entfernen Sie die Gesundheitsdatei aus dem Container:
kubectl exec "$LIVE_POD" -- rm /tmp/healthy
Beobachten Sie den Neustart-Zähler, bis er größer als Null ist. Die Liveness-Probe läuft alle drei Sekunden, daher kann dies einen kurzen Moment dauern.
for i in $(seq 1 20); do
RESTARTS="$(kubectl get pod "$LIVE_POD" -o jsonpath='{.status.containerStatuses[0].restartCount}')"
echo "restart-count=$RESTARTS"
if [ "$RESTARTS" != "0" ]; then
break
fi
sleep 3
done
Die erwartete Ausgabe enthält schließlich:
restart-count=1
Nachdem der Container neu gestartet wurde, erstellt der Startbefehl die Datei /tmp/healthy erneut. Bestätigen Sie, dass die Datei wieder vorhanden ist:
kubectl exec "$LIVE_POD" -- test -f /tmp/healthy
echo "health file recreated"
Erwartete Ausgabe:
health file recreated
Lesen Sie die Pod-Events und suchen Sie nach dem Fehler der Liveness-Probe:
kubectl describe pod "$LIVE_POD" | sed -n '/Events:/,$p'
Die erwartete Ausgabe enthält:
Warning Unhealthy ... Liveness probe failed
Normal Killing ... Container web failed liveness probe
Zusammenfassung
Sie haben beide wichtigen Anwendungs-Probes konfiguriert. Die Readiness-Probe steuerte, wann Pods den Service-Endpunkten beitraten, während die Liveness-Probe einen Container neu startete, nachdem dessen Gesundheitsdatei entfernt wurde. Sie haben außerdem EndpointSlices, Pod-Beschreibungen, Neustart-Zähler und Events untersucht, um die Probe-Konfiguration mit dem sichtbaren Verhalten von Kubernetes zu verknüpfen.


