GRUB2 引导管理器完全教程 / 第 12 章:最佳实践
第 12 章:最佳实践
12.1 GRUB 配置管理最佳实践
12.1.1 配置文件管理原则
| 原则 | 说明 |
|---|
| 不手动编辑 grub.cfg | 始终通过 /etc/default/grub 和 update-grub 管理 |
使用 /etc/grub.d/40_custom | 自定义菜单项放在 40_custom 中 |
| 版本控制 | 将 /etc/default/grub 和 /etc/grub.d/40_custom 纳入版本管理 |
| 使用 UUID | 始终使用 UUID 而非设备名指定分区 |
| 文档化修改 | 在自定义配置中添加注释说明 |
12.1.2 配置文件版本控制
# 初始化 Git 仓库
$ sudo mkdir -p /etc/grub-manage
$ cd /etc/grub-manage
$ sudo git init
# 跟踪配置文件
$ sudo cp /etc/default/grub .
$ sudo cp /etc/grub.d/40_custom .
$ sudo git add .
$ sudo git commit -m "Initial GRUB configuration"
# 每次修改后
$ sudo cp /etc/default/grub .
$ sudo cp /etc/grub.d/40_custom .
$ sudo git add .
$ sudo git commit -m "Description of changes"
12.1.3 推荐的 /etc/default/grub 配置
# /etc/default/grub — 生产环境推荐配置
# 启动项:使用上次成功启动的项
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
# 超时:5 秒足够选择
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=menu
# 内核参数
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
# 禁用子菜单(所有内核平铺显示,便于选择)
GRUB_DISABLE_SUBMENU=true
# 启用 os-prober(如需多系统)
GRUB_DISABLE_OS_PROBER=false
# 启用恢复模式菜单
GRUB_DISABLE_RECOVERY="false"
# 图形设置(根据显示器调整)
GRUB_GFXMODE=1920x1080
GRUB_GFXPAYLOAD_LINUX=keep
12.2 备份策略
12.2.1 备份内容清单
| 文件/目录 | 重要性 | 说明 |
|---|
/etc/default/grub | ⭐⭐⭐ | 用户配置 |
/etc/grub.d/40_custom | ⭐⭐⭐ | 自定义菜单 |
/boot/grub/grub.cfg | ⭐⭐ | 生成的配置(可重新生成) |
/boot/grub/grubenv | ⭐⭐ | 环境变量(默认启动项) |
/boot/grub/themes/ | ⭐ | 主题文件 |
/boot/grub/fonts/ | ⭐ | 字体文件 |
/boot/vmlinuz-* | ⭐⭐⭐ | 内核文件 |
/boot/initrd.img-* | ⭐⭐⭐ | initramfs |
12.2.2 自动备份脚本
#!/bin/bash
# /usr/local/bin/backup-grub.sh
# GRUB 配置自动备份脚本
BACKUP_DIR="/backup/grub/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
echo "Backing up GRUB configuration to $BACKUP_DIR"
# 备份配置文件
cp /etc/default/grub "$BACKUP_DIR/"
cp /etc/grub.d/40_custom "$BACKUP_DIR/" 2>/dev/null
# 备份生成的 grub.cfg
cp /boot/grub/grub.cfg "$BACKUP_DIR/"
cp /boot/grub/grubenv "$BACKUP_DIR/"
# 备份自定义文件列表
ls -la /boot/vmlinuz-* "$BACKUP_DIR/vmlinuz-list.txt" 2>/dev/null
ls -la /boot/initrd.img-* "$BACKUP_DIR/initrd-list.txt" 2>/dev/null
# 记录当前分区 UUID
blkid > "$BACKUP_DIR/blkid.txt"
# 记录当前安装的内核包
dpkg --list | grep linux-image > "$BACKUP_DIR/linux-images.txt" 2>/dev/null
echo "Backup completed: $BACKUP_DIR"
echo ""
echo "To restore, use:"
echo " sudo cp $BACKUP_DIR/grub /etc/default/"
echo " sudo cp $BACKUP_DIR/40_custom /etc/grub.d/"
echo " sudo update-grub"
12.2.3 定期备份(cron)
# 添加到 root 的 crontab
$ sudo crontab -e
# 每周日 2:00 AM 备份
0 2 * * 0 /usr/local/bin/backup-grub.sh
# 每次内核更新后备份(通过 apt hook)
# /etc/apt/apt.conf.d/99-backup-grub
DPkg::Post-Invoke {"/usr/local/bin/backup-grub.sh"};
12.2.4 完整磁盘备份
# 使用 dd 备份 MBR(前 446 字节引导代码)
$ sudo dd if=/dev/sda of=/backup/mbr.bin bs=446 count=1
# 备份整个 MBR(含分区表,512 字节)
$ sudo dd if=/dev/sda of=/backup/mbr-full.bin bs=512 count=1
# 备份 EFI 分区
$ sudo dd if=/dev/sda1 of=/backup/efi-partition.img bs=4M
# 或使用 tar
$ sudo tar czf /backup/efi-backup.tar.gz /boot/efi/
# 恢复 MBR
$ sudo dd if=/backup/mbr.bin of=/dev/sda bs=446 count=1
# 恢复 EFI 分区
$ sudo dd if=/backup/efi-partition.img of=/dev/sda1 bs=4M
12.3 内核更新策略
12.3.1 管理内核版本
# 查看已安装的内核
$ dpkg --list | grep linux-image
# ii linux-image-6.1.0-amd64 6.1.76-1 amd64 Linux 6.1 for 64-bit PCs
# ii linux-image-6.1.0-9-amd64 6.1.27-1 amd64 Linux 6.1 for 64-bit PCs
# 查看当前运行的内核
$ uname -r
# 6.1.0-9-amd64
# 设置默认启动内核(GRUB_SAVEDEFAULT=true 时自动管理)
$ sudo grub-editenv /boot/grub/grubenv set saved_entry="Debian GNU/Linux, with Linux 6.1.0-9-amd64"
12.3.2 保留旧内核
# 配置 apt 保留至少 N 个内核
# /etc/apt/apt.conf.d/01autoremove-kernels
# 通常由 linux-image-* 包的配置自动管理
# 手动保留特定内核(不自动删除)
$ sudo apt-mark hold linux-image-6.1.0-amd64
# 取消保留
$ sudo apt-mark unhold linux-image-6.1.0-amd64
12.3.3 清理旧内核
# 自动清理(推荐)
$ sudo apt autoremove --purge
# 手动删除特定旧内核
$ sudo apt remove --purge linux-image-5.10.0-amd64 linux-headers-5.10.0-amd64
# 清理后更新 GRUB
$ sudo update-grub
12.3.4 内核更新后验证
# 内核更新后应该做的检查
# 1. 确认 grub.cfg 已更新
$ grep menuentry /boot/grub/grub.cfg | head -5
# 2. 确认新内核和 initramfs 存在
$ ls -la /boot/vmlinuz-$(uname -r)
$ ls -la /boot/initrd.img-$(uname -r)
# 3. 确认 GRUB 模块完整
$ ls /boot/grub/x86_64-efi/ | wc -l
# 4. 测试引导(如果可能,在虚拟机中测试)
# 5. 保留旧内核直到确认新内核稳定
12.4 安全加固
12.4.1 安全加固检查清单
| 项目 | 状态 | 命令 |
|---|
| GRUB 密码保护 | 检查 | grep superusers /boot/grub/grub.cfg |
| Secure Boot 启用 | 检查 | mokutil --sb-state |
| BIOS/UEFI 密码 | 检查 | 进入 BIOS 检查 |
| 磁盘加密 | 检查 | lsblk -f | grep crypto |
| 文件权限 | 检查 | ls -la /boot/grub/grub.cfg |
| 外部引导禁用 | 检查 | BIOS 设置 |
| 固件更新 | 检查 | fwupdmgr get-updates |
12.4.2 文件权限加固
# GRUB 配置文件权限
$ sudo chmod 600 /boot/grub/grub.cfg
$ sudo chown root:root /boot/grub/grub.cfg
$ sudo chmod 600 /boot/grub/grubenv
$ sudo chown root:root /boot/grub/grubenv
# /etc/default/grub
$ sudo chmod 644 /etc/default/grub
$ sudo chown root:root /etc/default/grub
# /etc/grub.d/ 脚本
$ sudo chmod 755 /etc/grub.d/*
$ sudo chown root:root /etc/grub.d/*
# GRUB 模块目录
$ sudo chmod 700 /boot/grub/x86_64-efi/
$ sudo chown root:root /boot/grub/x86_64-efi/
12.4.3 固件更新
# 使用 fwupd 更新固件
$ sudo apt install fwupd
# 检查可用更新
$ sudo fwupdmgr get-updates
# 应用更新
$ sudo fwupdmgr update
# 查看设备信息
$ sudo fwupdmgr get-devices
12.5 多系统引导管理
12.5.1 多系统引导策略
| 策略 | 适用场景 | 实现方式 |
|---|
| GRUB 统一管理 | 2-5 个系统 | os-prober + 手动菜单 |
| GRUB 链式加载 | Windows + Linux | chainloader |
| 独立引导程序 | 各系统完全独立 | EFI 启动菜单切换 |
| rEFInd 图形管理 | 多系统桌面 | rEFInd 自动检测 |
12.5.2 Windows + Linux 共存
# 最佳实践:
# 1. 先安装 Windows(会设置 EFI 启动项)
# 2. 再安装 Linux(GRUB 会自动检测 Windows)
# 3. 设置 GRUB 为默认引导程序
# 如果 Windows 更新覆盖了 GRUB
$ sudo efibootmgr -v
$ sudo efibootmgr -o <debian-entry>,<windows-entry>
# 如果 os-prober 未检测到 Windows
$ sudo apt install os-prober
$ sudo nano /etc/default/grub
# GRUB_DISABLE_OS_PROBER=false
$ sudo update-grub
12.5.3 多 Linux 发行版共存
# 方案 1:共享 GRUB(推荐)
# 安装一个"主"发行版,由它管理 GRUB
# 其他发行版通过 os-prober 自动检测
# 方案 2:各发行版独立 GRUB
# 每个发行版有独立的 EFI 启动项
# 通过 UEFI 启动菜单或 efibootmgr 切换
# 查看所有 EFI 启动项
$ sudo efibootmgr -v
# Boot0000* ubuntu
# Boot0001* debian
# Boot0002* fedora
# Boot0003* Windows Boot Manager
12.5.4 高级多系统配置
# /etc/grub.d/40_custom
# 引导 Ubuntu
menuentry "Ubuntu 24.04" --class ubuntu {
search --no-floppy --fs-uuid --set=root yyyy-yyyy-yyyy
linux /boot/vmlinuz root=UUID=yyyy-yyyy-yyyy ro quiet
initrd /boot/initrd.img
}
# 引导 Fedora
menuentry "Fedora 39" --class fedora {
search --no-floppy --fs-uuid --set=root zzzz-zzzz-zzzz
linux /boot/vmlinuz root=UUID=zzzz-zzzz-zzzz ro quiet
initrd /boot/initramfs.img
}
# 引导 Windows
menuentry "Windows 11" --class windows {
search --no-floppy --fs-uuid --set=root XXXX-XXXX
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
12.6 性能优化
12.6.1 减少 GRUB 超时
# 设置较短的超时(如 2 秒)
GRUB_TIMEOUT=2
# 或使用 hidden 模式(按 Shift 显示菜单)
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
12.6.2 精简 GRUB 模块
# 减少预加载模块可以加快启动
# 仅加载必要模块
$ sudo grub-install --target=x86_64-efi \
--efi-directory=/boot/efi \
--modules="part_gpt ext2 fat linux" \
--bootloader-id=debian
12.6.3 减小背景图片大小
# 大图片会拖慢 GRUB 启动
# 建议 < 2MB
$ convert background.png -quality 80 -strip background_optimized.jpg
$ ls -lh background_optimized.jpg
12.7 监控与维护
12.7.1 定期检查脚本
#!/bin/bash
# /usr/local/bin/check-grub-health.sh
# GRUB 健康检查脚本
echo "=== GRUB Health Check ==="
echo ""
# 1. 检查 grub.cfg
echo "[1] Checking grub.cfg..."
if [ -f /boot/grub/grub.cfg ]; then
MENU_COUNT=$(grep -c "^menuentry" /boot/grub/grub.cfg)
echo " ✓ grub.cfg exists, $MENU_COUNT menu entries found"
else
echo " ✗ grub.cfg NOT FOUND!"
fi
# 2. 检查内核
echo "[2] Checking kernels..."
CURRENT_KERNEL=$(uname -r)
echo " Current kernel: $CURRENT_KERNEL"
if [ -f "/boot/vmlinuz-$CURRENT_KERNEL" ]; then
echo " ✓ Current kernel file exists"
else
echo " ✗ Current kernel file MISSING!"
fi
# 3. 检查 initramfs
echo "[3] Checking initramfs..."
if [ -f "/boot/initrd.img-$CURRENT_KERNEL" ]; then
echo " ✓ Current initramfs exists"
else
echo " ✗ Current initramfs MISSING!"
fi
# 4. 检查 GRUB 安装
echo "[4] Checking GRUB installation..."
if [ -d /boot/grub/x86_64-efi ] || [ -d /boot/grub/i386-pc ]; then
MODULE_COUNT=$(ls /boot/grub/x86_64-efi/*.mod 2>/dev/null | wc -l)
echo " ✓ GRUB modules found: $MODULE_COUNT"
else
echo " ✗ GRUB modules directory NOT FOUND!"
fi
# 5. 检查 EFI(UEFI 系统)
echo "[5] Checking EFI..."
if [ -d /sys/firmware/efi ]; then
if [ -f /boot/efi/EFI/debian/grubx64.efi ]; then
echo " ✓ GRUB EFI file exists"
else
echo " ✗ GRUB EFI file MISSING!"
fi
if [ -f /boot/efi/EFI/debian/shimx64.efi ]; then
echo " ✓ Shim EFI file exists (Secure Boot support)"
else
echo " ⚠ Shim not found (Secure Boot may not work)"
fi
fi
# 6. 检查 Secure Boot
echo "[6] Checking Secure Boot..."
if command -v mokutil &>/dev/null; then
SB_STATE=$(mokutil --sb-state 2>/dev/null)
echo " $SB_STATE"
fi
echo ""
echo "=== Health check complete ==="
12.7.2 设置定时检查
# 添加到 cron
$ sudo crontab -e
# 每周一 8:00 AM 检查
0 8 * * 1 /usr/local/bin/check-grub-health.sh | mail -s "GRUB Health Report" [email protected]
12.8 迁移与升级
12.8.1 BIOS 到 UEFI 迁移
# 迁移步骤(需要备份数据!)
# 1. 创建 EFI 分区
$ sudo gdisk /dev/sda
# 删除 MBR 保护分区,创建 GPT
# 创建 EFI 分区(512MB,类型 EF00)
# 2. 格式化 EFI 分区
$ sudo mkfs.vfat -F 32 -n EFI /dev/sda1
# 3. 从 Live 系统安装 GRUB (UEFI)
$ sudo mount /dev/sda2 /mnt
$ sudo mount /dev/sda1 /mnt/boot/efi
$ sudo chroot /mnt
$ grub-install --target=x86_64-efi --efi-directory=/boot/efi
$ update-grub
12.8.2 系统升级时的 GRUB 注意事项
# 大版本升级前
# 1. 备份当前配置
$ sudo /usr/local/bin/backup-grub.sh
# 2. 记录当前可引导的内核
$ ls /boot/vmlinuz-*
# 3. 确保旧内核保留
$ sudo apt-mark hold linux-image-$(uname -r)
# 升级后
# 4. 验证 GRUB 配置
$ sudo update-grub
$ grep menuentry /boot/grub/grub.cfg
# 5. 测试引导
$ sudo reboot
12.9 生产环境部署建议
12.9.1 服务器环境
# 服务器 GRUB 推荐配置
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
GRUB_TIMEOUT=3
GRUB_TIMEOUT_STYLE=menu
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"
GRUB_DISABLE_OS_PROBER=true
12.9.2 桌面环境
# 桌面 GRUB 推荐配置
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=menu
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
GRUB_GFXMODE=1920x1080
GRUB_GFXPAYLOAD_LINUX=keep
GRUB_THEME="/boot/grub/themes/mytheme/theme.txt"
GRUB_DISABLE_OS_PROBER=false
12.9.3 双系统环境
# 双系统 GRUB 推荐配置
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
GRUB_TIMEOUT=10
GRUB_TIMEOUT_STYLE=menu
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_DISABLE_OS_PROBER=false
GRUB_DISABLE_SUBMENU=true
12.10 GRUB 相关工具速查
| 工具 | 用途 | 命令 |
|---|
| grub-install | 安装 GRUB | grub-install /dev/sda |
| update-grub | 生成 grub.cfg | update-grub |
| grub-mkrescue | 创建救援镜像 | grub-mkrescue -o grub-rescue.iso |
| grub-editenv | 编辑环境变量 | grub-editenv list |
| grub-mkimage | 创建 GRUB 镜像 | grub-mkimage -O x86_64-efi ... |
| grub-probe | 探测设备信息 | grub-probe --target=fs /boot |
| efibootmgr | 管理 EFI 启动项 | efibootmgr -v |
| mokutil | 管理 MOK | mokutil --sb-state |
| sbsign | 签名 EFI 程序 | sbsign --key k.key --cert k.der |
| os-prober | 检测其他系统 | sudo os-prober |
12.11 扩展阅读
恭喜! 你已经完成了 GRUB2 完全教程的所有 12 章学习。
回到目录:GRUB2 教程概览
上一章:第 11 章:故障排除