Docker Namespace and Cgroups
Namespaces are one of a feature in the Linux Kernel and fundamental aspect of containers on Linux. On the other hand, namespaces provide a layer of isolation. Docker uses namespaces of various kinds to provide the isolation that containers need in order to remain portable and refrain from affecting the remainder of the host system. Each aspect of a container runs in a separate namespace and its access is limited to that namespace.
Namespace Types:
- Process ID
- Mount
- IPC (Interprocess communication)
- User (currently experimental support for)
- Network
In my knowledge, the most effective way to prevent privilege-escalation attacks from within a container is to configure your container’s applications to run as unprivileged users. For containers whose processes must run as the root user within the container, you can re-map this user to a less-privileged user on the Docker host. The mapped user is assigned a range of UIDs (0- 65536), but have no privileges on the host machine itself.
when we run docker with root use that easy to install packages and manage containers.Unfortunately, the issue is within docker container users can access the underline host machine as below. That’s a big risk …
# Run a container and mount host /etc onto /root/etc
$ docker run --rm -v /etc:/root/etc -it ubuntu# Make some change on /root/etc/hosts
root@29373h1f1332:/# vi /root/etc/hosts# Exit from the container
root@29373h1f1332:/# exit# Check /etc/hosts and try to delete it
$ cat /etc/hosts
$ rm /etc/hosts
As you can see, it is surprisingly easy, and it’s obvious that Docker wasn’t designed for shared computers. But now, with the User Namespaces, Docker lets you avoid this problem.
Enabling User Namespaces
Mainly Namespace Remapping manages two files:
- /etc/subuid
- /etc/subgid
You can follow the below example to understand how to setup namespace in a docker environment.
# Create a user called "dockremap"
$ sudo adduser dockremapper# Setup subuid and subgid
$ sudo sh -c 'echo dockremap:400000:65536 > /etc/subuid'
$ sudo sh -c 'echo dockremap:400000:65536 > /etc/subgid'$ kasunr@kasunr-desktop:~$ vim /etc/docker/daemon.json {
"userns-remap": "dockremap"}
And restart Docker:
$ sudo /etc/init.d/docker restart
Then you could see new docker containers couldn't have permission to the host machine /etc/
# Run a container and mount host1's /etc onto /root/etc
root@kasunr-desktop:# docker run --rm -v /etc:/root/etc -it ubuntu# try to delete host machine files
$ root@88373h1f1332:/# rm /root/etc/hosts
rm: cannot remove 'hosts': Permission denied
check the permission and file hierarchic new docker setup
root@kasunr-desktop:/var/lib/docker/400000.400000# cd ../
root@kasunr-desktop:/var/lib/docker# ls /var/lib/docker/400000.400000/
aufs builder containerd containers image network plugins runtimes swarm tmp trust volumes
root@kasunr-desktop:/var/lib/docker# ls /var/lib/docker/400000.400000/ -l
total 48
drwx------ 5 400000 400000 4096 Feb 16 12:09 aufs
drwx------ 2 root root 4096 Feb 16 12:09 builder
drwx--x--x 3 root root 4096 Feb 16 12:09 containerd
drwx------ 3 400000 400000 4096 Feb 16 15:06 containers
drwx------ 3 root root 4096 Feb 16 12:09 image
drwxr-x--- 3 root root 4096 Feb 16 12:09 network
drwx------ 4 root root 4096 Feb 16 12:09 plugins
drwx------ 2 root root 4096 Feb 16 12:09 runtimes
drwx------ 2 root root 4096 Feb 16 12:09 swarm
drwx------ 2 400000 400000 4096 Feb 16 12:10 tmp
drwx------ 2 root root 4096 Feb 16 12:09 trust
drwx------ 2 400000 400000 4096 Feb 16 12:09 volumes
To disable user namespaces for a specific container, add the --userns=host
flag to the docker container create
, docker container run
, or docker container exec
command.
More about linux namespace : https://www.linux.com/news/understanding-and-securing-linux-namespaces
Cgroups provide resource limitation and reporting capability within the container space. They allow granular control over what host resources are allocated to the containers and when they are allocated.
Common control groups
- CPU
- Memory
- Network Bandwidth
- Disk
- Priority
we could have a lot of flexibility to manage every cgroup according to our requirements.
Note : More information: Cgroups
For example you could see systemd-cgls and systemd-cgtop commands show how cgroup working on the underline host server.
kasunr@~:# $ systemd-cgls
Using these cgroup policies is very simple. If you for instance want to lock down a Docker container to the first CPU core, you’d append --cpuset-cpus=0
to your docker run
command.And also you could setup the cpu shares which you required.
$ docker run -d --name='kasun_priority_1' --cpuset-cpus=0 --cpu-shares=20 kasuntest1
$ docker run -d --name='kasun_priority_2' --cpuset-cpus=2 --cpu-shares=30 kasuntest2
And we could use the below command to change running container CPU shards.
sudo systemctl set-property docker-7d7ds9s7dhdsda044b29cb873cac460b429cfcbdd0e877c0868eb2a901dbf80.scope CPUShares=512
In Summary, Namespace gives the isolation for the container with the underline host where Cgroup gives the ability to allocate things to those containers. In my point of view, we would get some understanding and practical experience with namespace and Cgroups in the blog. I will share my more experience with the next post !.