Understanding Container Runtime Internals: containerd and runc in Practice
Most of us start our container journey with Docker. We run a simple command, and everything just works. But have you ever wondered what…
Understanding Container Runtime Internals: containerd and runc in Practice
Most of us start our container journey with Docker. We run a simple command, and everything just works. But have you ever wondered what actually happens under the hood?
In this article, I explored container internals using containerd and runc, going beyond Docker to understand how containers really run.
📦 What is containerd?
containerd is a high-level container runtime responsible for managing the full lifecycle of containers. It handles operations such as pulling images, managing storage, creating containers, and running workloads.
It sits between tools like Docker or Kubernetes and the Linux kernel, acting as the core engine that actually runs containers.
🔧 Architecture Flow
Client (ctr / CRI / Docker)
↓
containerd
↓
containerd-shim
↓
runc
↓
Linux Kernel
- containerd daemon → manages images, containers, tasks
- containerd-shim → keeps containers alive independently
- runc → actually runs containers using Linux features
🧠 Key Concepts You Must Know
Understanding containerd becomes easy when you separate these three concepts:
📌 Image
A packaged application (like hello-openshift) stored in registries.
📌 Container
A configured instance of an image — but not running yet.
📌 Task
The actual running process inside a container.
👉 The most important takeaway:
Container ≠ Running Task = Execution
🧪 Hands-On: Container Lifecycle Using containerd (ctr)
To understand this practically, I performed a simple lifecycle task using ctr.
🔹 Step 1: Pull Image
ctr image pull docker.io/openshift/hello-openshift:latest

🔹 Step 2: Create Container
ctr container create docker.io/openshift/hello-openshift:latest mycont2

🔹 Step 3: Start Task
ctr task start -d mycont2

At this point:
- Container exists ✅
- Task is running ✅
Key Observation
If you create a container but don’t start it:
- Container exists
- Task does NOT exist
Once you start it:
- Task appears
- Container becomes active
This is one of the most important concepts in container runtimes.
⚠️ Important Notes About containerd
- containerd does not build images (Docker does)
- It focuses only on runtime
- Used by:
- Kubernetes (via CRI)
- Docker internally
⚙️ Going Deeper: Running a Container Using runc
To truly understand containers, I went one level deeper and used runc directly — without Docker or containerd.
This is where things get interesting.
🔹 What is runc?
runc is a low-level runtime that directly interacts with the Linux kernel to create containers using:
- Namespaces
- cgroups
It does not manage images — it only runs containers from a prepared bundle.
.
🧪 Hands-On with runc
🔹 1. Install runc
First, ensure runc is installed on your system:
apt-get update
apt-get install -y runc

🔹 2. Create Working Directory
Create a directory to store your container bundle:
mkdir mycontainer
cd mycontainer

🔹 3. Create OCI Configuration
Generate the default OCI config file:
runc spec

👉 This creates:
config.json(defines how the container will run)
🔹 4. Create Root Filesystem and Download BusyBox
Create a minimal root filesystem:
mkdir rootfs
cd rootfs
wget https://busybox.net/downloads/binaries/1.21.1/busybox-x86_64
chmod +x busybox-x86_64

🔹 5. Run the Container
Go back and run the container:
cd ~/mycontainer
runc run myrunccontainer

🧠 What I Learned (Real Insight)
This exercise changed how I think about containers.
👉 A container is not a virtual machine 👉 It is just a process with isolation
runc creates that isolation using:
- PID namespace → separate process IDs
- Mount namespace → separate filesystem
- UTS namespace → separate hostname
- Network namespace → separate networking
🔥 The Big Picture
Now everything connects:
- Docker → User-friendly tool
- containerd → Manages lifecycle
- runc → Actually runs the container
👉 In short: containerd manages, runc executes
🚀 Final Thoughts
Before this, containers felt like a black box. After working with containerd and runc directly, things became much clearer.
Understanding these internals is especially useful if you’re working with:
- Kubernetes
- DevOps
- Cloud-native systems
Because at the end of the day:
Containers are just processes with boundaries.
📌 If You’re Learning DevOps
Don’t stop at Docker. Go one layer deeper — that’s where real understanding begins.
메타데이터
- post_id
- 152a1c751ffd
- slug
- understanding-container-runtime-internals-containerd-and-runc-in-practice-152a1c751ffd
- url
- https://medium.com/@shivajibedre67/understanding-container-runtime-internals-containerd-and-runc-in-practice-152a1c751ffd
- canonical_url
- https://medium.com/@shivajibedre67/understanding-container-runtime-internals-containerd-and-runc-in-practice-152a1c751ffd
- author_url
- https://medium.com/@shivajibedre67
- status
- ok
- fetched_at
- 2026-06-23 03:48:11