container-demo
                                
                                 container-demo copied to clipboard
                                
                                    container-demo copied to clipboard
                            
                            
                            
                        container-demo
This repository is a demo that allows you to experience the technology bihind container. You will need Linux to try this demo, however you can try most of the demos in your browser by using the gitpod we provide.
Technology you can experience.
Enjoy the container technology 🥰
Target audience
The target audience is people who have been exposed to containers such as docker, podman, and K8s, but want to know more about what containers are.
chroot
In this chart, we will try to change / using chroot.
We use chroot to simplify the story, but in reality, pivot_root is used.
Set up an experimental directory that will be / and a trial file in it.
$ ROOTFS=$(mktemp -d)
$ echo "Hello" > $ROOTFS/test.txt
Prepare to run the bash and cat commands. Since the / will be changed and the libraries cannot be linked, copy them with the cp command.
$ mkdir -p $ROOTFS/{bin,/lib/x86_64-linux-gnu,lib64}
$ cp -v /bin/{bash,cat} $ROOTFS/bin
$ ldd /bin/cat | grep -o '/lib.*\.[0-9]' | xargs -I{} cp -v {} $ROOTFS/{} 
$ ldd /bin/bash | grep -o '/lib.*\.[0-9]' | xargs -I{} cp -v {} $ROOTFS/{} 
Finally, it's time to chroot. Change / to the $ROOTFS directory you created first, and run bash. You can see that / has been changed because the first test.txt is in /.
$ sudo chroot $ROOTFS bash
bash-5.0# cat /test.txt
Hello
bash-5.0# exit
exit
Reference
Futher challenge
- Try pivot_root
make a container-like
In this chapter, we will use unshare command to create a namespace and the technique of changing / introduced in the previous chapter to create something container-like.
Namespace is a technique for isolating manipulable resources. For example, it isolates the space of a process.
⚠️ This is the only chapter that cannot be executed due to gitpod security.
Create the / directory where the container will work as in the previous chapter.
In this article, we will use busybox to create a container.
$ cd $(mktemp -d)
$ mkdir rootfs
$ docker export $(docker create busybox) | tar -C rootfs -xvf -
Now, we will use the unshare command to create a container. The options are roughly as follows.
- --mount- --uts- --ipc- --pid
 Isolate each namespace. For example, pid separates the process space. This can be experienced by using the- pscommand, where the source and visible processes are different.
- --fork
 When executing a command,- forkis used. This is because the pid namespace will be applied from the new process. This is because the pid namespace will be applied from the new process. You don't need to understand this at first.
- --mount-proc
 This is the magic that allows the- pscommand to run. More precisely, it is an option to mount procfs so that- pscommands can be executed.
- --root rootfs
 We will use the- rootfscreated in the first part as- /. You saw this in the previous chapter where we explained the technique to use.
$ sudo unshare --mount --uts --ipc --pid --fork --mount-proc --root rootfs sh
# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 11:50 pts/3    00:00:00 sh
root           2       1  0 11:50 pts/3    00:00:00 ps -ef
Reference
Futher challenge
- Try to make sure that other namespaces are isolated
- Reproduce the same environment as the demo without using the --fork,--mount-procand--root rootfsoptions.
join an existing container
In this chapter, we will experience joining an existing container.
Joining means joining the namespace of the target container.
This is similar to the behavior of docker exec.
First, create a container and get the pid of the container.
$ docker run -d --rm --name sample-container alpine sleep 1d
$ PID=$(docker inspect --format {{.State.Pid}} sample-container)
Next, use the nsenter command to join the container you have just created.
$ sudo nsenter --target $PID --uts --mount --ipc --net --pid /bin/sh
If you run the ps command in the joined container, you will see that the process space has been separated. In addition, you can run it with docker run first to see the processes of the sleep command.
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 sleep
   26 root      0:00 /bin/sh
   27 root      0:00 ps
/ # exit
⚠️ If you encounter the following error in gitpod, try to recreate the gitpod workspace.
docker: Error response from daemon: OCI runtime create failed
Reference
Futher challenge
- Try to make sure that other namespaces are isolated