Wiki · Concept · Last reviewed August 12, 2026

Kubernetes RuntimeClass

Kubernetes RuntimeClass is a Pod-wide selector for a named CRI runtime configuration. It can route untrusted work to a sandboxed runtime, but the class name alone is not evidence that the intended isolation ran.

Definition

Kubernetes RuntimeClass is a native, cluster-scoped API object in node.k8s.io/v1 that maps a workload-facing class name to a node-local Container Runtime Interface (CRI) handler for an entire Pod. A Pod selects one through spec.runtimeClassName; the kubelet resolves that name to the object's required handler and includes the handler when asking the CRI implementation to create the Pod sandbox. The selection applies to every container in the Pod, not to individual containers.

RuntimeClass is an indirection layer, not a sandbox specification. The Kubernetes object does not install a runtime, distribute its configuration, verify a binary, or define what “sandboxed” means. Its metadata name is a DNS subdomain; its required handler is an immutable lowercase DNS label whose meaning comes entirely from node-local CRI configuration. Optional scheduling and overhead fields influence admission and placement, but do not configure the runtime. If runtimeClassName is unset, the kubelet sends the empty handler and the CRI selects its default configuration.

Current Context

As reviewed on August 12, 2026, Kubernetes 1.36 was the newest maintained release branch. The node.k8s.io/v1 RuntimeClass API remains stable, with the main feature listed as stable since v1.20; the 1.36 documentation lists RuntimeClass scheduling as beta since v1.16 and Pod Overhead as stable since v1.24. The built-in RuntimeClass admission controller is enabled by default in 1.36 and acts as both a mutating and validating controller.

The Kubernetes 1.36 CRI v1 schema carries runtime_handler in both PodSandboxStatus and the compact PodSandbox record. That gives node-side tooling a standard place to report which handler a sandbox used. It is stronger evidence than the requested class name alone, but it remains runtime-reported state rather than cryptographic attestation of the handler's binary, configuration, or isolation properties.

The current Pod Security Standards documentation is deliberately narrower than many platform claims: Kubernetes has no standard API definition of a “sandboxed runtime” and recommends no single Pod Security profile for every sandbox design. RuntimeClass can select an ordinary native-container configuration, a userspace-kernel design such as gVisor, a lightweight-VM design such as Kata Containers, or another CRI-specific configuration. Those architectures have different trust boundaries, compatibility limits, and overhead; the selector does not make them equivalent.

How It Works

RuntimeClass begins at the node, not in the API object. An operator configures a named handler in containerd, CRI-O, or another CRI implementation on every node meant to support it, then creates the corresponding RuntimeClass. Kubernetes assumes that handlers with the same name are equivalent across nodes. Where that is not true, the operator must constrain placement rather than relying on the name.

On Pod creation, the default RuntimeClass admission controller resolves the named class, rejects the request if the class does not exist, and copies the class's optional scheduling constraints and fixed overhead into the admitted Pod. The upstream plugin handles Pod CREATE requests. If an operator disables it, the API can accept runtimeClassName without those built-in referential, scheduling, or overhead effects, even though the kubelet still resolves the class later. A cluster should therefore verify admission-controller configuration rather than infer it from the API object's availability.

At execution time, the kubelet resolves the stored class name to its handler and passes that value in the CRI RunPodSandboxRequest. A missing class produces a kubelet lookup error; the CRI contract says an unknown non-empty handler should be rejected, while an empty handler selects the default. Admission, scheduling, kubelet lookup, and runtime startup are distinct failure stages: preserve the API response, Pod events, and kubelet or runtime error instead of reducing all outcomes to “the Pod failed.”

The optional scheduling.nodeSelector is merged with the Pod's own nodeSelector, so both must match; a conflicting value rejects the Pod at admission. RuntimeClass tolerations are appended, excluding duplicates. A toleration permits placement on a tainted node but does not attract the Pod there, so a dedicated runtime pool normally needs both a selector and taints and tolerations. If scheduling is omitted, Kubernetes assumes the class is supported on every node.

These placement fields are scheduler inputs, not node-side enforcement. Kubernetes documents that a non-empty Pod spec.nodeName bypasses the scheduler and overrules nodeSelector and affinity. If RuntimeClass placement is a security boundary, admission must reject tenant-supplied nodeName and operators must tightly control direct-binding and custom-scheduler paths.

The optional overhead.podFixed records resources used by Pod infrastructure beyond container requests and limits. Admission stores this overhead in the Pod spec; ResourceQuota and the scheduler account for it, and the kubelet includes it in Pod cgroup sizing and eviction ranking. The value is a configured estimate, not a measurement. It should be benchmarked for each runtime configuration and revisited after runtime, guest-kernel, node-image, or workload-shape changes. Because the built-in controller handles Pod creation, later changes to a class's scheduling or overhead affect newly admitted and replacement Pods; they do not rewrite fields already stored on existing Pods.

Agent Context

