Containers: An Empathic Manifesto

Dejanu Alex
4 min readMay 9, 2024

--

Containers have become the defacto compute units of modern cloud-native applications…one might say that containers are the third computing model.

Short history

We’re not going to talk about Linux namespaces or control groups but one needs to acknowledge the history behind containers. Among the first projects that started to build on top of the aforementioned kernel features were Linux containers (LXC) and Let Me Contain That For You (LMCTFY), which focused on providing a good abstraction for process isolation.

Why was Docker important for the industry?

Docker made accessible and consistent container deployment and execution across diverse machines…one might say that it “gave the fire to the ordinary people”.

In the beginning (before version 1.11) Docker had a monolith daemon implementation in which the docker daemon handled the execution of containers. Starting with release 1.11 (which was the first release built on runC and containerd ) Docker shipped a runtime based on OCI standards.

The following are key milestones for the industry:

  • 2015: Docker donated its core container runtime engine runC to OCI as a reference implementation
  • 2017: Docker donated its core container runtime containerd to CNCF

Docker emphasized the aspect of “Shipping the SW from A to B” rather than the technical details of it.

When we use Docker, what actually happens is that docker talks with containerd which “drives” runC

Standardization and container runtimes

The rapid growth in interest and usage of container-based solutions has led to the need to establish standards around container technology.

OCI specs

The Open Container Initiative (OCI) — established in June 2015 by Docker and other industry leaders i.e. CoreOS, promotes common standards and specifications around containers more exactly: Runtime Specification (runtime-spec), Image Specification (image-spec) and Distribution Specification (distribution-spec).

CNCF container runtimes

containerd is a high-level container runtime on top of runC which manages namespaces, cgroups, union file systems, networking capabilities, and more for the container’s life cycle within the host. One key component of containerd is its default use of OCI-compliant runtimes i.e. runC.

runC is a low-level container runtime that implements the OCI runtime specification and interacts with the kernel to run the container.

source containerd.io

From a broad perspective, an OCI implementation would download an OCI Image and then unpack that image into an OCI Runtime filesystem bundle, that would be run by an OCI Runtime.

  • The Image Specification defines the requirements for an OCI-compliant image which consists of a manifest, an image index(optional), a set of filesystem layers (layout representing the contents of an image), and a configuration.
  • The Runtime Specification outlines how to run a “filesystem bundle” that is unpacked on disk.
  • The Distribution Specification mechanism that facilitates and standardizes the distribution of content i.e. act of uploading/downloading blobs and manifests to a registry.

Curious about how to spin up a container using runc, check out this quick killercoda lab.

runc

Kubernetes and container runtimes

Kubernetes doesn’t know how to run containers by itself, it relies on a container runtime to be installed on each node in the cluster so that pods can run there.

The flow is as follows: Kubernetes contacts the kubelet to launch a pod, and the kubelet forwards the request to the CRI-O daemon via the Kubernetes Container Runtime interface.

CRI is a plugin interface that enables kubelet to use a wide variety of container runtimes, without the need to recompile. CRI consists of protocol buffers and gRPC API.

k8s container runtimes

The beauty of design resides in two elements

demo: Handling Docker images

Conclusions

Setting the code to run in the container is usually the easy part; the hard part is to get your code to drop its assumption about the infrastructure it’s running on. Therefore by abstracting the user space and not the entire operating system, containers eliminate the toil of starting and maintaining independent instances of operating systems.

At the end of the day, containers are just a fancy way to run a process, needless to say, containers offer more benefits for distributed applications (particularly microservices ) than for larger, monolithic ones.

--

--

Dejanu Alex
Dejanu Alex

Written by Dejanu Alex

Seasoned DevOps engineer — Jack of all trades master of None

No responses yet