Skip to main content

A btop-like Kubernetes TUI dashboard for pods, nodes, CPU, memory, events, PVC usage, alerts, and health checks.

Project description

kutop

Latest release PyPI version Wheel CI Release workflow Python License Issues Stars Last commit

kutop is a modern, like-btop Kubernetes TUI dashboard for the terminal. It turns kubectl and your kubeconfig into a fast, readable view of pods, nodes, namespaces, CPU, memory, restarts, OOMKilled pods, warning events, PVC storage, Alertmanager alerts, and custom health checks.

It is built with Textual and runs locally with no in-cluster agent. kutop is useful when you want a Kubernetes terminal dashboard, pod monitor, node resource view, k8s observability console, or a kubetop/ktop style CLI that feels closer to btop.

Highlights

  • Kubernetes pod and node monitoring directly in the terminal.
  • Live CPU and memory trend sparklines plus per-pod usage-vs-limit gauges.
  • Problem-first signals for Pending, Failed, OOMKilled, CrashLoopBackOff, and restarting workloads.
  • Optional Events, PVC storage, Alertmanager, and health-check panels.
  • Multi-namespace views, sorting, filtering, grouping, and a configurable sidebar for fast cluster triage.
  • Profile-driven thresholds, pod ordering, timezone, alert sources, and health probes so the core stays generic.
  • Headless SVG screenshots for README assets, release notes, and visual QA.
NODES 2/2 │ PODS(R/P/F) 18/1/0 │ RESTARTS 7 │ OOM 1 │ WARN 2 │ ALERTS 3
CPU OVERALL  ▁▂▃▅▆▇█  62%  5.1/16        MEM OVERALL  ▃▄▅▆▇█  74%  47/64Gi
◆ worker-pool  node-a │
  ● api-0 (1/1)        ███████░░░ 70%   STS
  ● worker-9 OOMKilled (0/1)  █████████░ 95%   Deploy

Install

python -m pip install kutop
python -m pip install "kutop[profiles]"   # backward-compatible; YAML support is built in
python -m pip install "kutop[profiles] @ git+https://github.com/ken-jo/kutop.git"
python -m pip install "kutop @ git+https://github.com/ken-jo/kutop.git@v0.2.2"
python -m pip install -e ".[profiles]"   # local development from this directory

The project name, PyPI distribution, and Python package namespace are kutop. The kubetop command and python -m kubetop remain available only as compatibility aliases:

kutop --version
kubetop --version
python -m kutop --version
python -m kubetop --version

The PyPI name kubetop belongs to a different package. Pinned deps: textual==8.2.7, rich==15.0.0. Python 3.9+.

pip install @ken-jo/kutop is not valid pip syntax; use pip install kutop for PyPI releases, or the kutop @ git+https://... form for a GitHub branch, commit, or tag.

Other package managers after a tagged release:

brew tap ken-jo/kutop
brew install kutop

# One-shot install without a separate tap step:
brew install ken-jo/kutop/kutop

curl -fsSL https://ken-jo.github.io/kutop/apt/kutop.gpg \
  | sudo gpg --dearmor -o /usr/share/keyrings/kutop-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/kutop-archive-keyring.gpg] https://ken-jo.github.io/kutop/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/kutop.list
sudo apt update
sudo apt install kutop

Release setup for PyPI, Homebrew, and apt is documented in docs/release.md.

Run

kutop                               # generic view, namespace 'default'
kutop demo-ns 3                     # namespace demo-ns, 3s refresh
kutop ns-a,ns-b                     # multiple namespaces (comma list)
kutop --profile example             # load a profile (ordering / tz / thresholds)
python -m kutop demo-ns 3           # module form
python -m kubetop demo-ns 3         # legacy module alias
kutop --context demo-context demo-ns  # pick a kubeconfig context
kutop --allow-destructive           # enable pod delete (still confirm-gated)
kutop --dump-config                 # print the full annotated config skeleton
kutop --self-test                   # headless smoke test (no cluster), exits 0
kutop --snapshot out.svg            # render one frame to SVG and exit
kutop --snapshot out.svg --detail full  # wider diagnostic capture

Positional namespaces/interval only seed the first run; your in-app choices are saved to ~/.config/kutop/config.yaml and win on the next launch. Existing ~/.config/kubetop and legacy ~/.config/ktop configs are migrated on first load; named profiles are also resolved from those legacy profile directories.

Keybindings

Key Action
q quit
r refresh now
o options / settings (tabbed: View, Columns, Panels, Thresholds, Cluster, Profile)
Tab / b toggle the control sidebar
/ search / filter pods by name
s / S cycle sort column / flip sort direction (or click a column header)
g group pods under their node
l live logs for the focused pod (kubectl logs -f)
d describe the focused pod
x delete the focused pod (only with --allow-destructive, then confirm)
e / v toggle the Events / PVC panels
a / h toggle the Alerts / Health panels (profile-driven)
R reload ~/.config/kutop/config.yaml live

The NODE/POD column is resizable: drag the handle on its header to widen or narrow it (the width persists). Click any column header to sort by it.

Screenshots

kutop can render a headless SVG frame for README images, reviews, and visual QA. It uses live cluster data when reachable and falls back to a generic synthetic frame when not.

