Einführung
Im vorherigen Lab haben wir uns auf Logs und Events konzentriert. Diese dienen als erste Anhaltspunkte, doch manchmal ist es notwendig, einen laufenden Container direkt zu untersuchen oder einen Service vorübergehend vom eigenen Terminal aus zu erreichen. Kubernetes bietet hierfür zwei gängige Werkzeuge: kubectl exec und kubectl port-forward.
In diesem Lab stellen Sie eine kleine Webanwendung bereit, verwenden kubectl exec, um Dateien und Prozesse innerhalb eines Pods zu prüfen, und nutzen kubectl port-forward, um eine temporäre lokale Verbindung zum Service herzustellen. Der Arbeitsablauf ist bewusst einfach gehalten, damit Sie sich auf die Debugging-Techniken konzentrieren können, anstatt sich mit der Komplexität der Anwendung auseinanderzusetzen.
Einen Namespace für das Debugging vorbereiten
In diesem Schritt bereiten Sie einen sauberen Namespace für die Übungen mit exec und Port-Forwarding vor.
Beginnen Sie im Verzeichnis /home/labex/project. Hier werden Sie das Manifest der Anwendung 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 Pod für das Cluster-Netzwerk den Status "Ready" erreicht hat. Port-Forwarding nutzt die Verbindung zum API-Server, aber die Anwendung benötigt dennoch einen funktionsfähigen Pod und Service.
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-debug und legen Sie diesen als aktuellen Namespace fest:
kubectl create namespace ckad-prep-debug
kubectl config set-context --current --namespace=ckad-prep-debug
Bestätigen Sie den aktuellen Namespace:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Erwartete Ausgabe:
ckad-prep-debug
Eine kleine Webanwendung bereitstellen
In diesem Schritt stellen Sie eine einfache Anwendung bereit, die Sie anschließend untersuchen und auf die Sie zugreifen werden.
Der Pod schreibt eine index.html-Datei und startet BusyBox httpd auf Port 8080. Ein Service namens debug-web macht die Pods innerhalb des Clusters auf Port 80 verfügbar. Der Service ist Teil der Übung, da kubectl port-forward sowohl auf einen Service als auch auf einen Pod zielen kann.
Erstellen Sie die Datei debug-web.yaml:
cat > debug-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: debug-web
spec:
replicas: 2
selector:
matchLabels:
app: debug-web
template:
metadata:
labels:
app: debug-web
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: busybox:1.36
command:
- /bin/sh
- -c
- |
mkdir -p /www
echo "debug-web-ready" > /www/index.html
httpd -f -p 8080 -h /www
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: debug-web
spec:
selector:
app: debug-web
ports:
- port: 80
targetPort: 8080
EOF
Wenden Sie das Manifest an und warten Sie auf das Deployment:
kubectl apply -f debug-web.yaml
kubectl rollout status deployment/debug-web --timeout=120s
Die erwartete Ausgabe enthält:
deployment.apps/debug-web created
service/debug-web created
deployment "debug-web" successfully rolled out
Überprüfen Sie die Pods und den Service:
kubectl get pods -l app=debug-web
kubectl get service debug-web
Die erwartete Ausgabe zeigt zwei laufende Pods und einen ClusterIP-Service:
debug-web-... 1/1 Running
debug-web ClusterIP
Einen laufenden Container mit exec untersuchen
In diesem Schritt verwenden Sie kubectl exec, um Befehle innerhalb eines Anwendungs-Pods auszuführen.
kubectl exec ist nützlich, wenn der Pod zwar läuft, Sie aber prüfen müssen, was der Container "sieht". Es ist kein Ersatz für Logs und sollte nicht dazu verwendet werden, während des normalen Betriebs manuelle Änderungen vorzunehmen. In einem Debugging-Workflow hilft es Ihnen, Dateien, Prozesse, Umgebungsvariablen und das lokale Netzwerkverhalten aus der Sicht des Containers zu verifizieren.
Speichern Sie den Namen eines Pods in einer Shell-Variablen:
POD_NAME="$(kubectl get pods -l app=debug-web -o jsonpath='{.items[0].metadata.name}')"
echo "$POD_NAME"
Die erwartete Ausgabe ist ein Pod-Name:
debug-web-...
Führen Sie hostname innerhalb des Containers aus. Die Ausgabe sollte dem Pod-Namen entsprechen, da Kubernetes den Hostnamen des Containers auf Basis des Pod-Namens setzt.
kubectl exec "$POD_NAME" -- hostname
Erwartete Ausgabe:
debug-web-...
Listen Sie die laufenden Prozesse innerhalb des Containers auf:
kubectl exec "$POD_NAME" -- ps
Die erwartete Ausgabe enthält den httpd-Prozess:
PID USER TIME COMMAND
... root ... httpd -f -p 8080 -h /www
Lesen Sie die Datei, die vom Webserver bereitgestellt wird:
kubectl exec "$POD_NAME" -- cat /www/index.html
Erwartete Ausgabe:
debug-web-ready
Testen Sie abschließend den Webserver von innerhalb desselben Containers:
kubectl exec "$POD_NAME" -- wget -qO- http://127.0.0.1:8080
Erwartete Ausgabe:
debug-web-ready
Den Service mit Port Forwarding testen
In diesem Schritt verwenden Sie kubectl port-forward, um vom Terminal aus auf den Service zuzugreifen.
Port-Forwarding erstellt einen temporären Tunnel von einem lokalen Port zu einem Pod oder Service im Cluster. Dies ist für schnelles Debugging nützlich, da keine Änderung des Service-Typs, kein Ingress und keine Öffnung für externen Zugriff erforderlich ist. Ein im Vordergrund laufender kubectl port-forward-Befehl bleibt aktiv, bis Sie ihn beenden. Daher starten wir ihn in diesem Lab im Hintergrund, testen ihn und beenden ihn anschließend wieder.
Starten Sie ein Port-Forwarding vom lokalen Port 18080 zum Service-Port 80. Die Ausgabe wird in /tmp/debug-web-port-forward.log geschrieben, damit das Terminal weiterhin nutzbar bleibt.
kubectl port-forward service/debug-web 18080:80 > /tmp/debug-web-port-forward.log 2>&1 &
PF_PID=$!
sleep 3
cat /tmp/debug-web-port-forward.log
Die erwartete Ausgabe enthält:
Forwarding from 127.0.0.1:18080 -> 8080
Senden Sie eine Anfrage über den lokalen weitergeleiteten Port:
wget -qO- http://127.0.0.1:18080
Erwartete Ausgabe:
debug-web-ready
Beenden Sie den Hintergrundprozess des Port-Forwardings. Diese Bereinigung ist wichtig, da der lokale Port sonst belegt bliebe.
kill "$PF_PID"
wait "$PF_PID" 2>/dev/null || true
Bestätigen Sie, dass das Port-Forwarding-Log eine verarbeitete Verbindung aufgezeichnet hat:
cat /tmp/debug-web-port-forward.log
Die erwartete Ausgabe enthält:
Handling connection for 18080
Zusammenfassung
Sie haben zwei praktische Debugging-Werkzeuge kennengelernt. Sie haben kubectl exec verwendet, um den Hostnamen, die Prozesse, Dateien und die lokale HTTP-Antwort eines laufenden Containers zu untersuchen. Zudem haben Sie kubectl port-forward genutzt, um eine temporäre lokale Verbindung zu einem ClusterIP-Service herzustellen, diese vom Terminal aus getestet und den Hintergrundprozess sauber beendet.


