强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

GRUB2 引导管理器完全教程 / 第 12 章:最佳实践

第 12 章:最佳实践

12.1 GRUB 配置管理最佳实践

12.1.1 配置文件管理原则

原则说明
不手动编辑 grub.cfg始终通过 /etc/default/grubupdate-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 + Linuxchainloader
独立引导程序各系统完全独立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安装 GRUBgrub-install /dev/sda
update-grub生成 grub.cfgupdate-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管理 MOKmokutil --sb-state
sbsign签名 EFI 程序sbsign --key k.key --cert k.der
os-prober检测其他系统sudo os-prober

12.11 扩展阅读


恭喜! 你已经完成了 GRUB2 完全教程的所有 12 章学习。

回到目录:GRUB2 教程概览

上一章:第 11 章:故障排除