在CentOS系统中配置kdump实现内核崩溃转储,核心操作就是三步:安装kexec-tools工具包、配置/etc/kdump.conf指定转储路径和核心收集参数、通过systemctl启用kdump服务并预留崩溃内核内存。配置完成后用echo c > /proc/sysrq-trigger触发一次内核崩溃来验证转储是否成功生成vmcore文件。这套流程在CentOS 7和CentOS 8/Stream上基本一致,但细节参数有差异,下面我会逐一拆解。

kdump本质上是基于kexec机制的双内核方案。当系统内核发生panic时,kexec会加载一个预先准备好的捕获内核(capture kernel),这个捕获内核启动后把崩溃时的内存镜像(vmcore)dump到指定存储位置。运维人员拿到vmcore后,可以用crash工具配合对应的vmlinux和调试符号文件进行离线分析,定位内核崩溃根因。这是生产环境排查内核oops、kernel panic、硬件故障的必备手段。

一、环境准备和kdump组件安装

在CentOS 7上,直接用yum安装即可:

yum install kexec-tools -y

在CentOS 8/Stream上,包名有所变化:

dnf install kexec-tools -y

安装完成后,确认kexec服务已安装但不要启动它(kexec是手动触发重启用的,不是常驻服务)。我们要启用的是kdump服务:

systemctl enable kdump
systemctl start kdump

这里有一个很多人忽略的关键点:kdump需要在系统启动时预留一块独立的内存区域给捕获内核使用。如果你的机器内存是16GB,默认可能只预留很小一块,导致捕获内核无法正常启动。需要在GRUB引导参数中显式指定crashkernel的大小。

二、配置GRUB引导参数预留崩溃内核内存

编辑/etc/default/grub文件,找到GRUB_CMDLINE_LINUX这一行,追加crashkernel参数。根据内存大小,推荐配置如下:

# 内存4GB以下
GRUB_CMDLINE_LINUX="crashkernel=128M"

# 内存4GB-8GB
GRUB_CMDLINE_LINUX="crashkernel=256M"

# 内存8GB-16GB
GRUB_CMDLINE_LINUX="crashkernel=512M"

# 内存16GB以上
GRUB_CMDLINE_LINUX="crashkernel=512M"

CentOS 8/Stream使用GRUB2,修改后需要重新生成配置:

grub2-mkconfig -o /boot/grub2/grub.cfg

CentOS 7使用的是grub,命令是:

grub2-mkconfig -o /boot/grub2/grub.cfg

改完之后重启系统,用以下命令验证crashkernel是否生效:

cat /proc/cmdline | grep crashkernel
dmesg | grep -i crash

如果看到类似"Memory: 16384MB ... crashkernel=512M@160M"的输出,说明预留成功。

三、详细配置kdump.conf转储参数

kdump的主配置文件是/etc/kdump.conf,这个文件决定了vmcore存到哪里、怎么存、存什么内容。一个生产环境推荐的配置模板如下:

path /var/crash
core_collector makedumpfile -l --message-level 1 -d 31
default reboot

逐行解释:path指定转储文件的存放目录,默认是/var/crash,你也可以改成NFS挂载点或者本地磁盘分区。core_collector指定使用makedumpfile工具来压缩和过滤vmcore,其中-l表示使用lzo压缩,-d 31表示过滤掉空闲页和部分用户态页面,能大幅减小vmcore体积。default reboot表示转储完成后自动重启系统,生产环境一般都选这个。

如果你需要通过网络传输vmcore,可以配置netdump或者nfsdump。例如使用SSH传输:

path /var/crash
core_collector makedumpfile -l --message-level 1 -d 31
ssh root@192.168.1.100
sshkey /root/.ssh/kdump_id_rsa

这里sshkey指向一个专门用于kdump传输的私钥,需要提前在目标机器上配置好免密登录。另外,如果你的环境用的是iSCSI或者NFS存储,也可以直接把path指向挂载点。

还有一个容易踩坑的地方:如果你的系统启用了透明大页(THP),kdump可能会出现内存预留不足的问题。建议在kdump.conf中加入:

