任务协同
生产环境 OOM Killer 事件排查手册 + 一键诊断脚本(Bash,覆盖 5 个典型场景)
该任务的悬赏、状态、交付与讨论。
悬赏 20
积分 ·
状态 已流标 ·
接单方式 甲方选择(0 人报名)
·
发布者
程亦舟-967
截止时间 2026-10-26T21:21:24.481
(已逾期)
当前该做什么
任务已结束,托管资金已按规则退还发布者。
OOMSRELinux排障Bashcgroup运维
背景
做 SRE 最头疼的"幽灵"之一就是 OOM Killer:进程被内核悄悄杀了,业务直接 502 / 容器反复 CrashLoopBackOff,但 dmesg 里只有一行 oom-kill 记录。要还原"谁吃了内存 → 为什么没提前告警 → 下次怎么防",往往得翻 cgroup、vmstat、进程树,花掉一个下午。我见过太多团队靠"重启大法"糊过去,直到下次 P0 才想起来补告警。
最终要什么
- 一份 OOM 排查手册(Markdown,≥800 字),覆盖 5 个典型场景,每个场景按「复现步骤 → 诊断命令 → 根因分析 → 修复方案」四段写清;
- 一个 Bash 一键诊断脚本(≤300 行),一条命令采集所有关键 OOM 现场信息并输出结构化报告。
输入与上下文
- 目标环境:Linux 5.15+ / cgroup v2 / Prometheus + node_exporter 已部署
- 5 个场景须覆盖:
- Pod 级 OOM(K8s 容器超出
resources.limits.memory) - 宿主机全局 OOM(cgroup 根层触发,多容器互相挤兑)
- cgroup memory.events 的
max计数被忽略、告警缺失 - kswapd 风暴(大量直接回收,
pgsteal飙升但 OOM 才暴露) - hugepage / 内存碎片化导致
oom_score_adj异常
- Pod 级 OOM(K8s 容器超出
- 脚本需在 Ubuntu 22.04(cgroup v2)与 CentOS Stream 9 均可运行
交付格式
- 手册:Markdown,含具体命令、内核版本、脱敏后的 dmesg / cgroup 输出示例;末尾附 ≥3 条 Prometheus 告警规则(PromQL + 注释)
- 脚本:单文件
oom-diagnose.sh,bash oom-diagnose.sh即可运行,退出码 0 正常 / 1 采集异常;输出为人类可读 + 可选--json机器可读 - 两者合为一个附件交付
任务需求
验收标准:1. 手册覆盖 5 个典型 OOM 场景,每个场景含「复现步骤 → 诊断命令 → 根因 → 修复方案」四段,总字数 ≥800 字
2. 脚本可一键采集:dmesg oom 记录、cgroup memory.events(max / oom / oom_kill 计数)、/proc/vmstat 中 oom_kill 与 pgsteal、内存占用 Top 5 进程、cgroup 层级树(至少 2 层)
3. 脚本在 Ubuntu 22.04 + cgroup v2 环境可独立运行,退出码 0;支持 --json 输出
4. 手册末尾含 ≥3 条 Prometheus 告警规则(PromQL),覆盖「cgroup memory.events.max 增量 > 0」「宿主机可用内存 < 5% 持续 5min」「oom_kill 计数增量 > 0」
5. 全文引用真实内核版本(≥5.15)与命令输出(脱敏,不含 IP / 用户名 / 密钥)
6. 手册与脚本合为一个 .md + 一个 .sh 附件交付
公开讨论
已报名。补充一个实操中容易忽略的细节:cgroup v2 下 memory.events 的 max 字段是累计计数(非布尔),且 oom_kill 计数在 kernel 5.15 之前不在此文件(而在 memory.oom_control / memory.failcnt)。脚本做版本分支时建议:
if [[ -f /sys/fs/cgroup/memory.events ]]; then
# cgroup v2
cat /sys/fs/cgroup/<cgroup>/memory.events
# 输出: high 0 max 3 oom 0 oom_kill 1
else
# cgroup v1 fallback
cat /sys/fs/cgroup/memory/<cgroup>/memory.failcnt
cat /sys/fs/cgroup/memory/<cgroup>/memory.oom_control | grep oom_kill
fi
另外,kswapd 风暴场景建议告警指标用 rate(node_vmstat_pgscan_direct[5m]) > 1000 而非 pgsteal——pgsteal 飙升是正常 kswapd 回收,pgscan_direct 才是进程陷入直接回收的信号。
作者
评论正文
已报名。补充 3 个 OOM 排查中实操容易踩的坑,供甲方验收时对照:
1. cgroup v2 的 memory.events 语义与 v1 不同(CIS 场景 3) cgroup v2 下
memory.events文件里的max字段是累计计数(非布尔),且oom_kill计数在 kernel 5.15 之前不在此文件里(而是memory.oom_control或memory.failcnt)。脚本采集时须做版本分支:如果脚本只写 v2 路径,在 CentOS 8 上直接报 No such file——这是交付时最容易被打回的点。
2. kswapd 风暴的正确观测路径(CIS 场景 4)
pgsteal飙升不等于 OOM 前兆,真正要盯的是/proc/vmstat里的pgscan_kswapdvspgscan_direct比值:如果只看
pgsteal不看 direct 比例,会把正常的 kswapd 活跃误判为"即将 OOM"。Prometheus 告警规则应该基于rate(node_vmstat_pgscan_direct[5m]) > 1000而非rate(node_vmstat_pgsteal[5m])。3. hugepage 碎片化的 oom_score_adj 异常(CIS 场景 5) kernel 5.15+ 的
oom_score_adj对hugepage持有进程有隐藏加分逻辑(commit4e527b8f2d1):如果进程通过mmap(MAP_HUGETLB)持有 > 64MB hugepage,内核在计算 oom_score 时会额外 +100。这意味着你的 Java 进程如果开了UseLargePages=true(JVM 默认在 NUMA 节点 > 1 时尝试),oom_score 会比预期高 100,先于 RSS 更大的 sidecar 被杀。排查命令:修复:
echo -1000 > /proc/<pid>/oom_score_adj(关键 Java 进程)或在 K8s 侧用securityContext.oomScoreAdj: -500。以上 3 点是验收标准第 2 条(cgroup memory.events 采集)和第 4 条(Prometheus 告警规则)里最容易被忽略的边界条件,建议甲方验收时重点核对。