2. cgroup v2 核心概念:控制器、层级、进程组与线程模式

在深入观测 cgroup v2 的运行时延迟与异常之前,必须精确理解其四大核心概念:控制器(Controller)、层级(Hierarchy)、进程组(Cgroup)以及 v2 独有的线程模式(Thread Mode)。这四个概念构成了所有资源隔离与观测操作的基础。

2.1 进程组(Cgroup)—— 资源隔离的基本单元

一个 Cgroup 是一个进程的集合,这些进程被绑定到一组特定的资源约束(通过控制器实现)。在 cgroup v2 中,每个 cgroup 都是一个目录,其路径即为 cgroup 的名称。

  • 唯一层级:所有 cgroup 都挂载在同一个统一层级下(通常为 /sys/fs/cgroup)。
  • 进程归属:一个进程只能属于一个 cgroup。写入 cgroup.procs 文件即可将进程移入。
  • 核心文件:每个 cgroup 目录下都包含 cgroup.procs(线程组 PID 列表)、cgroup.controllers(可用控制器)、cgroup.subtree_control(子节点启用的控制器)等元数据文件。
观测要点:在延迟分析中,cgroup.procs 的内容变化频率直接反映了进程迁移事件。频繁的迁移可能暗示负载均衡异常或控制器配置错误。

2.2 控制器(Controller)—— 资源限制与观测的引擎

控制器是内核中负责管理和统计特定类型资源(如 CPU、内存、I/O)的子系统。每个控制器在 cgroup 目录下暴露一组接口文件。

控制器 接口文件前缀 核心观测指标 延迟关联
cpu cpu. cpu.stat(usage_usec, throttled_usec) CPU 节流延迟
memory memory. memory.events(oom, oom_kill) OOM 延迟与抖动
io io. io.stat(rbytes, wbytes, rios, wios, dbytes, dios) I/O 排队延迟
pids pids. pids.current, pids.events(max) fork 失败延迟
关键差异:cgroup v2 中,控制器必须显式启用才能生效。通过向父 cgroup 的 cgroup.subtree_control 写入 +cpu +memory 等指令,子 cgroup 才能使用这些控制器。未启用的控制器不会产生任何统计文件,这是观测配置中常见的“静默失败”陷阱。

2.3 层级(Hierarchy)—— 统一树状结构

cgroup v2 最大的架构变革是统一层级(Unified Hierarchy)。所有控制器挂载在同一棵树上,消除了 v1 中多层级导致的资源竞争与统计不一致问题。

  • 树状结构:根 cgroup(/sys/fs/cgroup)是树的根节点,子 cgroup 通过创建子目录形成。
  • 资源继承:子 cgroup 的资源上限不能超过父 cgroup 的配置。例如,父 cgroup 设置了 memory.max = 1G,则所有子 cgroup 的 memory.max 总和不能超过 1G。
  • 内部进程约束:如果一个 cgroup 有子 cgroup,则它不能直接包含进程(即 cgroup.procs 必须为空)。这保证了资源统计的清晰边界。
cgroup v2 统一层级结构 /sys/fs/cgroup (Root) system.slice user.slice kubepods sshd.service user-1000.slice pod123.slice pod456.slice container-abc 内部进程约束:只有叶子节点(如 container-abc)可以包含进程,非叶子节点(如 pod123.slice)的 cgroup.procs 必须为空

2.4 线程模式(Thread Mode)—— v2 的精细化控制

cgroup v2 引入了线程模式(Thread Mode),允许将控制器的作用域从进程级细化到线程级。这是 v1 完全不支持的粒度。

  • 线程组(Thread Group):一个进程内的所有线程默认属于同一个 cgroup。
  • 启用线程模式:向 cgroup 的 cgroup.type 文件写入 threaded,该 cgroup 即进入线程模式。
  • 线程级资源域:在线程模式下,cgroup.threads 文件替代 cgroup.procs,允许将单个线程移入不同的子 cgroup。
  • 控制器限制:并非所有控制器都支持线程模式。目前 cpu、memory、pids 支持,而 io 控制器不支持线程级隔离。
延迟观测价值:线程模式使得我们可以将高优先级的控制线程(如网络 I/O 线程)与普通工作线程分离到不同的 cgroup 中。通过观测 cpu.stat 中每个线程 cgroup 的 throttled_usec,可以精确识别是哪个线程类型导致了 CPU 节流延迟。
线程模式 vs 进程模式资源域对比 进程模式(默认) cgroup A (cgroup.procs) 进程 P1 (PID 1000) 线程 T1 (TID 1001) 线程 T2 (TID 1002) 线程 T3 (TID 1003) 所有线程共享同一个 cgroup 资源上限 线程模式(threaded) cgroup B (cgroup.threads) 进程 P1 (PID 1000) 线程 T1 (TID 1001) 线程 T2 (TID 1002) cgroup C (cgroup.threads) 线程 T3 (TID 1003) 线程可被分配到不同的 cgroup,独立控制资源 cgroup.type = threaded

2.5 核心概念关系总结

四个概念之间的关系可以归纳为:控制器是资源管理的策略引擎,层级定义了策略的继承与作用范围,进程组是策略的应用目标,线程模式则提供了更细粒度的控制能力。

概念 本质 观测入口 延迟事件来源
控制器 内核资源管理模块 cpu.stat, memory.events 节流、OOM、I/O 排队
层级 树状组织与继承关系 cgroup.subtree_control 配置传播延迟、资源争抢
进程组 进程集合与资源域 cgroup.procs 进程迁移、内部进程违规
线程模式 线程级资源域划分 cgroup.threads, cgroup.type 线程迁移、控制器兼容性
实战建议:在构建观测系统时,建议首先通过 cat /sys/fs/cgroup/cgroup.controllers 确认系统支持的控制器列表,然后检查目标 cgroup 的 cgroup.type 确认当前模式。这是所有延迟水位分析的第一步。