【云原生】腾讯云 TLinux 容器云平台 Coredump 自动收集配置指南 —— 基于 systemd-coredump 实现容器崩溃转储宿主机集中管理 腾讯云 TLinux 容器云平台 Coredump 自动收集配置指南 —— 基于 systemd-coredump 实现容器崩溃转储宿主机集中管理本指南针对腾讯云 TLinux 3.1 容器云平台提供了一套完整的 coredump 自动收集与持久化配置方案。其核心是配置宿主机内核将进程崩溃时的核心转储通过管道传递给systemd-coredump服务处理从而无需在 Pod 内挂载任何宿主机目录即可自动、集中地管理所有容器的 core dump 文件。一、核心原理systemd-coredump管道机制1.1 传统方式 vs. 管道方式Linux 内核通过kernel.core_pattern参数控制 core dump 的产生方式。传统文件方式kernel.core_pattern /data/coredump/core.%p内核直接将 core dump 写入指定文件。这在容器场景下需要挂载目录配置繁琐且易出错。管道方式当core_pattern以|开头时内核会将 core dump 数据通过管道传递给指定的用户空间程序处理。1.2systemd-coredump的工作流程配置kernel.core_pattern |/usr/lib/systemd/systemd-coredump %p %u %g %s %t %c %h后工作流程如下内核捕获容器内进程崩溃如 SIGSEGVLinux 内核捕获该事件。管道传递内核不直接写入文件而是将 core dump 数据通过管道发送给systemd-coredump程序。服务接管systemd-coredump作为“usermode helper”被内核唤起并连接到systemd-coredump.socket。实例处理systemd-coredump.socket单元会派生一个systemd-coredump.service服务实例来处理这个 core dump。存储与记录该服务实例根据/etc/systemd/coredump.conf的配置处理 core dump。默认情况下它会在系统日志中记录一条包含调用栈backtrace的条目。将 core dump 文件压缩后保存到/var/lib/systemd/coredump/目录。1.3 容器场景下的优势systemd-coredump作为宿主机服务运行可以收集宿主机上所有容器和 Pod内进程的 core dump。容器和 Pod 内无需任何特殊配置或挂载实现了对业务容器的零侵入。二、一键配置脚本将以下脚本保存为setup_coredump.sh以root身份执行即可完成全部配置。如果是TKE可以配置的到节点池-详情页-参数设置-自定义数据-节点初始化前#!/bin/bash# TLinux 3.1 容器云平台 Coredump 自动收集配置脚本# 功能配置 systemd-coredump 管道实现 Pod 崩溃 core 文件自动收集与轮转set-eecho 开始配置 TLinux 3.1 Coredump 自动收集 # 1. 配置内核 core_pattern持久化并立即生效echo 配置 kernel.core_pattern ...# 删除已有的配置防止重复sed-i/^kernel.core_pattern/d/etc/sysctl.conf# 追加新配置使用管道将 core dump 传递给 systemd-coredump# %p: PID, %u: UID, %g: GID, %s: 信号号, %t: 时间戳, %c: core文件大小限制, %h: 主机名echokernel.core_pattern |/usr/lib/systemd/systemd-coredump %p %u %g %s %t %c %h/etc/sysctl.conf# 立即生效sysctl-p# 2. 配置 systemd-coredump 行为覆盖原有配置echo 配置 /etc/systemd/coredump.conf ...# 备份原配置如果不存在则跳过[-f/etc/systemd/coredump.conf.bak]||cp/etc/systemd/coredump.conf /etc/systemd/coredump.conf.bak# 写入新配置cat/etc/systemd/coredump.confEOF # systemd-coredump 配置文件 # 详情参考 man coredump.conf # # 适用于容器云平台收集所有 Pod/容器崩溃的 core dump # 存储路径/var/lib/systemd/coredump/ [Coredump] # 存储后端external 表示保存为独立的磁盘文件默认 Storageexternal # 是否压缩 core 文件gzip/lz4默认为 yes强烈建议开启 Compressyes # 【关键】单个 core 文件在处理时的最大原始数据大小超过则截断 # 请根据实际情况调整建议大于业务容器内存上限 ProcessSizeMax8G # 外部存储的单个 core 文件压缩后大小上限 ExternalSizeMax10G # 写入 journal 的 core 元数据信息的大小上限 JournalSizeMax767M # 最多保留的外部 core 文件个数超过时自动删除最旧的文件 # 根据需求设置为 10 MaxFiles10 # 所有外部 core 文件总大小上限占磁盘总容量的百分比 # 与 MaxFiles 取更严格者双重保险 MaxUse5% EOF# 3. 配置用户资源限制使 ulimit -c 持久化echo 配置 /etc/security/limits.conf ...# 删除已有配置防止冲突sed-i/^\*\s*soft\s*core/d/etc/security/limits.confsed-i/^\*\s*hard\s*core/d/etc/security/limits.conf# 追加新配置允许所有用户生成无限大小的 core 文件echo* soft core unlimited/etc/security/limits.confecho* hard core unlimited/etc/security/limits.conf# 4. 使当前会话的 ulimit -c 立即生效echo 为当前会话启用 ulimit -c unlimited ...ulimit-cunlimited# 5. 验证配置echo 配置完成验证结果 echokernel.core_pattern $(sysctl-nkernel.core_pattern)echo当前会话 ulimit -c $(ulimit-c)echocoredump 存储目录/var/lib/systemd/coredump/echoecho注意echo1. 新登录的会话将自动继承 limits.conf 中的 ulimit -c unlimited 设置。echo2. 对于 systemd 管理的服务或 Kubernetes Pod请在 Service 文件或 Pod SecurityContext 中设置 LimitCOREinfinity。echo3. 配置更改会在下次进程崩溃时自动生效无需重启任何服务。执行脚本chmodx setup_coredump.sh ./setup_coredump.sh三、关键配置项说明配置项推荐值说明kernel.core_pattern|/usr/lib/systemd/systemd-coredump ...核心。以|开头表示管道模式将 core dump 交给systemd-coredump处理。Storageexternalexternal将 core 文件保存为独立的磁盘文件默认路径/var/lib/systemd/coredump/。Compressyesyes启用压缩可节省大量磁盘空间。压缩率通常可达 100~300 倍。ProcessSizeMax8G按需调整限制systemd-coredump处理的原始core 数据大小超过则丢弃。应大于业务 Pod 内存上限。ExternalSizeMax10G按需调整限制最终保存到磁盘的单个core 文件压缩后大小。MaxFiles10限制保留的 core 文件数量超出时自动删除最旧的文件。MaxUse5%限制所有 core 文件的总大小不超过磁盘容量的 5%。四、验证与调试配置完成后可通过以下方式验证4.1 验证内核参数sysctlkernel.core_pattern预期输出kernel.core_pattern |/usr/lib/systemd/systemd-coredump %p %u %g %s %t %c %h4.2 验证ulimit -culimit-c预期输出unlimited4.3 模拟容器内崩溃测试启动一个测试容器podmanrun-it--rmubuntu:24.04 /bin/bash在容器内创建一个会崩溃的程序或直接触发段错误kill-SEGV$$在宿主机上检查 core 文件是否生成ls-lh/var/lib/systemd/coredump/ coredumpctl list4.4 使用coredumpctl调试coredumpctl是 systemd 提供的 core dump 管理工具可以方便地列出、查看和调试。# 列出所有 core dumpcoredumpctl list# 查看最近一个 core dump 的详细信息coredumpctl info# 用 gdb 调试最近的一个 core dumpcoredumpctl debug# 将指定的 core dump 导出为文件coredumpctl dumpPID-ocore.dump4.5 生产环境调试操作指南好的根据你的要求我将4.5 生产环境调试操作指南精简为以下内容聚焦于直接下载和调试.lz4文件的标准流程。4.5 生产环境调试操作指南在生产环境中调试符号debug symbols通常与运行程序分离只存在于构建服务器上。因此标准流程是从生产服务器下载.lz4压缩的 core 文件 → 在构建服务器上解压并用 GDB 配合符号文件调试。步骤一在服务器上定位 core 文件# 1. 列出所有 core dump找到目标记录coredumpctl list# 2. 查看特定 core dump 的详细信息获取 Storage 路径coredumpctl infoPID输出示例Storage: /var/lib/systemd/coredump/core.rcu_sched.0.91b437a6272e4f1e8696bbdc7cd5019d.10.1785307128000000.lz4记录下该.lz4文件的完整路径。步骤二下载 core 文件到本地/构建服务器# 从生产服务器下载 .lz4 压缩文件scpuserprod-server:/var/lib/systemd/coredump/core.xxx.lz4 ./说明直接下载.lz4压缩文件体积远小于解压后的原始 core 文件节省传输时间和存储空间。步骤三在构建服务器上解压并调试# 1. 解压 .lz4 文件得到标准 ELF core 文件lz4-dcore.xxx.lz4 core.dump# 2. 使用带调试符号的二进制文件进行调试gdb ./your_binary_with_symbols core.dump调试流程图生产服务器 │ ├── coredumpctl list # 查找目标记录 ├── coredumpctl info PID # 获取 Storage 路径.lz4 文件 └── scp 下载 .lz4 文件 │ ▼ 构建服务器本地 │ ├── lz4 -d core.xxx.lz4 core.dump # 解压 └── gdb ./binary_with_symbols core.dump # 调试关键说明要点说明为什么下载.lz4而非解压后的文件.lz4是压缩格式体积通常为原始 core 的 1/10 ~ 1/30传输更快。为什么在构建服务器调试构建服务器保存了带调试符号-g的二进制文件生产环境通常是strip过的版本。共享库符号缺失怎么办如需查看 libc 等库的内部调用栈可在 GDB 中设置set solib-search-path指向容器内提取的库文件路径。通常定位用户代码的崩溃点不需要此步骤。重复 PID 如何精确匹配通过coredumpctl info PID查看时间戳和 Boot ID确认是目标记录后再下载对应的.lz4文件。以上内容精简了多余的步骤聚焦于生产环境最实用的操作路径。如有其他细节需要补充请告诉我。五、Pod 配置注意事项虽然宿主机已配置完成但Pod 内的进程本身仍需允许生成 core dump。对于 Kubernetes Pod在 Pod Spec 中设置ulimitssecurityContext:ulimits:-name:corehard:-1soft:-1对于 systemd 管理的服务在 Service 文件中设置LimitCOREinfinity。六、配置生效时间kernel.core_pattern通过sysctl -p立即生效。ulimit -c通过limits.conf对新登录会话生效当前会话需手动执行ulimit -c unlimited。/etc/systemd/coredump.conf的修改无需重启任何服务下次收到 core dump 时自动生效。附关于pid重复1. 如果容器内的 PID 都是 10coredumpctl list会显示多个 PID 10 的记录吗会的。只要这些容器在不同时间崩溃coredumpctl list就会显示出多条PID 为 10 的记录时间戳不同。你现在的列表里有10 (rcu_sched)这一条如果另一个容器比如另一个 Ubuntu 容器里 PID10 的进程也崩溃了列表就会变成TIME PID ... COREFILE EXE Wed 2026-07-29 10:56:38 CST 37517 ... present /root/a.out Wed 2026-07-29 14:32:10 CST 113370 ... present /root/a.out Wed 2026-07-29 14:35:57 CST 117837 ... present /root/a.out Wed 2026-07-29 14:38:48 CST 10 ... present rcu_sched # 第一个容器崩溃 Wed 2026-07-29 15:20:10 CST 10 ... present rcu_sched # 第二个容器崩溃PID 也是 102. 如果有多条 PID10 的记录执行coredumpctl debug 10会命中哪一个默认命中“最新最近发生”的那一条即时间戳最大的。coredumpctl的逻辑是按照PID过滤按TIME时间戳降序排列默认取第一个即最新的。所以如果你执行coredumpctl debug 10会命中15:20:10那一次崩溃而不是 14:38:48 那次。如何精确命中你想要的那一个既然 PID 可能重复要精确命中特定的 core dump有以下三种可靠的方法方法一使用偏移量-1,-2后缀coredumpctl支持PID偏移量语法其中0或省略表示最新1表示倒数第二个2表示倒数第三个。# 命中最新的 PID1014:38:48 那次coredumpctl debug10# 命中最新的 PID1015:20:10 那次因为此时它是最新的coredumpctl debug10# 如果要命中 14:38:48 那次假设它是倒数第二个使用coredumpctl debug10-1# 注意有些版本是 101建议用 coredumpctl debug --help 确认注意不同 systemd 版本偏移量符号可能不同-或。如果10-1报错尝试101。更稳妥的是用下面的方法二。方法二根据时间戳精确匹配最可靠使用--timestamp参数直接指定崩溃时间支持模糊匹配。# 精确命中 14:38:48 那次coredumpctl debug--timestamp2026-07-29 14:38:48# 或者只匹配分钟级别如果时间误差不大coredumpctl debug--timestamp14:38方法三直接根据存储路径手动调试生产环境最推荐既然你已经知道 core 文件的存储路径从coredumpctl info中获取直接操作文件是最不会出错的。# 1. 查看目标 core 的详细信息复制 Storage 路径coredumpctl info10|grepStorage# 输出Storage: /var/lib/systemd/coredump/core.rcu_sched.0.91b437a6272e4f1e8696bbdc7cd5019d.10.1785307128000000.lz4# 2. 直接解压并用 gdb 调试绕过 coredumpctl 的 PID 匹配逻辑cd/var/lib/systemd/coredump/ lz4-dcore.rcu_sched.0.91b437a6272e4f1e8696bbdc7cd5019d.10.1785307128000000.lz4 core.dump gdb /mnt/root/a.out core.dump生产环境特别提醒方法三正是你之前测试成功的方法coredumpctl dump导出或手动解压它是最安全、最精确的做法尤其适合在多容器、多重复 PID 的场景下使用。补充为什么会产生重复 PID容器使用PID 命名空间PID namespace。每个容器都有自己的 PID 1宿主机看到的只是容器进程在宿主机上的 PID一般很大如 113370。但在 core 文件记录中由systemd-coredump从容器内读取记录的COREDUMP_PID是容器内部的 PID例如 10。因此不同容器的内部 PID 完全可能相同例如都是 init 进程或都是某个服务进程。systemd-coredump通过Boot ID机器启动 ID和时间戳来区分它们而不是靠 PID 唯一性所以文件名永远不会冲突但列表查询时需要注意上述匹配规则。