Kubernetes Container Process Startup
Kubernetes Container Process Startup explains how containers are launched, managed, and maintained within a Kubernetes cluster environment.
Kubernetes Container Process Startup is the final, low-level stage of bringing a container to life on a node, encompassing the sequence of kernel and operating-system operations that transform a resolved container image and a fully configured container specification into an actual running process, executed by the OCI-compliant low-level runtime that the higher-level container runtime delegates to. While the kubelet and CRI runtime handle orchestration-level decisions — what to run, when, and with what configuration — container process startup is where those decisions are converted into concrete system calls that create namespaces, apply cgroup limits, and finally exec the container's entrypoint binary.
The Handoff to the Low-Level Runtime
From CRI Runtime to OCI Runtime
High-level runtimes such as containerd and CRI-O do not construct processes directly; instead, once the kubelet's CreateContainer and StartContainer calls have been received, the high-level runtime generates an OCI runtime bundle — a filesystem root plus a config.json describing the container's namespaces, mounts, cgroup path, capabilities, and process arguments — and invokes a low-level OCI runtime such as runc to actually create and start the process.
The OCI Runtime Specification
This handoff is governed by the OCI Runtime Specification, a vendor-neutral standard that defines exactly what fields a container configuration must contain and what operations a compliant runtime must support, which is what allows different high-level runtimes to rely on the same set of interchangeable low-level runtime implementations.
Constructing the Process Environment
Namespace Joining and Creation
At startup, the low-level runtime either creates new namespaces for the container or, for namespaces shared at the Pod level such as network and IPC, joins the container to namespaces already established by the Pod's sandbox; PID and mount namespaces are typically created fresh for each container unless the Pod spec explicitly requests a shared process namespace.
Cgroup Placement
The runtime places the new process into a cgroup already prepared according to the container's resource requests and limits, applying CPU shares or quota, memory limits, and, on cgroup v2 systems, unified resource controls, before the process begins executing so that resource constraints are active from the very first instruction.
Filesystem and Mount Preparation
The runtime assembles the container's root filesystem from the resolved image layers using a union or overlay filesystem, applies any volume mounts specified in the Pod spec by bind-mounting host or networked storage into the container's mount namespace, and sets up special filesystems such as /proc and /dev scoped to the container's own namespaces.
Security Context Application
Security-relevant settings — the user and group the process runs as, Linux capabilities added or dropped, a seccomp profile restricting available syscalls, and SELinux or AppArmor labels — are all applied as part of process creation, typically through the clone and execve system call sequence combined with capability-setting calls before the entrypoint binary is actually executed.
The Exec Step
Entrypoint Resolution
Before exec occurs, the runtime resolves the container's actual entrypoint by combining the image's built-in ENTRYPOINT and CMD with any command and args overrides specified in the Pod spec's container definition, producing the final argument vector that becomes the container's PID 1.
PID 1 Responsibilities
Because the container's main process typically runs as PID 1 within its own PID namespace, it inherits certain kernel responsibilities normally handled by an init system, such as reaping zombie child processes and correctly handling termination signals; applications that do not account for this can produce orphaned processes or fail to shut down cleanly on SIGTERM, which is why some workloads deliberately run a minimal init process ahead of their real entrypoint.
Reporting Back to the Runtime and kubelet
Once the exec succeeds, the low-level runtime reports the process as started to the high-level runtime, which updates the container's recorded state so that a subsequent ContainerStatus call from the kubelet reflects the container as running, completing the chain of state propagation from raw process startup back up to the orchestration layer.
Failure Modes During Startup
CreateContainerError and CrashLoopBackOff
If any step in this sequence fails — an invalid entrypoint, a missing binary, insufficient permissions, or a security policy violation — the low-level runtime returns an error that propagates up as a failed container creation, and if the container does start but exits immediately due to an application-level fault, repeated restart attempts under the Pod's restart policy surface as CrashLoopBackOff in the container's status.
Startup Probes and Slow-Starting Applications
For applications with substantial initialization time, a startup probe delays the point at which liveness and readiness probes begin to influence process supervision, preventing the kubelet from prematurely restarting a container whose process has started but whose application logic has not yet finished initializing.