Cloud Native 15 min read

Understanding RunC and Containerd: From OCI Specs to Cloud‑Native Runtimes

RunC, the OCI‑compliant low‑level container runtime originally derived from Docker’s libcontainer, works alongside high‑level runtimes like containerd and cri‑o, and this article explains its origins, lifecycle states, usage commands, and how it fits into the broader cloud‑native container ecosystem.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Understanding RunC and Containerd: From OCI Specs to Cloud‑Native Runtimes

What is RunC

Previous article "The Real Tool for Running Containers: Deep Dive into runc and OCI Specification" already explained Runc and OCI. Here we clarify the concept.

Docker, Google, CoreOS and other vendors created the Open Container Initiative (OCI), which defines two main specifications: the runtime spec and the image spec.

OCI’s runtime spec defines the container’s lifecycle states and the commands a runtime must provide. The diagram below shows the container state transition:

init state: a custom initial state indicating no container exists.

creating: the container is being created with the create command.

created: the container exists but is not running; the image and configuration are valid.

running: the container’s processes are up and executing the user’s workload.

stopped: the container has finished, errored, or been stopped; its information remains on the platform.

Origin of RunC

RunC was migrated from Docker’s libcontainer and implements container start/stop and resource isolation. Docker donated RunC to OCI as the reference implementation of the OCI runtime spec. Docker ships a docker‑runc implementation, and containerd can be configured to use a specific RunC implementation.

When you run a Docker container, the steps are:

Pull the image.

Extract the image into a bundle (a layered filesystem).

Run the container from the bundle.

Docker standardizes only the third step; the earlier steps are handled by the container runtime. OCI defines “run container” as the only required runtime functionality, which has caused confusion about what a container runtime actually does.

RunC can create OCI‑compliant containers, and other implementations such as Kata and gVisor also conform to the OCI spec.

How to use runc

<code># create the bundle
mkdir -p /mycontainer/rootfs

# use Docker to export a rootfs into the bundle
docker export $(docker create busybox) | tar -C /mycontainer/rootfs -xvf -

# generate the spec (default entrypoint is /bin/sh)
cd /mycontainer
runc spec

# launch the container
sudo -i
cd /mycontainer
runc run mycontainerid

# list containers
runc list

# stop the container
runc kill mycontainerid

# clean up
runc delete mycontainerid
</code>

runc can start any number of containers from the command line, but for automation a higher‑level container manager is needed.

Low‑Level vs High‑Level container runtimes

Examples of container runtimes include runc, LXC, lmctfy, Docker, rkt, cri‑o. Some, like containerd and cri‑o, use runc as the low‑level runtime while providing higher‑level features such as image management and APIs.

Low‑Level runtimes implement namespaces and cgroups to isolate resources. Implementations include:

runc – the most widely used low‑level runtime.

runv – a VM‑based OCI runtime (used by Kata and Firecracker).

runsc – Google’s gVisor sandbox.

wasm – experimental sandbox for WebAssembly containers.

High‑Level runtimes add image handling, registry interaction, networking, and API surfaces. They are typically used by developers who need more than just isolation, and they often delegate the actual container execution to a low‑level runtime.

Kubernetes only needs to support a high‑level runtime such as containerd; containerd then selects an appropriate low‑level runtime (runc, gVisor, runv, etc.) according to the OCI spec.

containerd

containerd originated as part of Docker but is now an independent daemon that manages container lifecycles, image storage, networking, and more. It uses runc under the hood to actually run containers.

Key responsibilities of containerd include:

Managing container lifecycle (create, start, stop, delete).

Pulling and pushing container images.

Storage management for images and container data.

Invoking runc to run containers.

Managing container network interfaces.

containerd runs on Linux, Windows, and ARM platforms. Above the low‑level runtimes are containerd components (runtime, core, API, backend, store, metadata) and clients such as the ctr CLI and Kubernetes via the CRI.

Major cloud platforms (Google Cloud, Docker, IBM Cloud, Azure, Rancher) support containerd, often as the default runtime because it offers a shorter call chain, fewer components, and lower resource usage.

Docker

Docker, released in 2013, introduced a complete container ecosystem: image format, Dockerfile builds, image management, container management, registry push/pull, and the docker run command.

Since Docker 1.11, the daemon has been split into modular components that align with OCI standards. containerd now handles the runtime and lifecycle, while other modules manage builds, volumes, logging, etc.

When a Docker container is created, the Docker daemon delegates the request to containerd, which spawns a containerd‑shim process to act as the container’s parent. This shim provides live‑restore capabilities and isolates the container’s PID 1 process from the daemon.

runc follows the OCI documentation to create a compliant container, and the actual launch is performed by containerd‑shim invoking runc.

References

https://www.ianlewis.org/en/container-runtimes-part-1-introduction-container-r

https://iximiuz.com/en/posts/journey-from-containerization-to-orchestration-and-beyond/#container-management

https://github.com/moby/moby/issues/35873#issuecomment-386467562

https://fankangbest.github.io/2017/11/24/containerd-containerd-shim%E5%92%8Crunc%E7%9A%84%E4%BE%9D%E5%AD%98%E5%85%B3%E7%B3%BB/

cloud-nativedockercontainerdrunccontainer runtimeOCI
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.