Linux containers & namespaces

Lee Wei
3 min readMay 18, 2021

This is a review for learning the relation between container and Linux namespaces. Before watching this video, I was still a bit confuse with the concept of a container. I thought that containers are always tied to Docker and containers are isolated from the Host OS. However, Docker is just a tool for running containers, we have other alternatives, like Podman, containerd etc. Yes, containers are isolated from the host, but the isolation of what?

Namespaces

The description from Linux namespace manual:

A namespace wraps a global system resource in an abstraction that
makes it appear to the processes within the namespace that they
have their own isolated instance of the global resource…...

I’ll stop you right there. This is my definition of namespace:

Namespaces can limit the visibility of resources for a certain group of processes.

Here are the list of namespaces that we can use:

UTS: isolate Hostname from the host OS. As you can see from the following example, our Macbook Pro’s hostname is different from the container hostname we just ran.

// user@hostname
leewei@Lee-Wei-deMacBook-Pro-2.local
$
$ docker run -ti --rm alpine sh
/ # hostname
ec5ab5f73dcd

User: isolate user and user group, it doesn’t overlap with the user id of the host OS. The users are different between the HostOS and the container.

// Current users in HostOS
$ less /etc/passwd
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
...
$ docker run -ti --rm alpine sh
/ # less /etc/passwd
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...

Mount: isolate mounted file system. We can actually browse our current directory in the container by mounting our current directory.

// HostOS root directory
$ ls /
Applications Library System Users Volumes bin cores dev etc home opt private sbin tmp usr var
// Container root directory
$ docker run -ti --rm alpine sh
/ # ls /
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
// Mount our home directory to container
$ docker run -ti --rm -v `pwd`:`pwd` -w `pwd` alpine sh
/Users/leewei $ ls
Applications Downloads Pictures blog dev keys
Calibre Library Library Postman

PID(Process ID): isolate container process from the host processes. The container cannot see other processes that are running on the HostOS. Each process has a directory /proc/[pid]/.

// HostOS processes
$ ps aux | grep zsh
leewei 56406 1.3 0.0 4372572 6044 s000 S 9:14PM 0:01.71 -zsh
leewei 56559 0.0 0.0 4347896 2748 s001 S+ 9:21PM 0:00.34 -zsh
$ docker run -ti --rm alpine sh
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 sh
7 root 0:00 ps aux

Network: isolate network devices and router from the host. I think this why we need to bind our container port to the host, ehh?🧐

Cgroup: restrict the resources that the container can use. It can prevent containers from using too much resources from the Host machine. The code set up a /sys/fs/cgroup directory for limiting the number of running processes on that container.

Fork Bomb

In that video, I also learned a special technique called fork bomb. This is actually a simple Bash function. Running this function can create a lot of processes and eat up the resources.

:(){ :|:& };:// We define a function called :
:(){
// pipe the output of : to :(recursion)
// also put this in the background by using &
:|:&
// terminate the function definition with ;
// call function :
};:

We can check our maximum process in our current host:

/ # ulimit -a
core file size (blocks) (-c) 0
data seg size (kb) (-d) unlimited
scheduling priority (-e) 0
file size (blocks) (-f) unlimited
pending signals (-i) 31732
max locked memory (kb) (-l) 64
max memory size (kb) (-m) unlimited
open files (-n) 1048576
POSIX message queues (bytes) (-q) 819200
real-time priority (-r) 0
stack size (kb) (-s) 8192
cpu time (seconds) (-t) unlimited
max user processes (-u) unlimited
virtual memory (kb) (-v) unlimited
file locks (-x) unlimited

Set our maximum user process to prevent fork bomb:

ulimit -S -u 100
/ # ulimit -u
100

Conclusion

It’s great to know how container actually works on a Linux machine. Container is very handy to use, however, we can have a security issue if we accidentally messed up with our namespace isolation.

--

--