Linux Learning Notes – cgroup (Part 2)

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

  1. Hierarchy v2 adopts a single hierarchy structure, with all controllers mounted under a unified view.
  2. Controllers Resource control modules (such as cpu, memory, io, etc.)
  3. cgroup Path Each cgroup has a unique path in the virtual file system.
  4. 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

  1. Modifying <span>cgroup.subtree_control</span> will affect all child cgroups.
  2. Resource limit values must comply with the constraints of the parent cgroup.
  3. Some controllers (such as <span>cpuset</span>) require additional configuration.
  4. cgroup configurations will not persist after a system reboot; persistence must be achieved through systemd or scripts.
  5. 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.

Leave a Comment