CGroup 资源限制原理
一、为什么需要 CGroup解决什么问题1. 核心痛点Namespace命名空间只能解决「隔离视图」的问题让容器看不到宿主机的进程、网络、文件系统但无法限制资源使用如果同一台宿主机上跑多个容器其中一个容器跑 CPU 密集型 / 内存吃满的任务会直接把宿主机的 CPU、内存占满导致其他容器、甚至宿主机本身卡死生产环境绝对不能出现这种情况。2. CGroup 的核心作用CGroupControl Groups控制组是 Linux 内核的机制专门解决资源限制、隔离、监控的问题把进程分组给每个组分配「资源上限」比如最多用 100M 内存、最多用 50% CPU防止某个进程 / 容器占满宿主机资源保证其他进程正常运行。二、CGroup 核心知识点1. CGroup 的 5 大核心功能功能大白话解释1. 限制资源使用量给进程组设资源上限比如内存最多 100M、CPU 最多 50%防止占满系统资源2. 分配资源优先级给不同组分配不同优先级高优先级任务分更多 CPU 时间3. 监控资源使用记录组内进程的 CPU、内存使用情况方便运维排查4. 进程生命周期管理支持挂起、恢复、终止组内所有进程5. 层次化结构支持组嵌套形成树状结构比如父组限制总资源子组细分2. CGroup 的子系统资源管理模块CGroup 通过 ** 子系统subsystem** 管理不同类型的资源/sys/fs/cgroup/目录下的文件夹就是各个子系统核心常用子系统表格子系统作用cpu限制 CPU 使用率按比例分配 CPU 时间memory限制内存使用量设置内存 / 交换区上限本次实验的核心blkio限制块设备磁盘的 I/O 操作devices控制组内进程对设备的访问权限freezer挂起 / 恢复组内进程net_cls标记网络数据包用于流量控制pids限制组内进程的最大数量cpuacct统计组内进程的 CPU 使用情况大白话每个子系统对应一种资源memory子系统管内存cpu子系统管 CPU各司其职。三、实战用 CGroup 限制内存1. 准备内存吃满程序// 核心逻辑死循环每次申请10MB内存填随机数据持续吃内存 // 直到内存耗尽被系统杀死用来测试CGroup内存限制不限制的话会一直吃内存直到宿主机内存耗尽系统卡死2. 目标创建一个名为demo的 CGroup 内存组限制组内进程最多用 100M 内存让两个吃内存的程序在 100M 时被杀死不影响宿主机。3. 步骤步骤 1创建 CGroup 内存组mkdir /sys/fs/cgroup/memory/demo/CGroup 是文件系统级别的管理在/sys/fs/cgroup/memory/下创建目录就等于创建了一个内存控制组内核会自动在目录下生成一堆配置文件比如memory.limit_in_bytes、memory.swappiness、tasks步骤 2设置内存限制# 限制最大内存为100MB100*1024*1024100000000字节 echo 100000000 /sys/fs/cgroup/memory/demo/memory.limit_in_bytes # 禁止使用交换分区swap让限制更严格演示效果更明显 echo 0 /sys/fs/cgroup/memory/demo/memory.swappinessmemory.limit_in_bytes内存上限超过这个值内核会杀死组内进程memory.swappiness控制 swap 使用设为 0 就是完全不用 swap内存超了直接杀进程步骤 3把进程加入 CGroup核心操作# 1. 打开两个bash终端获取两个bash的PID ps -ef | grep bash # 2. 把两个bash的PID写入tasks文件就等于把进程加入demo组 echo $$ /sys/fs/cgroup/memory/demo/taskstasks文件是 CGroup 的核心把进程 PID 写入 tasks就把进程加入了这个控制组之后在这两个 bash 里运行的所有程序比如./cgmemdemo都会继承这个 CGroup 的内存限制步骤 4运行吃内存程序验证限制在两个 bash 里分别运行./cgmemdemo效果如下程序会持续打印10mb、20mb...80mb到接近 100mb 时被内核杀死显示 Killed两个程序都在 100M 左右被杀死宿主机内存完全不受影响完美验证了 CGroup 的限制效果四、CGroup 的删除与历史1. 如何取消 CGroup 限制rmdir /sys/fs/cgroup/memory/demo/直接删除 CGroup 目录就等于取消限制注意必须等tasks文件里的所有进程都退出 / 转移到其他组才能删除目录否则会报错2. CGroup 的历史前身2006 年 Google 工程师开发的process containers项目2007 年改名为control groupsCGroup版本v1最初版本2008 年并入 Linux 2.6.24 内核v2Tejun Heo 重写内核 4.5 版本引入更高效、更灵活现在容器普遍用 v2容器应用Docker、K8s 的资源限制比如docker run --memory1g、--cpus1底层都是 CGroup 实现的五、CGroup vs Namespace容器的两大核心技术技术核心作用解决的问题大白话Namespace命名空间隔离视图让进程看不到宿主机 / 其他容器的资源给进程戴「滤镜」只能看到自己的世界CGroup控制组限制资源让进程不能占满宿主机的 CPU、内存等资源给进程上「枷锁」限制能使用的资源上限容器的本质 Namespace隔离视图 CGroup限制资源 Rootfs独立文件系统三者缺一不可共同实现了容器的隔离、资源管控、环境一致性。六、对应 Docker/K8s 的实际应用你在 Docker 里用的资源限制底层全是 CGroupdocker run --memory100m my-ml-app底层就是创建一个 memory CGroup限制内存 100Mdocker run --cpus1 my-ml-app底层就是创建一个 cpu CGroup限制最多用 1 核 CPUdocker run --blkio-weight500 my-ml-app底层就是 blkio CGroup限制磁盘 I/O 权重K8s 的resources.requests/limits底层也是 CGroup给 Pod 设置资源限制七、总结CGroup 是 Linux 内核的资源管理机制通过将进程分组对组内进程的 CPU、内存、磁盘 I/O 等资源进行限制、隔离和监控是容器资源隔离的核心技术Docker、K8s 的资源限制都基于 CGroup 实现。CGroup 是 Linux 内核的控制组机制用来解决容器的资源限制问题。Namespace 解决了视图隔离但无法限制资源CGroup 通过子系统比如 memory、cpu给进程组设置资源上限比如限制容器最多用 100M 内存、50% CPU防止某个容器占满宿主机资源保证系统稳定性。Docker 和 K8s 的资源限制底层都是 CGroup 实现的是容器技术的核心支柱之一。八、补充实验注意事项必须用 root 权限操作CGroup 的配置需要 root 权限普通用户无法修改/sys/fs/cgroup/下的文件进程继承 CGroup把 bash 加入 CGroup 后bash 里启动的所有子进程都会自动继承这个 CGroup 的限制v1 vs v2 的区别现在大部分系统用 cgroup v2目录结构和 v1 略有不同但核心逻辑一致OOM Killer 的作用当进程超过 CGroup 内存限制时内核会触发 OOM Killer杀死组内进程保护系统