The kubectl Problem Nobody Talks About
If you spend a significant chunk of your day on Kubernetes clusters, you already know the pain. You want to check why a pod keeps restarting, so you run kubectl get pods -n staging, find the culprit, then run kubectl describe pod my-app-7d9f8b-xkj2p -n staging, then kubectl logs my-app-7d9f8b-xkj2p -n staging --previous, then maybe exec into a container to poke around. That’s four commands to diagnose one thing — and you’re typing a 30-character pod name each time.
I ran into this problem in my first months on a production cluster. K9s fixed it. I’ve used it daily since, and it’s the first thing I install on any new machine where I’ll be touching Kubernetes.
What K9s Actually Is
K9s is a terminal-based UI for Kubernetes. It sits on top of your existing kubeconfig and gives you a continuously updated, interactive view of your cluster — no web browser, no extra backend, no server to maintain. Think of it as kubectl with a live dashboard and keyboard shortcuts built in.
A few things separate it from GUI-based dashboards:
- It’s a single binary — no Helm chart, no deployment, no database
- Works with any valid kubeconfig (local clusters, EKS, GKE, AKS — all the same)
- Reads live from the Kubernetes API, so everything you see is real-time
- RBAC-aware — it only shows what your kubeconfig user can access
- Fully keyboard-driven, which means once you learn the shortcuts, you move faster than any GUI
K9s doesn’t replace kubectl for scripting or CI/CD pipelines. It’s your interactive debugging companion for when you’re in the terminal figuring something out live.
Installation
K9s ships as a single binary and is available through most package managers:
# macOS
brew install derailed/k9s/k9s
# Linux (download latest release binary)
curl -Lo k9s.tar.gz https://github.com/derailed/k9s/releases/latest/download/k9s_Linux_amd64.tar.gz
tar -xzf k9s.tar.gz
sudo mv k9s /usr/local/bin/
# Windows (Chocolatey)
choco install k9s
# Or via go install
go install github.com/derailed/k9s@latest
Verify it’s working:
k9s version
With a valid kubeconfig in place, launching K9s is just:
k9s
To target a specific context or namespace from the start:
# Connect to a specific kubeconfig context
k9s --context production-cluster
# Start in a specific namespace
k9s -n kube-system
Core Concepts: Navigating the K9s Interface
The K9s interface has three main areas: the header showing your current cluster and namespace, the resource list in the center, and a help bar at the bottom showing available keys.
The Command Bar
Press : (colon) to open the command bar — this is how you switch between resource types. Type any Kubernetes resource name and hit Enter:
:pods # View all pods
:deployments # View deployments
:services # View services
:nodes # View cluster nodes
:namespaces # Switch namespaces
:configmaps # View configmaps
:secrets # View secrets (values masked by default)
:ingresses # View ingress resources
:events # Cluster events — very useful for debugging
Short aliases work too, just like in kubectl: :po, :deploy, :svc, :ns.
Essential Keyboard Shortcuts
These are the keys that make K9s worth learning. After a few hours, they’re muscle memory:
/— Filter the current resource list by name (type to search, Escape to clear)Enter— Drill into a resource (pod → containers → logs)l— View logs for the selected pods— Open a shell (exec) into the selected containerd— Describe the selected resource (equivalent tokubectl describe)e— Edit the resource YAML inlinectrl+d— Delete the selected resource (with confirmation prompt)ctrl+k— Kill/force-delete the resourcey— View the full YAML of the resourcenor0–9— Switch namespace (0 = all namespaces)?— Open the full help overlayctrl+corq— Quit
Switching Namespaces
Press 0 to see resources across all namespaces, or open :namespaces, navigate to the one you want, and press Enter to switch into it. K9s remembers your last namespace per context.
Hands-On: Real Debugging Workflows
Diagnosing a CrashLoopBackOff
This is the scenario you’ll hit most often. Open K9s, navigate to :pods, and use / to filter by app name. You’ll see STATUS showing CrashLoopBackOff and the RESTARTS count climbing. Select that pod and:
- Press
lto view current logs immediately - In the log view, press
pto toggle to previous container logs (the crashed instance) - Press
wto wrap long lines if needed - Press
fto follow (tail) the logs in real-time - Press
Escapeto go back, thendto describe the pod and check Events at the bottom
That whole investigation takes about 20 seconds in K9s. Compare that to five separate kubectl commands with a 30-character pod name pasted between each one.
Monitoring Node Resource Usage
Switch to :nodes and you’ll see CPU% and MEM% columns with color coding — green is healthy, yellow is warning, red is critical. Select any node and press Enter to see every pod running on it. Useful for spotting noisy neighbors when you’re troubleshooting resource pressure on a specific machine.
Port Forwarding Without kubectl
Select the pod or service you want to forward and press shift+f. K9s opens a dialog to set the local and remote port, then starts the forward. Active port-forwards are tracked under :pf. Handy when you need to hit an internal service from your laptop without touching any network rules.
Watching Events in Real-Time
The :events view is one of the most underused screens in K9s. Filter with / by namespace or app name. Events surface exactly what Kubernetes is doing behind the scenes — image pull failures, scheduling decisions, readiness probe failures. I keep this open in a second terminal pane whenever I’m deploying something new. It catches problems immediately that would otherwise take several kubectl describe calls to find.
Managing Deployments
At :deployments, select any deployment and:
- Press
sto scale it (K9s prompts for replica count) - Press
rto restart the deployment (rolling restart) - Press
eto edit the deployment YAML directly — change image tags, env vars, resource limits on the fly - Press Enter to drill into its ReplicaSets, then into individual pods
Using the Pulses View
Type :pulses for a cluster-wide overview showing resource counts and status across key resource types. One screen tells you if something is broadly wrong before you start digging into specifics.
Customization Worth Knowing
K9s stores its config at ~/.config/k9s/config.yaml on Linux and Mac, or %APPDATA%\k9s\config.yaml on Windows. Default namespace, skin theme, and UI behavior are all configurable there.
To change the color theme:
# List available skins
ls ~/.config/k9s/skins/
# Or download community skins from the K9s GitHub repo
# Then set in config.yaml:
# ui:
# skin: monokai
Teams can configure custom column views per resource type using ~/.config/k9s/views.yaml. This lets you pin fields that matter to your setup — pod QoS class, priority class, or whatever your on-call rotation actually watches — alongside the standard columns.
Wrapping Up
K9s removes the friction between you and your cluster. Instead of constructing kubectl commands from memory or copying pod names, you navigate visually — context always on screen, one keypress away from logs or a shell.
Start with what you already do in kubectl: check pod status, read logs, describe resources. Within a week, the shortcuts click. Within a month, going back to raw kubectl for interactive debugging feels like navigating a directory with no tab completion.
Running multiple clusters? K9s pairs cleanly with kubectx. Switch context, relaunch K9s, and everything reflects the new target immediately. No setup on the cluster side. Drop the binary in your PATH and you’re done.

