Cgroup v2 Unified Hierarchy for Linux Containers
Control group version 2 (cgroup v2) fundamentally redesigns how the Linux operating system monitors, allocates, and restricts hardware resources across processes. This article examines the significance of the cgroup v2 unified hierarchy, detailing how it replaces the fragmented multi-hierarchy model of cgroup v1 to solve persistent container isolation issues, streamline resource accounting for buffered I/O, empower rootless containers, and provide accurate pressure metrics for modern runtimes like Kubernetes, containerd, and Podman.
The Flaws of the Cgroup v1 Multi-Hierarchy Model
In cgroup v1, each resource controller—such as CPU, memory, block I/O, and process identifiers (PIDs)—operated inside its own independent hierarchy. A process could simultaneously reside in arbitrary paths across different controller trees.
This separation created major systemic issues for container engines:
- Uncoordinated Resource Accounting: Because controllers did not communicate, systems could not accurately manage overlapping resources. The most notorious failure was buffered I/O: memory writebacks (dirty pages) managed by the memory controller could not be matched to the block I/O controller, causing throttled containers to bypass disk limits or stall unrelated processes.
- Complex Management Overhead: Orchestrators and
container runtimes had to maintain parallel directory trees under
/sys/fs/cgroup/for every container, increasing synchronization errors and race conditions during container creation and teardown.
The Core Design: The Unified Hierarchy
Cgroup v2 eliminates orthogonal trees in favor of a single unified
hierarchy mounted at /sys/fs/cgroup. In this model, every
process belongs to exactly one cgroup, and all controllers are enabled
or disabled within that same single tree structure.
To maintain structural clarity, cgroup v2 enforces the "no internal processes" rule. A non-root cgroup can host child cgroups or active processes, but never both simultaneously. This prevents ambiguous resource division between internal tasks and child nodes, guaranteeing deterministic resource inheritance down the branch.
Key Advancements for Modern Container Runtimes
The adoption of the unified hierarchy brings crucial improvements to modern containerized environments:
1. Unified Memory and I/O Tracking
With a shared hierarchy, memory and block I/O subsystems collaborate. When a container writes data to disk through the page cache, the kernel tracks which cgroup owns the memory and properly charges the resulting background I/O to the exact same cgroup. Container runtimes can now enforce true disk throttling limits without dirty-page writebacks exhausting host memory.
2. Pressure Stall Information (PSI)
Cgroup v2 integrates Pressure Stall Information directly into
resource tracking files (cpu.pressure,
memory.pressure, io.pressure). Unlike simple
utilization percentages, PSI measures the actual time tasks spend
waiting for overloaded hardware. Container platforms use PSI to detect
resource saturation early, enabling proactive autoscaling or workload
migration before an Out-Of-Memory (OOM) event occurs.
3. Native Support for Rootless Containers
In cgroup v1, delegating control of individual resource subtrees safely to non-root users was virtually impossible without introducing security vulnerabilities. The unified hierarchy introduces a clear, secure delegation model. Non-privileged users can safely manage resource limits inside their own user namespaces, enabling modern rootless container execution in Docker and Podman without requiring system administrative privileges.
4. Deterministic OOM Killer Control
In cgroup v1, memory exhaustion often resulted in the host's OOM
killer terminating a single arbitrary process within a container,
leaving the container in an unstable, partially dead state. Cgroup v2
provides the memory.oom.group setting, which instructs the
kernel to terminate every process within the cgroup simultaneously when
an OOM event triggers, treating the container as an indivisible workload
unit.
The cgroup v2 unified hierarchy eliminates the architectural limitations of early Linux container implementations. By linking controllers into a cohesive tree, it provides container runtimes with the determinism, safety, and precise resource accounting required for dense, multi-tenant cloud infrastructure.