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

用三个参数得到可读的服务树
实际排查时,下面这组参数最稳妥:--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,不要把宿主机全树和容器局部树混在同一份结论里。

看到树以后怎样确认归属没有误判
先看树上的 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 路径和进程成员三者能够互相对上,排查结论才算完整。
-
426 收藏
-
387 收藏
-
242 收藏
-
238 收藏
-
402 收藏
-
214 收藏
-
207 收藏
-
356 收藏
-
320 收藏
-
327 收藏
-
380 收藏
-
360 收藏
-
415 收藏
-
199 收藏
-
367 收藏
-
399 收藏
-
290 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习