关键是要提前配置内核core_pattern、ulimit限制和持久化挂载路径:使用--sysctl设置core_pattern、--ulimit core=-1放开限制,并通过-v挂载宿主机目录(chmod 1777确保可写),Kubernetes中则用annotation配合卷挂载,同时验证信号类型与权限。
要让容器在异常退出时自动保留核心转储(core dump)文件,关键不是“等它退出后再补救”,而是提前配置好内核行为、资源限制和持久化路径,确保崩溃瞬间就能把内存快照写入安全位置。否则容器一退出,进程上下文消失,core 文件根本不会生成,更谈不上保留。
容器无法直接写入默认路径(如 / 或 /tmp),且多数镜像未启用 core dump。必须显式指定输出路径并确保可写:
docker run --sysctl kernel.core_pattern=/dump/core.%e.%p 将转储路径设为 /dump/(注意:该路径需与后续挂载点一致)-v /host/dump:/dump:shared 挂载宿主机目录,宿主机上提前执行 mkdir -p /host/dump && chmod 1777 /host/dump(1777 是必须的,否则非 root 进程无法写入)k8s.ksyun.com/kci-core-pattern: "/tmp/cores/core.%h.%e.%p.%t",同时挂载 NFS/CSI 卷到 /tmp/cores
默认 ulimit -c 是 0,即禁用 core dump。仅在容器内执行 ulimit -c unlimited 不可靠——它可能被 ENTRYPOINT 覆盖或不传递给子进程:
--ulimit core=-1(-1 表示 unlimited),这是 Docker 原生支持的方式,比在 Dockerfile 中 RUN ulimit 更稳定ulimit,尤其当主进程是 exec 方式启动(如 exec "$@")时,shell 的 ulimit 不会继承ulimit -c,应返回 unlimited 或一个正整数不是所有终止都会产生 core 文件。只有收到带 CORE 动作的信号(如 SIGSEGV、SIGABRT、SIGQUIT)才会触发转储;SIGKILL(如 OOMKilled)或 SIGTERM 不会。
kill -SEGV $(pidof yourapp)),再检查 /dump/ 是否出现 core.* 文件faulthandler.enable() 或用 gdb --args python app.py)systemd-coredump 接管,此时需检查其配置是否允许外部路径即使配置正确,也要确认文件真实落盘且未被清理:
docker ps -a | grep Exited,记下容器 IDdocker commit <id> debug-img 保存当前状态,再 docker run -it --rm -v $(pwd)/dumps:/dumps debug-img ls -l /dump/ 查看 core 是否存在/dump 在容器内未创建);可在 ENTRYPOINT 开头加 mkdir -p /dump 2>/dev/null || true 防御