Control Groups (cgroups) are a feature of the Linux kernel used to limit, record, and isolate the resource usage (CPU, memory, disk I/O, network, etc.) of process groups. cgroup v2 is the second generation implementation of cgroups, providing a more unified and consistent interface.
1. Core Concepts of cgroup v2
- Hierarchy v2 adopts a single hierarchy structure, with all controllers mounted under a unified view.
- Controllers Resource control modules (such as cpu, memory, io, etc.)
- cgroup Path Each cgroup has a unique path in the virtual file system.
- Process Ownership Processes can belong to any cgroup and are subject to the resource limits of that cgroup.
2. Basic Operation Steps
1. Mount the cgroup v2 File System
# Check if cgroup v2 is enabled on the current system
mount | grep cgroup
# If not enabled, add to /etc/fstab
cgroup2 /sys/fs/cgroup cgroup2 rw,relatime,nsdelegate 0 0
# Temporary mount
mount -t cgroup2 cgroup2 /sys/fs/cgroup
2. Create and Delete cgroup
# Enter the cgroup root directory
cd /sys/fs/cgroup
# Create a new cgroup (automatically creates a subdirectory)
mkdir myapp_group
# Delete cgroup
rmdir myapp_group
3. Enable Resource Controllers
# View currently available controllers
cat cgroup.controllers
# Enable controllers (such as memory and cpu)
echo '+memory +cpu' > cgroup.subtree_control
# Verify enabled controllers
cat cgroup.subtree_control
3. Resource Control Examples
1. CPU Limitation
Example: Limit the process to use a maximum of 1 CPU core (100ms/100ms)
# Create cgroup
mkdir cpu_limit_group
# Enable CPU controller
echo '+cpu' > cgroup.subtree_control
# Set CPU quota (period 100ms, quota 100ms)
echo '100000' > cpu_limit_group/cpu.max
# Add process PID to cgroup
echo 1234 > cpu_limit_group/cgroup.procs
2. Memory Limitation
Example: Limit memory usage to no more than 1GB
# Create cgroup
mkdir mem_limit_group
# Enable memory controller
echo '+memory' > cgroup.subtree_control
# Set hard memory limit (1GB)
echo '1G' > mem_limit_group/memory.max
# Set OOM priority (optional)
echo '100' > mem_limit_group/memory.oom.group
# Add process
echo 5678 > mem_limit_group/cgroup.procs
3. Disk I/O Limitation
Example: Limit disk read/write bandwidth
# Create cgroup
mkdir io_limit_group
# Enable io controller
echo '+io' > cgroup.subtree_control
# Find disk device number (e.g., /dev/sda)
lsblk -d -o NAME,MAJ:MIN
# Set read bandwidth limit (10MB/s)
echo '254:0 rbps=10485760' > io_limit_group/io.max
# Set write IOPS limit (1000 iops)
echo '254:0 wiops=1000' > io_limit_group/io.max
4. Mixed Resource Limitation
Example: Set comprehensive resource limits for a web service
# Create cgroup
mkdir web_service
# Enable all available controllers
echo '+cpu +memory +io +pids' > cgroup.subtree_control
# CPU limit (50% single core)
echo '50000 100000' > web_service/cpu.max
# Memory limit (2GB)
echo '2G' > web_service/memory.max
# Process count limit (100 processes)
echo '100' > web_service/pids.max
# Start service and join cgroup
systemd-run --scope -p MemoryMax=2G -p CPUQuota=50% /opt/webapp/start.sh
4. Advanced Functionality Examples
1. Resource Statistics Monitoring
# View memory usage statistics
cat memory.current
cat memory.stat
# View CPU usage statistics
cat cpu.stat
# View IO statistics
cat io.stat
2. OOM Control
# Disable OOM killer for a certain cgroup (report error instead of killing the process when memory exceeds limit)
echo '1' > memory.oom.group
# View OOM events
cat memory.oom.group
3. Nested cgroup Structure
# Create parent cgroup
mkdir parent_group
echo '+cpu +memory' > parent_group/cgroup.subtree_control
# Create child cgroup
mkdir parent_group/child1
echo '50000 100000' > parent_group/child1/cpu.max
mkdir parent_group/child2
echo '25000 100000' > parent_group/child2/cpu.max
# Set total limit for parent cgroup
echo '75000 100000' > parent_group/cpu.max
5. cgroup v2 in Docker
Docker has supported cgroup v2 since version 20.10. Example usage:
# Specify resource limits when running a container (automatically creates cgroup)
docker run -d \
--cpus=1.5 \
--memory=512m \
--blkio-weight=300 \
--name mycontainer \
nginx:alpine
# View the cgroup corresponding to the container
systemd-cgls | grep docker
6. Considerations
- Modifying
<span>cgroup.subtree_control</span>will affect all child cgroups. - Resource limit values must comply with the constraints of the parent cgroup.
- Some controllers (such as
<span>cpuset</span>) require additional configuration. - cgroup configurations will not persist after a system reboot; persistence must be achieved through systemd or scripts.
- When using the
<span>nsdelegate</span>mount option, cgroup operations within the namespace will be delegated to the container.
By using the above methods, cgroup v2 can be effectively utilized for fine-grained management of system resources, ensuring the quality of service (QoS) for critical applications while preventing system instability caused by resource abuse.