帮你快速理解、总结文档立即下载

kdump 与内核崩溃转储

最近更新时间:2026-08-24 18:27:31
我的收藏

功能概述

本文介绍 TencentOS Server 4 中 kdump 内核崩溃转储机制的安装、配置、触发测试和转储文件分析方法,帮助您在生产环境内核发生 panic 时保留现场内存镜像,便于事后定位内核崩溃根因。

背景信息

生产环境中内核 panic 虽然罕见,但一旦发生往往会导致整台机器重启、业务中断,且重启后现场丢失,难以定位根因。kdump 通过 kexec 在内核崩溃时快速启动一个预先加载的捕获内核(capture kernel),在最小化环境中将崩溃时的内核内存镜像保存为转储文件(vmcore),供后续使用 crash 工具进行离线分析。
TencentOS Server 4 默认支持 kdump。腾讯云 CVM 的公共镜像默认已预装 kexec-tools 并按内存大小自动预留 crashkernel(如 crashkernel=3G-16G:256M,16G-64G:384M,... 分档策略),kdump 服务开机自启;您可通过 cat /sys/kernel/kexec_crash_loaded 快速确认(输出 1 表示已就绪)。自建机房或自定义镜像环境可能未配置,未正确配置 kdump 的机器在 panic 后仅会重启,不保留任何现场信息,此时需按本文完成安装与配置。建议所有生产环境在初始化阶段确认 kdump 开启。

注意事项

开始配置 kdump 前,请您先确认以下事项。TencentOS Server 4 支持 x86_64 与 aarch64 两种架构,二者的 crashkernel 预留策略不同,请通过 uname -m 确认当前架构。
X86_64 架构:建议 crashkernel=256M(≤16GB 内存)或 256M,high(>16GB 内存)。腾讯云 CVM 公共镜像默认已按内存分档自动预留,无需手动配置
ARM(aarch64)架构:建议使用 crashkernel=512M,high,因 ARM 捕获内核初始化需要更多内存,预留不足会导致 kdump 加载失败。
root 权限:本文所有操作需以 root 用户执行,或通过 sudo -i 切换到 root。
dnf 源可用:安装 kexec-toolscrash 需要系统默认 dnf 源可访问;安装 kernel-debuginfo 需额外配置 debuginfo 源(默认源不含此包,配置方法见操作步骤 1)。
重启窗口crashkernel 内存预留参数修改后必须重启系统才能生效,请您提前规划重启窗口。
上述内容可通过以下命令快速确认:
# 确认系统架构
uname -m # 预期输出:x86_64 或 aarch64

# 确认当前用户为 root
whoami # 预期输出:root
# 确认磁盘空间(转储目录所在分区,默认 /var/crash)
df -h /var/crash # 预期输出:可用空间不低于物理内存的 20%
# 确认内核版本
uname -r # 预期输出:<kernel-version>,例如 6.6.79-25.8.tl4.x86_64
# 确认 dnf 源可用
dnf repolist # 预期输出:列出已配置的软件源

接口与参数说明

kdump 核心配置参数

参数
位置
取值
说明
crashkernel
kernel 启动参数
256M / 256M,high / 128M@64M
为捕获内核预留内存
KDUMP_KERNEL
/etc/sysconfig/kdump
内核镜像路径
捕获内核 vmlinuz 路径
KDUMP_INITRD
/etc/sysconfig/kdump
initramfs 路径
捕获内核 initramfs 路径
KDUMP_COMMANDLINE_APPEND
/etc/sysconfig/kdump
内核参数字符串
追加到捕获内核的启动参数
path
/etc/kdump.conf
目录路径
转储文件保存目录
core_collector
/etc/kdump.conf
makedumpfile 参数
转储文件过滤和压缩策略

makedumpfile 过滤级别

参数
含义
转储大小
-d 0
不过滤,完整转储
100%
-d 1
排除零页
~70-80%
-d 31
排除零页+缓存页+用户数据页(推荐)
~10-20%
-d 31 -c
排除零页+缓存页+用户数据页 + 压缩输出
最小

makedumpfile 参数详解

参数
说明
-l
压缩转储文件(LZO 压缩)
--message-level <n>
控制输出日志详细级别,1 表示仅打印进度信息
-d <bitmask>
过滤掩码,按位过滤不必要页面:bit0=零页、bit1=缓存页、bit2=用户数据页、bit3=空闲页;31 = 0b11111 表示排除以上所有
-c
对过滤后的数据进行压缩

配置示例

警告:kdump 配置涉及修改内核启动参数和重启系统,请您在维护窗口操作;触发 panic 测试会导致系统立即重启,严禁在生产环境执行。

1. 安装 kdump 相关软件包

# 安装 kexec-tools(kdump 核心)和 crash(分析工具)
dnf install kexec-tools crash

