Control groups (cgroups) let Linux limit and account for resource usage — CPU, memory, disk I/O — per process group, and they’re the foundation every container runtime uses to enforce resource limits.
# Create a cgroup (cgroups v2, the modern unified hierarchy) sudo mkdir /sys/fs/cgroup/mygroup # Limit CPU to 50% of one core echo "50000 100000" | sudo tee /sys/fs/cgroup/mygroup/cpu.max # Limit memory to 512MB echo "536870912" | sudo tee /sys/fs/cgroup/mygroup/memory.max # Add a process to the cgroup by PID echo $$ | sudo tee /sys/fs/cgroup/mygroup/cgroup.procs
What This Actually Enables
A container’s --memory=512m or --cpus=0.5 flag in Docker translates directly into cgroup limits like the ones above — cgroups are what stop a single misbehaving container from starving the entire host of CPU or memory, and what let a Kubernetes node accurately report resource usage per pod.
cgroups v1 vs v2
Most modern distros have moved to the unified cgroups v2 hierarchy shown above — v1 used separate, independently-mounted hierarchies per resource type (CPU, memory, etc.), which was more flexible but genuinely more confusing to reason about and configure correctly.