Headroom v0.2.0 — quiet-node and event fixes
2026-11
v0.2.0 fixes the defects found by auditing v0.1.0 and picks up the Go, x/net, grpc and otel vulnerability fixes. Everyone on v0.1.0 should upgrade. The release notes have the full list, the upgrade steps and what was tested.
What changes for you
- Limits now follow your settings on quiet nodes. In v0.1.0, flipping
dryRun, enrolling a namespace or settingmax-cpudid nothing until another pod landed on the node. Now each of those, and a LimitRange change, takes effect within seconds. This is a behaviour change: a config edit can resize every managed pod in the cluster, bounded only by the existing rate limits. - Events reach the API server. v0.1.0's role granted the wrong API group, so
CPULimitAdjustedand the refusal events were rejected on every install. The upgrade changes the manager's ClusterRole to fix this. - Full nodes shrink the pods they should. Pods whose memory request equals their limit, and pods with native sidecars, used to be refused on resize. They now resize.
- LimitRanges cap raises instead of refusing them. A refusal now says which object refused it, through two new
headroom_resizes_totalresults:limitrange-deniedandforbidden. Other 403s no longer count asquota-denied, so check any alert on that label. - Slack matches what the scheduler books. Pod overhead and init-container peaks now count, so limits drop on nodes running those pods.
- Pods under a VPA that writes CPU limits are left alone. A default-mode VPA and Headroom used to overwrite the same limit. Switch the VPA to
RequestsOnlyto use both. webhook.enable=falseworks. It used to leave the controller crash-looping.
Pods that Headroom no longer manages
Pods with pod-level spec.resources are now left alone on every Kubernetes version. Kubernetes 1.35 cannot resize them in place, and from 1.36 a container limit cannot rise past the pod-level CPU limit, which Headroom does not adjust. They get no birth limit and no resizes, so one with no pod-level CPU limit and a container with no CPU limit has no CPU ceiling at all. The runbook covers the optional ways to close that gap. A pod Headroom had already resized keeps that limit until it is recreated.
Known limits
A pod refused a resize keeps its share of the node while it is refused, so that slack sits unused until the cause is fixed. Under a fractional maxLimitRequestRatio, the cap is safe rather than tight, and a small request can hold a pod near its request. Q70 in the backlog tracks that.
Upgrade
helm upgrade --install kube-headroom-crds \
oci://ghcr.io/karlkfi/charts/kube-headroom-crds --version 0.2.0
helm upgrade --install kube-headroom \
oci://ghcr.io/karlkfi/charts/kube-headroom --version 0.2.0 \
--namespace kube-headroom-system --create-namespaceBefore enrolling more namespaces, run scripts/preflight-namespaces.sh, new in this release. It reports limits.cpu quotas and LimitRange caps. The API is still v1alpha1, and the HeadroomConfig schema did not change in this release.