需在容器运行时启用内核core dump并持久化:通过--ulimit core=-1:-1、--sysctl kernel.core_pattern和-v挂载宿主机目录实现,dockerfile仅预建目录与权限,归档逻辑放入entrypoint.sh。

要让微服务在容器中崩溃时自动捕获并归档核心转储(core dump),关键不是“重定向”而是**启用内核级 core dump 生成 + 容器内持久化路径 + 合理的 ulimit 和信号处理配置**。Docker 默认禁用 core dump,且容器文件系统是临时的,必须显式挂载持久卷并调整内核参数。
1. 在 Dockerfile 中启用 core dump 基础支持
需设置容器启动前的内核参数和资源限制:
- 使用 RUN sysctl -w kernel.core_pattern=/var/log/core.%e.%p.%t 设置 core 文件命名与路径(注意:该命令在构建期不生效,实际应在容器启动时执行)
- 改用 RUN echo '/var/log/core.%e.%p.%t' > /proc/sys/kernel/core_pattern 无效(/proc 不可写入构建层),应交由启动脚本或 --sysctl 参数完成
- 在 Dockerfile 中添加 RUN mkdir -p /var/log/coredumps && chmod 1777 /var/log/coredumps 预创建目录并设 sticky bit,避免多进程写入冲突
- 通过 USER 指令确保应用以非 root 用户运行时,仍能写入该目录(可 chown 或用 setcap 提权,见下文)
2. 启动时配置 ulimit 和 sysctl(必须在运行时完成)
Docker 构建阶段无法修改运行时内核参数或资源限制,必须在 docker run 或 docker-compose.yml 中声明:
- --ulimit core=-1:-1:解除 core 文件大小限制(-1 表示无上限)
- --sysctl kernel.core_pattern=/var/log/coredumps/core.%e.%p.%t:指定 core 文件保存路径与格式(%e=程序名,%p=PID,%t=时间戳)
- --sysctl fs.suid_dumpable=2:允许 setuid 程序生成 core(若微服务使用 drop privileges)
- 挂载宿主机目录:-v $(pwd)/coredumps:/var/log/coredumps:rw,确保崩溃后文件落盘可查
3. 处理非 root 用户写入权限问题
若微服务以普通用户(如 USER 1001)运行,默认无法向 /var/log/coredumps 写入 core 文件(内核拒绝):
- 方案一(推荐):启动前用 setcap 'cap_sys_ptrace+ep' /usr/bin/my-service 赋予调试能力,再配合 kernel.core_pattern 写入自有目录
- 方案二:在 entrypoint.sh 中动态设置 echo "/var/log/coredumps/core.%e.%p.%t" > /proc/sys/kernel/core_pattern(需容器有 --privileged 或 --cap-add=SYS_ADMIN)
- 方案三:直接以 root 启动微服务(不推荐),或用 chown 1001:1001 /var/log/coredumps 并确保 umask 允许写入
4. 可选:集成自动归档与清理逻辑
可在 entrypoint.sh 中加入轻量归档策略,无需额外守护进程:
- 启动前检查并压缩旧 core:find /var/log/coredumps -name 'core.*' -mmin +60 -exec gzip {} \;
- 限制数量:find /var/log/coredumps -name 'core.*' -type f | sort | head -n -10 | xargs rm -f
- 记录日志:echo "$(date): core generated for $(basename $0)" >> /var/log/coredumps/trace.log
- 若用 systemd 容器,可配置 systemd.coredump 服务接管,但需基础镜像含 systemd(通常不建议)
核心要点是:Dockerfile 只负责准备目录、权限和基础工具;真正启用 core dump 必须靠运行时参数(--ulimit、--sysctl、-v);归档逻辑建议放在启动脚本里,保持轻量可控。不复杂但容易忽略。











