See what your Kubernetes workloads actually use vs what they request — and get suggestions to right-size them.
Alpha software — This is a personal project, maintained by a single developer with the help of an AI coding agent. Expect rough edges. Contributions welcome, response times may vary.
Read-only — KubeAdjust never modifies your cluster. It only reads resource data. If you apply the suggestions manually, be aware that changing requests/limits on a running Pod triggers a restart.
Most clusters waste resources because requests and limits are set once and never revisited.
Before KubeAdjust: your Pod requests 2Gi memory, but only uses 180Mi. You don't know — it just runs.
After KubeAdjust: you see the over-provisioning instantly, with a concrete suggestion: "Reduce memory request to 256Mi (current P95: 195Mi)".
KubeAdjust shows for every Deployment, StatefulSet and CronJob:
- CPU and memory requests / limits / actual usage side-by-side
- Color-coded status (critical / warning / over-provisioned / healthy)
- Actionable right-sizing suggestions with confidence levels
- Optional sparklines from Prometheus (1h to 7d trends)
- Cluster-wide node overview with capacity, usage, limit overcommit indicator, node conditions (DiskPressure / MemoryPressure / PIDPressure), age, kubelet version, kernel, and OS image
- Namespace limit/request ratios — CPU ×N.N and MEM ×N.N at a glance above the workload list
- Cluster overview stats — live total and per-namespace average CPU/RAM consumed across all visible namespaces (falls back to requests when metrics-server is unavailable)
- Multi-cluster support — configure multiple clusters via
CLUSTERSenv var; tokens are stored per cluster so switching between visited clusters requires no re-authentication - OIDC / SSO authentication — optional SSO login via Keycloak, Dex, Google, or any OIDC provider. Works on managed clusters (EKS, GKE, AKS) with no K8s API server configuration required
- Managed cluster mode — configure a Service Account token (
SA_TOKEN) to skip the login form entirely. Users land directly on the dashboard with no token entry required - Shareable URLs — dashboard state (cluster, view, namespace) is reflected in query parameters. Share a link like
/dashboard?cluster=prod&view=namespaces&ns=paymentsto point someone directly to the right context
| Requirement | Minimum version |
|---|---|
| Kubernetes | 1.21 (batch/v1 CronJobs) |
| metrics-server | any (optional, enables live usage) |
| Prometheus | any (optional, enables sparklines + P95) |
| Go | 1.26+ (build only) |
| Node.js | 25+ (build only) |
The Helm chart lives in a dedicated repository — kubeadjust-helm.
helm repo add kubeadjust https://thomas6013.github.io/kubeadjust-helm
helm repo update
helm install kubeadjust kubeadjust/kubeadjust \
--namespace kubeadjust --create-namespace \
--set ingress.enabled=true \
--set ingress.host=kubeadjust.your-domain.comGet a login token:
kubectl create token kubeadjust -n kubeadjustgit clone https://github.com/thomas6013/kubeadjust.git && cd kubeadjust
export KUBE_API_SERVER=https://<your-cluster-api>
export KUBE_INSECURE_TLS=true # if self-signed cert
docker compose up --buildOpen http://localhost:3000, paste your token, done.
# Backend (Go 1.26+)
cd backend && KUBE_API_SERVER=https://<your-cluster> go run .
# Frontend (Node 25+)
cd frontend && npm install && npm run dev| Variable | Default | Description |
|---|---|---|
KUBE_API_SERVER |
https://kubernetes.default.svc |
Kubernetes API URL |
KUBE_INSECURE_TLS |
false |
Skip TLS verification |
PROMETHEUS_URL |
(empty) | Prometheus URL for sparklines (optional) |
ALLOWED_ORIGINS |
* |
CORS origins (comma-separated) |
PORT |
8080 |
Backend listen port |
OIDC_ENABLED |
false |
Enable OIDC/SSO login |
OIDC_ISSUER_URL |
(empty) | OIDC provider issuer URL |
OIDC_CLIENT_ID |
(empty) | OIDC client ID |
OIDC_CLIENT_SECRET |
(empty) | OIDC client secret |
OIDC_REDIRECT_URL |
(empty) | https://<host>/auth/callback |
SESSION_SECRET |
(empty) | ≥32-char random string for signing session tokens |
SA_TOKEN_<CLUSTER> |
(empty) | SA token for a named cluster, e.g. SA_TOKEN_PROD (OIDC multi-cluster) |
SA_TOKENS |
(empty) | Multi-cluster SA tokens: prod=token1,staging=token2 |
SA_TOKEN |
(empty) | SA token override for the default cluster (normally not needed — uses in-cluster token) |
OIDC_GROUPS |
(empty) | Comma-separated OIDC group names for access control |
Prometheus: set PROMETHEUS_URL to enable sparklines and P95-based suggestions. Works with or without http:// prefix.
metrics-server: required for live usage data. If not installed, enable the sub-chart: --set metrics-server.enabled=true.
Multi-cluster: configure clusters as a Helm map (backend.clusters.prod, backend.clusters.staging, …). Each cluster stores its token independently in sessionStorage — switching between clusters requires no re-authentication. Full Helm values reference is in kubeadjust-helm.
OIDC / SSO: see docs/oidc.md for a full setup guide. Works with any OIDC provider and on managed clusters (EKS, GKE, AKS) — no K8s API server configuration required.
Browser → Next.js (port 3000) → /api/* proxy → Go backend (port 8080)
├── Kubernetes API
├── metrics-server
└── Prometheus (optional)
Token mode (default): stateless — no database, no cache. Your K8s token is forwarded on every request, never stored server-side.
OIDC mode: the backend validates the OIDC ID token and issues a signed session JWT. A pre-configured Service Account token is used for all K8s API calls.
- Read-only RBAC — the Helm ClusterRole only has
get,list,watchpermissions - Token in sessionStorage — cleared on tab close, never logged or persisted
- PromQL injection prevention — strict whitelist validation on all label values
- 10MB response cap —
io.LimitReaderon all upstream responses - Nonce-based CSP — per-request nonce via
proxy.ts, nounsafe-inlineorunsafe-eval - K8s API retry — exponential backoff on transient 5xx/network errors (max 3 attempts)
- URL-encoded path parameters — all K8s API path segments escaped to prevent path traversal
- OIDC / SSO setup — Keycloak, Dex, Azure AD, Okta, Google Workspace
- Multi-cluster — configuring multiple K8s clusters
- Technical audit — security, performance, code quality analysis (v0.22.0)
See CONTRIBUTING.md.
Apache 2.0 — see LICENSE.
