How containers actually function and how Docker works
Made by: Soham Sen
# Install libcgroup and memtester
# In Arch linux, to install, run: yay -S libcgroup-git memtester
# Let's create a cgroup now
$ sudo cgcreate -a username -g memory:iambadatnaminggroups
# And then limit memory to 10 MB (10000000 bytes) and run memtester in it
$ echo 10000000 > /sys/fs/cgroup/iambadatnaminggroups/memory.max
$ sudo cgexec -g memory:iambadatnaminggroups memtester 8M
# Run below command in another terminal tab:
$ cat /sys/fs/cgroup/iambadatnaminggroups/memory.current
8564736 # Approx. 8.5MB is being consumed by the process
# Now let’s see what happens when we try to allocate 11MB!
$ sudo cgexec -g memory:iambadatnaminggroups memtester 11M
<... omitted output ...>
got 11MB (11534336 bytes), trying mlock ...[1] 87486 killed
# It goes OOM and gets killed!
Psst, these commands were written and tested in Bash and Arch Linux!
$ mkdir -p fakeroot/{bin,lib,lib64,usr/bin,usr/lib,usr/lib64} && cd fakeroot
# Copy some tools and their library dependencies to this fakeroot
$ cp /usr/bin/{bash,ls,cat,touch,rm} ./usr/bin/
$ cp ./usr/bin/bash ./bin/
$ libs=( $(ldd ./usr/bin/* | grep -P '=> (.*) \(' | cut -d ' ' -f3) )
$ for i in $libs; do
cp $i $(echo $i | sed 's/\/usr/./') && cp $i ".$i";
done
# Now, let's change root!
$ sudo chroot . /usr/bin/bash
# Have fun inside the chroot! Note that you can’t access
# anything outside the fakeroot folder from inside the chroot.
# PS: You can safely execute rm -rf / here without destroying your PC!
# It will just destroy the fakeroot environment.
Psst, these commands were written and tested in Bash and Arch Linux!
$ unshare -r bash
$ id
uid=0(root) gid=0(root) groups=0(root),65534(nobody)
Psst, these commands were written and tested in Bash and Arch Linux!
# First check the process tree on the host
$ pstree
systemd─┬─agetty
├─crond
├─dbus-daemon
├─dockerd─┬─containerd───23*[{containerd}]
│ └─30*[{dockerd}]
├─nginx───nginx
└─<... rest snipped ...>
# Next, create the pid namespace
$ sudo unshare -fp --mount-proc /bin/bash
# Create an example child process inside the namespace
$ sleep 999 &
# ... and another one to run bash
$ bash
# Now run pstree and see that bash is the parent process
$ pstree
bash─┬─bash───pstree
└─sleep
# Check all running processes and their PIDs
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 7732 4440 pts/1 S 02:48 0:00 /bin/bash
root 3 0.0 0.0 5356 692 pts/1 S 02:48 0:00 sleep 999
root 4 0.2 0.0 7732 4352 pts/1 S 02:48 0:00 bash
root 7 0.0 0.0 10240 3380 pts/1 R+ 02:48 0:00 ps aux
Psst, these commands were written and tested in Bash and Arch Linux!