登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

systemd-cgls 怎样查看服务 cgroup 树

来源:17golang原创

时间:2026-10-15 05:44:13 449浏览 收藏

排查 Linux 服务的进程归属时,ps 只能告诉你有哪些 PID;要看 systemd 为服务建立的 cgroup 层级,应使用 systemd-cgls。最小可用写法是把服务单元交给 --unit,再配合 --full 和 --no-pager:

# 只展开 nginx.service 的 cgroup 子树,并保留完整进程名
systemd-cgls --unit nginx.service --full --no-pager

官方手册地址:https://www.freedesktop.org/software/systemd/man/latest/systemd-cgls.html

要点速览
  • systemd-cgls --unit 服务名 是按服务定位 cgroup 树的入口。
  • --full 防止进程名被省略,--no-pager 便于脚本或日志留存。
  • 空 cgroup、内核线程和容器范围分别由 --all、-k、-M 控制。

先分清 cgroup 树和 PID 树

systemd-cgls 的重点不是重新排列进程,而是把 Linux control group hierarchy 按目录关系画成树。服务单元通常位于 systemd 的 slice 下面,服务自己的 cgroup 还可能包含由它创建的子组。这样看,定位资源限制、服务派生进程或容器边界会比只盯着 PID 更直接。

如果不知道准确的单元名,先从服务管理层确认名称,再把名称交给 --unit。不要把显示名、进程名或可执行文件名混用;cgroup 树匹配的是 unit。需要确认服务对应的 cgroup 入口时,可以先读取属性:

# 只读取服务对应的 cgroup 路径,不改变服务状态
systemctl show nginx.service --property=ControlGroup --value
systemd-cgls 按服务单元展开 slice、service cgroup 与子组的树形关系说明图
图1:systemd-cgls 的服务单元、父 slice、子 cgroup 与进程归属关系说明图,不是运行截图。

用三个参数得到可读的服务树

实际排查时,下面这组参数最稳妥:--unit 限定服务范围,--full 保留完整进程名,--no-pager 让输出直接回到当前终端。没有 --full 时,长命令行或进程名可能被省略;没有 --no-pager 时,输出可能进入分页器,不利于复制到工单。

# 以 ssh.service 为例,输出适合保存到排障记录
systemd-cgls --unit ssh.service --full --no-pager

# 需要同时看空的 cgroup 时,再显式打开空组显示
systemd-cgls --unit ssh.service --all --full --no-pager

命令成功时返回 0;如果单元名不存在、权限或 systemd 环境不满足,应该先处理错误,再解释树的内容。这里不要把“没有看到进程”直接等同于“服务没有 cgroup”:空组默认可能被隐藏,服务也可能刚好处于没有成员的状态。

按排查范围选择 --all、-k 和 -M

目标参数适用判断
看指定服务--unit NAME只展开某个 systemd unit 的子树
保留长名称-l / --full排查完整进程名或命令行
显示空组--all确认层级存在但暂时没有进程
包含内核线程-k需要观察内核线程时再打开
限定容器-M NAME只看指定 machine 对应的 cgroup 部分

参数应该围绕一个问题组合,而不是一次把所有开关都打开。例如调查某个服务的派生进程时,先用 --unit --full --no-pager;怀疑存在空的中间层级,再补 --all。查看容器内范围时使用 -M,不要把宿主机全树和容器局部树混在同一份结论里。

systemd-cgls 用 --unit、--full、--all、-k 和 -M 控制查看范围的参数边界说明图
图2:systemd-cgls 常用范围参数与观察结果的对应关系说明图,不是运行截图。

看到树以后怎样确认归属没有误判

先看树上的 unit 和 slice 名称,再看缩进层级,最后才把具体进程与服务联系起来。进程名相同并不意味着它们属于同一个服务;真正有用的是它们是否出现在目标 cgroup 及其子组下。若输出被截断,先补 --full;若怀疑是空组,补 --all;若只想确认入口路径,回到 systemctl show ... --property=ControlGroup 做交叉检查。

这套顺序可以避免两个常见误区:把整机全树中的同名进程当成目标服务成员,以及把隐藏的空组误读成层级不存在。命令本身只负责展示,不会替你修改 unit、移动进程或施加资源限制。

常见问题

systemd-cgls 不加参数会显示什么

如果当前目录位于 cgroup 挂载点下,会显示当前目录对应的 cgroup;否则通常显示完整的 systemd cgroup 层级。按服务排查时,显式使用 --unit 更不容易把范围看错。

为什么树里没有看到服务进程

先确认 unit 名称,再检查是否因为空组默认隐藏或输出范围过窄。使用 --all 查看空组,并用 systemctl show 的 ControlGroup 属性确认入口。

systemd-cgls 能代替 systemctl status 吗

不能完全代替。systemctl status 更偏向状态、日志摘要和主进程信息;systemd-cgls 专注于 cgroup 树及成员归属,适合补充资源与派生进程排查。

记住一个实用组合即可:先用 systemd-cgls --unit 服务名 --full --no-pager 锁定服务树,再按需要增加 --all、-k 或 -M。树形层级、ControlGroup 路径和进程成员三者能够互相对上,排查结论才算完整。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>