在 Linux 操作系统中「Cgroup」(Control Groups)是一项非常重要的技术,它允许系统管理员对运行的软件进程执行组织进行分组,并进行 CPU 、内存、IO 等资源的限制、统计和监控。
Cgroup 是由 Google 开发,后被各大 Linux 分支接受并组成为一个标准性的系统资源管理功能,当前已成为启动器 systemd 的核心技术之一。
通过 cgroup,我们可以:
限制软件使用的资源(如内存、CPU 、IO 、网络并发数量等)
统计或跟踪软件使用的资源
分配或分隔资源,并与容器技术结合。
Linux Cgroup 有两个主要版本:
v2 :结合管理,类似于组合式架构,让资源管理更简洁
cat /sys/fs/cgroup/cgroup.controllers # v2
ls /sys/fs/cgroup/memory/ # v1
在 /etc/default/grub 中添加:
GRUB_CMDLINE_LINUX="... systemd.unified_cgroup_hierarchy=1"
然后执行
sudo update-grub
sudo reboot
Cgroup 通过文件系统进行控制,形成一些相关目录,每一个目录就是一个进程组。
比如:
/sys/fs/cgroup/memory/mygroup/
/sys/fs/cgroup/cpu/mygroup/
通过将 pid 写入特定的 cgroup 文件,就可以把进程分配到该 cgroup 中。
sudo cgcreate -g memory,cpu:mygroup
echo 100000000 > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
echo 512 > /sys/fs/cgroup/cpu/mygroup/cpu.shares # 高值优先级高
echo 1234 > /sys/fs/cgroup/memory/mygroup/tasks
cgexec -g memory,cpu:mygroup stress --vm 1 --vm-bytes 128M
创建服务:
[Service]
Slice=mygroup.slice
MemoryMax=200M
CPUQuota=20%
如果一个 Java 运行时占定太多内存,可以这样制定:
sudo cgcreate -g memory:/java
sudo cgset -r memory.limit_in_bytes=1G java
sudo cgexec -g memory:java java -jar yourapp.jar
sudo cgcreate -g blkio:/limit
sudo cgset -r blkio.throttle.read_bps_device="8:0 1048576" limit # 限制阅读速度
Docker 和 k8s 都是基于 Cgroup 来进行资源隔离和管理的,例如:
docker run --memory="500m" --cpus="0.5" busybox
确认是 root 权限操作,确认路径正确
可通过创建 slice 或 service 配合
可使用 cgroup相关工具:
cgtop
cgexec
cgroupfs-mount
Cgroup 是环境隔离、资源限制和性能管理的基石,无论是纯 Linux 系统管理,还是容器和分应用环境,Cgroup 的熟悉程度展示了系统管理和性能调优能力。并且在终端、服务器、零件设备、实时操作系统中都有重要场景。