Skip to content

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.

mise installs k9s as a project tool. Run it from the project directory:

Terminal window
k9s

Start directly on a specific resource type:

Terminal window
k9s -c ingressroutes
k9s -c pods
k9s -c deploy

This is useful when k9s gets stuck on a view after certain navigation sequences — relaunch with -c to jump straight to the resource you want.

k9s uses vim keys for movement and a : command bar for switching resource views.

KeyAction
j / kMove down / up
g / GTop / bottom of list
:Open command bar (type a resource name)
/Filter current view
EscBack / close overlay
?Help (context-sensitive)

Type : followed by a resource name or alias:

:pods
:deploy
:svc
:ns
:events
:ingressroutes
:helmreleases
:kustomizations

Press 0 to view all namespaces. Press 19 to switch to a favorited namespace. Favorite a namespace by navigating to :ns, selecting one, and pressing u.

Select any resource and press one of these keys:

KeyAction
yView full YAML manifest
dDescribe (kubectl describe equivalent)
eEdit in $EDITOR
lView logs (pods only)
sShell into container
Shift+FPort-forward

IngressRoutes are Traefik CRDs that map hostnames to backend services. They hold the domain names — the Service YAML only shows ports.

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:

NamespaceNameDomain
docsdocsdocs.k8s.local
monitoringgrafanagrafana.k8s.local
traefiktraefik-dashboardtraefik.k8s.local

List all IngressRoutes:

Terminal window
kubectl get ingressroutes -A

Extract hostnames from the match rules:

Terminal window
kubectl get ingressroutes -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.spec.routes[*].match}{"\n"}{end}'

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.

KeyResource
Shift+DDeployments
Shift+VServices
Shift+EEvents
Shift+XSecrets
Shift+QConfigMaps
Shift+LIngressRoutes
Shift+BPVCs
Shift+WNodes
Shift+YNamespaces
KeyResource
Shift+HHelmReleases
Shift+KKustomizations
Shift+GGitRepositories

Shift+0 jumps to pods across all namespaces.

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, 09, 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}, F1F12.

In any list view, press Shift+letter to sort:

KeySort by
Shift+CCPU usage
Shift+MMemory usage
Shift+NName
Shift+AAge
Shift+SStatus
Shift+TRestart count