4.7 Kubernetes Container Runtime Execution
Kubernetes Container Runtime Execution manages container lifecycle through runtime interfaces, ensuring efficient and secure orchestration within Kubernetes clusters.
Kubernetes Container Runtime Execution is the layer of activity in which a CRI-compliant container runtime, guided by the kubelet, actually creates, starts, and manages the processes that make up an application container inside a previously established pod sandbox. It covers the low-level mechanics of image resolution, container process creation through an OCI-compatible runtime, and the ongoing supervision that keeps a container's process tree aligned with the state the kubelet expects.
From CRI Request to Running Process
The CreateContainer and StartContainer Calls
Once a pod sandbox is ready, the kubelet issues a CreateContainer CRI call for each container defined in the pod spec, supplying the container's image reference, command, arguments, environment variables, mounts, and security context. This is followed by a separate StartContainer call that actually transitions the container into a running state.
Delegation to an OCI Runtime
High-level runtimes like containerd and CRI-O do not directly manipulate Linux kernel primitives themselves. Instead, they generate an OCI runtime specification, a JSON document describing namespaces, cgroups, mounts, and capabilities, and hand it off to a low-level OCI-compliant runtime such as runc, which performs the actual clone, pivot_root, and execve system calls that bring the container process into existence.
containerd Shim Architecture
containerd uses a per-container shim process that sits between the containerd daemon and the container's actual process tree. The shim is responsible for reaping the container process, relaying stdio, and reporting exit status, allowing the containerd daemon itself to be restarted or upgraded without killing running containers.
Image Resolution and Pulling
Image Reference Resolution
Before a container can be created, its image must be present locally. The runtime resolves the image reference, which may include a registry hostname, repository path, and tag or digest, and checks its local image store to determine whether a pull is necessary.
ImagePullPolicy Enforcement
The kubelet enforces the pod's imagePullPolicy, which can be Always, IfNotPresent, or Never. This policy determines whether the runtime is instructed to pull a fresh copy of the image even if a local copy already exists, which is particularly relevant for mutable tags such as latest.
Layered Image Storage
Container images are composed of stacked, read-only filesystem layers, typically managed through an overlay filesystem driver such as overlayfs. When a container starts, the runtime creates a new writable layer on top of the image's read-only layers, giving the container its own filesystem view without duplicating the underlying image data.
Namespace and cgroup Application
Namespace Isolation
At container creation time, the runtime applies Linux namespaces, including PID, mount, and UTS namespaces, to isolate the container's process view, filesystem mounts, and hostname from the host and from other containers, while the network and often IPC namespaces are inherited from the shared pod sandbox.
cgroup Assignment
The runtime places the new container process into a cgroup subtree that reflects the resource limits and requests defined in the container spec, as well as the pod's overall QoS classification, enforcing CPU shares, CPU quota, and memory limits at the kernel level.
Security Context Application
Security-related fields from the pod and container spec, such as runAsUser, runAsNonRoot, Linux capabilities, seccomp profiles, and AppArmor or SELinux labels, are translated by the runtime into corresponding OCI runtime spec fields and enforced by the low-level runtime at process creation time.
Volume and Mount Handling
Mount Propagation
Volumes that were prepared by the kubelet's volume manager, such as ConfigMaps, Secrets, PersistentVolumeClaims, or emptyDir volumes, are passed to the runtime as bind mounts to be attached inside the container's mount namespace at the paths specified in the pod spec.
Read-Only and Writable Mounts
The runtime respects the read-only or writable designation of each mount, as well as any mount propagation mode such as HostToContainer or Bidirectional, ensuring that changes made inside the container's mount namespace behave according to the pod's declared expectations.
Process Supervision and Exit Handling
Monitoring Container Exit
The shim or equivalent supervising process monitors the container's main process. When that process exits, the runtime records the exit code and timestamp, which the kubelet later retrieves through a ContainerStatus call to determine whether the container terminated successfully or failed.
Zombie Process Reaping
Because container processes typically run as PID 1 within their own PID namespace, the runtime or shim takes on responsibility for reaping any zombie child processes that PID 1 does not handle itself, preventing process table exhaustion within the container's namespace.
Log Capture
Standard output and standard error streams from the container process are captured by the runtime and written to log files on the node, typically in a structured format that the kubelet can read and expose through the kubectl logs command and the CRI ReadContainerLogs mechanism.
Container Stop and Removal
Graceful Termination
When a container needs to stop, the runtime sends a termination signal, typically SIGTERM, to the container's main process, then waits up to the pod's configured grace period before escalating to SIGKILL if the process has not exited.
Removal and Cleanup
After a container has stopped, the kubelet may issue a RemoveContainer call to delete the container's writable layer and associated metadata from the runtime, reclaiming disk space, particularly during garbage collection of old, terminated containers that exceed retention limits.