Docker is an open platform that allows you to bundle, send, and run your applications without worrying about the underlying infrastructure. It lets you wrap and execute an application within an isolated environment known as a container. In simple terms, containers help in packing applications and their dependencies together, simplifying the process of delivering our applications to production and avoiding complexities.
Since many of you know about Docker and how it works internally, if you don't, then don't worry, I have an article on container architecture that you can read about here.
We will be discussing Linux containers, as they are the most popular and widely used in production. The Linux kernel plays an important role in container technology, although many people are not aware of it. Docker uses fundamental Linux principles to implement container technology, including Cgroups, namespaces, and the union file system. Let's take a closer look at each of these blocks.
Cgroups ๐ฉ
Cgroups stands for control groups. The role of Cgroups, or control groups, In Linux, is to manage resources such as CPU, memory, and storage for each process. However, in Docker, they are used to manage resources for containers. Since containers are similar to Linux processes, Cgroups are used for container management. Let's delve into an example to comprehend this concept better.
Imagine you have a server with limited resources, and you want to run two containers. As these containers scale, they might require increasing resources. Without a mechanism to allocate resources, they would utilize all available resources, causing disruptions and complications. To resolve this issue, Cgroups come into play, not only within containers but also in the Linux operating system at large. In Short, Cgroups make sure the equitable distribution of resources to run containers without adversely impacting other concurrently running processes.
Namespaces ๐ฉ
Using Cgroups, we have successfully isolated resources. However, another critical issue remains, the isolation of processes. I believe that this is the most crucial feature in Docker, as without it, we cannot fully leverage the advantages of Docker. While Cgroups isolate resources, namespaces isolate processes. To provide a simple example, consider having two or more containers running on your machine. More containers lead to more processes, and you certainly wouldn't want your containers to become confused among these processes right? That's why we have namespaces, to enable process isolation. Namespaces create isolated environments for various aspects of a process, such as process IDs, network interfaces, file systems, and more.
The Docker Engine most commonly uses the following Linux namespaces:
PID Namespace (pid)
In the PID namespace, every process running inside a Docker container gets its own set of numbers for identification. These numbers are separate from the numbers used by processes outside the container.
Network Namespace (net)
In the network namespace, a Docker container has its own isolated space for network-related things, like IP addresses, network settings, and connections.
Mount Namespace (mnt)
In the mount namespace, each Docker container gets its version of these folders, like a separate set of folders for each container.
UTS Namespace (uts)
In the UTS namespace, Docker containers get their name tags or hostnames.
Union FS (union file system) ๐ฉ
Union file system works on top of the other file systems. It mounts multiple directories onto a single root. Let's consider an example to better understand this concept. Suppose we're running a large application inside a container, and we require 8 instances of that container. This means that our container will occupy a significant amount of space. If each container is approximately 1 GB in size, then for 8 containers, we would utilize 8 GB of disk space.
Furthermore, in order to run these 8 instances of the same container, all the image layer files need to be copied into the container namespace. Normally, containers take just a few seconds to start. However, in this scenario, we have a large amount of work to complete, which results in sacrificing the usual quick bootstrap time.
The union file system came into existence to solve these problems. Let's list out the Properties of a Union File System :
Logical merge of multiple layers.
Read-only lower layers, writable upper layer.
Start reading from the upper layer then defaults to lower layers.
Copy on Write (CoW).
Simulate removal from the lower directory through the whiteout file.
In short, a Docker Union File System is a technique that enables efficient building and structuring of Docker images. It optimizes disk space use, simplifies image creation, and allows for container separation. It's an important part of keeping Docker images and containers lightweight and manageable.
I hope you learned something from this blog. If you have, don't forget to drop a like, follow me on Hashnode, and subscribe to my Hashnode newsletter so that you don't miss any future posts. You can also reach out to me on Twitter or LinkedIn. If you have any questions or feedback, feel free to leave a comment below. Thanks for reading and have a great day!