开放问答
K8s 容器里 core_pattern 管道写不出 coredump:segfault 现场抓不到、又不能重启,你们怎么落地取证?
该问题的正文、回答与评论。
提问者 程亦舟-167 · 状态 open
Kubernetescoredumpsegfault容器化SRE取证
背景 10 年 SRE,最近接手一个 12 节点集群(Kubernetes 1.28.4,containerd 1.7,cgroup v2,内核 5.15,x86_64)。集群里有一个 C++ 写的二进制协议网关(非 Go/Java,gdb 是主要排查手段),3 副本。安全基线要求镜像尽量精简,但为了排查保留了 gdb;节点侧没有额外挂载特权。
现象
近一个月该服务被 OOMKilled 过一次、segfault 两次(dmesg 里有 segfault at 0 ip ... error 4 in gw[400000+...])。segfault 后容器被 kubelet 拉起,进程直接消失,/var/crash 和容器内任何目录都没有 core 文件;kubectl exec 都来不及做——从 segfault 到 Pod Ready 只有几十秒,现场全没了。两次 segfault 都发生在流量高峰的长连接重连风暴窗口,疑似堆越界或空指针,但拿不到 core 就只能靠猜。
已尝试的排查与结果
- 节点
/proc/sys/kernel/core_pattern当前是core(默认),容器内/proc/sys/kernel/core_pattern看到的是|/bin/false之类的管道形式(containerd 默认注入),也就是说 core 走的是 kernel 全局 core_pattern 的管道,而管道里的程序在宿主机上下文执行、根本看不到容器文件系统——把 core 写进容器目录这条路在架构上就是不通的。 - 试过把节点 core_pattern 改成
core.%e.%p并给容器加ulimit -c unlimited(resources.limits加不了 ulimit,得走 securityContext 或 runtime 配置)——结果 core 落到了宿主机/(容器的工作目录映射),但宿主机磁盘只给系统留了 40G,一个 core 4.2G,落两次就爆盘,安全审计直接叫停。 - 想过用
kubectl cp或 sidecar 抓——但 segfault 是瞬时的,sidecar 没有 hook 时机;kubectl debug --target也赶不上进程退出。 - eBPF 路线评估过:
uprobe在abort/SIGSEGVhandler 上挂 hook 打日志,能拿到 RIP/栈寄存器,但没有完整内存镜像,对「哪个 buffer 越界」这类问题证据不够。
期望得到的答案形态 想请踩过这坑的同事给一份可落地的取证方案清单,最好包含:
- 生产 K8s 里让 coredump「能落盘、落对地方、落完能自动清理」的完整配置:core_pattern 的管道写法(比如用
apport/systemd-coredump/自定义脚本)、containerd 侧RuntimeOptions或securityContext的 ulimit 怎么给到容器、core 该落到哪个卷(hostPath?emptyDir?对象存储 sidecar 异步上传?)、以及权限(CAP_SYS_ADMIN到底要不要给业务容器、能不能只给一个 coredump-agent DaemonSet); - 一个「segfault 后 60 秒内保住现场」的 runbook:从 dmesg 告警触发 → 自动
crash/gdbattach 或抓/proc/<pid>/maps+smaps+stack→ core 上传对象存储 → 自动清理,每一步的命令或脚本骨架; - 如果最终放弃 core,退而求其次的「无 core 取证」组合:eBPF uprobe 挂哪些符号、
catchpoint SIGSEGV在 gdb 里的用法(前提是能 attach 上)、或者干脆在应用层加一个SIGSEGVhandler 自己 dump 关键结构体到日志——各自的适用边界和坑; - 安全审计视角:core 文件里几乎必然带密钥/凭据,脱敏或权限收敛的最低要求是什么。
欢迎贴你们集群的真实 core_pattern 配置 + 一次成功取证的完整时间线(dmesg / 脚本输出 / 对象存储路径),方便对比。
评论
暂无评论。