k9s Terminal UI
k9s gives you a live, navigable view of the cluster in a terminal. It replaces repetitive kubectl commands with a vim-style interface where you jump between resource types, filter by namespace, and inspect or edit resources in place.
Launching
Section titled “Launching”mise installs k9s as a project tool. Run it from the project directory:
k9sStart directly on a specific resource type:
k9s -c ingressroutesk9s -c podsk9s -c deployThis is useful when k9s gets stuck on a view after certain navigation sequences — relaunch with -c to jump straight to the resource you want.
Navigation
Section titled “Navigation”k9s uses vim keys for movement and a : command bar for switching resource views.
| Key | Action |
|---|---|
j / k | Move down / up |
g / G | Top / bottom of list |
: | Open command bar (type a resource name) |
/ | Filter current view |
Esc | Back / close overlay |
? | Help (context-sensitive) |
Switching resources
Section titled “Switching resources”Type : followed by a resource name or alias:
:pods:deploy:svc:ns:events:ingressroutes:helmreleases:kustomizationsSwitching namespaces
Section titled “Switching namespaces”Press 0 to view all namespaces. Press 1–9 to switch to a favorited namespace. Favorite a namespace by navigating to :ns, selecting one, and pressing u.
Inspecting resources
Section titled “Inspecting resources”Select any resource and press one of these keys:
| Key | Action |
|---|---|
y | View full YAML manifest |
d | Describe (kubectl describe equivalent) |
e | Edit in $EDITOR |
l | View logs (pods only) |
s | Shell into container |
Shift+F | Port-forward |
IngressRoutes
Section titled “IngressRoutes”IngressRoutes are Traefik CRDs that map hostnames to backend services. They hold the domain names — the Service YAML only shows ports.
From k9s
Section titled “From k9s”Navigate to :ingressroutes or press Shift+L (custom hotkey). Select a route and press y to see the Host(...) match rule:
spec: routes: - match: Host(`docs.k8s.local`)The current cluster has three IngressRoutes:
| Namespace | Name | Domain |
|---|---|---|
| docs | docs | docs.k8s.local |
| monitoring | grafana | grafana.k8s.local |
| traefik | traefik-dashboard | traefik.k8s.local |
From kubectl
Section titled “From kubectl”List all IngressRoutes:
kubectl get ingressroutes -AExtract hostnames from the match rules:
kubectl get ingressroutes -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.spec.routes[*].match}{"\n"}{end}'Custom hotkeys
Section titled “Custom hotkeys”The project ships a hotkeys file at ~/.local/share/k9s/hotkeys.yaml. k9s hot-reloads it — no restart needed. Custom hotkeys appear in the ? help view.
Resource views (Shift+letter)
Section titled “Resource views (Shift+letter)”| Key | Resource |
|---|---|
Shift+D | Deployments |
Shift+V | Services |
Shift+E | Events |
Shift+X | Secrets |
Shift+Q | ConfigMaps |
Shift+L | IngressRoutes |
Shift+B | PVCs |
Shift+W | Nodes |
Shift+Y | Namespaces |
Flux resources (Shift+letter)
Section titled “Flux resources (Shift+letter)”| Key | Resource |
|---|---|
Shift+H | HelmReleases |
Shift+K | Kustomizations |
Shift+G | GitRepositories |
Pods (Shift+number)
Section titled “Pods (Shift+number)”Shift+0 jumps to pods across all namespaces.
Reserved keys
Section titled “Reserved keys”These keys are built-in and cannot be overridden in hotkeys.yaml. Overriding them causes a “duplicate hotkey” load failure with no UI feedback beyond a small status message:
- Sort keys:
Shift+{A,C,F,I,M,N,O,P,R,S,T} - Jump Owner:
Shift+J - Navigation:
j,k,h,l,g,G,Enter,Esc,:,/,? - Actions:
y,d,v,e,l,s,f,x,r,Space,0–9,u - Ctrl combos:
Ctrl+{A,B,C,D,E,F,K,L,R,S,W,Z}
Safe keys for custom hotkeys: Shift+{0-9}, Shift+{B,D,E,G,H,K,L,Q,U,V,W,X,Y,Z}, F1–F12.
Sorting
Section titled “Sorting”In any list view, press Shift+letter to sort:
| Key | Sort by |
|---|---|
Shift+C | CPU usage |
Shift+M | Memory usage |
Shift+N | Name |
Shift+A | Age |
Shift+S | Status |
Shift+T | Restart count |