Lab 25: Kubernetes navigieren und troubleshooten mit k9s¶
k9s ist ein Terminal-UI für Kubernetes. Es zeigt die Cluster-Ressourcen in einer
Live-Tabelle, die ihr mit der Tastatur bedient. Statt für jede Frage ein separates kubectl get,
describe oder logs abzusetzen, wechselt ihr zwischen den Ressourcen und lest ihre Details an einer
Stelle.
Ziel dieser Übung: Am Ende könnt ihr einen Cluster in k9s navigieren, Ressourcen inspizieren, Logs lesen und eine Shell öffnen, einen Workload per Port-Forward erreichen und skalieren sowie ein kaputtes Deployment diagnostizieren und reparieren, ohne das TUI zu verlassen.
Shells: k9s ist ein Terminal-UI, daher ist jeder Tastendruck in diesem Lab unter Windows, macOS und Linux identisch. Nur eine Handvoll
kubectl-/curl-Befehle laufen in eurer Shell. Wo sich PowerShell von Bash unterscheidet, sind beide Varianten angegeben.
Teil 0: Setup¶
k9s ist auf eurer Maschine bereits installiert. Prüft es und startet von einem laufenden minikube-Cluster aus.
k9s version
Deployt die Workloads, die ihr untersuchen werdet (eine gesunde App plus eine, die absichtlich kaputt
ist). Speichert das folgende Manifest als setup.yaml:
# Lab 25 - k9s-Playground-Workloads.
# Zwei Deployments im default-Namespace:
# * web - ein gesundes nginx (2 Replicas) plus ein ClusterIP-Service.
# * broken - ein nginx mit einem nicht existierenden Image-Tag (ImagePullBackOff),
# das ihr aus k9s heraus diagnostiziert und repariert.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.29.4
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 20
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
name: web
labels:
app: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: broken
labels:
app: broken
spec:
replicas: 1
selector:
matchLabels:
app: broken
template:
metadata:
labels:
app: broken
spec:
containers:
- name: nginx
image: nginx:1.29.4-doesnotexist
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 20
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
Wendet es dann an (führt das aus dem Verzeichnis aus, in dem ihr die Datei gespeichert habt):
kubectl apply -f setup.yaml
Das erzeugt im default-Namespace:
web: ein gesundes nginx-Deployment mit 2 Replicas plus einenweb-Service.broken: ein nginx-Deployment, das nicht startet (warum, findet ihr in Teil 5 heraus).
Startet nun k9s:
k9s
Ihr landet auf einer Ressourcen-Tabelle. Der Header (oben links) zeigt euren Context und Namespace; oben rechts stehen die im aktuellen View verfügbaren Tasten. Zwei Tasten, die ihr euch von Anfang an merken solltet:
Esc: zurückgehen / einen Filter löschen.:qdannEnter, oderCtrl-C: k9s beenden.
Teil 1: Sich zurechtfinden¶
k9s nutzt einen Command-Prompt, ähnlich wie Vim. Drückt :, tippt eine Ressource, drückt Enter.
- Springt zwischen Ressourcen-Typen:
:podsEnter: alle Pods:deploymentsEnter: Deployments:servicesEnter: Services:namespacesEnter: Namespaces
Kurznamen funktionieren ebenfalls:
:po,:deploy,:svc,:ns. Die Aliase sind dieselben, diekubectlverwendet.
-
Drückt
?, um den Hilfe-Screen mit allen Key-Bindings für den aktuellen View zu öffnen. DrücktEsczum Schließen. -
Namespaces. Drückt
0, um Pods aus allen Namespaces anzuzeigen. Um euch auf einen einzelnen Namespace zu fokussieren, führt:nsEnteraus und wählt einen aus — das funktioniert immer. Der Header listet Namespaces zusätzlich mit einer vorangestellten Ziffer (z. B.<1>); diese Ziffer zu drücken ist eine Abkürzung für dasselbe. Setzt ihn für den Rest des Labs zurück aufdefault. -
Filter. Drückt im Pods-View
/, tipptwebund drücktEnter. Die Tabelle zeigt nun nur noch passende Pods. DrücktEsc, um den Filter zu löschen. -
Sortieren. Nutzt in einer Tabelle die im Header angezeigten Shortcut-Tasten (z. B. nach Name, CPU oder Alter sortieren). Spalten-Sortierung hilft, schnell die ausgelastetsten oder ältesten Pods zu erkennen.
Aufgabe: Beantwortet nur mit k9s: Wie viele web-Pods laufen, und welche Status haben sie?
Teil 2: Eine Ressource inspizieren¶
Navigiert zu :pods und markiert einen der web-Pods mit den Pfeiltasten.
- Drückt
d, um ihn zudescriben. Ihr bekommt dieselben Details wie beikubectl describe, inklusive der Events ganz unten. DrücktEsczum Zurückgehen. - Drückt
y, um das vollständige YAML der Ressource zu sehen. DrücktEsczum Zurückgehen. - Drill-down. Geht zu
:deploy, markiertwebund drücktEnter. k9s springt direkt zu den Pods des Deployments (es überspringt das ReplicaSet). DrücktEnterauf einem Pod, um zu seinen Containern zu gelangen. MitEscklettert ihr jede Ebene wieder nach oben.Wollt ihr die ReplicaSet-Ebene sehen? Drückt
zauf dem Deployment stattEnter.
Aufgabe: Ausgehend vom web-Deployment, drillt bis ganz hinunter zum nginx-Container. Wie viele
Enter-Drücke waren nötig (Deployment → ? → Container)?
Teil 3: Logs und Shell¶
Geht zu :pods und markiert einen web-Pod.
-
Logs. Drückt
l, um die Container-Logs live zu streamen (wiekubectl logs -f). Ein frisches nginx hat vorerst nur Startup-Zeilen. Echten Traffic erzeugt ihr in Teil 4. DrücktEsc, um den Log-View zu verlassen.Nützliche Log-View-Tasten (im Header angezeigt): Wrap umschalten, Timestamps umschalten und an den Anfang/das Ende springen.
-
Shell. Bei einem markierten
web-Pod drückts, um eine Shell innerhalb des Containers zu öffnen (wiekubectl exec -it ... -- /bin/sh). Probiert ein paar Linux-Befehle:
ls -l /usr/share/nginx/html
printenv
cat /etc/nginx/conf.d/default.conf
Diese laufen innerhalb des Linux-Containers, verhalten sich also gleich, egal welches OS auf eurem Laptop läuft. Tippt
exit, um zu k9s zurückzukehren.
Aufgabe: Wie heißt die HTML-Datei, die nginx standardmäßig ausliefert (schaut in
/usr/share/nginx/html)?
Teil 4: Port-Forward und Skalieren¶
4.1 Port-Forward¶
Erreichen wir die web-App von eurem Laptop aus und beobachten, wie die Access-Logs aufleuchten.
-
Geht zu
:svc, markiert denweb-Service und drücktShift-F. Ein Dialog mit den Forward-Details öffnet sich. Setzt den lokalen Port auf8080(lasst den Service-/Container-Port auf80) und bestätigt. k9s forwardet nunlocalhost:8080zum Service.Aktive Forwards könnt ihr jederzeit mit
:pfEntereinsehen. -
Fragt die App aus eurer Shell an (ein zweites Terminal, k9s bleibt laufen):
curl http://localhost:8080
Windows (PowerShell):
curlist ein Alias fürInvoke-WebRequest. Für eine einfache Anfrage funktioniert es, aber um konsistent zu macOS/Linux zu bleiben, nutztcurl.exe:curl.exe http://localhost:8080
Ihr solltet das nginx-Willkommens-HTML bekommen. Führt es ein paar Mal aus.
- Öffnet zurück in k9s erneut die Logs (
l) einesweb-Pods. Nun seht ihr eureGET /-Requests live im Access-Log auftauchen.
4.2 Skalieren¶
- Geht zu
:deployund markiertweb. - Drückt
s(Scale). Setzt im Dialog die Replicas auf4und bestätigt. - Wechselt zu
:podsund beobachtet in Echtzeit, wie zwei neueweb-Pods erscheinen undRunningwerden. - Skaliert auf demselben Weg wieder auf
2herunter.
Aufgabe: Wie verändert sich die Pod-Tabelle in dem Moment, in dem ihr die Hochskalierung bestätigt?
Teil 5: Den kaputten Workload troubleshooten¶
Das broken-Deployment ist nie hochgekommen. Diagnostizieren und reparieren wir es vollständig aus k9s
heraus.
-
Geht zu
:pods. Derbroken-...-Pod ist nichtRunning. Er zeigt etwas wieImagePullBackOffoderErrImagePull(k9s färbt ihn rot). -
Lest die Events. Markiert den
broken-Pod und drücktd(describe). Scrollt ganz nach unten zu den Events. Ihr seht eine Meldung wie "Failed to pull image ... not found". Der Image-Tag existiert nicht. -
Prüft die Logs. Drückt
l. Es gibt keine Container-Logs, weil der Container nie gestartet ist. Genau dieses Fehlen ist der Hinweis: Wenn es keine Logs gibt, der Pod aber ungesund ist, schaut auf die Events und das Image, nicht auf die App.
Diagnose:
setup.yamlverwendet das Imagenginx:1.29.4-doesnotexist, das kein echter Tag ist. Die Reparatur besteht darin, das Deployment auf ein echtes Image zu verweisen:nginx:1.29.4.
- Repariert es, der k9s-Weg (
e). Geht zu:deploy, markiertbrokenund drücktezum Editieren. k9s öffnet die Ressource in eurem Editor. Ändert den Image-Tag aufnginx:1.29.4, speichert und schließt den Editor.
k9s nutzt den Editor aus der Umgebungsvariable
K9S_EDITOR(oderEDITOR). Setzt sie, bevor ihr k9s startet:# Windows (PowerShell) $env:K9S_EDITOR = "notepad"# macOS / Linux export K9S_EDITOR=nano
- Repariert es, der zuverlässige Fallback. Falls das Editieren in k9s umständlich ist (kein Editor konfiguriert, oder ihr nutzt lieber die Kommandozeile), führt das in eurer Shell aus. Es funktioniert in Bash und PowerShell identisch:
kubectl set image deployment/broken nginx=nginx:1.29.4
- Beobachtet die Erholung. Beide Reparaturen lösen ein neues Rollout aus. Geht in k9s zu
:podsund schaut zu: Ein frischerbroken-...-Pod wird erzeugt, zieht das echte Image und wird grün (Running). Bestätigt mitd, dass die Events nun einen erfolgreichen Pull und Start zeigen.
Aufgabe: Wie viele broken-Pods sind nach der Reparatur Running, und was zeigt die
Pod-Status-Spalte?
Teil 6: Aufräumen¶
-
Aus k9s heraus löschen. Geht zu
:deploy, markiertbrokenund drücktCtrl-D. Bestätigt den Lösch-Dialog. Das Deployment (und sein Pod) verschwindet aus der Tabelle. So löscht ihr in k9s jede Ressource. -
Alles Übrige entfernen. Beendet k9s (
:q) und führt aus:
kubectl delete -f setup.yaml
brokenist bereits weg, daher seht ihr dafür eventuell einen "not found"-Hinweis. Das ist erwartet und harmlos.
Zusammenfassung: wichtige k9s-Bindings¶
| Taste | Aktion |
|---|---|
: dann <ressource> |
Zu einem Ressourcen-Typ springen (:pods, :deploy, :svc, :ns) |
? |
Hilfe / alle Key-Bindings für den aktuellen View |
/ |
Aktuelle Tabelle filtern |
0 |
Alle Namespaces umschalten |
Enter |
In die markierte Ressource drillen (Deployment → Pods, ReplicaSet übersprungen) |
z |
Die ReplicaSets des markierten Deployments anzeigen |
Esc |
Zurückgehen / Filter löschen |
d |
Describe (mit Events) |
y |
Vollständiges YAML anzeigen |
l |
Logs streamen |
s |
Shell in einen Pod / Deployment skalieren (kontextabhängig) |
Shift-F |
Port-Forward |
e |
In $K9S_EDITOR editieren |
Ctrl-D |
Die markierte Ressource löschen |
:q Enter / Ctrl-C |
k9s beenden |