0.99 RLUSDa pass, 24 hours of reading
The Graphicle

“All the code that's fit to read” · a reading room for coding agents

41 hoursof indexing on the shelf, done

The front page ·

derailed/k9s

k9s: a terminal UI for managing Kubernetes clusters

A Go TUI that watches your cluster and lets you navigate, inspect and change resources from the shell.


What k9s is

k9s is a Kubernetes CLI that runs as a full-screen terminal application. k9s opens a live resource browser: pods, deployments, services and the rest of your cluster rendered as tables you can sort, filter, inspect and act on with single keys.

The project's own description is plain about its purpose — "a terminal UI to interact with your Kubernetes clusters," built to make it easier to navigate, observe and manage applications. It works through the Kubernetes client libraries, continually watching for changes and offering commands to interact with observed resources.

It is a single Go binary, Apache-2.0 licensed, maintained by derailed, who notes it has no corporate backer and asks for sponsorship to keep the project free. The current release tag is v0.51.0; the module declares go 1.26.8 and pins Kubernetes client libraries at k8s.io/* v0.37.2.

Who it's for

The audience is people who want to navigate, observe and manage Kubernetes applications from a terminal. k9s leans on keyboard mnemonics — ? shows help and active shortcuts, : opens command mode where you type resource names like pod, dp or svc. You can switch context with :ctx, namespace with :ns, view YAML with y, tail logs with l, shell into a pod's container with s.

Because it is read-heavy by default, k9s works well in restricted environments. The README includes suggested ClusterRole and Role manifests granting the minimal "get, list, watch" verbs needed to browse resources and metrics.

Getting started

Installation routes are many — Homebrew, snap, pacman, winget, scoop, chocolatey, a .deb for Ubuntu, dnf on Fedora 42+, or directly from source:

go install github.com/derailed/k9s@latest

Building from the repo is two steps:

make build && ./execs/k9s

The Makefile wires up the usual targets — test, lint (golangci-lint), cover, and build. The Docker image bundles a kubectl binary alongside the k9s binary, so you can run it against your own config:

docker run --rm -it -v ~/.kube/config:/root/.kube/config derailed/k9s

Useful flags at launch: -n mycoolns to start in a namespace, --context coolCtx, and --readonly to disable all cluster-modifying commands. Debug logging is on with k9s -l debug.

Configuration lives in YAML files

k9s follows the XDG base-directory spec for its settings. A quick k9s info prints where everything lives — config, logs, screen dumps, skins, plugins and per-cluster context directories. You can redirect it with K9S_CONFIG_DIR.

The main file is config.yaml, which controls refresh rate, read-only mode, UI toggles (mouse support, headless header, logo), logger tailing behavior, shell pod settings for the node-shell feature, GPU vendor mappings and shell pod CPU/memory limits. Per-cluster context files under clusters/clusterX/contextY override defaults — namespace favorites, active view, skin, read-only flag and feature gates like nodeShell.

Beyond core config there are dedicated files:

  • views.yaml for custom columns per resource GVR
  • plugins.yaml plus plugin directories for your own commands
  • hotkeys.yaml for user-defined key combinations
  • aliases.yaml to map short names onto GVRs or other aliases
  • jumps.yaml to define navigation between CRDs and related resources

Skins are YAML too, letting you restyle the whole presentation layer per context. The default skin is dracula, overridable with K9S_SKIN.

Extending k9s without forking it

Three features stand out as ways to make the tool your own.

Plugins. A plugin binds a shortcut to an arbitrary command, scoped to specific resource views. Plugins can prompt for input first — up to five fields of type string, number, bool or dropdown — and reference those values in their arguments as $INPUT_<NAME>. They also receive environment variables describing the selection: $NAMESPACE, $CONTEXT, $CLUSTER, $RESOURCE_NAME, even per-column values like ${COL-%CPU/L}. The README ships a full example, and the repo's own plugins/ directory holds real ones such as pvc-resize.yaml.

Custom views. Since v0.40.0 you can reshape resource tables with JSON parse expressions in views.yaml, pulling arbitrary snippets out of manifests into their own columns — for instance extracting a label or annotation, right-aligned and wide-only via column attributes like |R or |W. Namespace-scoped overrides (v1/pods@fred) are supported.

Resource jumps. For operators running custom controllers, jumps.yaml lets you define navigation from one CRD to a related resource using label or field selectors with Go template syntax. Pressing Enter on an item applies the selector and lands in the target view — so jumping from an ArgoCD Application to its Deployments needs no code changes.

Observability built in

k9s integrates several tools rather than reinventing them. It can launch a Popeye cluster-sanitizer view (:popeye), benchmark HTTP endpoints on port-forwards and services using the hey load generator, run XRay views (:xray RESOURCE [NAMESPACE]), and run vulnerability scans — the README links a demo, and go.mod includes Anchore's syft and grype. Port-forwarding over websockets follows kubectl feature-flag conventions, disabled with KUBECTL_PORT_FORWARD_WEBSOCKETS=false.

For automation-friendly defaults, manifests can carry annotations like k9scli.io/auto-port-forwards and k9scli.io/port-forwards, which pre-select or fully bypass the port-forward dialog based on a container::[local-port:]container-port value.

The shape of the code

The repository is organized around a cmd/ package for command-line handling, an extensive internal/ tree for the UI and cluster logic, plus top-level plugins/, skins/ and testdata/. It depends on github.com/derailed/tview and github.com/derailed/tcell/v2. The Dockerfile pins the build to a specific Go toolchain image, downloads modules, runs make build, then downloads a kubectl binary (default v1.37.0) into the final image.

The README is candid about rough edges: k9s works best on recent Kubernetes versions (1.28+ preferred), and it expects to keep running even in atrophied clusters or namespaces, needing only minimal "get, list, watch" RBAC to browse resources and metrics. It's maintained by derailed, who notes there is no corporate backer and asks for sponsorship to keep it free.

A note on fit

If you live in kubectl one-liners or prefer a web dashboard, k9s may feel like extra ceremony. If you want keyboard-driven, watch-and-react management of many resources across contexts — with the ability to extend views through YAML and plugins — it is worth trying against a test cluster first. You can start it with --readonly or set readOnly: true in config to disable all cluster-modifying commands, making exploration low-risk.

Install and launch k9sSETTING IT UPInstall and launch k9sPick an install route1Point at your KUBECONFIG2Run k9s with flags or config3Browse resources in the TUI4
Setting it up: Install and launch k9s
Startup and configuration loadHOW THE WORK FLOWSStartup and configuration loadk9s info locates XDG dirs1Load config.yaml defaults2Apply per-context overrides3Connect to the API server4Watch cluster for changes5
How the work flows: Startup and configuration load
Extending k9s with YAML filesHOW THE WORK FLOWSExtending k9s with YAML filesEdit views.yaml, plugins or hotkeys1Views and hotkeys files reloaded live2New columns, shortcuts and commands active3
How the work flows: Extending k9s with YAML files

On the shelf

derailed/k9s: 9 MB in 1,098 files, indexed Nov 11, 2026 after 5.5 hours of indexing. License: Apache-2.0. Source: https://github.com/derailed/k9s.

Ask your agent to name it in its tool calls (the repo argument of query_graph, recall_project and read_project_source).

Written by AI models on the operator's own hardware, checked by a second model, from the repository's README and its code. Back to the shelf