RHEL 10 systemd cgroup v2:MemoryMax、CPUQuota 与 OOM 实测
This content is not available in your language yet.
RHEL 10 默认 cgroup v2:单一层级、/sys/fs/cgroup/<slice>/<unit>/ 下直接是 memory.max、cpu.max 这类文件。systemd 的 MemoryMax/CPUQuota 最终就写到这里。
在 PVE 393 rhel9-lab(RHEL 10.2,systemd 257)执行:
stat -fc %T /sys/fs/cgroup# cgroup2fssudo systemd-run --unit=cgtest --property=MemoryMax=64M --property=CPUQuota=20% --collect sleep 120sudo systemctl show cgtest -p MemoryMax -p MemoryCurrent -p CPUQuota -p ControlGroupsudo cat /sys/fs/cgroup/system.slice/cgtest.service/memory.maxsudo cat /sys/fs/cgroup/system.slice/cgtest.service/cpu.maxE3 记录:plans/content-expansion/evidence/rhel/rhel-systemd-cgroup/run.json(7 步,含 limits/OOM)。
先给结论:cgroup2fs 单层级
Section titled “先给结论:cgroup2fs 单层级”stat -fc %T /sys/fs/cgroup返回cgroup2fs;- 没有 v1 的
memory/、cpu/子系统目录; - unit 路径:
/sys/fs/cgroup/system.slice/cgtest.service; MemoryMax=64M→memory.max=67108864;CPUQuota=20%→cpu.max=20000 100000(20ms/100ms)。
systemd-run
Section titled “systemd-run”sudo systemd-run --unit=cgtest \ --property=MemoryMax=64M \ --property=CPUQuota=20% \ --collect sleep 120# Running as unit: cgtest.service; invocation ID: ...--collect 让 unit 退出后自动清理;sleep 120 只是让 unit 保持运行,方便观察。
读 limits
Section titled “读 limits”$ sudo systemctl show cgtest -p MemoryMax -p MemoryCurrent -p CPUQuota -p ControlGroupControlGroup=/system.slice/cgtest.serviceMemoryCurrent=294912MemoryMax=67108864CPUQuota=20%systemctl show 的 MemoryMax 是字节;CPUQuota 显示百分比,落到 cpu.max 才是 quota period。
$ sudo cat /sys/fs/cgroup/system.slice/cgtest.service/memory.max67108864$ sudo cat /sys/fs/cgroup/system.slice/cgtest.service/cpu.max20000 100000MemoryCurrent 与 cgtop
Section titled “MemoryCurrent 与 cgtop”$ sudo systemctl show cgtest -p MemoryCurrentMemoryCurrent=294912$ sudo systemd-cgtop -n1 -b --order=memory | grep cgtestsystem.slice/cgtest.service 1 - 200K - -sleep 只占几百 K;要看真实压力,得让 unit 真正分配内存/跑 CPU。
sudo systemd-run --unit=cgmem --property=MemoryMax=32M --collect \ bash -c 'python3 -c "a=bytearray(64*1024*1024)"'journalctl -u cgmem:
systemd[1]: cgmem.service: A process of this unit has been killed by the OOM killer.systemd[1]: cgmem.service: Main process exited, code=killed, status=9/KILLsystemd[1]: cgmem.service: Failed with result 'oom-kill'.32M 限额下分配 64M 被 cgroup OOM killer 杀掉,不是整机 OOM。
--collect 的副作用
Section titled “--collect 的副作用”unit 退出后 --collect 会把它移除:
$ sudo systemctl show cgmem -p MemoryMaxMemoryMax=infinity不是限制没生效,而是 unit 已经不存在;要复查限制,在运行中读,或看持久化的 .service/drop-in。
临时 unit 只适合实验。生产写 .service:
[Service]MemoryMax=512MCPUQuota=50%或 drop-in:
[Service]MemoryMax=512MCPUQuota=50%然后 systemctl daemon-reload && systemctl restart myapp。
-
cgroup2fs确认是 v2; -
systemctl show的 MemoryMax/CPUQuota 符合预期; -
memory.max/cpu.max与 show 对得上; - 运行中看
MemoryCurrent/cgtop; - OOM 日志是
oom-kill而不是整机 OOM; - 持久化写
.service/drop-in,不依赖systemd-run。
未实测与边界
Section titled “未实测与边界”- 未测试
MemoryHigh/MemorySwapMax; - 未测试
IOWeight/TasksMax; - 未测试
systemd-oomd; - 未测试容器/用户 slice 的嵌套限制。
- RHEL tuned 性能基线 — 系统级性能
- RHEL 10 网络排障 — 另一类资源观测
- 官方:Using systemd unit files to customize and optimize your system