Main dashboard with every panel enabled: Summary, Trends, Alerts, the custom Health plugin panel, Pods, Events, and PVC storage:

kutop main dashboard with alerts, custom health, events, and PVC panels

Options modal views:

View Columns Panels
kutop options view tab kutop options columns tab kutop options panels tab
Thresholds Cluster Profile
kutop options thresholds tab kutop options cluster tab kutop options profile tab
kutop --snapshot /tmp/kutop.svg
kutop --snapshot /tmp/kutop-wide.svg --detail wide
kutop --snapshot /tmp/kutop-full.svg --detail full
kutop --snapshot /tmp/kutop-full.svg --detail full --size 220x54
kutop --snapshot /tmp/kutop-options.svg --snapshot-view options-panels --size 96x30

The detail presets are one-shot column layouts:

Detail Default size Use
normal 140x40 Same visible columns as the interactive default
wide 160x44 Prioritises namespace, readiness, phase, reason, owner, node, and key resources
full 220x54 Enables every table column and the PVC panel; increase --size for far-right columns

--snapshot-view accepts main, options-view, options-columns, options-panels, options-thresholds, options-cluster, and options-profile.

Profiles

A profile externalises everything that would otherwise be hardcoded. See kutop/profiles/example.yaml for a fully commented template:

name: my-stack
namespaces: [team-a, team-b]
timezone: ""                  # "" -> host local tz; or an IANA name
ordering:
  - { prefix: ingress-, weight: 10 }
  - { prefix: api-,     weight: 20 }
thresholds:
  cpu_warn: 75
  cpu_crit: 90
  mem_warn: 80
  mem_crit: 92
# alertmanager_url: "/api/v1/namespaces/monitoring/services/<svc>:9093/proxy/api/v2/alerts"

Profiles resolve by name from ~/.config/kutop/profiles/<name>.yaml and the packaged kutop/profiles/ directory, or by explicit path. Without a profile the core runs fully (alphabetical ordering, local timezone, generic thresholds).

Alerts & custom panels (no port-forward)

The Alerts and custom Health panels are opt-in and profile-driven. A /-prefixed URL in alertmanager_url / health_probes[].url is fetched via kubectl get --raw through the Kubernetes API-server proxy, so it uses your kubeconfig auth with no localhost port-forward. Health is a self-contained custom panel plugin (kutop/plugins/health.py); the core does not depend on it.

To update the custom panel without changing code, edit a profile or ~/.config/kutop/config.yaml:

panels:
  health: true
probes:
  health_probes:
    - name: api
      url: /api/v1/namespaces/default/services/api/proxy/health
      fields:
        ready: "ready=(\\w+)"
        latency: "latency_ms=(\\d+)"
    - name: worker
      url: /api/v1/namespaces/default/services/worker/proxy/metrics
      fields:
        lag: "queue_lag=(\\d+)"

For a new code-backed custom panel, use the existing plugin seam:

  1. Add a module under kutop/plugins/<name>.py.
  2. Expose a PLUGIN object with panel_id, is_enabled(config), fetch(fetcher, snapshot), make_panel(), and render(panel, snapshot).
  3. Append the module path to _BUILTIN_PLUGIN_MODULES in kutop/plugins/__init__.py.
  4. Keep plugin fetch/render best-effort: a custom panel must never crash the main Kubernetes dashboard.

How it works

  • kubectl calls run in a background thread worker; the UI thread never blocks, and a refresh is skipped while one is in flight (no thrashing on slow clusters).
  • Node/pod CPU & memory come from kubectl top + kubectl get -o json.
  • PVC usage comes from the kubelet summary API (/api/v1/nodes/<node>/proxy/stats/summary) because metrics-server does not expose it — a node whose summary call fails is skipped, others still report.
  • OOMKilled / CrashLoopBackOff / Pending pods are highlighted distinctly; node rows lead with the nodegroup (EKS/GKE/AKS label), then the short instance name.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kutop-0.2.2.tar.gz (88.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kutop-0.2.2-py3-none-any.whl (88.8 kB view details)

Uploaded Python 3

File details

Details for the file kutop-0.2.2.tar.gz.

File metadata

  • Download URL: kutop-0.2.2.tar.gz
  • Upload date:
  • Size: 88.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kutop-0.2.2.tar.gz
Algorithm Hash digest
SHA256 72d52227049554791ab9f729c2e5a160c279f8576e053daa84bf8849661ec5b8
MD5 043b15d6c9467e0ea45cb629021c2301
BLAKE2b-256 583453c74ccb30a4f9d4ec1cfcb43cbbcf81fd33d7618812919579bde1f229f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for kutop-0.2.2.tar.gz:

Publisher: release.yml on ken-jo/kutop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kutop-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: kutop-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 88.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kutop-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9292138401388d5cc29dd849a49e7aacdde968154c0657427ca3cc1110d0cf11
MD5 d9dfc5daaa9581beb98194d59c57fa55
BLAKE2b-256 b972d854b1beef35573e043076a89368b3098c9b099302b15a73f87c02b60943

See more details on using hashes here.

Provenance

The following attestation bundles were made for kutop-0.2.2-py3-none-any.whl:

Publisher: release.yml on ken-jo/kutop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page