# 安装 kernel-debuginfo(crash 工具分析 vmcore 必需,提供 vmlinux 调试符号)
# 注意:kernel-debuginfo 不在默认源中,需先添加 debuginfo 源:
cat > /etc/yum.repos.d/tl4-debuginfo.repo << 'EOF'
[tl4-debuginfo]
name=TencentOS Server 4 - Debuginfo
baseurl=https://mirrors.tencent.com/tlinux/4.0/BaseOS/x86_64/debug/tree/
enabled=1
gpgcheck=0
EOF
# debuginfo 包版本必须与运行内核完全一致(uname -r 查看);若源中暂无对应版本,请等待源更新
dnf install kernel-debuginfo-$(uname -r)

# 验证 kernel-debuginfo 安装结果:vmlinux 调试符号文件应存在
ls /usr/lib/debug/lib/modules/$(uname -r)/vmlinux
# 预期输出:/usr/lib/debug/lib/modules/<kernel-version>/vmlinux

2. 配置 crashkernel 内存预留

# 查看当前 crashkernel 配置
cat /proc/cmdline | grep crashkernel

# 使用 grubby 设置 crashkernel
# x86_64 架构:建议 256M(≤16GB 内存)或 256M,high(>16GB 内存)
grubby --update-kernel=ALL --args="crashkernel=256M"

# aarch64(ARM)架构:建议使用 512M,high,因 ARM 捕获内核需要更多内存
# grubby --update-kernel=ALL --args="crashkernel=512M,high"

# 重启使配置生效
reboot
重启后验证 kdump 是否加载:
# 查看 kdump 是否已加载
cat /sys/kernel/kexec_crash_loaded
# 预期输出:1(1 表示 kdump 已加载,0 表示未加载)

# 查看内核日志中 crashkernel 预留信息
dmesg | grep -i crash
# 预期输出:包含 "Reserving XXXMB of memory for crashkernel" 等行

3. 配置 kdump 主配置文件

执行 vim /etc/sysconfig/kdump 编辑主配置文件。以下示例中 <kernel-version> 为占位符,实际使用时请替换为 uname -r 的输出值(例如 6.6.79-25.8.tl4.x86_64):
# 捕获内核镜像路径
KDUMP_KERNEL="/boot/vmlinuz-<kernel-version>"
# 捕获内核 initramfs 路径
KDUMP_INITRD="/boot/initramfs-<kernel-version>kdump.img"
# KDUMP_COMMANDLINE_APPEND 用于追加自定义参数(避免与默认参数重复)
KDUMP_COMMANDLINE_APPEND="panic=1 swiotlb=noforce novmcoredd"

4. 配置转储目标

执行 vim /etc/kdump.conf 编辑转储目标配置文件:
# 本地文件系统转储
path /var/crash
# core_collector 使用 makedumpfile 过滤并压缩
# -l:LZO 压缩;--message-level 1:仅打印进度;-d 31:排除零页+缓存页+用户数据页
core_collector makedumpfile -l --message-level 1 -d 31

# NFS 转储(可选)
# nfs my.server.com:/export/crash
# path /var/crash
# core_collector makedumpfile -l --message-level 1 -d 31

5. 启动 kdump 服务

# 设置开机自启
systemctl enable kdump

# 启动 kdump 服务
systemctl start kdump

# 查看服务状态
systemctl status kdump
# 预期输出:Active: active (exited) 且无报错

6. 验证 kdump 配置完整性

# 重建 kdump initramfs(修改配置后或内核升级后执行)
kdumpctl rebuild
# 预期输出:提示 rebuild 成功,无报错

# 验证 kdump 服务状态
kdumpctl status
# 预期输出:kdump is operational

7. 触发内核崩溃测试

警告:以下命令会立即导致内核 panic 并重启系统,仅在测试环境执行!严禁在生产环境执行,否则会导致业务中断和数据丢失。
# 启用 sysrq
echo 1 > /proc/sys/kernel/sysrq

# 触发内核崩溃(仅在测试环境执行)
echo c > /proc/sysrq-trigger
系统将 panic 并重启进入捕获内核,转储文件保存到 /var/crash/ 目录下。

8. 分析转储文件

# 查看转储文件
ls -la /var/crash/
# 预期输出:列出以 IP-日期时间 命名的目录,例如 127.0.0.1-2026-08-09-14:30

ls /var/crash/127.0.0.1-$(date +%Y-%m-%d-%H:%M)/
# 预期输出:包含 vmcore 文件

# 使用 crash 工具分析(需提前安装 kernel-debuginfo 提供 vmlinux)
# 将 <dump-dir> 替换为实际的转储目录名,<kernel-version> 替换为 uname -r 输出
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/<dump-dir>/vmcore
crash 交互命令示例:
crash> bt # 查看崩溃调用栈(backtrace)
crash> ps # 查看崩溃时进程列表
crash> log # 查看内核日志(dmesg)
crash> sys # 查看系统信息
crash> quit # 退出 crash

