Fehlerbehebung bei Kubernetes-Konnektivität: Effektive Nutzung von exec und port-forward
Beheben Sie Kubernetes-Konnektivitäts- und interne Anwendungsprobleme mit Zuversicht. Dieser Leitfaden bietet praktische Beispiele zur Verwendung von `kubectl exec` zum Ausführen von Befehlen in Containern und `kubectl port-forward` zum sicheren Zugriff auf Dienste von Ihrem lokalen Rechner. Lernen Sie, Netzwerkprobleme zu diagnostizieren, Konfigurationen zu überprüfen und tiefe Einblicke in das Verhalten Ihrer Anwendung im Cluster zu gewinnen.
Fehlerbehebung bei Kubernetes-Konnektivität: Effektive Nutzung von exec und port-forward
Wenn ein Kubernetes-Dienst eine Zeitüberschreitung aufweist, müssen Sie normalerweise eine einfache Frage beantworten, bevor Sie etwas reparieren können: Wo hört die Verbindung auf zu funktionieren? kubectl exec ermöglicht es Ihnen, von innerhalb des Clusters, nahe der Anwendung, zu testen. kubectl port-forward ermöglicht es Ihnen, einen Pod oder Dienst auf Ihren Laptop zu bringen, ohne einen Ingress, LoadBalancer, eine Firewall-Regel oder einen DNS-Eintrag zu ändern.
Zusammen verwendet, helfen Ihnen diese beiden Befehle, das Rätselraten zu vermeiden. Sie können testen, ob die App lauscht, ob der Cluster-DNS funktioniert, ob ein Dienst auf die richtigen Pods verweist und ob das Problem im Kubernetes-Netzwerk oder in der Anwendung selbst liegt.
Grundlegendes zu kubectl exec
Der Befehl kubectl exec ermöglicht es Ihnen, Befehle in einem laufenden Container innerhalb eines Pods auszuführen. Dies ist äußerst nützlich, um Logs zu überprüfen, Konfigurationen zu prüfen und Diagnosetools direkt dort auszuführen, wo Ihre Anwendung lebt.
Verwenden Sie es in der Produktion mit Vorsicht. Sie führen einen Befehl in einem echten Workload-Container aus. Ein harmloses env, cat, curl oder ss ist normal. Das Installieren von Paketen, das Ändern von Dateien oder das Ausführen teurer Diagnosen in einem Live-Pod kann das ursprüngliche Problem verbergen oder ein neues schaffen.
Grundlegende Syntax
Die grundlegende Syntax für kubectl exec lautet:
kubectl exec <pod-name> -- <command> [args...]
<pod-name>: Der Name des Pods, in dem Sie einen Befehl ausführen möchten.--: Dieser Trenner ist entscheidend. Er unterscheidet zwischenkubectl-Flags und dem Befehl, den Sie im Container ausführen möchten.<command>: Der Befehl, der im Container ausgeführt werden soll (z.B.ls,cat,ping).[args...]: Alle Argumente für den Befehl.
Interaktiver Shell-Zugriff
Eine der häufigsten Verwendungen von kubectl exec ist der Zugriff auf eine interaktive Shell (wie bash oder sh) in einem Container. Dies ermöglicht es Ihnen, das Dateisystem des Containers zu erkunden und mehrere Befehle auszuführen.
Um eine interaktive Shell zu erhalten:
kubectl exec -it <pod-name> -- /bin/bash
-i(oder--stdin): Hält stdin offen, auch wenn nicht verbunden.-t(oder--tty): Weist ein Pseudo-TTY zu, das für interaktive Shell-Sitzungen erforderlich ist.
Beispiel: Zugriff auf eine Bash-Shell in einem Pod namens my-app-pod:
kubectl exec -it my-app-pod -- /bin/bash
Sobald Sie drin sind, können Sie Standard-Linux-Befehle verwenden. Um die Shell zu verlassen, geben Sie exit ein oder drücken Sie Strg+D. Wenn /bin/bash nicht vorhanden ist, versuchen Sie /bin/sh; viele kleine Images werden nicht mit Bash ausgeliefert.
Ausführen eines einzelnen Befehls
Sie können auch einen einzelnen Befehl ohne interaktive Shell ausführen. Dies ist nützlich für schnelle Überprüfungen oder Skripting.
Beispiel: Überprüfen von Dateien im /app-Verzeichnis von my-app-pod:
kubectl exec my-app-pod -- ls /app
Beispiel: Anzeigen des Inhalts einer Konfigurationsdatei config.yaml:
kubectl exec my-app-pod -- cat /etc/my-app/config.yaml
Angeben eines Containers innerhalb eines Pods
Wenn Ihr Pod mehrere Container hat, müssen Sie mit dem Flag -c angeben, in welchem Container der Befehl ausgeführt werden soll.
kubectl exec <pod-name> -c <container-name> -- <command>
Beispiel: Ausführen von env im sidecar-container von multi-container-pod:
kubectl exec multi-container-pod -c sidecar-container -- env
Grundlegendes zu kubectl port-forward
Der Befehl kubectl port-forward ermöglicht es Ihnen, einen sicheren Tunnel von Ihrem lokalen Rechner zu einem bestimmten Pod oder Dienst in Ihrem Kubernetes-Cluster einzurichten. Dies ist unschätzbar wertvoll für das Debuggen von Anwendungen, die nicht extern verfügbar sind, den Zugriff auf Datenbanken oder das Testen interner APIs.
Es ist kein Produktionsverkehrspfad. Es ist ein Debugging-Tunnel über Ihre Kubernetes-API-Verbindung. Wenn die API-Server-Verbindung abbricht, bricht auch Ihr lokaler Tunnel ab.
Grundlegende Syntax
Die allgemeine Syntax lautet:
kubectl port-forward <pod-name> <local-port>:<remote-port>
<pod-name>: Der Name des Pods, mit dem Sie eine Verbindung herstellen möchten.<local-port>: Der Port auf Ihrem lokalen Rechner, der auf Verbindungen lauscht.<remote-port>: Der Port auf dem Pod, der den weitergeleiteten Datenverkehr empfängt.
Beispiel: Weiterleitung von lokalem Port 8080 an Port 80 von my-app-pod:
kubectl port-forward my-app-pod 8080:80
Sobald dieser Befehl ausgeführt wird, können Sie auf Ihre Anwendung zugreifen, indem Sie in Ihrem Webbrowser zu http://localhost:8080 navigieren oder Tools wie curl auf Ihrem lokalen Rechner verwenden.
Weiterleitung an einen Dienst
Sie können Datenverkehr auch an einen Kubernetes-Dienst statt an einen bestimmten Pod weiterleiten. kubectl wählt automatisch einen Pod aus, der diesen Dienst unterstützt.
kubectl port-forward service/<service-name> <local-port>:<service-port>
Beispiel: Weiterleitung von lokalem Port 3000 an Port 80 des Dienstes my-service:
kubectl port-forward service/my-service 3000:80
Beim Weiterleiten an einen Dienst denken Sie daran, dass kubectl einen unterstützenden Pod auswählt. Wenn nur ein Replikat defekt ist, kann die Weiterleitung auf Dienstebene es übersehen. Zum Beispiel kann ein Deployment mit drei Pods zwei gesunde Pods und einen Pod mit einer fehlerhaften Konfiguration haben. Die Weiterleitung an service/my-service könnte einen gesunden Pod auswählen und den Dienst intakt erscheinen lassen. Wenn Sie ein replikatspezifisches Problem vermuten, leiten Sie an den genauen Pod-Namen weiter.
Weiterleitung an Deployments oder StatefulSets
Ähnlich können Sie an Deployments oder StatefulSets weiterleiten. kubectl wählt einen der Pods aus, die von der angegebenen Ressource verwaltet werden.
kubectl port-forward deployment/<deployment-name> <local-port>:<container-port>
kubectl port-forward statefulset/<statefulset-name> <local-port>:<container-port>
Bindung an eine bestimmte Adresse
Standardmäßig bindet port-forward an localhost. Sie können mit dem Flag --address eine andere lokale Adresse angeben.
kubectl port-forward --address 127.0.0.1 <pod-name> <local-port>:<remote-port>
Mehrere Port-Weiterleitungen
kubectl port-forward kann mehrere Ports gleichzeitig weiterleiten.
kubectl port-forward my-app-pod 8080:80 9090:90
Dieser Befehl leitet den lokalen Port 8080 an den Pod-Port 80 und den lokalen Port 9090 an den Pod-Port 90 weiter.
Häufige Fehlerbehebungsszenarien und Lösungen
Szenario 1: Anwendung reagiert nicht, aber Pod scheint gesund.
- Problem: Der Pod läuft, aber Anfragen an seinen Dienst schlagen fehl oder haben eine Zeitüberschreitung. Die Anwendung könnte interne Konfigurationsprobleme haben oder hängen.
- Lösung mit
kubectl exec:- Holen Sie sich eine interaktive Shell in den Pod:
kubectl exec -it <pod-name> -- /bin/bash - Überprüfen Sie in der Shell die Anwendungslogs (z.B.
tail -f /var/log/myapp.log). - Überprüfen Sie die internen Konfigurationsdateien der Anwendung.
- Überprüfen Sie die Netzwerkkonnektivität vom Pod zu anderen Diensten mit
pingodercurl(falls installiert).
- Holen Sie sich eine interaktive Shell in den Pod:
- Lösung mit
kubectl port-forward:- Leiten Sie einen Port an den Lauschport der Anwendung weiter:
kubectl port-forward <pod-name> 8080:<app-port> - Versuchen Sie, lokal über
http://localhost:8080auf die Anwendung zuzugreifen. Dies hilft festzustellen, ob das Problem bei der Kubernetes-Dienstermittlung oder dem Ingress liegt oder ob die Anwendung selbst nicht antwortet.
- Leiten Sie einen Port an den Lauschport der Anwendung weiter:
Wenn die Port-Weiterleitung funktioniert, aber die normale Dienst-URL fehlschlägt, überprüfen Sie den Dienst-Selektor und die Endpunkte:
kubectl get service <service-name> -n <namespace> -o yaml
kubectl get endpoints <service-name> -n <namespace>
kubectl get pods -n <namespace> --show-labels
Ein sehr häufiger Fehler ist ein Label-Mismatch. Die Pods sind gesund, der Dienst existiert, aber der Selektor stimmt nicht mit den Pod-Labels überein, sodass der Dienst keine Endpunkte hat.
Szenario 2: Debuggen einer Datenbank, die in einem Pod läuft.
- Problem: Sie müssen Ihren lokalen Datenbank-Client mit einer Datenbank verbinden, die in einem Kubernetes-Pod läuft, um Daten zu überprüfen oder Abfragen auszuführen.
- Lösung mit
kubectl port-forward:- Identifizieren Sie den Pod, der die Datenbank ausführt, und seinen Port (z.B.
mysql-pod, Port3306). - Leiten Sie einen lokalen Port an den Datenbankport weiter:
kubectl port-forward mysql-pod 3306:3306 - Konfigurieren Sie Ihren lokalen Datenbank-Client, um sich mit den entsprechenden Datenbank-Anmeldeinformationen mit
localhost:3306zu verbinden.
- Identifizieren Sie den Pod, der die Datenbank ausführt, und seinen Port (z.B.
Szenario 3: Diagnose von DNS-Auflösungsproblemen innerhalb eines Pods.
- Problem: Eine Anwendung in einem Pod kann andere Dienste nicht über ihre Dienstnamen erreichen, was auf ein DNS-Problem hindeutet.
- Lösung mit
kubectl exec:- Holen Sie sich eine interaktive Shell in den Pod:
kubectl exec -it <pod-name> -- /bin/bash - Versuchen Sie in der Shell, einen bekannten Dienstnamen aufzulösen:
nslookup <service-name>.<namespace>.svc.cluster.localoderdig <service-name>.<namespace>.svc.cluster.local. - Überprüfen Sie den Inhalt von
/etc/resolv.conf, um sicherzustellen, dass die DNS-Konfiguration des Clusters im Pod korrekt ist.
- Holen Sie sich eine interaktive Shell in den Pod:
Wenn das Image kein nslookup, dig oder curl enthält, verwenden Sie einen temporären Debug-Pod im selben Namespace:
kubectl run net-debug -n <namespace> --rm -it --image=curlimages/curl -- sh
Testen Sie von dort aus denselben Dienstnamen, den Ihre Anwendung verwendet. Dies hilft, "mein Anwendungsimage hat keine Tools" von "Cluster-DNS ist defekt" zu unterscheiden.
Szenario 4: Port-Weiterleitung verbindet, schließt dann sofort.
- Problem:
kubectl port-forwardgibt eine Weiterleitungsnachricht aus, aber die Verbindung wird geschlossen, wenn Sie den Browser öffnen odercurlausführen. - Wahrscheinliche Ursachen: Der Zielprozess lauscht nicht auf dem Remote-Port, die Anwendung bindet nur an
127.0.0.1im Container, oder der Pod startet neu, während der Tunnel geöffnet ist. - Überprüfungen:
kubectl exec <pod-name> -n <namespace> -- ss -lntp kubectl get pod <pod-name> -n <namespace> -w kubectl logs <pod-name> -n <namespace> --tail=100
Wenn der Prozess auf Port 8080 lauscht, Sie aber an 80 weiterleiten, ist der Tunnel selbst in Ordnung; das Ziel ist falsch. Wenn der Pod während des Tests neu startet, beheben Sie die Ursache des Neustarts, bevor Sie das Netzwerk verfolgen.
Szenario 5: Dienst funktioniert von einem Pod, aber nicht von einem anderen.
- Problem: Ein Backend kann Redis erreichen, aber ein Worker-Pod in einem anderen Namespace nicht.
- Überprüfungen mit
exec:kubectl exec <source-pod> -n <source-namespace> -- curl -v http://<service>.<target-namespace>.svc.cluster.local:<port> kubectl exec <source-pod> -n <source-namespace> -- cat /etc/resolv.conf
Wenn DNS auflöst, aber TCP fehlschlägt, überprüfen Sie NetworkPolicies, Dienst-Endpunkte und ob die Zielanwendung Datenverkehr aus diesem Namespace akzeptiert. Wenn DNS nicht auflöst, testen Sie den vollqualifizierten Dienstnamen, bevor Sie die App beschuldigen.
Eine einfache Konnektivitätsleiter
Wenn eine Anfrage fehlschlägt, testen Sie vom Nächsten zum Entferntesten:
- Testen Sie im Pod den lokalen App-Prozess:
kubectl exec <pod> -n <namespace> -- curl -v http://127.0.0.1:<port>/health - Testen Sie von einem anderen Pod im selben Namespace den Dienst:
kubectl run curl-test -n <namespace> --rm -it --image=curlimages/curl -- curl -v http://<service>:<port>/health - Testen Sie von Ihrem Laptop über Port-Weiterleitung:
kubectl port-forward service/<service> -n <namespace> 8080:<service-port> curl -v http://localhost:8080/health - Erst nachdem diese bestanden haben, bewegen Sie sich nach außen zu Ingress, Load-Balancern, DNS und Firewall-Regeln.
Diese Reihenfolge spart Zeit, weil jeder Schritt eine Schicht beweist. Wenn localhost im Pod fehlschlägt, ist Ingress irrelevant. Wenn Pod-lokal erfolgreich ist, aber der Dienstzugriff fehlschlägt, ist die App wahrscheinlich in Ordnung und die Kubernetes-Dienstermittlung muss überprüft werden.
Eine weitere Gewohnheit hilft: Halten Sie den Namespace beim Debuggen explizit. Viele verwirrende Sitzungen entstehen, wenn kubectl exec im Standard-Namespace ausgeführt wird, während der defekte Workload woanders lebt. Setzen Sie entweder den Namespace in Ihrem Kontext für die Sitzung oder fügen Sie -n <namespace> zu jedem Befehl hinzu. Das zusätzliche Tippen ist billiger, als den falschen Pod zu testen.
Speichern Sie auch den genauen Befehl, der den Fehler bewiesen hat. Die nächste Person im Bereitschaftsdienst kann ihn erneut ausführen, ohne Ihren Kontext aus dem Gedächtnis rekonstruieren zu müssen.
Best Practices und Tipps
- Lassen Sie
port-forwardlaufen:kubectl port-forwardläuft im Vordergrund. Sie müssen das Terminalfenster offen halten. Um es im Hintergrund auszuführen, können Sie Tools wienohupoderscreen/tmuxverwenden. - Verwenden Sie beim Debuggen spezifische Pods: Während die Weiterleitung an Dienste praktisch ist, ist die Weiterleitung an einen bestimmten Pod mit seinem Namen oft effektiver, um Probleme mit einer bestimmten Instanz zu lokalisieren.
- Sicherheit: Achten Sie darauf, welche Ports Sie freigeben. Vermeiden Sie die Weiterleitung sensibler Ports, es sei denn, es ist unbedingt erforderlich, und stellen Sie sicher, dass Ihr lokaler Rechner gesichert ist.
- Ressourcennutzung:
kubectl execkann Ressourcen verbrauchen. Verwenden Sie es mit Bedacht, insbesondere in Produktionsclustern. - Berechtigungen: Stellen Sie sicher, dass Ihr
kubectl-Kontext die erforderlichen Berechtigungen hat, um Befehle in Pods auszuführen oder Ports weiterzuleiten.
Was Sie nach der Behebung aufschreiben sollten
Gutes Debuggen hinterlässt eine Spur. Erfassen Sie die fehlgeschlagene URL, den Quell-Pod, den Zieldienst, den Namespace, den genauen Befehl, der das Problem reproduziert hat, und die Schicht, in der es fehlgeschlagen ist. "Konnektivitätsproblem" ist zu vage, um beim nächsten Mal zu helfen. "Dienst-Selektor stimmte nach Label-Umbenennung nicht mit Pods überein" ist ein behebbares Muster.