Docker containerd integration

In an effort to make Docker Engine smaller, better, faster, stronger, we looked for components of the current engine that we can break out into separate projects and improve along the way. One of those components is the Docker runtime for managing containers. With standalone runtimes like runc, we need a clean integration point for adding runc to the stack as well as managing 100s of containers.

So we started the containerd project to move the container supervision out of the core Docker Engine and into a separate daemon. containerd has full support for starting OCI bundles and managing their lifecycle. This allows users to replace the runc binary on their system with an alternate runtime and get the benefits of still using Docker’s API.

So why another project? Why are you all busy refactoring things instead of fixing real issues? Well…

containerd improves on parallel container start times so if you need to launch multiple containers as fast as possible you should see improvements with this release. On my laptop, I can launch 100 containers in 1.64 seconds. That is 60 containers per second. When starting a container most of the time is spent within syscalls and system level operations. It does not make sense to launch all 100 containers concurrently since the majority of the startup time is mostly spent waiting on hardware/kernel to complete the operations. containerd uses events to schedule container start requests and various other operations lock free. It has a configurable limit to how many containers it will start concurrently, by default we have it set at 10 workers. This allows you to make as many API requests as you want and containerd will start containers as fast as it can without totally overwhelming the system.

Containerd
Because the containerd integration also brings in runc the model for starting a container has changed a little in order to support the OCI runtime specification. When you make a request to Docker Engine we will do all the image management stuff as normal but after that the first thing is to generate an OCI bundle for the container. This will contain information from the image that you pulled and runtime information that you provided via the API. After the configuration has been generated Docker will mount the container’s root filesystem inside the bundle before making the call to containerd to start the container.

containerd’s API is very simple. We decided to build it with gRPC for performance as well as the ability to easily create client libraries. The basic request to start a container via the API is to only provide the path to the OCI bundle and the ID for the container. By keeping the API simple we minimize the changes in the API when new features are added.

We also have very minimal state in containerd. After the container has exited Docker will delete the generated bundle and any runtime state will be gone. This allows us to separate container runtime state on disk to only live as long as the container is running.

You should start to see more features like live migration and the ability to reattach to running containers so that Docker can be upgraded without affecting your containers in future releases of Docker as a result of this integration.

Give containerd a try with the latest Docker Engine 1.11 release. To install on your laptop, download Docker Toolbox. For other platforms, check out the installation instructions.


Learn More about Docker