预期结果

操作步骤
预期输出
验证方法
安装软件包
dnf install 成功,无报错
rpm -q kexec-tools crash kernel-debuginfo 列出已安装
配置 crashkernel 并重启
cat /sys/kernel/kexec_crash_loaded 输出 1
dmesg | grep crash 显示预留内存
启动 kdump 服务
Active: active (exited)
systemctl status kdump
kdumpctl rebuild
rebuild 成功提示
kdumpctl status 输出 operational
触发 panic(测试)
系统重启后 /var/crash/ 下生成 vmcore
ls /var/crash/ 存在转储目录
crash 分析
进入 crash 交互界面
进入 crash 交互界面后可正常执行 bt、ps、log 等命令

常见问题

Q1:kdump 服务启动失败,报错 "No kdump initial ramdisk found"

原因:kdump 的 initramfs 未生成或路径配置错误。
解决方案:重建 kdump initramfs 并核对路径配置。
# 1. 手动重建 kdump initramfs
kdumpctl rebuild

# 2. 检查 /etc/sysconfig/kdump 中 KDUMP_INITRD 路径是否正确
# 将 <kernel-version> 替换为 uname -r 输出值
grep KDUMP_INITRD /etc/sysconfig/kdump
# 预期输出:KDUMP_INITRD="/boot/initramfs-<kernel-version>kdump.img"

# 3. 确认 initramfs 文件存在
ls -la /boot/initramfs-$(uname -r)kdump.img

# 4. 重启服务
systemctl restart kdump

Q2:panic 重启后没有转储文件(/var/crash 为空)

原因crashkernel 内存预留失败或预留不足,导致捕获内核无法启动。
解决方案:确认 crashkernel 预留状态,预留失败则增大预留值后重启。
# 1. 确认 crashkernel 已预留
cat /proc/cmdline | grep crashkernel
# 预期输出:包含 crashkernel=256M 或类似参数

# 2. 确认 kdump 已加载
cat /sys/kernel/kexec_crash_loaded
# 预期输出:1

# 3. 查看 dmesg 确认预留是否成功
dmesg | grep -i "crashkernel"
# 预期输出:Reserving XXXMB of memory for crashkernel

# 4. 如果预留失败,增大 crashkernel 值后重启
# x86_64:grubby --update-kernel=ALL --args="crashkernel=256M,high"
# aarch64:grubby --update-kernel=ALL --args="crashkernel=512M,high"

Q3:转储文件写入失败,报磁盘空间不足

原因/var/crash 所在分区可用空间不足以容纳 vmcore。
解决方案:清理旧转储文件或降低转储体积,仍不足时更换转储目标。
# 1. 查看当前可用空间
df -h /var/crash

# 2. 清理旧的转储文件(请先确认旧转储已完成分析或归档——vmcore 是不可再生的故障现场,删除后无法恢复)
rm -rf /var/crash/127.0.0.1-*

# 3. 增大 makedumpfile 过滤级别,减小转储文件大小
# 编辑 /etc/kdump.conf,将 core_collector 改为:
# core_collector makedumpfile -l --message-level 1 -d 31 -c

# 4. 或将转储目标改为空间更大的分区或 NFS 挂载点

Q4:内核升级后 kdump 失效

原因:升级内核后,捕获内核路径与运行内核不匹配,kdump initramfs 未更新。
解决方案:更新捕获内核路径并重建 initramfs,使 kdump 与新内核匹配。
# 1. 更新 /etc/sysconfig/kdump 中的 KDUMP_KERNEL 和 KDUMP_INITRD 路径
# 将 <kernel-version> 替换为新内核版本(uname -r 输出)
# KDUMP_KERNEL="/boot/vmlinuz-<kernel-version>"
# KDUMP_INITRD="/boot/initramfs-<kernel-version>kdump.img"

# 2. 安装新内核对应的 kernel-debuginfo
dnf install kernel-debuginfo-$(uname -r)

# 3. 重建 kdump initramfs
kdumpctl rebuild

# 4. 重启 kdump 服务
systemctl restart kdump

# 5. 验证
kdumpctl status

Q5:crash 工具报错 "cannot find vmlinux" 或 "debuginfo not installed"

原因:未安装 kernel-debuginfo 或版本不匹配。
解决方案:安装与当前运行内核版本匹配的 kernel-debuginfo。
# 1. 安装与当前内核版本匹配的 kernel-debuginfo
dnf install kernel-debuginfo

# 2. 确认 vmlinux 文件存在
ls /usr/lib/debug/lib/modules/$(uname -r)/vmlinux

# 3. 如果版本不匹配,安装对应版本
dnf install kernel-debuginfo-$(uname -r)