k8s-pod-foamtree
k8sfoams is a local, read-only dashboard that answers one question: where is my cluster's requested CPU and memory actually going, and how much room is left on each node?
It visualizes resource requests — what the scheduler reserves — not live usage. That makes it a tool for spotting over-requesting pods and idle headroom, not a performance monitor. It runs on your laptop, reads ~/.kube/config (or $KUBECONFIG) with the standard Kubernetes client, and needs no in-cluster deployment and no metrics-server.
How it works
- Lists nodes (
status.capacity) and all non-terminated pods. Pods inSucceeded/Failedare excluded — they still report requests via the API but no longer reserve anything. - Normalizes CPU to millicores and memory with
bitmath. A pod's effective request ismax(sum(regular containers), max(init containers))— init containers run sequentially, so they are maxed, not summed. This is what the scheduler actually reserves. - Nests the result node → pod → container and adds a synthetic
emptychild per node for free capacity, then serves it as JSON. - A React single-page app (no build step — React and Babel come from a CDN) fetches CPU and memory in parallel, merges them, and renders. The view auto-refreshes every 60 seconds by default.
2D map
A squarified treemap. Each node is a square box, each pod is a foam inside it. A pod with more than one container is split into sub-foams. The empty foam is unused (free) capacity on that node. Pick CPU or Memory with the Resource control.
3D cubes
An isometric view: one plate per node, one cube per pod. A cube encodes both resources at once:
- width × depth (footprint) → CPU request
- height → memory request
- color → node
Both dimensions are square-root scaled, so a 10× larger pod is not 10× wider. Because a cube already shows both resources, the CPU/Memory picker is disabled in 3D and a Zoom slider takes its place.
Switch views with the sidebar View control or the 2D/3D pill in the header. It is client-side state — no flag, no restart. The scene is pure CSS 3D, not WebGL, so it needs no GPU support.
Controls
- Memory unit: MiB, GiB (default), or TiB.
- Context: the sidebar lists every context from your kubeconfig, active one first, tagged by provider. Switching only changes the context inside the k8sfoams web server — your ~/.kube/config file is never modified.
- Refresh: slider from 5 to 600 seconds, plus a Refresh now button.
- Filter: the header search box filters nodes by name.
- Focus: click a node to open an overlay listing its pods with per-pod CPU/memory and container breakdown.
HTTP API
| Route | Returns |
|---|---|
GET / |
the dashboard |
GET /healthcheck |
{"status": "ok"} |
GET /resources/cpu, GET /resources/memory |
treemap JSON; optional ?context=<name>. CPU in millicores, memory in decimal kB |
GET /contexts |
[{"context": "...", "active": true}] |
Installation
Prerequisites
Install uv package manager:
curl -LsSf https://astral.sh/uv/install.sh | sh
Install from source
# Install dependencies and the package in development mode
make restore_dev
# Or install without dev dependencies
make restore
Install via PyPi
pip install k8sfoams
# or with uv
uv pip install k8sfoams
Run k8s-pod-foamtree
After installation, run the application:
# Using make
make run
# Or directly
k8sfoams
# Or with uv run
uv run k8sfoams
Command lines arguments
- host: host IP address on which server listen, default is 127.0.0.1
- port: port number on which server listen, default is 8080
- d: turn on debug mode when server starts
Example:
k8sfoams --host 0.0.0.0 --port 8080 -d
Development
Running tests
# Run all tests (type checking, linting, security, unit tests)
make tests
# Run individual test suites
make unit_tests
make static_code_analysis
make check_types
make bandit
CI/CD targets
For CI/CD environments (GitHub Actions, etc.), use these targets that work with system Python:
make restore_ci # Install dependencies with --system flag
make tests_ci # Run all tests without uv run prefix
Building the package
make build
Clean build artifacts
make clean
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file k8sfoams-1.4.1.tar.gz.
File metadata
- Download URL: k8sfoams-1.4.1.tar.gz
- Upload date:
- Size: 39.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d79d7550e2ada453bea0d13d0fb671c2e2c40ab4257589a351cb47a8d46d62f
|
|
| MD5 |
cf95dad8265bf1ce869c9a5a760606dd
|
|
| BLAKE2b-256 |
76a636bf0d494d511473991c118cebcbee032d559e20e515394bdf6042a79427
|
File details
Details for the file k8sfoams-1.4.1-py3-none-any.whl.
File metadata
- Download URL: k8sfoams-1.4.1-py3-none-any.whl
- Upload date:
- Size: 40.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e9b7b5ec8a8c0b4f7e39b525c6baccd63b98443a9b090137fdf82be74f92020
|
|
| MD5 |
673c81ce5e7e48825889d43bcbeeb2c0
|
|
| BLAKE2b-256 |
19b885b48df2d5c86818eca7dedec07f6ed9d7cd5225f13a8085348e1b2c68e5
|