Quickstart: 15 minutes to a protected node

The shortest path from an empty namespace to kernel-enforced QoS with live telemetry and the management dashboard. Nothing here changes your workloads until you assign a PriorityClass in the final step.

0. Requirements

RequirementWhy
Kubernetes ≥ 1.33 on standard node poolsAutopilot-style managed modes forbid the privileged DaemonSet.
Node kernel ≥ 6.12 with CONFIG_SCHED_CLASS_EXT=y + BTFsched_ext is the enforcement mechanism. Verified today: GKE ≥1.36 (COS-129), EKS AL2023 + Bottlerocket ≥1.33. See platform support.
helm ≥ 3.8, kubectl, cluster-adminThe chart installs RBAC and PriorityClasses.
Network access to ghcr.ioPrebuilt, signed multi-arch images (amd64 + arm64). Building from source remains supported — see the appendix below.

1. Install

One command. Images are prebuilt, multi-arch (amd64 + arm64), signed with keyless cosign, and ship with SPDX SBOM attestations:

helm install temper oci://ghcr.io/byte-lab/charts/temper \
  --namespace temper --create-namespace \
  --set dashboard.enabled=true \
  --set priorityClasses.enabled=true

This deploys the node agent DaemonSet (which loads the kernel scheduler on each node), the management dashboard, RBAC, and the recommended temper-* PriorityClasses. The scheduler plugin, controller, and overcommit webhook are off by default — that is complement mode. Enable them later with scheduler.enabled, controller.enabled, and webhook.enabled.

2. Verify the node is protected

kubectl -n temper get pods        # agent Running on every node
kubectl get node <node> -o jsonpath='{.metadata.annotations.temper\.codes/agent-status}'
# "ready" — the scheduler is attached and enforcing

If a node’s kernel lacks sched_ext, the agent says so loudly in its logs and the node simply stays on the stock scheduler — Temper never degrades a node it cannot protect.

3. Protect your first workload

Give one latency-critical workload a PriorityClass and watch it land in a protected tier:

kubectl patch deployment my-service --type merge \
  -p '{"spec":{"template":{"spec":{"priorityClassName":"temper-critical"}}}}'

Then open the dashboard:

TOKEN=$(kubectl -n temper get secret temper-temper-dashboard-token -o jsonpath='{.data.token}' | base64 -d)
kubectl -n temper port-forward svc/temper-temper-dashboard 8090:8090
# → http://localhost:8090 — paste the token at the login page

You get the hierarchy explorer (cluster → node → pod with live perf, logs, and manifests), the savings view, and audit-logged actions. Tour: management plane.

4. The kill switch (know it before you need it)

Fleet-wide instant revert to the stock kernel scheduler:

kubectl annotate node --all temper.codes/safe-mode-requested=true

Nodes revert to CFS in milliseconds — it is kernel-native sched_ext behavior, and the failover has been measured under load. Remove the annotation to re-engage.

Appendix: building from source

Everything above also works with images you build yourself — the repository ships every Dockerfile. Build with docker build -f docker/agent/Dockerfile . (and docker/dashboard/Dockerfile), push to your registry, and override agent.image.repository/dashboard.image.repository at install. This is also the air-gap path: mirror the images into your internal registry and point the same values at it.

Where next