Pitch
By the end of this post, we will appreciate the idea of a container, within the Linux context. For most people, when you mention containers, the first thing that comes to mind is Docker. What if I told you that containers have nothing to do with Docker; instead it is the other way round.
Actually, this series will introduce Linux container internals without ever using Docker, just to pass the point across.
ℹ️ NOTE: all the examples below are based on
Ubuntu 22.04.1 LTS
running on Windows Subsystem for Linux (WSL2). However, you can still run this on any Linux distro (VM or machine).
Enter chroot
Create a directory, e.g. container_intro
:
mkdir container_intro
Add a simple file to the directory:
echo "CONTAINER" > container_intro/CONTAINER_ROOT
Let's try to chroot
into the directory:
sudo chroot container_intro
You will get this error: chroot: failed to run command ‘/bin/bash’: No such file or directory
. This means that we can get into this directory and use it as our root /
, when we try to execute bash
which should be in /bin/bash
, it is not found.
Let's copy /bin/bash
(and one more command ls
, that we will run afterwards) from the current system to our directory:
mkdir container_intro/bin
cp /bin/bash /bin/ls container_intro/bin
Now back to chroot
:
sudo chroot container_into
Still not working! This is because bash
has dependency on other libraries. Let's view them:
ldd /bin/bash
linux-vdso.so.1 (0x00007ffe20ff5000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fdbf1438000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdbf1210000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdbf15d2000)
Let's go ahead and copy them into our directory:
mkdir container_intro/lib{,64} # creates both lib and lib64
cp /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libc.so.6 \
container_intro/lib
cp /lib64/ld-linux-x86-64.so.2 container_intro/lib64
Let's do the same for ls
:
ldd /bin/ls
linux-vdso.so.1 (0x00007ffcccf2f000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f932a5fc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f932a3d4000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f932a33d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f932a653000)
cp /lib/x86_64-linux-gnu/libselinux.so.1 /lib/x86_64-linux-gnu/libc.so.6 \
/lib/x86_64-linux-gnu/libpcre2-8.so.0 container_intro/lib
cp /lib64/ld-linux-x86-64.so.2 container_intro/lib64
Finally, back to our chroot
:
sudo chroot container_intro
And we are in! We should see the prompt:
bash-5.1#
Let's run ls
:
bash-5.1# ls
CONTAINER_ROOT bin lib lib64
bash-5.1#
Now, essentially, we are contained within that directory as our whole world (file system). As far as we are concerned, we can't jump out of it.
Next Episode: Spoiler Alert
We have looked at a hacky solution for getting only two processes: bash
and ls
up and running. In the next episode, we will look at setting up a full filesystem. For the eager learners, you can check out debootstrap
. See you next!
Thanks for reading this far. If you followed this walkthrough hands-on, here is a small gift for you! 😀
Footnote / Further Reading: