Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tinydocker

C11 License: MIT

Minimal container runtime in C11, built from scratch on Linux primitives. No external libraries: namespaces, chroot and cgroups v2 are driven directly through syscalls and the kernel filesystem interface.

Architecture

tinydocker [OPTIONS] -- COMMAND
  ||
  \/
argument parser -> container config { hostname, rootfs, cpus, memory }
  ||
  \/
cgroup setup (v2 unified hierarchy)
  |-> /sys/fs/cgroup/tinydocker-<pid>/cpu.max
  |-> /sys/fs/cgroup/tinydocker-<pid>/memory.max
  ||
  \/
clone(CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS)
  ||
  \/
child process
  |-> sethostname()
  |-> chroot(rootfs) + chdir("/")
  |-> mount("proc", "/proc", "proc")
  |-> execvp(COMMAND)

The parent creates the cgroup, writes the child PID into cgroup.procs, then waits. The child runs in its own UTS, PID and mount namespaces, so ps inside the container sees a process tree starting at PID 1.

Isolation

Namespace Isolates
UTS Hostname, so the container can set its own without affecting the host
PID Process tree, with the entrypoint as PID 1
Mount Mount points, so /proc is mounted for the container only

chroot confines the filesystem view to a minimal rootfs, and /proc is remounted inside so process introspection reflects the container rather than the host.

Resource limits

Limits are enforced through the cgroups v2 unified hierarchy. A dedicated cgroup is created per container, cpu.max and memory.max are written from the CLI flags, and the container PID is moved into it before exec. A process exceeding memory.max is killed by the kernel OOM killer, exactly as it would be under Docker.

Quick start

make                                          # build to build/bin/tinydocker
sudo ./build/bin/tinydocker -- /bin/sh        # defaults: 1 CPU, 512 MB
sudo ./build/bin/tinydocker -h web -c 2 -m 1024 -- /bin/sh
Flag Description Default
`-h, --hostname NAME Container hostname container
-r, --rootfs PATH Root filesystem to chroot into ./rootfs
-c, --cpus N CPU limit 1
-m, --memory SIZE Memory limit in MB 512

Requires Linux with cgroups v2 (unified hierarchy) and root privileges. Tested on Ubuntu 22.04 LTS.

Roadmap

  • Networking: veth pair, Linux bridge, static IP assignment and NAT through iptables, adding CLONE_NEWNET to the isolation set.
  • Volumes: -v /host:/container bind mounts.
  • Image loading: extract a .tar image into the rootfs instead of requiring a prebuilt one.

About

TinyDocker is a minimal container runtime in C11 to learn namespaces and cgroups. Still in early development.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages