Unit 1.9 · about 5 h
238 / 324Namespaces, cgroups and container boundaries
Assume Programming's health-containers-runbooks unit, including non-root packaging, readiness, shutdown and restart exercises. Here you inspect the kernel views and accounting behind those runtime settings, and deliberately diagnose one contained OOM rather than rebuild the health-service exercise.
- explain
- implement
You can now
- Inspect namespace views, credentials, mounts and effective cgroup limits for one bounded container.
- Reproduce a cgroup memory-limit failure and retain runtime evidence before removing the container.
- Explain PID 1 signal/reaping duties and distinguish CPU throttling, OOM, failed task creation and full storage.
- Trace image layers, copy-up and mounted data to their visibility and lifetime boundaries.
Covers
- Namespaces, cgroups, mounts, users and container resource limits
- Container images, layers, signals, shutdown and filesystem boundaries
Study, in this order
5 steps
- Linux NamespacesAlgoMaster Operating Systems - selected observation route
Namespace Views vs. Physical Reality; Mount Namespaces; PID Namespaces; User Namespaces; Cgroup Namespaces; Inspecting a Container's Namespaces; Separation Limits of Namespaces
Depth · Inspect actual membership. Do not assume all namespace identifiers differ, that namespace root is host root, or that namespaces create resource budgets.
- Control GroupsAlgoMaster Operating Systems - selected observation route
The Unified Cgroup v2 Tree; The Cgroup Hierarchy; Hard CPU Bandwidth Boundaries from Quotas; CPU Placement with Cpuset; Memory Accounting; Meanings of Cgroup Memory Boundaries; Limiting Process and Thread Creation
Depth · Read status through the runtime-created cgroup. Do not write policy into a system-owned hierarchy or enable privileged scheduling.
- PID 1 and Signal HandlingAlgoMaster Operating Systems - selected observation route
Special Signal Behavior of PID 1; Signals to PID 1 vs. Broadcasts; Using exec in an Entrypoint Script; Direct Execution: Signal Routing vs. Handling; Child-Reaping Responsibilities of PID 1; When to Use a Minimal Init Process
- Container Resource FailuresAlgoMaster Operating Systems - selected observation route
Failure Shapes Across Resource Limits; Finding the Effective Boundary; Reading Memory Events as Evidence; Exit Code 137 vs. OOM Proof; Capturing Evidence Before the Container Disappears
Depth · Classify delay, failed operation, death and platform eviction separately. A live PID 1 does not prove every worker survived.
- Container File SystemsAlgoMaster: hardware and container storage companions
What an Image Contains; Immutable Image Layers; The OverlayFS Model; Writing Causes Copy-Up; Markers for Lower-Layer File Deletion; The Container Writable Layer; Persistent Data Outside the Instance Layer; Image Paths Hidden by Mounts
Depth · Explain manifests/configuration/layer diffs and the OverlayFS model without assuming every runtime uses that driver. Stop before driver tuning.
Focus on
- Namespaces scope lookup and visibility while sharing the kernel. Cgroup namespaces scope the hierarchy view, not budgets. A non-root UID and user-namespace mapping are different facts; inspect
uid_mapand actual membership rather than infer authority fromwhoami. - CPU quota limits aggregate time, cpuset limits eligible CPUs and weight affects contested sharing. Memory charges include cache and kernel work, not merely application heap or summed RSS.
- Exec-form startup routes the stop signal to the intended program but does not install its handler. PID 1 must handle expected signals and reap children or delegate to a suitable init;
SIGKILLoffers no cleanup path. - Copy-up creates a writable version; whiteouts hide lower files without erasing old layer bytes. Mounts can hide image paths; volumes, bind mounts and tmpfs have different lifetimes. Keep exit reason, limits and event deltas before teardown; a replacement instance's counters cannot explain the old failure.
Reproduce closed-book
python:3.14-slim image pinned by digest (python@sha256:a2b82f3c48559aa0a8446d9af49826b6e2b2016f4cd2afabfe6013ec53729170), or another official Python image whose digest you record. Write an OOM probe that prints getpid/getuid and /sys/fs/cgroup/{memory.max,memory.swap.max,cpu.max,memory.events}, prints READY with flush, then waits for /tmp/go before retaining newly allocated 8 MiB bytearrays in a list indefinitely. Start it with docker run -d --network=none --user=65534:65534 --cpuset-cpus=2 --cpus=0.5 --memory=64m --memory-swap=64m IMAGE python -I -u PROBE, using a read-only bind-mounted probe or equivalent -c code. Save its returned container ID; do not use --rm. After READY, record docker version, image digest, docker inspect limits, host PID and docker logs. Compare readlink /proc/self/ns/{pid,mnt,net,uts,user,cgroup} outside with docker exec CID readlink /proc/1/ns/TYPE and read uid_map. Host /proc/<pid>/ns access may be denied; the exec view is a documented fallback, not permission bypass. On a cgroup v2 host the probe prints memory.max 67108864, memory.swap.max 0 and cpu.max '50000 100000'. Run docker exec CID touch /tmp/go, then docker wait CID and docker inspect --format 'exit={{.State.ExitCode}} oom={{.State.OOMKilled}}' CID. Verify exit=137 and oom=true before docker rm CID; preserve full state/logs and use exact-ID cleanup on failure. This is one bounded OOM observation, not a throughput experiment or proof of graceful shutdown. No Kubernetes cluster action is required.Traps
- Using
--rmand losing stopped-container evidence, or treating 137 alone as OOM proof. An unhealthy flag does not itself trigger a plain Docker restart; Kubernetes readiness, liveness and eviction are separate actions. - Calling
--cpus=0.5a core reservation or assumingtaskseton the Docker client pins the container. Set--cpuset-cpus=2for the workload. - Calling an image-layer deletion secret erasure, a container stop volume deletion, or a persistent volume an automatic durability guarantee.
Practice
The section mini-project covers this: one retained and inspected container OOM, namespace/credential and mount diagrams, configured versus effective limits, an explanation of PID 1 duties, and an orchestrator checklist separating exit-driven restart, readiness, liveness, eviction and volume lifecycle. Reuse Programming's shutdown evidence instead of repeating its service exercise.
Self-test
-
With
cpu.max='50000 100000', how fast can two simultaneous busy threads spend the quota?In the ideal model, 25 ms of wall time consumes 50 ms aggregate CPU time. Quota replenishes per period; actual scheduling and affinity can prevent that parallel execution. -
Why does
--memory=64m--memory-swap=64mgive zero allowed swap in this run?Docker'smemory-swapvalue is the total memory-plus-swap budget. Equal totals leave no swap budget; the cgroup-v2memory.swap.maxobservation is 0. -
Does a different mount namespace imply different stored bytes?
No. Different mount trees can deliberately reach the same underlying file through bind mounts or shared filesystems. Views and storage ownership are separate. -
How should CPU exhaustion, PID exhaustion and memory OOM differ?
CPU quota usually delays runnable work;pids.maxrejects new processes or threads; unreclaimable pressure atmemory.maxcan kill a selected task. Capture policy and matching counter deltas rather than diagnose from host idle capacity.
Completion criterion
Stop when
You retain exit=137 plus OOMKilled=true before cleanup, explain the effective no-swap and CPU policies, and map namespace, credential, storage and supervisor boundaries without claiming a private kernel or untested shutdown behavior.
Leads to
- 1.6 Resident size, virtual size and allocator retention Reconcile cgroup charges with process-level residency before changing a memory budget.
Comes after
- 1.4 File descriptors, pipes, signals and process lifecycleCarry lifecycle ownership into a PID namespace.
- 1.6 Resident size, virtual size and allocator retentionDiagnose memory limits using the cgroup's scope, not process RSS alone.
- 1.8 I/O access patterns and storage devicesLocate the mount and resource boundary around the same I/O path.
- 7.2 Identity, authorization, least privilege and secretsState where container boundaries stop protecting secrets and identities.
Resources for this unit
- AlgoMaster Operating Systems - selected observation route After OSTEP, use the matching lessons as a second explanation and recall check: fork, exec, wait, and exit; Zombies and Orphans; Signals; Context Switching; The Process Address Space; Paging; The TLB: Hits, Misses, and Invalidation; Page Faults; Copy-on-Write; mmap and Memory-Mapped Files; How malloc Works; VSZ, RSS, PSS, and What They Mean; File Descriptors; The Page Cache and Write-Back; Durability and fsync; Crash Consistency; Linux Namespaces; Control Groups; PID 1 and Signal Handling; Container Resource Failures; and the Investigating lessons. Treat quizzes as recall checks and keep your own traces as evidence.
- AlgoMaster: hardware and container storage companions Use Memory Ordering, Barriers, and False Sharing (coherence and false-sharing headings only); Huge Pages, NUMA, and ASLR (NUMA headings only); Storage Hardware; RAID Fundamentals (comparison and backup boundaries); and Container File Systems. These fill hardware and image-layer gaps outside the pool's selected OS revision lessons.
Also in this section
- Operating Systems: Three Easy Pieces - selected foundations Read Chapters 4-7, 13-15, 18-21, 36, 39-40, 42 and 45. Work from process state to address translation, devices, files, journaling and integrity. For every chapter, draw the owned state and one failure boundary instead of collecting summaries.
- MIT 6.1810 - selected xv6 process and memory labs Use Fall 2025 Lectures 1, 3-6, 8 and 10-11. Complete the util lab, one syscall task, and the page-table inspection plus ugetpid task from pgtbl. Add cow only if copy-on-write remains unclear. Keep all work in your own course checkout and stop before the full xv6 sequence.
- OSTEP homework - process, paging, disk and integrity simulators Solve process-run.py, paging-linear-translate.py, paging-policy.py, disk.py, fsck.py and checksum.py for at least two seeds each before using the answer flag. Then reproduce one prediction using strace, /proc or a small local program.
- Linux proc and strace references Use proc(5), getrusage(2), mmap(2), fsync(2), rename(2), wait(2) and signal(7) while tracing a parent-child pipe, page faults, file publication and a resource-limit failure. Record exact commands and raw observations.
- Nand2Tetris - Projects 1 and 4 only Use Project 1 for Boolean logic and Project 4 for machine-language execution only if the binary or instruction-level entry check fails. Do not take the full course as a second systems curriculum.
- Algorithmica - Algorithms for Modern Hardware Use the Instruction-Level Parallelism, SIMD Parallelism and RAM & CPU Caches chapters for measured pipeline, branch, vectorization, bandwidth, latency and cache-line effects. The figures are the author's Zen 2 measurements at a fixed 2 GHz: predict and measure your own.
- MIT 6.S894 Accelerated Computing - Throughput Processors Use Lecture 2 for the processor model behind this section: superscalar issue, out-of-order execution, speculation and SIMD's need for coherent control. The labs run on the course's remote machines and target AVX-512 and NVIDIA GPUs, so they belong to the GPU track.
- Auto-Vectorization in LLVM Use The Loop Vectorizer Usage and Diagnostics sections for the Clang remarks the pipelines unit asks for; the Features list is optional depth.