Skip to main content

Command Palette

Search for a command to run...

Mastering Container Fundamentals: From Isolation to Control

Updated
6 min read
Mastering Container Fundamentals: From Isolation to Control
S

I'm Srijan, a passionate DevOps enthusiast currently pursuing a Bachelor's degree in Information Technology. With a love for programming in both Golang and Python, I bring two years of valuable tech experience to the table. As an avid advocate for open source technologies, I'm dedicated to fostering collaborative and innovative solutions within the tech community.

Introduction

Picture a world where developers no longer fret over tangled webs of dependencies and scaling nightmares. Welcome to the realm of containers, where life is a whole lot simpler.

You've likely heard of containers, perhaps even incorporated them into your everyday developer's toolkit. In the upcoming sections, we will delve deeper into the world of containers, gaining a comprehensive understanding of how they offer operating-system-level virtualization by abstracting the "user space" and sharing the host system's kernel. Let's understand how containers work from the ground up.


This blog will be structured into three pivotal sections:

  1. File System Isolation (using chroot)

  2. Process Isolation (using namespaces)

  3. Memory Restrictions (using c-groups)

Also, there are many more things in a container but these three are the building blocks, so in this blog, we will cover only these three.

File System Isolation

To begin with creating our container we need to start with File System Isolation. And for this, we will be using a file called Rootfs.

Rootfs stands for "Root file system" used in Unix-like Operating System. The root file system is the top-level directory structure that contains all the files and directories necessary for the operating system to function properly.

💡
Rootfs contains all the essential directories like " /bin ", " /etc ", " /lib ", "/sbin", "/usr" and more, each serving a specific purpose in the operating system.

Now Let's isolate our file. For this, we will first download rootfs image depending upon our operating system. Here I am downloading an Ubuntu base rootfs file system.

Click here to download the image

After downloading your rootfs image let's untar it. Here I have moved the untared files into a folder named rootfs for easiness.

     tar -xvzf ubuntu-base-14.04-core-amd64.tar.gz -C ./rootfs

This will create a folder named rootfs in your present directory. Here is an example.

As you can see there are all the essential files inside our rootfs folder so now we can start with the process of isolating this.

Running chroot for rootfs.

    sudo chroot rootfs /bin/bash

By running this we enter into our rootfs file and then run the ls -l command. And your output would be something like this.

Great! We have entered it into our file system. But you must be thinking why chroot, what good does it do?

chroot stands for change-root in a Unix-like operating system. When you use the chroot command, you're effectively creating a confined environment where the specified directory becomes the new root directory for all file path references.

chroot
The primary use of chroot is to create a restricted environment, often referred to as a "chroot jail."

To check whether your file is isolated or not, go back to the main file by exiting from the chroot. Write an exit command to do so. Create a new file named 'test.txt' in the directory where your rootfs file is. Here in my case, it is in the Downloads folder.

touch test.txt

As you can see there was no test.txt file earlier but we created one by running the following command.

Now, let's go back into chrooted file by running the same command of chroot and then try to access our newly created file "test.txt" by changing our directory.

The above figure shows it very clearly, we can not. Even after we try to move to the previous directory by running the cd .. command, we are unable to access our file.

Hence we have isolated our rootfs file system. Congratulations on holding this long, it's only a short way from here.


Process Isolation

Any container has its processes isolated from the host machine's process. In other words, there should be no interaction between the processes of the container and the host. But so far our rootfs folder has not achieved this. This is how we can check it.

Firstly, we will use two terminals for this. On the left side is the host system and on the right is chrooted environment. Now check the process and their IDs on both sides.

ps aux

Run this in both environments.

On the chrooted side you might have to mount the proc by running the following command before you run ps aux.

mount -t proc proc /proc

So we know that the processes are not isolated as on both sides process IDs are the same.

To prevent this we will use namespace. So what are namespaces in Linux?

It provides process and resource isolation. To know in-depth check the namespace dropdown below.

Namespaces
In Linux, namespaces are a kernel feature that provides process and resource isolation. They allow multiple processes to have their own independent views of certain resources, such as process IDs (PIDs), network interfaces, file systems, and more. Namespaces are fundamental to containerization technologies like Docker and provide a way to create isolated environments for applications.

Let's now implement this. On the right side exit out of the chrooted environment and run the following

sudo unshare --pid --fork --mount-proc=$PWD/rootfs/proc chroot $PWD/rootfs /bin/bash

This will apply the unshare and also move back to the chrooted environment

Now run ps and ps aux on the right side as well as on the left side.

It is clearly visible that this time the processes are different and hence we can say that our container is now process isolated.


Memory Restriction

Our rootfs file has now gone through file system isolation and Process Isolation, but still, any other process in the host can consume all the memory or memory that is required by any process in a chrooted environment.

To prevent this we will be using Control Groups(cgroup).

"Cgroups, short for Control Groups, are a Linux kernel feature that manages and regulates the allocation of system resources, like CPU and memory, for processes or groups of processes. They are essential for resource control, isolation, and optimization, especially in containerized environments

Now try out the following command to create a Cgroup for memory Control and Set memory limits.

sudo mkdir /sys/fs/cgroup/memory/my_chroot_memory
echo 536870912 | sudo tee /sys/fs/cgroup/memory/my_chroot_memory/memory.limit_in_bytes

Here, 536870912 represents 512MB in bytes.

Now to move Process to Cgroup and verify that our memory limits have been applied successfully.

sudo echo <PID of the process in the chrooted environment> > /sys/fs/cgroup/memory/my_chroot_memory/cgroup.procs
cat /sys/fs/cgroup/memory/my_chroot_memory/memory.usage_in_bytes

Now that we've completed Memory Restriction, our container is primed and ready. But our exploration doesn't have to end here. You can take your container journey even further by exposing host directories to the container using 'mount --bind' and delving into advanced security capabilities if you so choose.


Conclusion

As we wrap up our exploration, our container has successfully traversed the realms of File System Isolation, Process Isolation, and Memory Restriction. But, as we know, containers like Docker or Podman offer a multitude of features that extend far beyond these fundamental aspects. They encompass Networking, Security, Scaling, and much more. Yet, beneath all these functionalities, there's one fundamental truth: it all comes back to Linux. This is why comprehending the core functionality of a container is paramount.

Thank you for joining us on this journey!

A

Very Informative blog...keep it up👏