Deep dive into Container
In this tutorial, we are going to discuss deep dive into containers. If we do DevOps, we are probably familiar with Docker, Kubernetes, and Containers. But have we ever wondered what the hell is docker? What are containers? Docker is a container? Docker is not a container and I will explain what it is in this tutorial.
A container is a form of OS virtualization that might be used to run an application. Inside a container, there should be all the necessary executables, binary code, libraries, and configuration files to run the application. So how does the container do that?
To do that, the container is built from a few new features of the Linux kernel, of which the two main features are “namespaces” and “cgroups”.
Namespaces are one of a feature in the Linux Kernel and a fundamental aspect of containers on Linux. On the other hand, namespaces provide a layer of isolation. Namespaces are a feature of the Linux kernel that partitions kernel resources such that one set of processes sees one set of resources while another set of processes sees a different set of resources.
This is a feature of Linux that allows us to create something like a virtual machine, quite similar to the function of virtual machine tools. This main feature makes our process completely separate from the other processes.
There are different types of namespaces available in Linux.
- PID — The PID namespace allows us to create separate processes.
- Network — The networking namespace allows us to run the program on any port without conflict with other processes running on the same computer.
- Interprocess communication (IPC) namespace has its own IPC resources, for example, POSIX message queues.
- Mount — Mount namespace allows you to mount and unmount the filesystem without affecting the host filesystem.
- UNIX Time-Sharing (UTS) namespace allows a single system to appear to have different host and domain names for different processes.
Creating a Linux namespace is quite simple, we use a package called
unshare to create a separate process.
[email protected]:~$ sudo unshare --fork --pid --mount-proc bash
It will create a separate process and assign the bash shell to it.
Now Try to run the
[email protected]:~# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.2 0.0 22740 4968 pts/0 S 16:07 0:00 bash root 9 0.0 0.0 37372 3236 pts/0 R+ 16:08 0:00 ps aux
Here we will see it has only two processes running,
ps. Now you can open another terminal on the server and type the command
[email protected]:~$ ps aux | grep unshare root 1627 0.0 0.0 65604 4232 pts/0 S 16:07 0:00 sudo unshare --fork --pid --mount-proc bash root 1628 0.0 0.0 7460 724 pts/0 S 16:07 0:00 unshare --fork --pid --mount-proc bash ashok 15718 0.0 0.0 14428 1008 pts/2 S+ 17:34 0:00 grep --color=auto unshare
You will see the
unshare process is running, you can think it similar to the containers listed when you run the
docker ps command. To exit the namespace, type
[email protected]:~# exit
Now when you run the
ps aux command again on the server, we will see that the
unshare process earlier is gone.
We could have created a process separate from the other process with Linux namespaces. But if we create multiple namespaces, then how can we limit the resources of each namespace so that it doesn’t take up the resources of another namespace?
Luckily, in 2007 some people developed cgroups just for us. This is a Linux feature that allows you to limit the resources of a process. Cgroups will determine the limit of CPU and Memory that a process can use.
Cgroups (abbreviated from control groups) is a Linux kernel feature that limits, accounts for, and isolates the resource usage (CPU, memory, disk I/O, network, etc.) of a collection of processes. The control groups functionality was merged into the Linux kernel mainline in kernel version 2.6.24, which was released in January 2008.
Following are the common resources that can be controlled with cgroups.
- CPU: limit the amount of CPU time used by a group of processes
- Memory: limit the amount of memory used by a group of processes
- I/O: limit the amount of disk I/O used by a group of processes
- Network: limit the amount of network bandwidth used by a group of processes