Virtualization & Containers

the OCI runtime

/ OH-see-eye /

When you type a command to start a container, something has to do the actual low-level work of turning a downloaded image into a live, isolated process. That something is the container runtime, and the Open Container Initiative (OCI) standardised exactly what it must do so that any tool can drive any compliant runtime. The OCI defines two specs that fit together: the image spec (what a container image looks like, covered separately) and the runtime spec (how to take an unpacked image plus a configuration and actually run it). The reference low-level runtime is a small program called runc.

Walk through what the runtime does, because it ties this whole field together. It is handed a directory - the unpacked root filesystem of the image - and a config.json that describes the desired container: which namespaces to create, which cgroup limits to apply, what to mount, which user to run as, and the command to execute. The runtime then makes the kernel calls you have already met: it creates the requested namespaces (PID, net, mount, and so on) so the process gets its isolated view, places the process in cgroups so its resources are bounded, sets up the root filesystem, drops privileges, and finally executes the container's entry process. From the kernel's point of view there is no 'container' object at all - just a process wearing namespaces and cgroups, exactly as the runtime arranged.

Why the layering matters: this clean split means the high-level tools you use day to day (Docker, Podman, Kubernetes via its CRI) handle images, networking, and orchestration, then delegate the final 'actually create the container' step to a small, swappable OCI runtime like runc. Because the interface is standardised, you can replace runc with a different runtime that creates a stronger sandbox without changing anything above it - which is precisely how microVM runtimes and user-space-kernel runtimes plug in. The honest framing: the OCI runtime is the thin, boring, essential piece that converts a spec into real namespaces and cgroups; the magic of containers is mostly the kernel features it invokes, standardised so the ecosystem interoperates.

Given a root filesystem and a config.json, the command 'runc run mycontainer' creates the namespaces and cgroups named in the config and execs the listed process. Higher tools like Docker prepare the image and config, then call a runc-compatible runtime to do this final step.

runc turns an image plus config.json into real namespaces and cgroups, then execs the process.

There is no 'container' kernel object - the OCI runtime just assembles namespaces, cgroups, and a root filesystem around a process. Because the interface is standardised, runc can be swapped for a stronger-isolation runtime (a microVM or user-space-kernel sandbox) with no change above it.

Also called
runccontainer runtimeOpen Container Initiative runtimeOCI 容器執行時