Docker is a platform to build, ship and run distributed applications – meaning that it runs applications in a distributed fashion across many machines, often with a variety of hardware and OS configurations. For this to be possible, it needs a sandboxing environment capable of abstracting the specifics of the underlying host (for portability), without requiring a complete rewrite of the application (for ubiquity), and without introducing excessive performance overhead (for scale).
Over the last 5 years Linux has gradually gained a collection of features which make this kind of abstraction possible. Those individual features have esoteric names like “control groups”, “namespaces”, “seccomp”, “capabilities”, “apparmor” and so on. But collectively, they are known as “OS containers” or sometimes “lightweight virtualization”. Docker makes heavy use of these features and has become famous for it. Because “containers” are actually an array of complicated, sometimes arcane system features, it has been integrated into a unified low-level component which is simply called as runC. Docker has thrown it’s inertia behind runC and containerd to pave the way for future success.
What is runC?
runC is a lightweight, portable container runtime. It includes all of the plumbing code used by Docker to interact with system features related to containers. It is a standalone binary that allows you to run a single OCI container. This is big because now everyone has a standard way to run a container which creates better portability and creates good code hygiene.
It is designed with the following principles
- Designed for security.
- Usable at large scale, in production, today.
- No dependency on the rest of the Docker platform: just the container runtime and nothing else.
runC integrates well with existing process supervisors to provide a production container runtime environment for applications. It can be used with your existing process monitoring tools and the container will be spawned as a direct child of the process supervisor.
Containers are configured using bundles. A bundle for a container is a directory that includes a specification file named “config.json” and a root filesystem. The root filesystem contains the contents of the container.
RunC is a reference implementation of the Open Container spec, which means both Docker and Cloud Foundry will be running the same code, and both Docker and Cloud Foundry apps will be using Open Containers. It has two major advantages:
- It lets us reuse some awesome code and be part of the Open Container community.
- CF applications will be using not only the same kernel primitives as Docker apps (as they already are today), but also the exact same runtime container engine.
This will minimize incompatibility for Docker lifecycle and result in a first class experience for users, as well as letting us reuse and contribute back to a great open-source code base.
Features of runC are:
- Full support for Linux namespaces, including user namespaces
- Native support for all security features available in Linux: Selinux, Apparmor, seccomp, control groups, capability drop, pivotroot, uid/gid dropping etc. If Linux can do it, runC can do it.
- Native support for live migration, with the help of the CRIU team at Parallels
- Native support of Windows 10 containers is being contributed directly by Microsoft engineers
- Planned native support for Arm, Power, Sparc with direct participation and support from Arm, Intel, Qualcomm, IBM, and the entire hardware manufacturers’ ecosystem.
- Planned native support for bleeding edge hardware features – DPDK, sr-iov, tpm, secure enclave, etc.
- Portable performance profiles, contributed by Google engineers based on their experience deploying containers in production.
- A formally specified configuration format, governed by the Open Container Project under the auspices of the Linux Foundation. In other words: it’s a real standard.
Advantages of runC :
- Embeddable: Containers are started as a child process of runC and can be embedded into various other systems without having to run a Docker daemon.
- Battle Hardened: runC is built on libcontainer, the same container technology powering millions of Docker Engine installations.
- Compatible with Docker: Docker images can be run with runC.
Now we shall see another feature of Docker Engine i.e. containerd
containerd is a daemon with an API and a command line client, to manage containers on one machine. It uses runC to run containers according to the OCI specification. containerd has advanced features such as seccomp and user namespace support as well as checkpoint and restore for cloning and live migration of containers. containerd is a new piece of infrastructure plumbing that allows you to run multiple containers using runC. containerd is claimed to have 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.
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 it is set to 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.
Advantages of containerd:
- Built for Performance: Starting 1000 containers concurrently runs at 126-140 containers per second.
- Easy to use: containerd provides a daemon and a command line client to manage containers.
- Battle Hardened: containerd is built on runC, the same container technology powering millions of Docker Engine installations.
- Compatible with Docker: Docker images can be run with containerd.
Thus Docker Engine 1.11 will use containerd for container supervision. Because containerd ultimately relies on runC and the OCI specification for container execution, this will open the door for the Engine to be able to use any OCI compliant runtime.”
This new architecture will also open the door for potentially making it possible to upgrade the daemon without shutting down all running containers in the future, and will bring a significant performance boost when handling a big amount of containers. Following the plumbing philosophy, a great aspect of this design is that Docker Engine execution layer will be entirely relying on well delimited tools that can be used independently, with the drawback that it won’t ship as a single binary anymore.”[i]
Thank you for reading my blog.
Do share your feedback and comments!!!