背景信息
cgroup 是 Linux 内核中限制进程资源使用的功能,可以限制进程使用的 CPU、内存、网络等资源,避免单进程占用过多资源导致系统崩溃。cgroup 分为 cgroup v1(2007 年合入内核)和 cgroup v2(2016 年正式发布)两代,主要差异如下:
对比项 | cgroup v1 | cgroup v2 |
层级结构 | 多层次结构,同一进程可能同时出现在不同 cgroup 中,含义混乱 | 统一层级模型,所有控制器共享同一棵 cgroup 树 |
线程粒度 | 控制不稳定,父 cgroup 线程和子 cgroup 线程竞争资源时行为不可预测 | 引入线程化机制(Threaded Mode),支持同一进程的不同线程分配到不同 cgroup |
接口命名 | 字段单位和命名不统一(如 memory.limit_in_bytes vs cpu.cfs_quota_us),学习成本高 | 统一接口命名( *.max、*.current、*.events、*.stat),并新增 io.latency、memory.pressure 等高级特性 |
生态现状 | 用户基数庞大,但 systemd 从 v256 起默认不支持 cgroup v1 | 上游社区和各大发行版已全面转向(RHEL 9 起默认使用 cgroup v2);TencentOS Server 4 默认使用 cgroup v2( unified 模式) |
前提条件
执行本文档中 cgroup 查询、配置或迁移操作前,请确认已满足以下条件:
root 权限:cgroup 接口文件位于
/sys/fs/cgroup,写操作需 root。确认当前 cgroup 模式:执行
mount | grep cgroup,确认当前是 cgroup2(unified)还是多个 cgroup 挂载点(legacy),避免误操作。备份 grub 配置(迁移场景必须):修改启动参数前务必备份。
维护窗口:cgroup v1 > cgroup v2 迁移涉及修改 GRUB 启动参数并重启系统,请安排维护窗口,确保业务可容忍停机。
systemd 版本要求:cgroup v2 完整支持需要 systemd ≥ 239(TencentOS Server 4 默认满足)。若从旧系统迁移,请先执行
systemctl --version 确认。不在容器内执行迁移:cgroup 模式由宿主机内核启动参数决定,容器内无法修改;所有迁移操作必须在宿主机执行。
注意事项
TencentOS Server 4 默认使用 cgroup v2(
unified 模式)。cgroup v2 的
no internal process constraint 规则要求:当一个 cgroup 启用了控制器(如 memory.max),它不能同时直接包含进程,进程必须放在叶子 cgroup 中。线程化 cgroup 操作不可逆:一旦设为
threaded,无法恢复为 domain。线程化 cgroup 的父级必须是有效的域 cgroup 或线程 cgroup。cpu.max 中 max 表示无限制,$MAX=0 表示完全禁止 CPU 使用。注意不要误设为 0 100000,会导致进程无法运行。memory.swap.max 设为 0 会完全禁止 swap 使用,可能导致内存不足时进程被 OOM Kill。建议根据业务实际内存特征设置合理值。io.latency 是 cgroup v2 新增的 IO 延迟目标机制,设备超过目标延迟时内核会优先调度该 cgroup 的 IO 请求,适用于对延迟敏感的业务。cgroup v2 统计接口(
*.stat、*.current)是只读的,不要尝试写入。memory.reclaim 是只写接口,写入字节数会触发主动内存回收。从 cgroup v1 迁移到 cgroup v2 时,原有 systemd unit 中的
CPUQuota、MemoryLimit 等指令在 cgroup v2 下继续有效,systemd 会自动翻译为 cgroup v2 接口。但直接操作 /sys/fs/cgroup 的脚本需要更新接口路径。容器运行时兼容性:Docker < 20.10、containerd < 1.6、Kubernetes < 1.25 对 cgroup v2 支持不完整。迁移前请升级容器对应组件版本,并在 Docker daemon 配置
/etc/docker/daemon.json 中确认无需特殊 --cgroup-driver 参数(cgroup v2 下 systemd 自动使用 systemd 驱动)。生产环境风险:cgroup v1 升级 cgroup v2 迁移不可在线切换,必须重启;部分 cgroup v1 脚本/监控指标(如直接读取
/sys/fs/cgroup/memory/...)在 cgroup v2 下路径失效,需您提前梳理并改造。接口与参数说明
cgroup 模式切换参数
启动参数 | 取值 | 说明 |
systemd.unified_cgroup_hierarchy=1 | 0/1 | 1=使用 cgroup v2(unified) 0=使用 cgroup v1(legacy),默认值:1(TencentOS Server 4) |
systemd.legacy_systemd_cgroup_controller=1 | 0/1 | 1=由 systemd 统一代理管理 cgroup v1 控制器 0=由内核直接管理 cgroup v1 控制器,仅在 legacy(cgroup v1)模式下有效 |
SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 | 0/1 | 1=强制启用 cgroup v1 0=不强制(默认), systemd v256 及以上版本无法使用 cgroup v1 |
cgroup v1 与 cgroup v2 核心 API 映射表
常用控制器接口的 cgroup v1 与 cgroup v2 映射如下表所示:
子系统 | cgroup v1 接口 | cgroup v2 接口 | 说明 |
cpu | cpu.cfs_quota_us + cpu.cfs_period_us | cpu.max | 合并为单接口,格式 "$MAX $PERIOD" |
cpu | cpu.cfs_burst_us | cpu.max.burst | 突发 CPU 配额 |
cpu | cpu.shares | cpu.weight | 权重(1-10000),仅在设备繁忙时生效 |
cpu | cpuacct.stat + cpuacct.usage | cpu.stat | 统一统计接口 |
cpu | cpu.rt_period_us + cpu.rt_runtime_us | — | 已删除,实时调度不再由 cgroup 控制 |
cpuset | cpuset.effective_cpus | cpuset.cpus.effective | 有效 CPU 列表 |
cpuset | cpuset.effective_mems | cpuset.mems.effective | 有效内存节点列表 |
cpuset | cpuset.memory_pressure | memory.pressure | 合并到 memory 子系统 |
memory | memory.limit_in_bytes | memory.max | 内存硬限制 |
memory | memory.soft_limit_in_bytes | memory.low | 内存软限制(保证量) |
memory | memory.usage_in_bytes | memory.current | 当前内存使用量 |
memory | memory.max_usage_in_bytes | memory.peak | 历史最大使用量 |
memory | memory.memsw.limit_in_bytes | memory.swap.max | swap 限制 |
memory | memory.swappiness | — | 已删除,改用 memory.swap.max |
memory | memory.oom_control | — | 已删除,改用 memory.oom.kill 事件 |
memory | memory.kmem.* | — | 已删除,内核内存不再单独计费 |
blkio | blkio.throttle.read_bps_device 等 4 个 | io.max | 合并为单接口 |
blkio | blkio.throttle.io_service* | io.stat | 统计接口 |
blkio | blkio.bfq.io_service* | — | 已删除 |
blkio | — | io.latency | 新增:IO 延迟目标 |
hugetlb | hugetlb.<size>.usage_in_bytes | hugetlb.<size>.current | 当前使用量 |
hugetlb | hugetlb.<size>.limit_in_bytes | hugetlb.<size>.max | 限制 |
hugetlb | hugetlb.<size>.max_usage_in_bytes | hugetlb.<size>.events | 事件通知 |
rdma | — | rdma.max / rdma.current | 新增:RDMA 资源限制 |
pids | — | pids.peak | 新增:历史最大进程数 |
cgroup v2 核心接口详解
cpu.max
格式:
"$MAX $PERIOD",例如 "500000 100000" 表示在 100ms 周期内最多用 50ms CPU(即 0.5 核)。换算说明:
cpu.max 的值单位为微秒(μs)。$MAX 是周期内允许运行的时间,$PERIOD 是调度周期长度。核数 = $MAX / $PERIOD。常用换算:1 核 =
100000 100000(100ms / 100ms)0.5 核 =
50000 100000 或 500000 10000002 核 =
200000 100000无限制 =
max 100000(max 表示不限 CPU 用量,周期仍为 100ms)查看当前值(
<cgroup_name> 为您创建的 cgroup 名称):cat /sys/fs/cgroup/<cgroup_name>/cpu.max
输出示例(已设置为 0.5 核时):
500000 1000000
设置为 0.5 核(500000μs / 1000000μs = 0.5):
echo "500000 1000000" > /sys/fs/cgroup/<cgroup_name>/cpu.max
写入后再次执行
cat /sys/fs/cgroup/<cgroup_name>/cpu.max 确认已生效,输出示例:500000 1000000
设置为无限制(表示不限制该 cgroup 的 CPU 用量):
echo "max 100000" > /sys/fs/cgroup/<cgroup_name>/cpu.max
写入后执行
cat /sys/fs/cgroup/<cgroup_name>/cpu.max,输出示例:max 100000
memory.max / memory.high / memory.low
接口 | 语义 | 超过后行为 |
memory.max | 硬限制 | 触发 OOM Killer |
memory.high | 软限制 | 触发内存回收,影响性能但不杀进程 |
memory.low | 保证量 | 低于此值时不回收该 cgroup 内存 |
memory.swap.max | swap 上限 | 超过后拒绝 swap 分配 |
io.max
格式:
"$MAJ:MIN rbps=<N> wbps=<N> riops=<N> wiops=<N>"。限制 8:16 设备读写带宽各 10MB/s、IOPS 各 500:
echo "8:16 rbps=10485760 wbps=10485760 riops=500 wiops=500" > /sys/fs/cgroup/<cgroup_name>/io.max
查看当前限制:
cat /sys/fs/cgroup/<cgroup_name>/io.max
输出示例:
8:16 rbps=10485760 wbps=10485760 riops=500 wiops=500
线程化 cgroup(Threaded Mode)
cgroup v2 引入线程化机制,允许同一进程的不同线程分配到不同 cgroup 中,解决 cgroup v1 线程粒度控制不稳定的问题。其中支持线程化的控制器有
cpu、cpuset、perf_event、pids。接口 | 取值 | 说明 |
cgroup.type | domain/threaded | 读写:设置 cgroup 类型 |
从 cgroup v1 迁移到 cgroup v2 操作步骤
警告:
本节操作涉及修改 GRUB 启动参数并重启系统,属于高风险变更,执行前请务必:
备份 GRUB 配置:
cp /etc/default/grub /etc/default/grub.bak.$(date +%F-%H%M);确认维护窗口:重启将导致业务中断,请确保已通知相关方并安排停机窗口;
步骤1:确认当前 cgroup 模式
# 查看当前 cgroup 挂载模式mount | grep cgroup# v2(unified)预期输出:cgroup2 on /sys/fs/cgroup type cgroup2 (...)# v1(legacy)预期输出:cgroup on /sys/fs/cgroup/cpuset type cgroup (cpuset),cgroup on /sys/fs/cgroup/memory type cgroup (memory) ...(多个挂载点)# 通过 stat 进一步确认 cgroup v2stat -fc %T /sys/fs/cgroup/# v2 预期输出:cgroup2fs# v1 预期输出:tmpfs
验证方法:若
mount | grep cgroup 仅显示一行 cgroup2 on /sys/fs/cgroup,说明已是 cgroup v2,无需迁移;若显示多个 cgroup on /sys/fs/cgroup/<controller>,则是 cgroup v1,继续后续步骤。步骤2:修改 GRUB 启动参数
# 备份原配置cp /etc/default/grub /etc/default/grub.bak.$(date +%F-%H%M)# 预期输出:无报错;可用 ls -l /etc/default/grub.bak.* 确认# 在 GRUB_CMDLINE_LINUX 中追加/修改以下参数(确保 unified_cgroup_hierarchy=1)# 使用 grubby 直接添加(推荐,避免手工编辑出错)grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1 systemd.legacy_systemd_cgroup_controller=0"# 预期输出:无报错# 查看当前内核启动参数,确认已追加grubby --info=ALL | grep -E 'args|kernel'# 预期输出:args 中应包含 systemd.unified_cgroup_hierarchy=1
验证方法:
grubby --info=ALL | grep args 输出中应能看到 systemd.unified_cgroup_hierarchy=1。步骤3:重新生成 GRUB 配置
# 重新生成 grub.cfg(x86_64 使用 grub2-mkconfig)grub2-mkconfig -o /boot/grub2/grub.cfg# 预期输出:Generating grub configuration file ... done# aarch64 平台路径可能不同,使用:# grub2-mkconfig -o /etc/grub2-efi.cfg 或 grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg# 验证生成结果(确认配置文件中包含 unified_cgroup_hierarchy=1)grep unified_cgroup_hierarchy /boot/grub2/grub.cfg# 预期输出:能匹配到 systemd.unified_cgroup_hierarchy=1
步骤4:重启系统
# 重启系统(维护窗口内执行)sync && reboot# 预期输出:系统重启;重新登录后执行下一步验证
验证方法:系统重启完成后,SSH 重新登录,执行
uptime 确认系统已正常启动。步骤5:验证迁移成功
# 验证1:mount 验证(应为单一 cgroup2 挂载)mount | grep cgroup# 预期输出:cgroup2 on /sys/fs/cgroup type cgroup2 (...)# 验证2:stat 文件系统类型stat -fc %T /sys/fs/cgroup/# 预期输出:cgroup2fs# 验证3:控制器挂载情况(v2 下控制器通过 /sys/fs/cgroup/cgroup.controllers 暴露)cat /sys/fs/cgroup/cgroup.controllers# 预期输出:cpuset cpu io memory hugetlb pids rdma(具体列表取决于内核配置)# 验证4:v1 接口已卸载(不应存在 /sys/fs/cgroup/memory 等子目录)ls /sys/fs/cgroup/ | grep -E '^(cpu|memory|blkio|cpuset)$'# 预期输出:空(v1 子目录应已不存在)
常用管理命令
查看 cgroup 模式
查看当前 cgroup 模式:
mount | grep cgroup
输出示例:
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
unified(cgroup v2)模式返回一行
cgroup2 挂载;legacy(cgroup v1)模式返回多个 cgroup 挂载点(cpu、memory、...)。查看 cgroup 版本:
cat /proc/cgroups
输出示例:
#subsys_name hierarchy num_cgroups enabledcpuset 0 188 1cpu 0 188 1cpuacct 0 188 1blkio 0 188 1memory 0 188 1devices 0 188 1freezer 0 188 1net_cls 0 188 1perf_event 0 188 1net_prio 0 188 1hugetlb 0 188 1pids 0 188 1rdma 0 188 1misc 0 188 1
切换 cgroup 模式(cgroup v2 > cgroup v1,不推荐)
以下场景可参考本节步骤将 cgroup v2 切回 cgroup v1:
业务依赖仅支持 cgroup v1 的旧版工具链(如 libcgroup 老接口、特定监控 agent)
遗留脚本深度耦合 cgroup v1 目录结构且短期无法改造。
切换模式需修改 GRUB 启动参数并重新生成配置,重启后持久化生效(无需额外配置)(如需恢复 cgroup v2,反向删除这些参数并重启即可)。在 GRUB 启动参数中添加:
systemd.legacy_systemd_cgroup_controller=1systemd.unified_cgroup_hierarchy=0SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1
重启后验证:
mount | grep cgroup
输出示例(已切回 cgroup v1,返回多个挂载点):
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)cgroup on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)...
使用 systemd 操作 cgroup
查看 cgroup 层级结构:
systemd-cgls
输出示例:
Control group /:-.slice├─user.slice (#1203)│ └─user-0.slice (#41553)│ └─session-1.scope...└─system.slice (#65)├─sshd.service (#2701)│ └─674 sshd: /usr/sbin/sshd -D...
启动一个受 cgroup 控制的 service:
systemctl start <service_name>
命令执行成功时无输出。
修改 service 的资源限制:
systemctl set-property <service_name> CPUQuota=50% MemoryLimit=1G
命令执行成功时无输出。
设置后可通过
systemctl show <service_name> | grep -E "CPUQuota|MemoryLimit" 查看已生效的限值。手动创建 cgroup 并限制资源
创建 cgroup(
<cgroup_name> 替换为实际名称,如 webapp),并依次设置 CPU、内存、IO 限制,将进程加入 cgroup:mkdir /sys/fs/cgroup/<cgroup_name>echo "500000 1000000" > /sys/fs/cgroup/<cgroup_name>/cpu.maxecho 1073741824 > /sys/fs/cgroup/<cgroup_name>/memory.maxecho "8:16 rbps=10485760 wbps=10485760" > /sys/fs/cgroup/<cgroup_name>/io.maxecho $PID > /sys/fs/cgroup/<cgroup_name>/cgroup.procs
以上命令执行成功时均无输出,可通过下述命令验证限制是否生效。
验证限制生效:
cat /sys/fs/cgroup/<cgroup_name>/cpu.statcat /sys/fs/cgroup/<cgroup_name>/memory.currentcat /sys/fs/cgroup/<cgroup_name>/io.stat
输出示例(
cpu.stat 第一条为例,数值随进程运行增长;memory.current 应 ≤ memory.max):usage_usec 1532600user_usec 810400system_usec 722200nr_periods 12nr_throttled 6throttled_usec 3900000
使用 systemd-run 临时测试
启动一个临时服务并限制 CPU:
systemd-run --unit=test-cpu --slice=test-.slice -p CPUQuota=50% -p MemoryLimit=512M /bin/bash -c "while true; do true; done"
输出示例(返回该服务的运行信息):
Running as unit: test-cpu.service
查看资源使用:
systemctl status test-cpusystemd-cgls test-.slice
systemctl status test-cpu 输出示例:● test-cpu.service - /bin/bash -c while true; do true; doneLoaded: loaded (/run/systemd/transient/test-cpu.service; transient)Active: active (running) since Sat 2026-08-22 11:00:00 CST; 5s agoMain PID: 2475 (bash)Tasks: 1 (limit: 48621)Memory: 512.0M (max: 512.0M)CPU: 2.5s
启用线程化 cgroup
将 cgroup 标记为线程化(操作不可逆),并将进程的不同线程加入不同子 cgroup:
echo threaded > /sys/fs/cgroup/<cgroup_name>/cgroup.typeecho $TID > /sys/fs/cgroup/<cgroup_name>/worker_threads/cgroup.threads
执行
cat /sys/fs/cgroup/<cgroup_name>/cgroup.type 确认类型已变更,输出示例:threaded
预期结果
资源限制生效验证
mount、控制器及 cgroup v1 接口卸载的验证方法已在 步骤5:验证迁移成功 中给出,此处不再重复。
资源限制生效验证
创建 cgroup 并设置
cpu.max、memory.max 后:cat /sys/fs/cgroup/<cgroup_name>/cpu.stat 应输出 usage_usec、user_usec、system_usec 等统计字段,且数值随进程运行增长。cat /sys/fs/cgroup/<cgroup_name>/memory.current 应输出当前内存使用字节数,应 ≤ memory.max。超过
memory.max 时,memory.events 中 oom 计数应递增,进程被 OOM Kill。其他注意事项
TencentOS Server 4 默认使用 cgroup v2(
unified 模式),不建议切回 cgroup v1。如必须使用 cgroup v1,需在 GRUB 启动参数中添加 systemd.unified_cgroup_hierarchy=0 并重启。cgroup v2 的
no internal process constraint 规则要求:当一个 cgroup 启用了控制器(如 memory.max),它不能同时直接包含进程,进程必须放在叶子 cgroup 中。这是与 cgroup v1 最大的行为差异之一。线程化 cgroup 操作不可逆:一旦设为
threaded,无法恢复为 domain。线程化 cgroup 的父级必须是有效的域 cgroup 或线程 cgroup。cpu.max 中 max 表示无限制,$MAX=0 表示完全禁止 CPU 使用。注意不要误设为 0 100000,会导致进程无法运行。memory.swap.max 设为 0 会完全禁止 swap 使用,可能导致内存不足时进程被 OOM Kill。建议根据业务实际内存特征设置合理值。io.latency 是 cgroup v2 新增的 IO 延迟目标机制,设备超过目标延迟时内核会优先调度该 cgroup 的 IO 请求,适用于对延迟敏感的业务。cgroup v2 统计接口(
*.stat、*.current)是只读的,不要尝试写入。memory.reclaim 是只写接口,写入字节数会触发主动内存回收。从 cgroup v1 迁移到 cgroup v2 时,原有 systemd unit 中的
CPUQuota、MemoryLimit 等指令在 cgroup v2 下继续有效,systemd 会自动翻译为 cgroup v2 接口。但直接操作 /sys/fs/cgroup 的脚本需要更新接口路径。容器运行时兼容性:Docker < 20.10、containerd < 1.6、Kubernetes < 1.25 对 cgroup v2 支持不完整或默认不启用。迁移前请升级容器运行时,并在 Docker daemon 配置
/etc/docker/daemon.json 中确认无需特殊 --cgroup-driver 参数(cgroup v2 下 systemd 自动使用 systemd 驱动)。systemd 版本要求:cgroup v2 完整支持需要 systemd ≥ 239,TencentOS Server 4 默认满足;若从旧系统迁移,请先执行
systemctl --version 确认。生产环境风险:cgroup v1 > cgroup v2 迁移不可在线切换,必须重启;部分 cgroup v1 脚本/监控指标(如直接读取
/sys/fs/cgroup/memory/...)在 cgroup v2 下路径失效,需提前梳理并改造。常见问题
Q1:迁移到 cgroup v2 后,容器启动失败,日志提示 "cgroup v2 not supported"?
A:容器运行时版本过旧。解决:升级 Docker ≥ 20.10、containerd ≥ 1.6 或 Kubernetes ≥ 1.25;对 Docker 检查
/etc/docker/daemon.json,确保未显式指定 --exec-opt native.cgroupdriver=cgroupfs(cgroup v2 下应使用 systemd 驱动)。升级后重启容器运行时:systemctl restart docker 或 systemctl restart containerd。Q2:应用日志报
memory.kmem.limit_in_bytes 读写失败 / "No such file or directory"?
A:这是 cgroup v1 的内核内存计费接口,在 cgroup v2 中已删除(内核内存不再单独计费,统一并入 memory.max)。解决:更新应用/容器运行时配置,移除对 memory.kmem.* 的引用,改用 memory.max 控制总内存(含内核内存)。Q3:迁移到 cgroup v2 后业务异常,如何回退到 cgroup v1?
A:反向修改 GRUB 参数并重启。步骤:
# 以下命令执行成功时均无输出# 移除 unified_cgroup_hierarchy=1,添加 v1 参数grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller=1 SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1"# 重新生成 grub 配置grub2-mkconfig -o /boot/grub2/grub.cfg# 重启sync && reboot
重启后验证:
mount | grep cgroup
输出示例(恢复为多个 cgroup 挂载点):
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)cgroup on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)...
注意:systemd v256 及以上版本不再支持回退到 cgroup v1;若设置
SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 后仍无法回退,说明该系统已无法降级到 cgroup v1,请在 cgroup v2 兼容模式下改造业务(或更换搭载较低版本 systemd 的机器)。Q4:
echo "500000 100000" > cpu.max 后进程 CPU 被完全限制无法运行?
A:参数理解错误。500000 100000 表示在 100ms 周期内允许 500ms CPU 时间,即 5 核(不是 0.5 核)。若想限制为 0.5 核,应使用 50000 100000 或 500000 1000000。换算公式:核数 = $MAX / $PERIOD。配置$MAX=0 会完全禁止 CPU 使用,属于危险配置。Q5:创建子 cgroup 报错 "Device or resource busy" 或 "Invalid argument"?
A:常见原因:
父 cgroup 已直接包含进程,违反 cgroup v2 的
no internal process constraint,需将进程移到叶子 cgroup;未启用对应控制器,需在父级
cgroup.subtree_control 写入 +cpu +memory +io 等,重新启用;对线程化 cgroup 的父级类型不匹配。
排查:
执行
cat /sys/fs/cgroup/cgroup.controllers 查看当前可启用的控制器。执行
cat /sys/fs/cgroup/cgroup.subtree_control 查看父级已启用的控制器(与可启用列表对比是否缺失)。确认无误后,在父级启用控制器:
echo "+cpu +memory +io" > /sys/fs/cgroup/cgroup.subtree_control
启用后再次执行
cat /sys/fs/cgroup/cgroup.subtree_control 确认输出包含 cpu memory io。Q6:
stat -fc %T /sys/fs/cgroup/ 输出 tmpfs 而非 cgroup2fs?
A:当前仍是 cgroup v1 模式,迁移未成功。完成迁移后该命令应返回 cgroup2fs(cgroup v1 模式返回 tmpfs)。请按以下方向排查:执行
grubby --info=ALL | grep args,确认 systemd.unified_cgroup_hierarchy=1 已写入内核启动参数。确认已执行
grub2-mkconfig -o /boot/grub2/grub.cfg 重新生成配置,并已重启系统。执行
systemctl --version,确认 systemd 版本 ≥ 239。