k9s is a terminal-based UI that provides a curses-style interface to interact with your Kubernetes clusters. It gives you a real-time view of your cluster, with keyboard-driven navigation and built-in actions for the most common kubectl operations.
Installation
Homebrew (macOS/Linux)
brew install derailed/k9s/k9s
# Verify
k9s version
Package Managers
# macOS via MacPorts
sudo port install k9s
# Windows via Scoop
scoop install k9s
# Windows via Chocolatey
choco install k9s
# Arch Linux
pacman -S k9s
# Nix
nix-env -iA nixpkgs.k9s
Manual Installation
# Linux — download latest release
VERSION=$(curl -s https://api.github.com/repos/derailed/k9s/releases/latest | jq -r .tag_name)
curl -L "https://github.com/derailed/k9s/releases/download/${VERSION}/k9s_Linux_amd64.tar.gz" | \
tar xz -C /usr/local/bin k9s
# macOS (arm64)
curl -L "https://github.com/derailed/k9s/releases/download/${VERSION}/k9s_Darwin_arm64.tar.gz" | \
tar xz -C /usr/local/bin k9s
Run with Docker
docker run --rm -it \
-v ~/.kube/config:/root/.kube/config \
quay.io/derailed/k9s
Configuration
Launch Options
# Start k9s (uses current kubeconfig context)
k9s
# Start in a specific namespace
k9s -n production
# Start with a specific context
k9s --context staging
# Start focused on a specific resource type
k9s --command pods
# Read-only mode — prevents destructive actions
k9s --readonly
# Logging verbosity
k9s --logLevel debug
Config File
# ~/.config/k9s/config.yaml
k9s:
liveViewAutoScroll: true # Auto-scroll log view
maxConnRetry: 5
readOnly: false
noExitOnCtrlC: false
ui:
skin: monokai # Skin name (see ~/.config/k9s/skins/)
enableMouse: true
headless: false
logoless: false
crumbsless: false
reactive: false
noIcons: false
refreshRate: 2 # Seconds between refreshes
skipLatestRevCheck: false
disablePodCounting: false
logger:
tail: 100
buffer: 5000
sinceSeconds: -1 # -1 = all logs
textWrap: false
showTime: false
thresholds:
cpu:
critical: 90
warn: 70
memory:
critical: 90
warn: 70
Custom Aliases
# ~/.config/k9s/aliases.yaml
aliases:
dp: deployments
svc: services
ns: namespaces
no: nodes
ing: ingresses
cm: configmaps
sec: secrets
pvc: persistentvolumeclaims
po: pods
rs: replicasets
sts: statefulsets
ds: daemonsets
cj: cronjobs
hpa: horizontalpodautoscalers
Core Commands
Global Keyboard Shortcuts
| Shortcut | Description |
|---|
: | Open command mode to enter resource type |
/ | Filter resources by name or label |
? | Show help / all available shortcuts |
Ctrl+a | Show all available resource aliases |
Ctrl+d | Delete selected resource |
Ctrl+k | Kill (force delete) selected resource |
Ctrl+e | Edit resource in your $EDITOR |
Ctrl+s | Save current view to a file |
Ctrl+u | Clear the current filter |
Ctrl+w | Toggle wide output columns |
Ctrl+r | Refresh current view |
Ctrl+f | Toggle fullscreen |
Ctrl+c | Exit k9s |
q | Quit current view / go back |
Esc | Clear filter or go back |
g | Jump to top of list |
G | Jump to bottom of list |
h or ← | Go back in breadcrumb |
Enter | Drill into resource |
d | Describe selected resource |
e | Edit selected resource YAML |
l | View logs for selected pod |
s | Shell into selected pod |
f | Port-forward selected pod/service |
y | Show resource YAML |
u | User impersonation |
Resource Navigation Commands
| Command | Description |
|---|
:pods or :po | Navigate to Pods view |
:deployments or :dp | Navigate to Deployments |
:services or :svc | Navigate to Services |
:namespaces or :ns | Navigate to Namespaces |
:nodes or :no | Navigate to Nodes |
:ingresses or :ing | Navigate to Ingresses |
:configmaps or :cm | Navigate to ConfigMaps |
:secrets or :sec | Navigate to Secrets |
:pvcs | Navigate to PersistentVolumeClaims |
:events or :ev | Navigate to Events |
:contexts or :ctx | Switch kubeconfig context |
:all | Show all resource types |
:namespaced-resources | List namespaced resource types |
:cluster-resources | List cluster-scoped resource types |
:crds | Navigate to CustomResourceDefinitions |
:helm | Navigate to Helm releases |
:popeye or :pop | Run Popeye linter |
:xrays | Show X-ray tree view |
:pulse | Show cluster pulse dashboard |
:benchmarks | Run HTTP benchmarks |
Log Viewing Shortcuts
| Shortcut | Description |
|---|
l | Open logs for selected pod |
0 | Show logs for all containers |
1-9 | Show logs for container N |
t | Toggle timestamps in logs |
w | Toggle log line wrapping |
s | Toggle auto-scroll |
/ | Filter log output |
Ctrl+s | Save logs to file |
f | Full-screen log view |
Advanced Usage
Plugins
# ~/.config/k9s/plugins.yaml — add custom menu actions
plugins:
# kubectl neat — clean up managed fields from YAML
neat:
shortCut: Ctrl-N
description: Neat dump
scopes:
- all
command: bash
background: false
args:
- -c
- kubectl neat get --context $CONTEXT -n $NAMESPACE $RESOURCE_NAME $NAME -o yaml | less
# Get pod's resource requests/limits
get-all:
shortCut: g
confirm: false
description: get all
scopes:
- namespaces
command: kubectl
background: false
args:
- get
- all
- -n
- $NAME
- --context
- $CONTEXT
Custom Skins
# ~/.config/k9s/skins/monokai.yaml
k9s:
body:
fgColor: "#f8f8f2"
bgColor: "#272822"
logoColor: "#f92672"
prompt:
fgColor: "#f8f8f2"
bgColor: "#272822"
suggestColor: "#66d9ef"
info:
fgColor: "#66d9ef"
sectionColor: "#a6e22e"
frame:
border:
fgColor: "#75715e"
focusColor: "#f92672"
menu:
fgColor: "#f8f8f2"
keyColor: "#f92672"
crumbs:
fgColor: "#f8f8f2"
bgColor: "#75715e"
activeColor: "#f92672"
status:
newColor: "#a6e22e"
modifyColor: "#66d9ef"
addColor: "#a6e22e"
errorColor: "#f92672"
highlightColor: "#e6db74"
killColor: "#f92672"
completedColor: "#75715e"
Benchmarks (HTTP Load Test)
# Port-forward a service, then run a benchmark from within k9s:
# 1. Navigate to :services
# 2. Select a service and press b to benchmark
# Benchmark results appear in :benchmarks
X-Ray View
# Navigate to :xrays for a hierarchical view
# Shows: Deployment -> ReplicaSet -> Pod -> Container relationships
# Useful for diagnosing ownership chains
# In xray view:
# x — toggle X-ray
# Enter — drill into resource
Common Workflows
Stream Logs from Multiple Pods
# 1. Navigate to :pods
# 2. Filter by label: /app=backend
# 3. Press l on any pod to view logs
# Shift+l to view logs for all selected pods simultaneously
Port-Forward and Test
# 1. Navigate to :services or :pods
# 2. Select the resource
# 3. Press f to start port-forward
# 4. k9s shows the local port in the footer
# 5. Test in another terminal: curl localhost:<local-port>/health
Exec into a Container
# 1. Navigate to :pods
# 2. Select a pod
# 3. Press s (shell) — defaults to /bin/sh
# 4. For multi-container pods: press s and select container
# Pro tip: if /bin/sh is unavailable, set K9S_EXEC_SHELL=bash
export K9S_EXEC_SHELL=/bin/bash
Rolling Restart a Deployment
# 1. Navigate to :deployments
# 2. Select the deployment
# 3. Press r to trigger a rolling restart
# 4. Watch the Pods view update in real time
Investigate a CrashLoopBackOff
# 1. Navigate to :pods
# 2. Find the pod in CrashLoopBackOff (red row)
# 3. Press d to describe — check Events section
# 4. Press l to view logs (previous container logs with p)
# 5. Press y to inspect the YAML spec for resource limits
Tips and Best Practices
- Use
:ctx to switch contexts without leaving k9s — no need to run kubectl config use-context in a separate terminal.
- Filter with
/ accepts label selectors like app=frontend,env=prod as well as plain name substrings.
- Press
? on any view — keybindings are context-sensitive; the help overlay shows only what’s available for the current resource type.
- Use
--readonly in production — prevents accidental deletions when you just need to inspect a cluster.
- Customize
aliases.yaml — short aliases like :dp for deployments speed up navigation significantly.
- Popeye integration (
:popeye) runs a linter against your cluster config, surfacing misconfigurations and resource waste.
- The pulse view (
:pulse) shows a live dashboard of pod counts, CPU/memory, and event rates — good for a quick health check.
- Install the
neat plugin — it strips managedFields from YAML output, making resource specs much easier to read.
Ctrl+w toggles wide output — reveals additional columns like node affinity, QoS class, and nominated node.
- Set
liveViewAutoScroll: true in config — log views will tail automatically without pressing s each time.