This is a tiny container based in Docker. It uses a Ubuntu 22.04 Jammy Jellyfish Base image.
The code was taken from Liz Rice talks: 1 and 2.
Warning It only works on Ubuntu 22.04 LTS Jammy Jellyfish.
If you're not on Ubuntu 22.04 LTS, make sure to have vagrant
installed on your machine as well as Virtualbox.
I suggest you use the VM anyway.
Run:
$ vagrant init ubuntu/jammy64
$ vagrant up
$ vagrant ssh
You're now in a Ubuntu VM. There's still a few things you need to do.
Still in the VM, run:
$ sudo apt install qemu-user-static
$ sudo systemctl restart systemd-binfmt.service
Clone the repo:
$ git clone https://github.com/isaacvicente/little-container.git
In order to have the Ubuntu Base filesystem, run the setup
script:
$ cd little-conteiner && ./setup
Run the little container in rootless mode by:
$ go run main.go run bash
Now you're inside the container!
Note Only the
run
command was implemented. Also, you cannot use theapt
command to install or update packages inside the container, as the base system doesn't have the packages to sign GPG keys.
Nowadays containers are everywhere. Everyone is talking about Docker wonders. But how do containers works, underneath the hood?
A container is just a process. This is why containers are lighter than virtual machines, as the containers uses the host's resources and kernel as opposed to VMs, which have their own kernel and resources (of course, it's not their resources, but it's a emulation of a real machine, so you have to give these resources to the VM right away, or kinda of).
Containers are built from existing Linux kernel features, namely being: namespaces, chroot and control groups (cgroups).
Namespaces delimiters what a process can see. By default, a regular process can see what's happening around it. But that's not what we want for containers, right?
There's a few namespaces:
- PID: The PID namespace provides processes with an independent set of process IDs (PIDs) from other namespaces. The PID namespace makes the first process created within it assigned with PID 1.
- MNT: Mount namespaces control mount points, and provide you to mount and unmount folders without affecting other namespaces.
- NET: Network namespaces create their network stack for the process.
- UTS: UNIX Time-Sharing namespaces allow a process has a separate hostname and domain name.
- USER: User namespaces create their own set of UIDS and GIDS for the process.
- IPC: IPC namespaces isolate processes from inter-process communication, this prevents processes in different IPC namespaces from using.
A chroot
on Unix and
Unix-like operating
systems is
an operation that changes the apparent root
directory for
the current running process and its
children. A
program that is run in such a modified environment cannot name (and therefore
normally cannot access) files outside the designated directory tree.
Control groups, usually referred to as cgroups, are a Linux kernel feature which allow processes to be organized into hierarchical groups whose usage of various types of resources can then be limited and monitored. That way, a process can have a limited I/O rate, or a limited number of children processes.
- Namespaces
- PID
- MNT
- NET
- UTS
- USER
- IPC
- Chroot
- Cgroups
The code in Liz's talks didn't work for Cgroups, and I couldn't figure out how to make it work.
This was a brief overview about containers. With all these building blocks you can start to have a container. They are a little more complicated than shown. Anyway, this is for educational sake, so I don't need to be really technical.
Everything here is licensed under GPLv3 license.