Navigate a Kubernetes cluster with k9s
Browse pods, deployments and services with k9s: switch contexts, filter views, read logs, open a shell, port-forward, and run it read-only.
Updated
in short
Run k9s --context <name>, type : and a resource name such as pod or deploy to switch views, / to filter, then l for logs, s for a shell and Shift-F to port-forward.
k9s is a terminal UI over the Kubernetes API. It reads the same kubeconfig as kubectl and shows live tables of resources that you move through with the keyboard, so you can go from a failing deployment to its pod logs without typing resource names.
This guide covers starting k9s against the right cluster, the command and filter prompts, logs, shells, port-forwards, read-only mode and where the configuration files live.
Tools used
Before you start
- A working kubeconfig:
kubectl get podssucceeds against the cluster kubectlon yourPATH(k9s calls it for shells and edits)- A terminal with 256-color support
Steps
Step 1: Install k9s
Install from a package manager or download a release tarball from GitHub.
k9s versionconfirms the install.sh# macOS or Linux with Homebrew brew install derailed/k9s/k9s # Arch Linux sudo pacman -S k9s # Windows winget install k9sshk9s versionStep 2: Start it against the right cluster and namespace
With no flags, k9s uses the current context from your kubeconfig.
--contextpicks another context,-na namespace,-Aall namespaces, and--kubeconfiga different kubeconfig file.-csets the first view, for example-c deploy.Inside k9s,
:ctxlists contexts and:nslists namespaces; select one and press Enter to switch.shk9s --context staging -n paymentsshk9s --kubeconfig ~/.kube/prod-config -A -c deployStep 3: Switch views with
:Press
:and type a resource name, then Enter. Singular, plural and short names all work::pod,:deploy,:svc,:ing,:cm,:secret,:node. Add a namespace after the name to scope it, as in:pod kube-system.Ctrl-Alists every resource and alias the cluster offers.In a table, Enter drills down (deployment to its pods, pod to its containers),
ddescribes,yshows YAML, andEscgoes back.?shows all key bindings for the current view.text:deploy :pod kube-system :svcStep 4: Filter with
/Press
/and type a regular expression to filter the current table by name, for exampleapi|worker. Prefix with!to invert the match, use-lto filter by labels, and-ffor a fuzzy match.Escclears the filter.Since k9s 0.30.0, the command prompt also takes filters directly:
:pod /apior:pod app=web,env=prod.text/api|worker /! Running /-l app=web /-f chkoutStep 5: Read logs
Select a pod, container or deployment and press
lto stream its logs;pshows the previous container's logs after a restart. In the log view,0follows the tail,2to6show the last 1m, 5m, 15m, 30m or 1h,wtoggles line wrap,ttoggles timestamps,stoggles autoscroll andftoggles full screen. Press/to filter log lines.How many lines k9s loads by default is set under
k9s.loggerinconfig.yaml(tail,buffer,sinceSeconds).Step 6: Open a shell and port-forward
Select a pod and press
sto open a shell. If the pod has several containers, k9s asks which one. It runskubectl execwithbash, falling back tosh, so images without a shell (such as distroless images) cannot be entered this way. Exit the shell to return to k9s.Shift-Fon a pod, container or service opens a port-forward dialog for the local and container ports.:pflists active forwards, andCtrl-Dthere stops one. Port-forwards end when k9s exits.Step 7: Use read-only mode on production clusters
--readonlydisables commands that change the cluster: delete, kill, edit, and shell or attach into pods. Viewing, logs and port-forwards still work. To make it the default, setreadOnly: trueinconfig.yaml, or in a single context's config file to protect only that cluster.--writeoverrides the setting for one session.shk9s --context prod --readonlyyaml# $XDG_CONFIG_HOME/k9s/config.yaml (~/.config/k9s/config.yaml on Linux) k9s: readOnly: trueStep 8: Find the config files and set a skin
Since k9s 0.30.0, the main config is
config.yaml(notconfig.yml) in the k9s config directory:~/.config/k9son Linux,~/Library/Application Support/k9son macOS and%LOCALAPPDATA%\k9son Windows, unlessXDG_CONFIG_HOMEorK9S_CONFIG_DIRpoints elsewhere.aliases.yaml,plugins.yaml,hotkeys.yaml,views.yamland theskins/directory live there too. Per-context settings live underclusters/in the data directory (~/.local/share/k9son Linux).k9s infoprints the exact paths on your machine.To apply a skin, copy a YAML file from the
skinsdirectory of the k9s repository intoskins/and set its name, without the extension, ink9s.ui.skin.K9S_SKINoverrides it for one run.shk9s infoyaml# config.yaml k9s: ui: skin: dracula # loads skins/dracula.yaml
Troubleshooting
- Colors look wrong or missing: k9s needs 256 colors. Set
TERM=xterm-256color. kubectl command is not in your pathwhen pressings: install kubectl or add it toPATH.sandedo nothing: k9s is in read-only mode. Start it with--write, or setreadOnly: false.- Settings ignored after an upgrade: 0.30.0 moved files and renamed
.ymlto.yaml. Compare withk9s info. eopens the wrong editor: setKUBE_EDITORorEDITOR.- Something else fails:
k9s infoshows the log file path; start withk9s -l debugfor more detail.
Tips
-jumps back to the previous view, likecd -.[and]move through command history.:xray dpshows deployments as a tree of their related resources. It also takespo,svc,rs,stsandds.Shift-Jon a pod jumps to its owner, such as the replica set or job that created it.
FAQ
- Where does k9s keep per-cluster settings?
- Under `clusters/<cluster>/<context>/config.yaml` in its data directory (`~/.local/share/k9s` on Linux). That file holds the active namespace, favorites, last view and per-context options such as `readOnly`.
- Can k9s show resources from custom resource definitions?
- Yes. CRDs appear in `Ctrl-A` and can be opened with `:` and their name or short name, like built-in resources.
- Why can I not open a shell in some pods?
- k9s runs `bash` or `sh` inside the container. Images that ship neither, such as distroless images, have no shell to open.