Skip to content
Search RHEL

This page uses Chinese content. Search opens the Chinese documentation.

    Browse this documentation

    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)执行:

    Terminal window
    stat -fc %T /sys/fs/cgroup
    # cgroup2fs
    sudo systemd-run --unit=cgtest --property=MemoryMax=64M --property=CPUQuota=20% --collect sleep 120
    sudo systemctl show cgtest -p MemoryMax -p MemoryCurrent -p CPUQuota -p ControlGroup
    sudo cat /sys/fs/cgroup/system.slice/cgtest.service/memory.max
    sudo cat /sys/fs/cgroup/system.slice/cgtest.service/cpu.max

    E3 记录:plans/content-expansion/evidence/rhel/rhel-systemd-cgroup/run.json(7 步,含 limits/OOM)。

    • 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)。
    Terminal window
    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 保持运行,方便观察。

    $ sudo systemctl show cgtest -p MemoryMax -p MemoryCurrent -p CPUQuota -p ControlGroup
    ControlGroup=/system.slice/cgtest.service
    MemoryCurrent=294912
    MemoryMax=67108864
    CPUQuota=20%

    systemctl show 的 MemoryMax 是字节;CPUQuota 显示百分比,落到 cpu.max 才是 quota period。

    $ sudo cat /sys/fs/cgroup/system.slice/cgtest.service/memory.max
    67108864
    $ sudo cat /sys/fs/cgroup/system.slice/cgtest.service/cpu.max
    20000 100000
    $ sudo systemctl show cgtest -p MemoryCurrent
    MemoryCurrent=294912
    $ sudo systemd-cgtop -n1 -b --order=memory | grep cgtest
    system.slice/cgtest.service 1 - 200K - -

    sleep 只占几百 K;要看真实压力,得让 unit 真正分配内存/跑 CPU。

    Terminal window
    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/KILL
    systemd[1]: cgmem.service: Failed with result 'oom-kill'.

    32M 限额下分配 64M 被 cgroup OOM killer 杀掉,不是整机 OOM。

    unit 退出后 --collect 会把它移除:

    $ sudo systemctl show cgmem -p MemoryMax
    MemoryMax=infinity

    不是限制没生效,而是 unit 已经不存在;要复查限制,在运行中读,或看持久化的 .service/drop-in。

    临时 unit 只适合实验。生产写 .service:

    [Service]
    MemoryMax=512M
    CPUQuota=50%

    或 drop-in:

    /etc/systemd/system/myapp.service.d/limits.conf
    [Service]
    MemoryMax=512M
    CPUQuota=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。
    • 未测试 MemoryHigh/MemorySwapMax;
    • 未测试 IOWeight/TasksMax;
    • 未测试 systemd-oomd;
    • 未测试容器/用户 slice 的嵌套限制。