bigywater.tech
Docker · 78

cgroup 文件:直接读 memory.max 与 cpu.max

docker run 的资源限制参数最后落在哪里?这篇直接读容器的 cgroup v2 目录,把每个参数对应的文件和数值一一列出来,还看了 docker pause 在 cgroup 里是什么样子。

86 个文件
一个容器的 cgroup v2 目录里的文件数
50000 100000
--cpus 0.5 在 cpu.max 里的内容
cgroup.freeze = 1
docker pause 之后 cgroup 里的冻结标志

位置

实测 · 本机执行输出
  /sys/fs/cgroup 的文件系统类型:cgroup2fs
  主进程的 /proc/<pid>/cgroup(相对读取者自己的 cgroup 命名空间):0::/../<容器ID>
  在虚拟机的 /sys/fs/cgroup 下找到的目录:/sys/fs/cgroup/docker/<容器ID>
  容器的 cgroup 目录里有 86 个文件;cgroup.controllers = cpuset cpu io memory hugetlb pids rdma

这台虚拟机用 cgroup v2,每个容器在 /sys/fs/cgroup/docker/<容器ID>。读 /proc/<pid>/cgroup 得到的是相对读取者自己 cgroup 命名空间的路径(这次是 ../<容器ID>),所以我是在虚拟机的 /sys/fs/cgroup 下按容器 ID 找到真实目录的;容器内部看到的路径,我没有单独验证。

参数与文件

实测 · 本机执行输出
  cpu.max               = 50000 100000
  cpu.weight            = 59
  memory.max            = 104857600
  memory.swap.max       = 0
  pids.max              = 50
  cpuset.cpus           = 0-1
  cpuset.cpus.effective = 0-1
  io.max                = 254:0 rbps=max wbps=1048576 riops=max wiops=max

--cpus 对应 cpu.max;--cpu-shares 被换算成 cpu.weight(512 → 59,见 c34);--memory 与 --memory-swap 对应 memory.max 和 memory.swap.max(swap 是总和减内存,见 c36);--pids-limit 对应 pids.max(c38);--cpuset-cpus 对应 cpuset.cpus;--device-write-bps 对应 io.max,按设备号(254:0 是虚拟机的 vda)。

进程与统计

实测 · 本机执行输出
  cgroup.procs:['59365'];docker top 的 PID 列:['59365'];一致吗?True
  cgroup.type = domain;memory.current = 0.5 MiB;pids.current = 1

cgroup.procs 列出的进程就是 docker top 看到的进程;memory.current、pids.current 等是运行时统计,docker stats 读的就是它们(见 c70)。

暂停

实测 · 本机执行输出
  暂停前:cgroup.freeze = 0;cgroup.events = populated 1 frozen 0
  docker pause 后:cgroup.freeze = 1;cgroup.events = populated 1 frozen 1
  unpause 后:cgroup.freeze = 0

docker pause 把 cgroup.freeze 写成 1,cgroup.events 里 frozen 变成 1;unpause 写回 0。按我的理解进程没有收到信号,只是被内核冻住,这一点没有专门验证。

生命周期

实测 · 本机执行输出
  docker stop 之后目录还在吗?已删除

容器停止后,这个 cgroup 目录随之删除。

分步演示

cgroup 文件
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。cgroup 目录在虚拟机里用特权容器加 nsenter 读取(方法见 c19),目录用 find 按容器 ID 定位;容器参数:--cpus 0.5 --memory 100m --memory-swap 100m --pids-limit 50 --cpu-shares 512 --cpuset-cpus 0-1 --device-write-bps /dev/vda:1mb;PID 与容器 ID 每次运行不同;实验后已删除容器
    • 没有验证:cgroup v1 的目录结构、memory.high / memory.low 的行为(c36 里 --memory-reservation 对应 memory.low)、io.weight、hugetlb 与 rdma 控制器、嵌套 cgroup(容器里再建子 cgroup)、cgroup 的 BPF 设备过滤(见 c45)
    京ICP备2026067502号-1京公网安备11010502063487号