demystifying-containers rebuilds container knowledge from the kernel up
A series of blog posts and talks about the world of containers 📦
At a glance
- What is it?
- demystifying-containers is a series of blog posts, talks and runnable examples that teaches containers as a stack, starting with Linux namespaces and cgroups and ending with OCI runtimes, images and security. It suits engineers who use containers daily and cannot explain what the runtime actually does.
- Who is it for?
- Work through demystifying-containers if you are an engineer who ships containers and cannot yet explain how a runtime starts one, because every part pairs a historical explanation with code you compile and run. Do not adopt it as a production reference for a single narrow question, since the content spans the whole stack and reads as a teaching series rather than a manual.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A stack taught from the bottom, with history attached
Most container writing starts at the command line. This series starts at the Linux kernel and works upward, and that ordering is the whole idea. The stated aim is to provide a pragmatic view on containers from a historic perspective, discovering modern cloud architectures layer by layer, so the reader ends up at writing secure cloud native applications with an understanding of why the pieces are shaped the way they are.
The series is built as four parts, and each part is a blog post plus a talk plus slides. Part I covers kernel space, Part II container runtimes, Part III container images, Part IV container security. The posts are published in the repository itself, and they are also cross-posted to CNCF, Medium and SUSE, with talk recordings on YouTube and slides on Slides.com.
The historic angle is not decoration. Part I starts with the history of UNIX and Linux and looks at chroot, namespaces and cgroups before the reader writes any code, and Part II traces container runtimes to their historic origins before digging into specific projects. The claim in the README is that this background makes it easier to understand how features in the kernel, container tools, runtimes, software defined networks and orchestration software like Kubernetes are designed and how they work under the hood.
This is a reading and hands-on project, not a library. There is nothing to depend on and no API to call.
Part I writes namespaces and cgroup examples in C and Rust
The first part is the foundation, and it is the one that teaches by making the reader build things. It covers the history of UNIX and Linux, then works through solutions such as chroot, namespaces and cgroups combined with hacking the reader's own examples, and finishes by peeling some containers to build intuition for the later topics.
The examples are real code, not pseudocode. The Makefile in the repository root has a build target for the C examples, and the source files are named after what they demonstrate:
build/c: ## Build the C examples.
build/rust: ## Build the Rust memory example.
build/docker: ## Build all container images.The C programs are compiled from part1-kernel-space/src, and the Rust one is the memory cgroup demo, built from a Cargo manifest in the same tree. The prerequisites confirm the shape of the exercise: gcc and make for compiling the C examples, and cargo, the Rust toolchain, for the memory cgroup demo.
That combination is deliberate. Reading about namespaces is one thing, and having a program that creates one and then examining what the kernel reports about your own process is another. The Rust example exists because a memory cgroup is easier to demonstrate with an allocator that actually allocates.
Part II runs OCI containers without running Kubernetes
The second part moves to container runtimes and starts from their historic origins before digging into two dedicated projects, runc and CRI-O. The stated plan is to build a foundation about how container runtimes work under the hood by starting with the lower level runtime runc, and then to use the more advanced runtime CRI-O to run Kubernetes native workloads without even running Kubernetes at all.
That last clause is the interesting part. CRI-O is normally encountered as the thing that talks to a kubelet inside a cluster, so the series uses it the other way round, as a runtime you can drive yourself to watch a Kubernetes-shaped workload run without the control plane. The tooling list for this part includes runc for running OCI containers directly, crictl from the cri-tools project for CRI-O interaction, and skopeo and umoci for downloading and unpacking container images.
There is also a convenience path for readers who do not want to assemble the toolchain by hand. A crio-playground container image bundles the Part II dependencies, and the repository includes a Dockerfile under part2-container-runtimes/src/ that builds it locally.
Part III takes images apart and rebuilds them
The third part is about container images, again starting with the historic background and the evolution of different image formats. After that the reader looks at what is inside the latest Open Container Initiative image specification by crafting, modifying and pulling apart self-built image examples, and picks up image creation practices along the way using buildah, podman and skopeo.
The tools split neatly by task. skopeo and umoci handle the download and unpack side, which is how the reader gets at the layers to see what a specification actually requires. buildah and podman cover the build and run side, so the examples are made with a rootless-friendly toolchain rather than only with a daemon. The Makefile carries a build/docker target that builds the images for Part II and Part III, including a separate Dockerfile-debian for the Debian variant, so the images used in the posts are reproducible from the repository.
The practices the post picks up are not incidental to the format work. Understanding the image specification is what makes the advice about layer structure and base images meaningful, rather than a list of rules to follow without the reason.
Part IV argues with the fear that containers are not secure enough
The fourth part opens with a problem it wants to name. Security topics in the container ecosystem are overwhelming, and after several security vulnerabilities in 2019 the press questioned whether containers are secure enough for applications and whether moving from virtual machines to container-based workloads was a good idea. The series notes that micro VMs exist to add another layer of security for sensitive applications, then asks whether security is really a problem when running applications inside containers.
Its answer is that it is, when the security possibilities are not understood or not used at all, which makes the part a catalogue of mechanisms rather than a scare piece. The low level mechanisms cover Linux capabilities and seccomp, and the heavier mechanisms are SELinux and AppArmor, with the aim of building a common ground of understanding about container security. The part then moves up a level to securing workloads inside Kubernetes clusters with Pod Security Admission, and to securing the container images themselves.
The results are checked with end-user applications rather than only with unit-level assertions, which the README calls out specifically: the experiments are verified using Kubernetes and Podman.
Root, user namespaces and a long toolchain list
The prerequisites section is the honest part of the series, and it is where most readers will hit a wall. Following the hands-on examples needs a Linux system with gcc and make, cargo, runc, skopeo, umoci, crictl, buildah, podman and jq for inspecting JSON output.
The permission requirement is stated just as plainly: most examples require root privileges or a user namespace with appropriate mappings. That is not a detail of the examples, it is the subject of them. User namespaces are how an unprivileged process can create the namespace and cgroup view that the code is demonstrating, and the mapping requirement is what makes the ids line up.
The repository is arranged as four directories, one per part, each holding its own post, sources and Dockerfile, with the Makefile at the root tying the build targets together. There is also a verification target for the table of contents, a Hadolint configuration for the Dockerfiles, a markdownlint configuration, a prettier ignore file and a typos configuration, which tells you that the linting of the prose is treated as part of the build.
The cost of a part is not only the reading. Each part needs its own tools installed and its own examples compiled before the code in the post means anything.
Apache-2.0 licensed, prose and code in one repository, no releases
The project is licensed under Apache-2.0, with the LICENSE file at the repository root. That matters for a teaching repository in a practical way: a company can take the posts, the slides and the C and Rust examples and use them internally, including in training, as long as the licence terms are respected.
The repository has no GitHub releases, which is not a gap for a series of posts, since the content is versioned by the commits and the posts are cross-published elsewhere. The last push was on 2026-10-16, so the content is being maintained rather than left as a finished artifact from a past conference season. The default branch is main.
The Makefile at the root is the entry point for the hands-on side, and the targets are grouped into build, verify and utility sections:
all: build/c build/rust build/docker ## Build everything.
verify/mdtoc: ## Verify table of contents in markdown files.
clean: ## Cleanup build artifacts.The verify target regenerates the table of contents in the markdown files, which is a small detail that indicates the posts are maintained documents with generated navigation rather than text dumped into a repository once. The clean target removes the compiled C binaries and runs cargo clean for the Rust example.
What you get at the end of the four parts is an explanation that connects the kernel, the runtime, the image format and the security controls, with a compiled program behind each claim.
Editorial conclusion
Work through demystifying-containers if you are an engineer who ships containers and cannot yet explain how a runtime starts one, because every part pairs a historical explanation with code you compile and run. Do not adopt it as a production reference for a single narrow question, since the content spans the whole stack and reads as a teaching series rather than a manual. Before you start, install the toolchain each part needs, most of all root privileges or a user namespace with mappings, and budget the time to read Part I before touching the runtime parts, since the later ones assume the vocabulary it introduces.
Frequently asked questions
What does the demystifying-containers project cover?
It is a four part series of blog posts and talks: Part I on kernel space, Part II on container runtimes, Part III on container images, and Part IV on container security, each with hands-on examples.
What do I need installed to follow the examples?
A Linux system with gcc and make, cargo, runc, skopeo, umoci, crictl, buildah, podman and jq. Most examples also require root privileges or a user namespace with appropriate mappings.
Do I need Kubernetes to follow the container runtime part?
No. Part II uses CRI-O to run Kubernetes native workloads without running Kubernetes at all, and a crio-playground container image bundles the Part II dependencies for convenience.
How do I build the examples in the repository?
The Makefile provides build targets for the C examples, the Rust memory example and the container images, an all target that builds everything, a verify target for markdown tables of contents, and a clean target that removes the artifacts.
Can I reuse the content from demystifying-containers in my company?
The project is licensed under Apache-2.0, and the repository contains the posts, slides and example sources, so it can be reused internally under those terms. The posts are also published on CNCF, Medium and SUSE.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/saschagrunert-demystifying-containers)Was this useful?