What Is a Container Runtime? Explained Simply (2026)
Every container needs a runtime to actually run. Docker has one. Kubernetes has one. They're different. Here's what a container runtime is, why it matters, and how containerd, runc, CRI-O, and Docker relate to each other.
When you run a container — with Docker, Kubernetes, or anything else — something has to actually create and run that container. That something is the container runtime.
Most engineers use containers every day without knowing what the runtime is or why it matters. Here's a clear explanation.
What a Container Runtime Does
A container runtime is software that:
- Creates and manages container processes — starts them, stops them, monitors them
- Sets up isolation — uses Linux namespaces and cgroups to isolate the container from the host
- Manages container images — pulls them from registries, stores layers, unpacks them
- Handles networking and storage — attaches network interfaces and volumes to containers
Without a container runtime, you can't run containers. It's the engine underneath everything else.
The Two Levels of Container Runtime
This is where it gets a bit confusing, so let's separate them clearly.
Low-Level Runtime (OCI Runtime)
Creates and runs the actual container process. Directly interacts with the Linux kernel — namespaces, cgroups, filesystem.
The standard here is the OCI Runtime Specification (Open Container Initiative).
Main example: runc
- Created by Docker, donated to OCI
- Almost every container in production runs via runc (directly or indirectly)
- Very minimal: takes a container bundle, calls the kernel APIs, starts the process
There are alternatives: crun (faster, written in C), gVisor/runsc (sandboxed runtime for security), kata-containers (VM-based isolation).
High-Level Runtime (Container Manager)
Manages the full container lifecycle: pulling images, setting up networking, monitoring containers, providing APIs for other tools.
The high-level runtime talks to the low-level runtime to actually start containers.
Main examples:
- containerd — most widely used in production today
- CRI-O — designed specifically for Kubernetes
- Docker Engine — the original, now wraps containerd underneath
How Docker Fits In
When you run docker run nginx, here's what actually happens:
You → Docker CLI
↓
Docker Daemon
↓
containerd ← high-level runtime
↓
containerd-shim
↓
runc ← low-level runtime (creates actual container)
↓
Linux Kernel (namespaces, cgroups)
Docker is not really one thing — it's a tool (the CLI), a daemon, and under the hood it uses containerd and runc.
When Kubernetes removed "Dockershim" in 2022, it didn't remove the ability to run Docker-built containers. It removed the shim that made Docker (the daemon) work as a Kubernetes runtime. containerd — which Docker itself uses — became the default Kubernetes runtime.
How Kubernetes Uses Container Runtimes
Kubernetes doesn't talk to container runtimes directly. It uses a standard interface: the Container Runtime Interface (CRI).
CRI is a gRPC API that Kubernetes defines. Any runtime that implements CRI can work with Kubernetes.
Kubernetes kubelet
↓
CRI (gRPC API)
↓
containerd or CRI-O
↓
runc
↓
containers
containerd and CRI-O both implement CRI. Docker Engine didn't (which is why Dockershim was needed — it was a translation layer). That translation layer was removed in Kubernetes 1.24.
containerd
The most widely deployed container runtime today. Used by:
- AWS EKS (default)
- GKE
- AKS
- Most Kubernetes distributions
containerd handles:
- Pulling and storing images (content store)
- Creating and managing containers
- Snapshotting filesystems
- Namespace isolation for multiple consumers (Kubernetes gets its own namespace)
# Check which runtime your Kubernetes node uses
kubectl describe node <node-name> | grep "Container Runtime"
# Container Runtime Version: containerd://1.7.x
# On the node directly, use ctr (containerd CLI)
ctr images list
ctr containers listCRI-O
A lightweight runtime built specifically for Kubernetes. If containerd is a general-purpose runtime that supports Kubernetes among other things, CRI-O is designed purely to run Kubernetes workloads.
Used by:
- Red Hat OpenShift (default)
- Some enterprise Kubernetes distributions
Smaller footprint, fewer features than containerd, but very stable for Kubernetes use.
gVisor and Kata Containers — Security Runtimes
For workloads that need extra isolation (multi-tenant environments, untrusted code):
gVisor (runsc): Intercepts system calls in user space. Container processes don't touch the real kernel directly — gVisor acts as a kernel interceptor. Provides strong isolation, some performance overhead.
# Use gVisor runtime class in Kubernetes
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
---
spec:
runtimeClassName: gvisor # Add to pod specKata Containers: Each container runs in its own lightweight VM with a minimal kernel. Very strong isolation, heavier than gVisor, but stronger security guarantees.
What OCI Is
OCI = Open Container Initiative. An industry standards body (under Linux Foundation) that defines:
- OCI Image Spec — what a container image looks like (layers, manifest, config)
- OCI Runtime Spec — how a container runtime must start containers
- OCI Distribution Spec — how registries serve images
Any Docker image is an OCI image. Any OCI image runs on any OCI-compatible runtime. This is why a container built with Docker runs on containerd, CRI-O, or anything else.
Which Runtime Should You Care About?
For most engineers: You never configure the container runtime directly. Kubernetes uses containerd on most managed clusters. You don't interact with it.
What you should know:
- Your containers are likely running via
containerd → runc - Images are OCI-compatible and portable
- Runtime class (
runtimeClassName) lets you choose different runtimes per workload if needed
If you're a platform engineer or cluster admin:
- Know how to check which runtime is running (
kubectl describe node) - Understand containerd's configuration (
/etc/containerd/config.toml) - Know how to configure mirror registries and insecure registries in containerd config
If you're building for security:
- Know that gVisor and Kata exist
- Understand the tradeoffs: isolation vs performance
Quick Summary
| Component | What it is |
|---|---|
runc | Low-level OCI runtime — creates actual container processes |
containerd | High-level runtime — manages images, containers, used by K8s and Docker |
CRI-O | High-level runtime — built specifically for Kubernetes |
Docker Engine | Uses containerd internally; adds developer UX and CLI |
CRI | Kubernetes interface for talking to any container runtime |
OCI | Standards that make containers portable across runtimes |
The container ecosystem looks complicated but it's really just: standards at the bottom (OCI), a layer that manages containers (containerd/CRI-O), and tools that use those (Kubernetes, Docker).
Related: What Is a Pod Lifecycle in Kubernetes | Docker Security Best Practices | What Is a Container Registry
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Kind vs K3d vs Minikube — Best Local Kubernetes in 2026
Three tools for running Kubernetes on your laptop. They're not all equal — kind is fastest for CI, k3d is lightest for dev, minikube has the best feature set. Here's the full comparison.
Best DevOps Tools Every Engineer Should Know in 2026
A comprehensive guide to the essential DevOps tools for containers, CI/CD, infrastructure, monitoring, and security — curated for practicing engineers.
Build a Kubernetes Cluster with kubeadm from Scratch (2026)
Step-by-step guide to building a real multi-node Kubernetes cluster using kubeadm — no managed services, no shortcuts.