3. GRUB配置实战:从配置文件到启动优化

GRUB2的配置,说实话,是很多运维同学的痛点。我记得刚入行那会儿,改个启动参数要折腾半天,生怕改错了系统起不来。今天咱们就把这块彻底讲透。

3.1 GRUB2配置文件结构

GRUB2的配置文件体系,说白了就是「模板+生成」的模式。不像老版GRUB直接编辑一个文件,GRUB2分了两层:

  • /etc/default/grub:这是我们的「配置模板」,你在这里写参数
  • /boot/grub/grub.cfg:这是「最终产物」,由模板自动生成
  • /etc/grub.d/:这是「脚本片段目录」,各种模块的配置脚本

为什么会这样设计?你想想看,如果直接编辑grub.cfg,内核升级时配置就丢了。用模板生成的方式,每次升级内核,grub-mkconfig会自动合并你的自定义参数。

核心原则:永远不要直接编辑grub.cfg! 除非你清楚自己在做什么。

3.2 /etc/default/grub 详解

这个文件是咱们配置的主战场。我挑几个最常用的参数讲讲:

参数名 作用 我的建议值
GRUB_TIMEOUT 启动菜单等待秒数 5(生产环境)或 0(快速启动)
GRUB_DEFAULT 默认启动项 0 或 saved
GRUB_CMDLINE_LINUX 内核启动参数 按需配置,见下文
GRUB_GFXMODE 图形模式分辨率 1024x768 或 auto
GRUB_DISABLE_RECOVERY 是否禁用恢复模式 true(生产环境推荐)

举个实际例子,我最近帮一家电商公司优化服务器启动:

# /etc/default/grub 典型配置
GRUB_TIMEOUT=3
GRUB_DEFAULT=saved
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_GFXMODE=1024x768
GRUB_DISABLE_RECOVERY=true
GRUB_SAVEDEFAULT=true

这里有几个坑,我踩过:

  • GRUB_CMDLINE_LINUX 和 GRUB_CMDLINE_LINUX_DEFAULT 的区别:前者对所有启动项生效,后者只对默认项生效。我习惯把通用参数放前者,调试参数放后者。
  • net.ifnames=0 这个参数,如果你用传统网卡命名(eth0),必须加上。我曾经在一台新服务器上忘了加,结果网卡名变成了enp2s0f0,监控脚本全炸了。
  • console=ttyS0 是给串口控制台用的,机房远程管理卡必备。

3.3 grub-mkconfig 命令使用

改完配置文件,下一步就是生成真正的grub.cfg。命令很简单:

# 生成GRUB配置
grub-mkconfig -o /boot/grub/grub.cfg

# 或者简写(某些发行版)
update-grub

嗯,这里要注意:

  1. 必须用root权限执行,不然写不进/boot目录
  2. 执行前最好备份:cp /boot/grub/grub.cfg /boot/grub/grub.cfg.bak
  3. 检查输出日志:看看有没有「Found linux image」之类的提示,确认新内核被识别

我的小技巧: 执行grub-mkconfig后,用 grep menuentry /boot/grub/grub.cfg 快速查看生成的启动项列表,确认你的配置生效了。

3.4 手动编辑grub.cfg的注意事项

虽然我说「永远不要直接编辑」,但有些场景确实需要手动改。比如:

  • 系统已经进不去了,需要用Live CD修复
  • 临时调试,不想影响模板配置
  • 某些特殊参数,模板不支持

如果你非要手动编辑,记住这几条铁律:

手动编辑grub.cfg的避坑指南:

  • 先备份!先备份!先备份! 我曾经手滑删了一行,重启后直接进grub rescue模式,折腾了半小时才修好。
  • 语法检查: 用 grub-script-check /boot/grub/grub.cfg 验证语法
  • 注意缩进: GRUB2的配置文件对缩进敏感,menuentry和}必须对齐
  • 不要改自动生成的部分: 文件开头有注释标记 ### BEGIN /etc/grub.d/ 的区域,改了也会被覆盖
  • 测试后再重启: 如果条件允许,先在测试机上验证

手动编辑的典型场景,比如临时加一个调试内核参数:

# 在grub.cfg中找到对应的menuentry
menuentry 'Ubuntu (调试模式)' --class ubuntu {
    recordfail
    load_video
    gfxmode $linux_gfx_mode
    insmod gzio
    # 手动添加调试参数
    linux /vmlinuz-5.15.0-generic root=/dev/sda1 ro console=tty0 debug ignore_loglevel
    initrd /initrd.img-5.15.0-generic
}

看到没?我在linux行后面加了 debug ignore_loglevel,这样内核启动时会输出详细日志。调试完记得删掉,不然生产环境日志刷屏。

3.5 实战:批量配置启动参数

最后分享一个批量配置的脚本,我在管理100+台服务器时用的:

#!/bin/bash
# 批量配置GRUB启动参数
# 用法:./batch_grub_config.sh server_list.txt

SERVER_LIST=$1
GRUB_CONFIG="/etc/default/grub"

# 要添加的内核参数
KERNEL_PARAMS="console=tty0 console=ttyS0,115200n8 net.ifnames=0"

while read server; do
    echo "配置服务器: $server"
    
    # 通过SSH远程执行
    ssh root@$server "
        # 备份原配置
        cp $GRUB_CONFIG ${GRUB_CONFIG}.bak
        
        # 追加内核参数
        sed -i 's/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"$KERNEL_PARAMS\"/' $GRUB_CONFIG
        
        # 生成新配置
        grub-mkconfig -o /boot/grub/grub.cfg
        
        echo '配置完成'
    "
done < $SERVER_LIST

这个脚本我用了两年,稳定得很。不过要注意:

  • 先在小范围测试,比如先配5台
  • 确保SSH免密登录已经配好
  • 最好配合Ansible或SaltStack使用,更规范

3.6 本章知识体系

下面这张图,是我梳理的GRUB配置核心逻辑:

GRUB2配置核心流程 /etc/default/grub 用户配置模板 /etc/grub.d/ 模块化脚本片段 grub-mkconfig 自动生成命令 读取 合并 /boot/grub/grub.cfg 最终启动配置文件 输出 ⚠ 手动编辑grub.cfg的风险 内核升级后配置丢失 | 语法错误导致无法启动 | 与模板配置冲突 ✅ 最佳实践 修改/etc/default/grub → 执行grub-mkconfig → 验证配置 → 重启测试

这张图把GRUB2的配置流程讲得很清楚:模板层、脚本层、生成命令、最终产物,以及手动编辑的风险。我个人建议,把这图打印出来贴工位上,每次配GRUB时看一眼,能少踩很多坑。

可可精品资料库