Docker logo

Docker and its Anatomy

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!