有一次值班一台服务器在升级内核后重启grub 直接进不去只有一行grub rescue。当时手上没有安装盘也没想起 mkbootdisk 这个命令能做应急启动盘最后是拿另一台机器熬了大半夜才把系统拉起来。后来我专门把 mkbootdisk 从原理到实操完整过了一遍——它能为目前系统生成一张可引导的启动盘把当前运行的内核、initrd 和引导信息打包进一个介质关键时刻直接绕过硬盘引导。这篇就围绕它讲讲原理、实操和踩坑经验适合还在维护 CentOS/RHEL 系服务器的运维同学也适合那些在虚拟化环境里做故障演练的人。系统引导坏了怎么办这张盘就是答案。1. 什么时候你会需要一张“当前系统的启动盘”1.1 引导故障运维迟早要面对的事系统无法启动的场景在真实环境里比想象中频繁得多。我整理了一下自己遇到过的高频情况内核升级后新内核起不来旧内核又因为/boot空间不足被清理掉了进退两难。grub 配置文件损坏、被覆盖或者分区表变动后引导条目失效。手动改了/etc/fstab写错 UUID 或设备名导致根分区挂载失败系统直接 drop 到紧急模式甚至起不来。启动分区误格式化、误删除或者磁盘控制器驱动没进 initramfs。这些情况有个共同点数据还在只是引导链路断了。这时候只要手里有一张和当前系统匹配的启动盘就能从盘上把内核拉起来然后挂载硬盘根分区进系统去做修复。这正是 mkbootdisk 的核心用途——它不是给你做一张“通用救援盘”而是做一张只属于这台机器、这个内核版本、这套驱动的“精确钥匙”。很多人第一反应是拿系统安装光盘或安装 U 盘的 rescue 模式。安装盘当然有用但有三个问题第一版本不一定匹配比如 CentOS 8 的盘去 rescue 一个 CentOS 7 的系统文件系统识别和 chroot 都会别扭第二找盘、插盘、启动、进 rescue 菜单链路太长第三rescue 模式默认不会自动加载原系统的所有驱动和 LVM 卷组还得手动折腾。mkbootdisk 做出来的盘内核版本就是当前系统的版本启动后直接进原系统省掉中间一大串步骤。1.2 “目前系统”三个字是关键mkbootdisk 的名字里藏着它的定位——为目前系统制作启动盘。它默认读取当前正在运行的uname -r内核版本自动在/boot下找对应的vmlinuz-版本再用当前系统的配置生成 initrd。整个过程不需要你手动指定内核路径也不需要手工拼 initrd一条命令就能得到和当前环境完全一致的引导介质。这个特性在紧急情况下尤其重要。手工做启动盘的人最容易死在 initrd 上initrd 里要是缺了磁盘控制器驱动比如 SAS 卡、NVMe、特定的 RAID 卡内核根本找不到根分区启动盘做得再漂亮也白搭。mkbootdisk 的方式是从当前系统现有配置里提取驱动列表基本能保证“你现在能跑起来做了盘也能跑起来”。1.3 适用发行版这是 Red Hat 系专属mkbootdisk 是 Red Hat 系工具的典型风格CentOS / RHEL / Fedora 上可以直接安装使用设计上也依赖同系列的 mkinitrd老版本或 dracut新版本来生成 initramfs。Debian/Ubuntu 上虽然能勉强编译安装但和自家的引导体系并不匹配对应方案通常是mkinitramfs或直接改/etc/initramfs-tools的配置。所以如果你维护的是 Debian 系机器可以了解这个思路但别指望原样照搬。下面的内容我以 CentOS 7 环境为主线展开这也是 mkbootdisk 实际出场率最高的舞台。2. 先看懂 mkbootdisk 在背后做了什么2.1 生成启动盘的三步走从命令行接口看mkbootdisk 是一条命令但它背后实际做了三件事定位内核与启动参数。根据你指定的内核版本缺省就是当前uname -r去/boot目录找vmlinuz-version然后从现有 grub 配置里收集该内核的启动参数尤其是root指向的根分区设备。生成 initrd。调用 mkinitrdEL6 时代或 dracutEL7 时代以当前系统的模块配置为基础生成一个包含磁盘控制器驱动、文件系统驱动和 LVM 支持的 initrd放在临时目录。组装引导介质。把目标设备格式化成可引导格式依次写入引导代码、内核、initrd并生成一份极简 grub 配置。这份配置会带上当前系统的根分区信息例如root/dev/sda2。所以从这张盘启动时内核先从盘上加载initrd 随后加载对应驱动然后直接挂载硬盘上的根文件系统进入你已经熟悉的系统环境。用配钥匙来类比就是你不需要懂钥匙坯子怎么车、牙口怎么铣只需要告诉师傅“配一把我现在这扇门的钥匙”剩下的都是工具本身的工作。mkbootdisk 也一样“目前系统”就是你的钥匙坯子它负责把内核、initrd 和引导记录封装成一张能启动的盘。2.2 常用参数逐个拆解man mkbootdisk里参数不多但每个都值得认真看一眼参数作用说明--device设备指定输出目标默认是 /dev/fd0可以换成镜像文件或其他块设备--size大小指定目标大小单位是 1024 字节块软盘时代写 1440--kernelargs参数追加内核启动参数比如selinux0、quiet会写进启动配置--noverify跳过写后校验写入后默认会回读校验跳过更快但少了保险--mkinitrd-args参数传给 mkinitrd 的参数需要定制 initrd 时偶尔会用--version显示版本确认自己用的是哪个版本特别提醒--size的坑它指的是可写空间单位是 1KB 块。在软盘时代写--size 1440是标准操作但如果你输出到 U 盘或镜像文件还带着 1440 这个数字就麻烦了。EL7 的内核加 initramfs 动辄 30MB 以上软盘那点空间根本放不下。我见过有人拿大 U 盘做启动盘没指定 size结果工具探测到的是整个 U 盘容量但因为格式化和分区问题反而报错——这类问题在实战部分会细讲。2.3 依赖项为什么说它是“整套工具链”的一部分mkbootdisk 不是一个孤立程序实际执行时会调用mkinitrdEL6或dracutEL7负责构建 initramfs。grub或lilo负责写引导扇区。e2fsprogs等文件系统工具负责格式化目标设备。所以在排查“mkbootdisk 执行失败”的时候别只盯着命令本身先确认它依赖的工具是不是齐全、版本是不是匹配。我在老 CentOS 6 上遇到过命令直接报错最后发现是mkinitrd没装yum install mkinitrd之后才恢复正常。新版环境里则要留意 dracut 是否可用EL7 上如果 dracut 被误删mkbootdisk 照样罢工。3. 实战在 CentOS 7 环境下生成并验证启动盘3.1 环境准备与安装拿一台 CentOS 7.9 虚拟机演示内核版本用登录后执行uname -r获取。第一步先确认命令是否存在which mkbootdisk如果没有输出直接安装yum install -y mkbootdiskCentOS 7 的 base 源里就有这个包不需要额外配源。如果你用的是 CentOS 8 或 RHEL 8默认 BaseOS/AppStream 仓库里大概率找不到它这时不建议强行编译直接考虑下面第 5 章提到的替代方案更省心。我的经验是mkbootdisk 在 EL7 及更早的系统上才是主力工具EL8 之后它的生态位已经被 dracut 和 grub2-mkrescue 取代了。3.2 生成启动盘镜像先确认当前内核版本然后生成镜像文件uname -r # 3.10.0-1160.el7.x86_64生成到/root/centos7-boot.imgmkbootdisk --device /root/centos7-boot.img $(uname -r)这里有个容易踩的版本差异。老版本的 mkbootdisk 支持直接把普通文件当作目标设备写但某些版本会拒绝打开“不是块设备”的文件。为了避免这种不确定性推荐更通用的做法先创建一个固定大小的镜像再用losetup挂成块设备dd if/dev/zero of/root/centos7-boot.img bs1M count50 losetup /dev/loop0 /root/centos7-boot.img mkbootdisk --device /dev/loop0 $(uname -r) losetup -d /dev/loop050MB 对 EL7 完全够用vmlinuz 加 initramfs 加引导扇区实际占用一般在 35MB 左右。如果你是在老软盘时代--device /dev/fd0 --size 1440就是当年的标准写法前提是你还有软驱和软盘。3.3 验证启动盘是否真的能引导这一步最关键。生成完镜像后别急着收工一定要验证一次。最简单的验证方式是在 KVM/QEMU 虚拟机里启动它qemu-system-x86_64 -m 1024 -boot ordera \ -drive file/root/centos7-boot.img,formatraw,iffloppy \ -drive file/path/to/原来的系统盘.img,formatraw,ifide注意-boot ordera的含义是从第一软驱启动虚拟软驱里放的就是刚生成的镜像。如果能出现 grub 菜单并成功进入内核说明启动盘工作正常。顺利的话会看到极简的引导选项然后进入熟悉的登录提示。真机上操作的区别在于把-drive换成真实软驱或 USB 设备。真机基本没有软驱最常见的落地方式是把 mkbootdisk 生成的镜像保存成文件需要时用dd写到 U 盘或者直接在虚拟机里作为备用引导介质存放。另外提醒一句U 盘的实际可引导性还取决于主板对 USB 启动和分区表的支持所以做出来一定先在目标机器上试一次别到救火的时候才发现起不来。3.4 什么时间点适合制作启动盘结合我的习惯下面四个时间点值得做一次系统刚装完、所有驱动正常时趁热打铁做一张“初始状态盘”。每次升级内核后重做确保盘里的内核版本不被甩下。改动过/etc/fstab或 grub 配置后因为启动参数可能已经变了。出差、进机房、上架新机器前把盘和系统 ISO 一起放工具包。原则就一条在系统健康的时候把备用钥匙配好别等门锁坏了才想起找配钥匙师傅。4. 高频报错与完整排查链路4.1 从一次“设备不存在”讲起有次我在一台 CentOS 6 虚拟机里执行mkbootdisk --device /dev/fd0 $(uname -r)结果直接报错mkbootdisk: unable to open device /dev/fd0: No such file or directory我起初以为权限不够加了 sudo 还是报错。排查链路如下先确认设备节点是否存在ls -l /dev/fd0看内核模块是否加载lsmod | grep floppy检查虚拟机的 BIOS/配置是否启用了软驱如果都没问题再考虑权限和 SELinux最后真相很简单这台虚拟机根本没有软驱内核没加载 floppy 模块自然没有/dev/fd0。报错信息里写着 No such file or directory人容易往权限和文件系统上想忽略了最朴素的“设备根本不存在”。这个案例给所有排查问题的人一个提醒先确认对象存在再研究方法和权限。4.2 内核文件缺失/boot与内核版本不同步另一个高频报错是找不到对应的 vmlinuzmkbootdisk: unable to find kernel file /boot/vmlinuz-xxx原因通常是命令行里指定的内核版本号和/boot下实际存在的文件对不上。比如你手动传了一个旧内核版本但/boot里因为yum clean、自动清理或者误删已经找不到对应的 vmlinuz。排查顺序执行ls -l /boot/vmlinuz-*列出所有内核文件确认目标版本是否存在。如果缺的恰好是当前运行内核的 vmlinuz别慌——系统能跑说明内核已经加载进内存文件通常只是被误删可以从同版本机器的/boot拷贝或者用yum reinstall kernel-版本重新提取。确认uname -r和文件名精确对应注意架构后缀x86_64、i686等一个字母都不能差。4.3 空间不足与文件系统格式冲突老写法--size 1440在 EL7 上必然失败因为内核加 initramfs 已经远超 1.44MB。如果你把目标设备设成 U 盘又指定了一个过小的 size也会在写入阶段报空间不足。排查思路先看实际占用du -sh /boot/vmlinuz-* /boot/initramfs-*按实际大小重新规划目标设备EL7 建议 50MB 起步。如果目标是整块块设备U 盘、回环设备让 mkbootdisk 自动探测容量别再用软盘时代的数字。还有一种情况是目标设备已经有文件系统或分区表残留mkbootdisk 格式化时报错。这时可以先把目标重新分区或直接清零前几百 KBdd if/dev/zero of/dev/loop0 bs512 count2048再重新跑 mkbootdisk。4.4 权限与执行环境的隐性坑mkbootdisk 必须要有 root 权限因为它要格式化设备、写引导扇区。普通用户执行通常会卡在 Permission denied。但多一道 sudo 也不是万事大吉sudo 的环境里如果 PATH 不包含/sbin可能直接报command not found。看到这个错误排查思路不是“命令没装”而是先看看 PATHsudo /sbin/mkbootdisk --device /root/boot.img $(uname -r)直接写全路径干净利落。5. mkbootdisk 在现代环境中的实际用法5.1 软盘退场后的新归宿mkbootdisk 最初就是为软盘设计的命令里到处是/dev/fd0的影子。现在软驱和软盘基本绝迹这个命令还有用吗我的答案是在虚拟化环境里不但有用而且依然好用。用losetup把生成结果挂成镜像文件随 VM 的配置一起备份作为虚拟机的“软盘救援镜像”。KVM 虚拟机做故障演练时把它当成虚拟软驱里的引导盘反复练习 grub 修复和内核实战。转写镜像到 U 盘做一个低成本的应急引导 U 盘适合没有光驱、没有 IPMI 的物理机。U 盘的做法同样是用 mkbootdisk 先生成镜像文件然后dd到 U 盘设备。但 U 盘实际使用通常比镜像文件复杂涉及分区表、主板固件对 USB 启动的支持等强烈建议先在目标机器上实测再入库归档。5.2 和其他启动盘方案怎么选现在应急引导方案不少我常用来对比的是四个方案优点缺点适用场景mkbootdisk 生成镜像内核版本与当前系统完全一致制作成本极低引导界面简陋跨机器复用性差应急修复本机引导、KVM 虚拟软驱、单机精确救援系统安装盘 rescue 模式兼容性好自带完整救援工具版本可能不匹配启动链路长从零救援、文件系统级修复、重建引导grub2-mkrescue 制作通用应急 U 盘引导能力强可加载多种内核和工具需要额外安装依赖生成的介质较大做成通用应急盘多台机器复用dd 直接拷 ISO 到 U 盘操作简单粗暴要求 ISO 本身支持 U 盘引导无法记录操作痕迹用现成 ISO 快速做启动 U 盘mkbootdisk 的核心优势就是“版本精确匹配”和“快速生成”两点。它不需要网络、不需要额外镜像一条命令几十秒就能产出。缺点也很明显它生成的盘不通用换一台硬件就可能起不来而且引导界面极简不适合做日常工具箱。5.3 组合使用的思路现在我的工作习惯是mkbootdisk 负责“精确匹配当前系统”的急救盘grub2-mkrescue 负责“通用救援”的应急 U 盘系统 ISO 作为最后的兜底。三件套各有分工。系统正常时每月生成一次 mkbootdisk 镜像放在/root或单独目录里改过引导相关配置就重新生成一次。真出问题时先用通用盘拉起系统再用精确盘修复 grub 和内核整个流程非常顺。6. 用 mkbootdisk 前必须想清楚的事盘是给“当前系统”用的别指望跨机复用。mkbootdisk 生成的盘绑定了当前内核和驱动换一台机器就可能起不来尤其是磁盘控制器型号不同的时候。所以每台重要机器最好都有自己的盘不要拿 A 机器的盘去救 B 机器。输出设备选型比命令本身更重要。设备文件、镜像文件、块设备都是合法输出但不同版本对普通文件的支持程度不同。我建议统一走losetup挂回环设备这条路兼容性最好不容易被版本差异卡住。做完一定要验证。系统真的挂了之后你没有现场 debug 的机会。所以生成完镜像必须在虚拟机里做一次引导测试确认能进系统再归档。这一步省不了。和同系工具链版本匹配。EL6 和 EL7 的 initrd 生成机制不同mkbootdisk 也跟着变。跨版本使用可能出现 initramfs 生成方式不兼容的问题不要混。别把鸡蛋放一个篮子里。mkbootdisk 只是应急手段之一建议同时保留系统 ISO 或一台可 PXE 引导的机器。真实故障面前冗余永远比技巧可靠。说实话这个命令用到的频率不高但每次用到都是救火级别。我复盘过那次 grub rescue 的深夜故障如果当时提前给每台机器备好一张 mkbootdisk 镜像恢复时间可能从几个小时缩短到十几分钟。所以我的建议是今天花五分钟把命令装好、把盘做出来、放到安全位置以后等于给自己买了个保险。再扩展一步这套“精确钥匙 通用钥匙 兜底 ISO”的组合拳思路也完全可以用在非 Linux 系统的应急备份规划里。
阅读完成 · 觉得有帮助?