Kubernetes Runtime Architecture
Kubernetes Runtime Architecture defines how Kubernetes manages containerized applications through a layered system of control planes and node agents.
Kubernetes Runtime Architecture is the internal layering of the software stack responsible for actually creating and running containers on a node: the Container Runtime Interface (CRI) exposed to the kubelet, a high-level container runtime such as containerd or CRI-O implementing that interface, and a low-level runtime such as runc beneath it, actually invoking the kernel primitives that isolate a container process. Runtime architecture describes how these layers divide responsibility, each narrower in scope than the one above it, down to the point of actual process creation.
The Layered Runtime Stack
Three Formal Layers
The runtime stack is formally divided into three layers: the kubelet, which decides what should run based on PodSpecs; a high-level runtime, which manages the lifecycle of containers and images and exposes the CRI; and a low-level runtime, which performs the actual, OCI-specified mechanics of creating an isolated process.
runtime_stack:
- kubelet # decides what to run
- high_level: # containerd / CRI-O
- image_management
- container_lifecycle
- CRI_server
- low_level: # runc / crun
- namespace_setup
- cgroup_setup
- process_exec
The Container Runtime Interface
gRPC Contract
The CRI is formally a gRPC API defining two services, an ImageService for pulling, listing, and removing images, and a RuntimeService for creating Pod sandboxes and managing container lifecycles within them, together forming the complete contract the kubelet relies on regardless of which specific high-level runtime is installed.
crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps
crictl images
Pod Sandbox as a First-Class CRI Concept
Beneath the Pod abstraction exposed by the API, the CRI formally defines a "Pod sandbox," a shared namespace context created once per Pod, into which individual containers are subsequently placed; this concept exists specifically at the CRI layer to give the shared-namespace semantics of a Pod a concrete runtime implementation.
High-Level Runtime Responsibilities
containerd
containerd formally implements the CRI while additionally managing image pulling and storage, container execution, and low-level runtime invocation, structured internally as a set of plugins around a core gRPC API, with its own separation between a client-facing daemon and the low-level runtime it shells out to for actual process creation.
CRI-O
CRI-O formally implements the exact same CRI contract with a design deliberately scoped to Kubernetes' specific needs, aiming for a minimal surface area rather than the broader feature set of a general-purpose container engine, illustrating that the CRI boundary permits architecturally distinct implementations to be interchangeable from the kubelet's point of view.
Low-Level Runtime Responsibilities
OCI Runtime Specification
A low-level runtime such as runc formally implements the Open Container Initiative (OCI) runtime specification, a standardized, minimal contract for creating a single isolated process given a filesystem bundle and configuration, the narrowest and most foundational layer of the entire runtime stack.
runc spec
runc run codartium-container
Direct Kernel Interaction
At this layer, the runtime formally invokes Linux kernel primitives directly, creating namespaces (PID, mount, network, IPC, UTS), configuring cgroups for resource limits, and setting up the container's root filesystem, translating the OCI bundle's declarative configuration into actual, running kernel-level isolation.
Runtime Classes and Alternative Implementations
RuntimeClass
A RuntimeClass object formally allows a Pod to select among multiple installed low-level runtimes on the same node, such as a standard runc-based runtime alongside a sandboxed alternative like gVisor or Kata Containers, each trading off isolation strength against performance characteristics differently.
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
spec:
runtimeClassName: gvisor
Sandboxed Runtimes
A sandboxed low-level runtime such as gVisor or Kata Containers formally interposes an additional isolation boundary, a user-space kernel emulation layer or a lightweight virtual machine respectively, between the container process and the host kernel, strengthening isolation at the cost of additional overhead compared to runc's direct namespace-based approach.
crictl runp --runtime gvisor sandbox-config.json
Why the Runtime Stack Is Layered This Way
Separating decision-making (kubelet), lifecycle and image management (high-level runtime), and raw process isolation (low-level runtime) into formally distinct layers connected by standardized interfaces, CRI above, the OCI runtime spec below, is what allows any layer to be swapped independently: a different high-level runtime requires no kubelet changes, and a different low-level runtime, selected per Pod via RuntimeClass, requires no changes to the high-level runtime's own logic.