要在容器中可靠捕获core dump,必须同时满足四条件:一、启动时设--ulimit core=-1解除进程级限制;二、通过--sysctl kernel.core_pattern=/tmp/core.%e.%p.%t配置路径并挂载1777权限的可写卷;三、适配容器用户uid与目录权限,推荐宿主机预建/var/log/container-cores并chmod 1777后挂载;四、禁用或配置宿主机systemd-coredump避免干扰。
要在容器生命周期内可靠捕获程序结构异常(如段错误、非法指令)产生的 core dump,不能只套用宿主机配置——必须同时满足进程级限制、内核参数传播、文件系统可写和持久化四个条件。关键不是“能不能生成”,而是“生成后能不能拿到、能不能分析”。
一、解除容器内 ulimit -c 限制
默认所有 Docker 容器的 ulimit -c 是 0,即禁用 core dump。该限制作用于容器内所有进程,且不继承自宿主机。
- 启动容器时显式设置:
docker run --ulimit core=-1 ...(-1表示 unlimited) - 若使用 Kubernetes,需在 Pod spec 的
securityContext中声明:
limits:
- type: "core"
max: -1 - 验证方式:进入容器执行
ulimit -c,输出应为unlimited或一个正整数
二、配置有效的 core_pattern 并确保路径可写
容器中 /proc/sys/kernel/core_pattern 默认指向 core(当前目录),但容器根文件系统通常是只读或临时挂载的,导致 core 文件写入失败或静默丢弃。
- 推荐做法:将 core_pattern 指向一个明确挂载的、有写权限的路径,例如
/tmp/core.%e.%p.%t - Docker 启动时注入:
--sysctl kernel.core_pattern=/tmp/core.%e.%p.%t - Kubernetes 中需通过
initContainer或宿主机提前配置(因多数集群禁止 Pod 修改 sysctl) - 必须挂载可写 volume 到该路径,例如
-v /host/crash:/tmp,并确保宿主机目录权限为1777
三、适配容器用户与文件系统权限
容器内 UID 通常不是真实 root(尤其启用 user namespace 时),而内核要求 core 文件写入目标目录必须满足 sticky bit + full rwx(即 chmod 1777),否则直接拒绝写入。
- 不要依赖容器内
mkdir /tmp/coredir && chmod 1777—— 多数基础镜像(如 Alpine)的/tmp已是1777,但 Ubuntu 镜像可能不是 - 更稳妥的方式:在宿主机创建专用目录,设好权限,再挂载进容器:
sudo mkdir -p /var/log/container-cores && sudo chmod 1777 /var/log/container-cores - 若应用以非 root 用户运行(如
USER 1001),需确认该用户对挂载目录有写权限(可通过uid=1001:gid=1001绑定挂载解决)
四、避免 systemd-coredump 干扰(仅限 host 级调试)
当容器崩溃退出后,宿主机的 systemd-coredump 可能抢先截获信号并接管转储,导致容器内配置失效、core 文件出现在 /var/lib/systemd/coredump/ 而非你指定的路径。
- 如需完全由容器控制流程,可在宿主机临时禁用:
sudo systemctl stop systemd-coredump - 生产环境不建议永久关闭,可改用过滤策略:编辑
/etc/systemd/coredump.conf,设置Storage=none或MaxUse=0 - 验证是否生效:崩溃后检查
journalctl -u systemd-coredump是否有新日志