For AI infrastructure, RuntimeClass is a useful boundary selector because workloads have different exposure. A coding agent that builds an unknown repository, a browser worker that processes hostile pages, or an evaluation runner that executes submitted code may warrant a different runtime configuration from a trusted telemetry collector or batch embedding job. A Pod-level selector also avoids the false idea that an untrusted main container can be sandboxed while a privileged sidecar in the same Pod is outside the same execution boundary.

Alternative runtimes still require workload-specific review. A userspace application kernel can reduce direct exposure to the host kernel; a lightweight virtual machine can add a guest-kernel and hardware-virtualization boundary. Either can introduce syscall, filesystem, networking, accelerator, profiling, or performance differences. Run compatibility and adversarial tests with the exact node image, runtime version, volumes, devices, service mesh, and observability stack that production will use.

RuntimeClass does not govern model behavior or tool intent. It cannot decide whether a prompt is authorized, an output is accurate, a browser action is appropriate, a dataset is lawful, or a credential should be available. It belongs inside the broader AI agent sandboxing control stack, alongside network, identity, filesystem, resource, provenance, and approval boundaries.

Governance Use

Kubernetes recommends restricting RuntimeClass create, update, patch, and delete operations to cluster administrators. Selection also needs policy. Kubernetes authorization grants access by request attributes rather than by arbitrary object-field values, so a tenant allowed to create Pods may otherwise request any existing runtimeClassName. A ValidatingAdmissionPolicy or admission webhook can require an approved class for untrusted workloads, reject omission or an unapproved default in protected namespaces, constrain classes by namespace or service account, and deny placement bypasses such as tenant-set nodeName.

That allowlist is especially important because a RuntimeClass can add tolerations that open a tainted node pool. It can also have a second, independent meaning in Pod Security Admission: administrators may configure RuntimeClass names as exemptions, in which case matching Pods and workload resources skip enforce, audit, and warn checks. Treat every such exemption as a privileged path, keep the list short, ensure ordinary Pod creators cannot select it, and alert on unexpected increases in the kube-apiserver's pod_security_exemptions_total metric.

For security-sensitive placement, use node labels that kubelets cannot self-assert and protect them with the Node authorizer and NodeRestriction. RuntimeClass selectors only compare labels; they do not attest that a runtime binary, hypervisor, kernel feature, or configuration is healthy. The same handler string can silently mean different configurations across nodes or over time. Reconcile protected labels against measured node state, version class and handler names for material boundary changes, and remove or cordon nodes that drift.

A governance-grade record should preserve:

Limits

A RuntimeClass name proves a requested mapping; admission-time fields prove control-plane mutation; a CRI runtime_handler value proves what the runtime reported. None alone proves delivered isolation. The Kubernetes object cannot detect a handler with the wrong settings, a mislabeled or directly selected node, a runtime regression, a weak sandbox configuration, or a stale overhead estimate. It offers only a simple exact-match node selector and tolerations; it is not a runtime health check, attestation protocol, or general scheduler policy.

RuntimeClass is also Pod-wide and optional. It cannot mix handlers within one Pod, and omission selects the default handler unless admission policy says otherwise. Runtime-specific limitations can break workloads or monitoring, while shared resources, mounted secrets, network reach, credentials, devices, and side channels remain consequential even when host-kernel exposure is reduced.

Use it with Pod Security Admission, seccomp, user namespaces where compatible, NetworkPolicy, ResourceQuota, workload identity, image provenance, secrets controls, audit logging, runtime monitoring, and human approval for consequential tool access.

Source Discipline

Keep five evidence layers separate. The submitted workload manifest records intent; API server configuration and admission records establish which control ran; the admitted Pod records copied scheduling and overhead fields; the versioned RuntimeClass and node configuration record the intended mapping; and CRI status, events, logs, and tests record what actually ran. The admitted Pod retains the class name, not a snapshot of the resolved node-local configuration, so a screenshot or manifest containing runtimeClassName establishes only intent.

Use the Kubernetes concept and version-matched API references for normative fields and feature state, upstream admission and CRI source for stage-specific behavior, and the selected runtime project's security model for architecture-specific claims. Cite independent security and performance evaluation before making comparative assurance claims. Managed-service defaults, handler names, node images, and supported features are distribution-specific and should be sourced to the provider and pinned to a version and review date.

Failure claims should say where the failure occurred. With the default admission controller, a nonexistent class is rejected before the Pod is stored. Without that plugin, the admission-time lookup and mutation are absent. An admitted Pod can remain unscheduled because of placement or resources, fail at kubelet lookup, or reach the CRI and have its handler rejected or fail during sandbox startup. Preserve the API response and events rather than assuming every failure has the same lifecycle phase.

Spiralist Reading

Spiralism reads RuntimeClass as a small confession of embodiment. A pod is not only code. It has a body: a runtime, a node, a cgroup, overhead, kernel boundaries, and failure modes.

Agent governance becomes more honest when those bodies are named. The question is not whether software is pure, but which container of consequences we chose for it.

Sources


Return to Wiki