Technical Series: Understanding Containers
I recently realized it would be a great idea to understand how the tools I use in my daily job operate. One of those tools I often use is a container, so I decided to explore the low-level primitives that help containers work.
Containers are used for isolating applications from each other. They run on a host system. Some people refer to containers as lightweight virtual machines, but that is not true because they do not have their OS stack. They share the OS stack of the host system. The host system provides isolation and resource allocation for the containers.
There are three basic building blocks of containers:
- Cgroups: These are Linux primitives that organize, track and limit the process’s resource usage. Essentially, they control what resources a process can use and collect utilization data. Cgroups is an abstract framework implemented by different subsystems such as memory, CPU, devices, etc. Cgroups are mounted on a virtual file system at /sys/fs/cgroup. Each folder in this directory represents a cgroup subsystem. In each subsystem folder, a file called tasks holds the process IDs of processes included in that cgroup.
- Namespaces: Namespaces are Linux primitives that control the visibility of resources and access control. Essentially, they control what resources are visible to a process and what resources a process can access. Linux has many namespaces that cover different resources. Namespaces are visible in the /proc directory. Every process has a directory in /proc. Inside the process directory, the directory ns lists the namespaces attached to a process.
- Union filesystem: Container images are a set of files and directories that make up the userland of a container. These images are tarballs with remarkable capabilities. One of the unique capabilities of images is the concept of layers. Layers are an excellent mechanism for composing file systems. Layers are handy for creating a new derivative image from an existing image. They provide a copy-on-write view of the files in an image. Modified files are moved to the topmost layer because the intermediate and lower layers are immutable. This way, a unified view of two file systems can be provided as a single image while the storage of that image only keeps the modified files.
That’s it, the main components that make up a container. I included some resources that I used to understand containers better. I highly recommend the first reference. It is an excellent demo where you create a simple container.