kdump_args --no-hugepages

或者直接在GRUB中禁用THP:

GRUB_CMDLINE_LINUX="transparent_hugepage=never crashkernel=512M"

四、触发内核崩溃进行转储测试

配置完成并重启后,就可以手动触发一次内核崩溃来验证kdump是否正常工作。最安全的方式是通过sysrq触发:

echo c > /proc/sysrq-trigger

执行这条命令后,系统会立即触发kernel panic,然后kdump捕获内核启动,把内存镜像写入/var/crash目录。整个过程通常需要1-3分钟,取决于内存大小和makedumpfile的过滤程度。完成后系统会自动重启。

重启后检查转储结果:

ls -lh /var/crash/

你应该能看到类似这样的文件:

vmlinuz-3.10.0-1160.el7.x86_64
vmcore-3.10.0-1160.el7.x86_64.20240101-120000

如果目录为空或者没有vmcore文件,说明转储失败。常见失败原因包括:crashkernel内存预留不足、SELinux阻止写入、磁盘空间不够、makedumpfile参数错误。排查方法是查看kdump服务日志:

journalctl -u kdump -xe

以及查看dmesg中的kdump相关信息:

dmesg | grep -i kdump

五、用crash工具分析vmcore文件

拿到vmcore后,需要安装crash工具和对应内核的debuginfo包才能分析:

yum install crash kernel-debuginfo-$(uname -r) -y

然后启动crash:

crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/vmcore-$(uname -r)

进入crash交互界面后,最常用的命令是bt(backtrace)查看崩溃时的内核调用栈:

crash> bt
PID: 12345  TASK: ffff88001a2b3c40  CPU: 2  COMMAND: "nginx"
 #0 [ffff88001a2b3c40] machine_kexec at ffffffff8103a120
 #1 [ffff88001a2b3c80] crash_kexec at ffffffff810c1234
 #2 [ffff88001a2b3cc0] panic at ffffffff810c4567
 ...

通过调用栈可以定位到具体是哪个内核模块或函数导致了崩溃。如果是驱动问题,还可以用mod命令查看加载的模块,用log命令查看内核日志。

六、生产环境的注意事项和常见问题

第一,kdump不要和业务争抢资源。crashkernel预留的内存是从系统总内存中扣掉的,如果预留过大会影响业务性能。一般512M对大多数场景够用,除非你的vmcore经常很大需要完整内存镜像。

第二,/var/crash目录要确保有足够空间。一个16GB内存的机器,经过makedumpfile压缩后vmcore可能还有2-4GB,如果不压缩可能达到10GB以上。建议单独挂一个分区或者用NFS远程存储。

第三,CentOS 8上kdump的默认行为有变化,makedumpfile可能需要单独安装:

dnf install makedumpfile -y

第四,如果你的系统使用了LVM或者加密磁盘,kdump可能无法正常写入。需要确保/var/crash所在的文件系统在捕获内核启动时可以正常挂载。建议把path设置在一个简单的ext4或xfs分区上。

第五,不要在虚拟机上测试kdump时忘记关闭虚拟机的内存气球(memory balloon)功能,这会导致crashkernel预留失败。在KVM环境下,需要在虚拟机XML中禁用balloon或者固定内存大小。

第六,自动化运维场景下,建议把kdump测试纳入定期巡检脚本。可以写一个简单的cron任务,每月触发一次sysrq崩溃测试并检查vmcore生成情况,确保kdump随时可用。毕竟真正出故障的时候才发现kdump没配好,那就晚了。

七、总结

CentOS上配置kdump并不复杂,核心就是装工具、配GRUB预留内存、改kdump.conf、启用服务、触发测试、分析结果这六步。但细节决定成败,crashkernel大小、THP处理、存储路径、SELinux策略、makedumpfile参数每一个都可能成为坑。建议在测试环境完整跑通一遍流程,确认vmcore能正常生成和分析后,再推广到生产集群。内核崩溃不可避免,但有了kdump,你就有了事后定位问题的能力,这是运维基本功中非常重要的一环。