What’s the difference between runc, containerd, docker? Well, I asked myself the exact same question…
Container space seems to be very fragmented in the past months and it’s getting more and more crowded every day. To be honest I miss times, when there was just one monolithic Docker and basically everything in the container lifecycle was Docker. Right now it’s pretty much the opposite. I kind of lost track of all these new projects appearing on the horizon like containerd, runc, kata containers, cri-o, rkt… Are these like on the same level as Docker? What’s actually Docker nowadays? I had to do quite some reading to answer that question for myself. And since I already did that I decided to share that in a blogpost.
I was already pretty deep in the research and started to understand how many of these projects fit together when I run into this container runtime blog series and I must say I would not be able to explain the confusion around the what actually is a container runtime better than Ian Lewis did. So I think you should definitely start there…
So did you finish reading that? Good… Now we can build on top of that.
So in the past it was just Docker. In 2016 the container space was booming and docker decided to split the monolith into separate parts, some of which other projects can even build on — that’s how containerd happened. That was Docker 1.11 (so pretty much ancient history). Containerd is a daemon that acts as API facade for various container runtimes and OS. When using containerd, you no longer work with syscalls, instead you work with higher-level entities like snapshot and container — the rest is abstracted away. If you want to understand containerd even more in depth, there’s a design documentation in their GitHub repo. Under the hood, containerd uses runc to do all the linux work.
What’s not seem to be discussed that much is that with Docker 1.11 another separate component is containerd-shim. This is the parent process of every container started and it also allows daemon-less containers (so e.g. upgrading docker daemon without restarting all your containers, which was a big pain, yay!).
So what is actually Docker nowadays? Docker still provides nice end-to-end experience when it comes to containers especially for developers. Docker consists of several components — the one we are most familiar with is the proprietary and user facing is dockerd. Dockerd is the thing that helps you work with volumes, networking or even orchestration. And of course it can launch containers or manage images as well, but containerd is listening on linux socket and this is just translated to calls to its GRPC API.
Unfortunately that’s not the end of the story. There’s still many projects that we haven’t even touched. Let’s throw some more container runtime world names into the post before we end.
CRI is getting a lot of publicity which is an interface to decouple Kubernetes from various runtimes — CRI-O is an implementation of that which is OCI compliant. To this you can plug for example containerd (through cri-containerd) or rkt — where cri-o stands is nicely described in this blogpost. But by default it uses only runc.
But let’s go back to rkt which is probably the closest to an actual Docker competitor — you can read all about their differences on this page. It’s a project originally created by CoreOS, now it belongs to RedHat. Another pretty interesting project recently made 1.0 is kata containers. It is claiming to be all the isolation you love from VMs but that can be easily plugged into all the tooling we have around containers — this means you can spin up these VMs (or kata containers if you wish) through docker or Kubernetes.
The container space is really exciting and it’s hard to keep up with the amount of new and exciting projects that appear every month.