Goal
Write a small program (Go is the classic choice — Liz Rice's Containers from Scratch is the seed, and John Crickett's "Build Your Own Docker" challenge covers the same ground) that runs a command in its own container: isolated view, limited resources, its own root filesystem, eventually a real image pulled from a registry. It proves, in code you wrote, that a container is an ordinary Linux process wearing kernel features.
Subject: full brief & instructions
Practices
- Kubernetes & containers deep dive — namespaces, cgroups, and OCI images, implemented instead of recited.
- Linux system deep dive — processes, mounts, and cgroup v2 as working material.
- Networking fundamentals — the veth-pair milestone is network plumbing by hand.
Milestones
- Isolate the view —
mycontainer run <cmd>re-executes itself with new UTS and PID namespaces (clone flags), sets a hostname inside. Shippable: the hostname change is invisible outside;psinside will still lie until milestone 2. - A root of one's own — extract an Alpine rootfs,
pivot_root(or chroot) into it, mount a fresh/proc. Shippable: the process sees itself as PID 1 in a clean filesystem and can't reach the host's. - Limit the resources — create a cgroup v2 group, set memory and CPU limits, add the child to it. Shippable: a memory-hog inside gets OOM-killed at your limit while the host shrugs.
- Give it a network — a new network namespace wired to the host with a veth pair,
addresses assigned, NAT out. Shippable:
pingfrom inside the container reaches the internet. - Real images — pull an image from a registry (OCI distribution API: manifest,
then layers), unpack the layers in order — or assemble them with overlayfs for
proper copy-on-write. Shippable:
mycontainer run alpine shwith nothing pre-extracted. - The UX — argument parsing,
--mem/--cpuflags, exit-code propagation, cleanup on exit. Shippable: a colleague can use it without reading the source.
Stretch goals
- Rootless mode with user namespaces — the hard mode that explains Podman's design.
mycontainer execinto a running container (enter its namespaces viasetns).- Speak the OCI runtime spec (a
config.json-drivencreate/start) and compare againstrunc.
Related
- Build your own container runtime — subject — the standalone program spec: command semantics, per-stage requirements, and acceptance checks.
- Kubernetes & containers deep dive — the concept note this drills; its Practice section cites this exercise.
- Linux system deep dive — the kernel features this exercise turns into muscle memory.
- Kubernetes the Hard Way — the same demystification one layer up.