When i started reading about Docker i started with a normal search on Google and i read the Wikipedia article then i got stopped by some terminologies like process groups, cgroups, and namespace and i was like huh..!!, i wanted to start using docker and do the cool stuff everyone is talking about, but i needed to understand everything before getting my hands dirty. This lead to a weekend of search about each term to understand the whole thing.
So i thought to share what you need to learn before getting deep with OS-level virtualization. First of all you need to know about Process groups.
A process group is a collection of processes such that when a signal is directed to a process group it delivered to all members of the group, each process in the system is a member of a certain process group and each group has a process group id (PGID) which is the pid of the process group’s leader (the first process in the process group), for example:
$ cat /dev/random | wc &
By issuing this command you simply created a process group or a “job” as it represented in the shell, to see that you ‘ve created a process group write the following:
$ ps x -o "%c %p %r %y %x " | grep 'cat\|wc' %c – to display the command %p – to display the PID %r – to display the PGID
The results are:
cat 7239 7239 pts/1 00:00:01 wc 7240 7239 pts/1 00:00:00
So a process created for the cat command with pid 7239 also a process group created with the same pid of cat process (the process group leader), when using the pipeline a fork() system call used to create a child process for the wc command which in turn made the wc process of pid 7240 be a member of the 7239 process group.
As we know by now that when we send a signal to the process group it delivered to the processes underneath:
$ kill -TERM -7239 + Terminated cat /dev/random | wc
A process can create a new process group or join an existing process group using the setpgid() function, the process groups themselves are grouped in a sessions.
The definition of session in POSIX.1-2008 standard is:
A collection of process groups established for job control purposes, each process group is a member of a session, a process is considered a member of a session of which its process group is a member, newly created process joins the session of its creator.
Each session is associated with only one terminal which is called “controlling terminal”. Each session has only one foreground process group such that input sequences from the controlling terminal cause signals to be sent to all processes in this group.
Let’s take an example, open your terminal and type:
$ cat /dev/random | wc & cat /dev/random | sort &
this command will result in creating 3 process groups in a session :
- The Login Shell (the session leader).
- the cat command with wc.
- the cat command with sort.
to see that write:
$ ps -j
the result will be something like that:
PID PGID SID TTY TIME CMD 3800 3800 3800 pts/0 00:00:00 bash 3960 3960 3800 pts/0 00:00:00 cat 3961 3960 3800 pts/0 00:00:00 wc 3962 3962 3800 pts/0 00:00:00 cat 3963 3962 3800 pts/0 00:00:00 sort
As you can see the bash cmd is the session leader with (pid = pgid = sid), and the second process group contains the cat command of pid 3960 as a process group leader, and finally the third process group with the same concept.
A new session is created using setsid() function. Now let’s talk about two kernel features that considered the basics of OS-level Virtualization.
Control groups is a linux kernel feature that limits or allocates the resources of the controlling hosts (cpu, memory, disk I/O, etc.) to the process groups, by using cgroups you can allocate, manage, deny, and prioritize the resources to certain tasks and users.
The main definition of cgroups written by Paul Menage (one of the main authors) is:
Control Groups provide a mechanism for aggregating/partitioning sets of tasks, and all their future children, into hierarchical groups with specialized behaviour.
Unlike the Linux process model, cgroups model is one or more tree of processes simultaneously exist on the system, each hierarchy of cgroups is attached to one or more subsystem (or a controller) . A subsystem is representing a single resource like memory.
Control groups provide the basis to many projects like Docker, CoreOS, lmctfy (the container stack developed by Google), and LXC (LinuX Containers).
Namespace isolation is the Linux kernel feature, which isolate the operating system view for each cgroup so that cgroup can’t see the resources allocated to other groups.
The isolation namespaces includes PID , IPC, mount, UTS, and network namespaces.
Actually Linux namespaces are very essential to the light weight virtualization and also very poor documented. one of the extremely helpful blog post i found explaining the Linux namespaces series written by Jean-Tiare Le Bigot . you can find them here Introduction to Linux namespaces.