Isolating Containers Workloads using Namespaces
Namespace
A linux namespace is a kernel construct, which allows for the isolation of an operating system resources, from the perspective of a running process.
or
Namespace makes a process believe that it has uniquely access to resources inside an OS.
Namespace Types:
Mount Namespace:
Isolates the set of filesystem mount points seen by a process in namespace.
UTS Namespace:
Isolates system identifiers for hostname for a process in namespace
PID Namespace:
Isolates the process ID number space for a process in the namespace.
IPC Namespace:
Isolates system V IPC objects, and POSIX message queues, for a process in namespace.
Network Namespace:
Isolates the set of networking resources, for a process in the namespace.
User Namespace:
Isolates the set of User IDs and Groups IDs
Cgroup Namespaces
Isolates view of the cgroup hierarchy root directories and helps in allocating resources.
Identifying Namespaces
Lets have a look at how namespaces look like or are structures insides Linux OS.
Namespaces available inside host operating system are also called root namespace, default namespace or global namespace.
Run below command in host operating system
$ ls -l /proc/self/ns
NOTE: IP of above aws instance differs with upcoming screenshots due to change in instance.
Here, all the Namespaces are present with some long digits of integer values which are called INODE values of namespace.
If a INODE value is different, then that process has its own isolated environment,
Now, check Namespaces inside alpine container and lets see the difference.
INODE values of container namespaces are different than that of Host operating system except of Cgroups
Creating Namespaces
Linux kernel provides 3 important system calls
Clone()
It clones a new process from a calling process and may also place that new process in one or more new namespaces.
unshare()
unshare system call enables the calling process from its existing process to one or more new namespaces.
setns()
It enables the calling process into one or more preexisting namespaces.
Sharing Namespaces
We may also customize namespaces based on our requirement but there also comes the responsibility of handling it with caution. We will see why to be careful.
Above table shows what can be shared and what not while creating a container.
Demo
In order to share PID of newly created container with host and other container. We do the following
Host OS PID Namespaces INODE value
$ docker container run -it --rm --name alpine1 --pid=host alpine sh
Caution: Container has access to all of host's processes
$ docker container run -it --rm --name alpine2 --pid=container:alpine1 alpine sh
Caution:Use Case: Utility container with debugging tools(e.g ptrace)
- Sharing IPC Namespace
$ docker container run -it --rm --name pankaj --ipc=host ubuntu bash
Below is running container with IPC shared with host.
Now lets see the INODE IPC namespace value of our host system.
As we have shared the IPC value of both host and container. So it is same.
The User Namespace is also same due to no use of UserNamespaces remapping.
Caution: Container has access to all of host's IPC objects.
$ docker container run -it --rm --name alpine --ipc=container:pankaj alpine sh
Caution:Use Case: Provides a more secure means of inter-process communication.
Now lets see IPC Inode value of alpine container.
Again it is also same.