如何判断node节点是否启用cgroup?
要判断 Linux 节点是否启用了 cgroup(Control Groups),可以通过以下方法验证:
方法 1:检查 /proc/cgroups
文件
查看内核支持的 cgroup 子系统列表:
cat /proc/cgroups
输出说明:
-
若文件不存在或所有子系统
enabled=0
,则 cgroup 未启用。
各字段含义:
- subsys_name:子系统名称(资源控制器类型)。
- hierarchy:子系统挂载的层级编号。相同编号表示这些子系统共享同一个层级。
- num_cgroups:该子系统下的 cgroup 数量。
- enabled:是否启用该子系统(1 = 启用,0 = 禁用)
主要子系统(资源控制器)
- cpu:限制 CPU 时间片分配。
- memory:限制内存使用量。
- blkio:限制块设备(如磁盘)的 I/O 速率。
- cpuset:为进程分配特定 CPU 核心和内存节点。
- devices:控制对设备的访问权限。
- freezer:暂停或恢复一组进程。
- net_cls:标记网络数据包,用于流量控制。
- pids:限制进程 / 线程数量(Kubernetes 中常用)。
层级(Hierarchy)的意义
- cgroups 通过 层级 组织子系统。同一层级的子系统共享 cgroup 树结构。
- 例如:
cpu
和cpuacct
的hierarchy
都是 7,表示它们共享同一个 cgroup 树,便于统一管理 CPU 时间和统计。
如何使用这些信息?
1)检查子系统是否启用:
- 例如,若
memory
的enabled
为 0,则无法限制容器内存。 - 常见场景:排查容器内存限制不生效的问题。
2)查看系统资源控制能力:
- 若缺少某些子系统(如
pids
),可能需要升级内核或调整配置。
3)诊断 cgroup 相关问题:
- 若
num_cgroups
异常高,可能存在资源泄漏或配置错误。
与容器的关系:
Docker/Kubernetes 依赖 cgroups 实现资源隔离:
- Docker:通过
docker run --cpus=2 --memory=512m
等参数创建 cgroup。 - Kubernetes:通过
resources.limits
和requests
配置 Pod 的 cgroup。
方法 2:检查挂载点
查看 cgroup 的挂载信息:
$ mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset,cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu,cpuset)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
或
$cat /proc/mounts | grep cgroup
tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
cgroup /sys/fs/cgroup/cpuset,cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu,cpuset 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
cgroup /sys/fs/cgroup/net_cls cgroup rw,nosuid,nodev,noexec,relatime,net_cls 0 0
cgroup v1 输出:
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
...
cgroup v2 输出(统一挂载点):
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
方法 3:检查内核启动参数
确认内核启动时启用了 cgroup:
cat /proc/cmdline | grep cgroup
输出示例:
BOOT_IMAGE=/vmlinuz-5.4.0-80-generic root=UUID=... ro cgroup_enable=memory swapaccount=1
-
cgroup_enable=memory
表示启用了内存 cgroup 子系统。 -
若未显式禁用(如
cgroup_disable=memory
),默认启用。
方法 4:检查 /sys/fs/cgroup
目录
验证 cgroup 文件系统目录结构:
$ ls /sys/fs/cgroup
blkio cpu cpuacct cpuset cpuset,cpu,cpuacct devices freezer hugetlb memory net_cls perf_event pids systemd
-
cgroup v1:包含多个子系统子目录(如
cpu
,memory
)。 -
cgroup v2:仅一个统一目录(如
unified
或cgroup.controllers
文件)。
方法 5:通过 systemd 检查
systemd 默认使用 cgroup 管理服务:
systemd-cgls
输出示例:
$systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
├─user.slice
│ ├─user-1382544.slice
│ │ ├─session-1310.scope
│ │ │ ├─73042 sshd: mingyu.ygq [priv
│ │ │ ├─73044 sshd: mingyu.ygq@pts/
│ │ │ ├─73097 -bash
│ │ │ ├─73799 systemd-cgls
│ │ │ └─73800 systemd-cgls
│ │ ├─session-967.scope
│ │ │ ├─54780 sshd: mingyu.ygq [priv
│ │ │ ├─54782 sshd: mingyu.ygq@pts/
│ │ │ └─54783 -bash
│ │ └─session-1.scope
│ │ ├─1356 sshd: mingyu.ygq [priv
│ │ ├─1358 sshd: mingyu.ygq@pts/
│ │ ├─1363 -bash
│ │ ├─1528 sudo bash -c bash
│ │ └─1674 bash
│ └─user-0.slice
│ └─session-c5.scope
│ └─1744 /home/staragent/plugins/Argus_Ant.src/Argus_Ant.cur/bin/argusagent
└─system.slice├─aliyun.service│ └─67033 /usr/local/share/aliyun-assist/2.2.100.9/aliyun-service├─ntpd.service│ └─1893 /usr/sbin/ntpd -u ntp:ntp -g
...
若输出层级结构,表示 cgroup 已启用。
方法 6:检查内核配置
查看内核编译配置(需 kernel-devel
包):
$ grep -E "CONFIG_CGROUPS=|CONFIG_CGROUP_*" /boot/config-$(uname -r)
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_CPUACCT_MORE=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_WRITEBACK=y
关键选项:
-
CONFIG_CGROUPS=y
:cgroup 框架已启用。 -
CONFIG_CGROUP_CPUACCT=y
:CPU 统计子系统启用。 -
CONFIG_CGROUP_MEMORY=y
:内存控制子系统启用。
总结
检查项 | 预期结果 |
---|---|
/proc/cgroups | 各子系统 enabled=1 |
mount | grep cgroup | 存在 cgroup v1/v2 挂载点 |
/sys/fs/cgroup | 包含子系统目录(v1)或统一控制器文件(v2) |
systemd-cgls | 显示层级化的 cgroup 结构 |
内核配置 | CONFIG_CGROUPS=y 及相关子系统配置为 y |
常见问题
1. 节点未启用 cgroup
-
现象:
/proc/cgroups
为空或enabled=0
。 -
解决:在内核启动参数中添加
cgroup_enable=memory
等选项,并重启。
2. cgroup v1 与 v2 混合使用
-
现象:同时挂载 v1 和 v2。
-
解决:需配置统一模式(如
systemd.unified_cgroup_hierarchy=1
)。
通过上述方法,可快速确认节点是否启用 cgroup 及其版本(v1/v2),为容器编排(如 Kubernetes/Docker)或资源管理提供基础支持。