containerd - What is a shim?
In containerd, a Shim is a small, lightweight process that sits between the containerd daemon and the actual container process.
For every container (or Pod) you run, there is a dedicated shim process (usually named containerd-shim-runc-v2).
Why do we need it?
In the early days of Docker, the daemon managed the containers directly. This had a major flaw: If the Docker daemon crashed or needed an update, every single container on the host would also die. This is because the containers were child processes of the daemon.
The Shim was invented to decouple the container’s lifecycle from the daemon’s lifecycle.
The Three Main Jobs of a Shim
A. Daemonless Execution (The "Survivor" Role)
Once containerd tells the shim to start a container, the shim starts the container and then stays alive. If containerd crashes or is restarted for an upgrade, the shim keeps running the container. When containerd comes back online, it "re-attaches" to the shims to regain control.
B. Exit Code Collection
When a container process finishes, someone needs to be there to "catch" its exit code so that the orchestrator (like Kubernetes) knows if it succeeded or failed. If containerd is down when a container finishes, the Shim stays alive to hold that exit code in memory until containerd is back to collect it.
C. Terminal and I/O Management
The shim keeps the "pipes" open for stdin, stdout, and stderr. It ensures that logs are captured and terminal sessions stay active, even if the main management daemon is busy or restarting.
How the Process Flows
When you start a container, the chain of command looks like this:
containerd(The manager) receives a request to run a container.containerdstarts thecontainerd-shim.- The Shim calls
runc(the low-level runtime) to actually create the container. runcsets up the namespaces/cgroups, starts the container process, and then immediately exits.- The Shim remains, acting as the "parent" of the container process for the rest of its life.
The "Babysitter" Analogy 🍼
Imagine a parent (containerd) hiring a babysitter (the shim) to watch a child (the container).
- The parent gives the instructions and then leaves the room.
- The babysitter stays with the child constantly.
- If the parent is busy or steps out of the house, the child is still safe because the babysitter is there.
- When the child finally goes to sleep (the process exits), the babysitter makes a note of the time and wait for the parent to return to report what happened.
Seeing it in Action
You can see the shims on your Linux system by running:
ps aux | grep containerd-shim
If you have 10 containers running, you will see 10 shim processes. You'll notice they use very little memory (usually a few MBs) because their only job is to wait and watch.