Stage 4 · Provision
Container Fundamentals
Control Groups
Use cgroups concepts for CPU, memory, process, and I/O limits enforced by the Linux kernel.
What Cgroups Do
Control groups (cgroups) are a Linux kernel feature that limits, accounts for, and isolates the resource usage of process groups. While namespaces control what a container can see, cgroups control what a container can consume. Without cgroups, a single container could monopolize all CPU, memory, and disk I/O on a host.
Docker creates a cgroup for each container and configures limits based on the flags you pass to docker run. The kernel enforces these limits in real time. If a container exceeds its memory limit, the kernel kills its processes (OOM kill). If it exceeds its CPU limit, the kernel throttles execution.
CPU Limits
CPU limits control how much processor time a container can use. There are two types: hard limits (cpus) that cap maximum usage, and shares (cpu-shares) that distribute CPU proportionally when contention exists.
# Limit to 1.5 CPU cores
docker run --cpus=1.5 myapp
# Limit to 50% of one CPU
docker run --cpus=0.5 myapp
# CPU shares (relative weight, default 1024)
docker run --cpu-shares=512 myapp # Half the default weight
docker run --cpu-shares=2048 myapp # Double the default weight
# Pin to specific CPUs
docker run --cpuset-cpus="0,1" myapp--cpus=0.5 means the container can use at most 50% of one CPU core over any 100ms window. CPU shares only matter when multiple containers compete for CPU on the same host.
Memory Limits
Memory limits prevent containers from consuming more RAM than allocated. When a container exceeds its memory limit, the kernel's OOM (Out of Memory) killer terminates processes in the container. The container then restarts if its restart policy allows it.
# Limit to 512MB
docker run --memory=512m myapp
# Limit swap separately
docker run --memory=512m --memory-swap=1g myapp
# Hard limit with no swap
docker run --memory=512m --memory-swap=512m myapp
# OOM disable (use with caution)
docker run --memory=512m --oom-kill-disable myappBy default, Docker allows a container to use as much swap as its memory limit. Setting --memory-swap equal to --memory disables swap entirely. Disabling OOM kill is dangerous — an unbounded container can destabilize the host.
The OOM killer terminates processes without warning. Monitor container memory usage with docker stats and set memory limits that match your application's actual needs. A container using 400MB should have a 512MB limit, not unlimited.
I/O Limits
Block I/O limits control read and write speeds to disk devices. These limits use the device path and are specified in bytes per second. They are useful for preventing a single container from saturating disk I/O and starving other workloads.
# Limit read speed to 10MB/s
docker run --device-read-bps /dev/sda:10mb myapp
# Limit write speed to 5MB/s
docker run --device-write-bps /dev/sda:5mb myapp
# Limit IOPS
docker run --device-read-iops /dev/sda:1000 myapp
docker run --device-write-iops /dev/sda:500 myappI/O limits are device-specific. The /dev/sda path refers to the host device. These limits apply per-device across all containers sharing that device.
Docker Run Limits
Combine CPU, memory, and I/O limits to create well-behaved containers. Every production container should have explicit resource limits. Without them, a misbehaving container can consume all host resources and cause cascading failures.
docker run -d \
--name api \
--cpus=2 \
--memory=1g \
--memory-swap=1g \
--device-read-bps /dev/sda:50mb \
--device-write-bps /dev/sda:20mb \
--restart=unless-stopped \
myapp:latestThis container gets 2 CPU cores, 1GB RAM with no swap, and limited disk I/O. These limits ensure the container cannot destabilize the host or starve other services.
Monitoring Cgroups
Docker exposes cgroup statistics through docker stats and the cgroup filesystem on the host. Monitoring these metrics helps you right-size resource limits and detect issues before they cause outages.
# Live stats for all containers
docker stats
# Format specific metrics
docker stats --format "table {{.Name}} {{.CPUPerc}} {{.MemUsage}}"
# Check container OOM kills
docker inspect mycontainer --format '{{.State.OOMKilled}}'
# Host cgroup filesystem (advanced)
ls /sys/fs/cgroup/memory/docker/
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.usage_in_bytesdocker stats shows real-time CPU, memory, network, and I/O usage. Use it to validate that your limits are appropriate and that containers are not approaching their constraints.
Cgroup v2 provides unified hierarchy and more accurate metrics. Most modern Linux distributions use cgroup v2 by default. Check with stat -fc %T /sys/fs/cgroup/ — cgroup2fs means v2 is active.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.