016f93ab4f
Add a monorepo for small single-purpose CLI tools that share a common library, so tools reuse TUI primitives and Kubernetes client bootstrapping instead of duplicating them. - common/tui: direction markers, style palette, width-aware padding/layout - common/kube: in-cluster→kubeconfig client loading + core/metrics clients - podgap: live TUI comparing pod requests/limits vs actual usage, with up/down markers showing per-pod change since the last refresh - Makefile auto-discovers tool directories: make <tool> | all | install
75 lines
2.8 KiB
Markdown
75 lines
2.8 KiB
Markdown
# podgap
|
||
|
||
Shows the **gap** between what Kubernetes pods reserve (requests/limits) and what
|
||
they actually use — live, in a terminal UI that refreshes in place and marks
|
||
whether each pod's usage rose (▲) or fell (▼) since the last refresh. Use it to
|
||
find over-provisioned pods (reserving cores they never touch) and
|
||
under-provisioned ones (running hot against their limits).
|
||
|
||
Usage is summed across all containers in a pod; only `Running` pods are shown.
|
||
Reads live data from the `metrics.k8s.io` API (same source as `kubectl top`).
|
||
|
||
## Build
|
||
|
||
```sh
|
||
make podgap # from the repo root → ./bin/podgap
|
||
# or: go build -o podgap ./podgap
|
||
```
|
||
|
||
## Usage
|
||
|
||
```sh
|
||
podgap # live TUI, all namespaces, refresh every 3s
|
||
podgap --top 15 -i 5s # top 15 by CPU waste, refresh every 5s
|
||
podgap -n observability -s mem-util
|
||
podgap --over # over-provisioned pods (right-size DOWN candidates)
|
||
podgap --under # usage over request or near limit (right-size UP)
|
||
podgap -o json # one-shot machine output (no TUI); also -o csv
|
||
```
|
||
|
||
### Keys
|
||
|
||
| Key | Action |
|
||
|-----|--------|
|
||
| `↑`/`↓`, `j`/`k` | Scroll |
|
||
| `pgup`/`pgdn`, `g`/`G` | Page / jump to top/bottom |
|
||
| `c` / `C` | Sort by CPU waste / CPU utilization |
|
||
| `m` / `M` | Sort by memory waste / memory utilization |
|
||
| `n` | Sort by name |
|
||
| `p` / `space` | Pause / resume auto-refresh |
|
||
| `r` | Refresh now |
|
||
| `q` / `esc` | Quit |
|
||
|
||
### Reading the table
|
||
|
||
```
|
||
NAMESPACE POD CPU req→use/lim ▲ CPU% MEM req→use/lim ▲ MEM% CPU wst MEM wst
|
||
```
|
||
|
||
- **req→use/lim** — configured request, live usage, configured limit (`-` if unset).
|
||
- **▲ / ▼ / ·** — usage rose / fell / held steady since the last refresh.
|
||
- **CPU% / MEM%** — usage as a percentage of the *request*; tinted amber ≥80%,
|
||
red ≥100% (`n/a` if no request set).
|
||
- **wst** (waste) — `request − usage`. Positive = idle reserved capacity;
|
||
negative = over the request (a right-size-*up* candidate).
|
||
|
||
## Flags
|
||
|
||
| Flag | Default | Description |
|
||
|------|---------|-------------|
|
||
| `-n, --namespace` | all | Namespace to inspect |
|
||
| `-s, --sort` | `cpu-waste` | `cpu-waste`, `mem-waste`, `cpu-util`, `mem-util`, `cpu-use`, `mem-use`, `name` |
|
||
| `--top` | `0` (all) | Show only the top N rows |
|
||
| `-i, --interval` | `3s` | TUI refresh interval |
|
||
| `-o, --output` | `tui` | `tui`, `json`, `csv` |
|
||
| `--over` | off | Only over-provisioned pods (util < `--threshold`) |
|
||
| `--under` | off | Only under-provisioned pods |
|
||
| `--threshold` | `0.5` | Utilization fraction defining "over-provisioned" |
|
||
| `--kubeconfig` | — | Path to kubeconfig (default: in-cluster, then `$KUBECONFIG`, then `~/.kube/config`) |
|
||
|
||
## Requirements
|
||
|
||
- A cluster with metrics-server / the `metrics.k8s.io/v1beta1` API (check with
|
||
`kubectl top pods`).
|
||
- RBAC: `list` on `pods` and on `pods.metrics.k8s.io`.
|