Linux Cgroups(Control Groups)是内核提供的资源分配、限制和监控机制,通过层级化进程分组实现资源的精细化控制。以下从核心原理、操作示例和版本演进三方面详细分析:
一、核心原理与架构
1. 层级结构(Hierarchy)
- 每个Cgroup层级是一棵树形结构,节点为进程组(Cgroup)。
- 子节点继承父节点的资源限制,并支持额外约束(如限制子组内存不超过父组80%)。
- 示例:创建/sys/fs/cgroup/memory/app目录即生成一个内存控制组。
2. 控制器(Controller/Subsystem)
控制器是内核模块,负责具体资源管理:
- CPU控制器:通过cpu.shares分配CPU时间权重,或cpu.cfs_quota_us设定绝对配额(如限制进程组最多使用50% CPU)。
- 内存控制器:通过memory.limit_in_bytes限制物理内存(如100MB),memory.swappiness控制Swap使用。
- 其他控制器:blkio:限制磁盘I/O带宽pids:限制进程数量net_cls:标记网络包实现带宽控制。
3. 进程绑定机制
- 将进程PID写入cgroup.procs文件加入控制组(如echo 1234 > /sys/fs/cgroup/memory/app/cgroup.procs)。
- 进程的子进程自动继承父进程所属Cgroup。
二、操作示例:限制CPU与内存
1. 创建CPU限制组
# 创建Cgroup目录
mkdir /sys/fs/cgroup/cpu/app
# 限制该组进程每100ms周期内最多使用50ms CPU时间(即50%)
echo 50000 > /sys/fs/cgroup/cpu/app/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/app/cpu.cfs_period_us
# 将进程PID加入该组
echo 1234 > /sys/fs/cgroup/cpu/app/cgroup.procs
效果:PID 1234及其子进程的CPU占用率不超过50%。
2. 创建内存限制组
mkdir /sys/fs/cgroup/memory/app
# 限制内存上限为100MB,超过则触发OOM Killer
echo 100M > /sys/fs/cgroup/memory/app/memory.limit_in_bytes
echo 1234 > /sys/fs/cgroup/memory/app/cgroup.procs
效果:进程组占用内存超100MB时,内核终止组内进程。
三、Cgroups v1 与 v2 架构对比
特性 | Cgroups v1 | Cgroups v2(Unified Hierarchy) |
层级设计 | 多棵树,每树绑定单一控制器 | 单棵树整合所有控制器 |
资源限制 | 控制器独立配置,易冲突(如CPU与内存分离) | 统一配置文件(如cgroup.controllers) |
内存控制 | 仅限物理内存 | 支持内存+Swap+内核内存统一限制 |
进程迁移 | 需手动操作 | 自动迁移子树 |
v2优势:避免资源竞争(如CPU和内存限制冲突),简化管理逻辑。
四、应用场景
- 容器资源隔离
Docker/Kubernetes 使用Cgroups限制容器CPU、内存等资源,防止单一容器耗尽宿主机资源。 - 系统服务管理
Systemd 为每个服务创建Cgroup(如systemctl set-property httpd.service CPUQuota=50%)。 - 多租户环境
云平台通过Cgroups实现租户间的资源配额(如AWS ECS任务级CPU共享)。
关键设计思想
- 层级化资源分配:资源按树形结构逐级分配,实现细粒度控制。
- 控制器解耦:各资源类型由独立模块管理,扩展性强(如新增GPU控制器)。
- 动态调整:运行时修改限制参数(如echo 200M > memory.limit_in_bytes),无需重启进程。