面试官问"Linux 启动流程",90% 的初级运维都答不全
一、问题背景
面试官问"Linux 启动流程",能完整答出来的候选人不到 10%。大多数初中级运维停留在"开机 → 加载内核 → init 进程 → 跑服务"这四个关键词上,再往下就被问倒了。
但生产环境遇到的启动问题远比"按一下电源"复杂:
- 机器开机卡在
A start job is running for ...,超时后进 emergency /etc/fstab- default.target 被改,机器卡在 rescue.target
- 服务启动顺序不对,A 服务依赖 B 服务,B 没起就 hang
- 性能问题出在 initramfs 阶段还没到 systemd
- GPU、NVMe、网卡驱动在内核里没加载,根盘都看不到
这些问题不深入启动流程,连日志该看哪个文件都不知道。这一篇把整个启动链路从硬件到 systemd 全打通,再把常见故障的"看哪里 → 改哪里 → 怎么回滚"串成完整闭环。
二、适用场景
- 处理 fstab 错误、UUID 漂移、文件系统损坏
- 救援模式:忘记 root 密码、误删关键库、误改 sudoers
- 系统迁移(BIOS → UEFI,MBR → GPT)
- 性能优化:压缩 initramfs、并行启动、I/O 调度
- 排查 NetworkManager 与传统 network 冲突
三、核心知识点
3.1 启动大阶段
把启动过程拆成 6 个阶段,对应不同的日志、不同的修复手段:
- 硬件自检(POST)
- 引导加载器(Bootloader)
- 内核加载:解压内核,挂载 initramfs,启动 init 进程
- initramfs 初始化:加载磁盘、文件系统、加密、LVM、RAID 模块
- 根文件系统切换
- systemd 启动:执行 default.target,启动所有 unit
3.2 BIOS vs UEFI
- BIOS(Legacy):MBR 分区表,启动慢,2TB 磁盘上限
- UEFI:GPT 分区表,启动快,支持 Secure Boot
- 现代服务器基本都是 UEFI,部分云厂商只支持 UEFI
UEFI 模式下引导文件:
/boot/efi/EFI/centos/shimx64.efi
/boot/efi/EFI/centos/grubx64.efi
/boot/efi/EFI/BOOT/BOOTX64.EFI
3.3 GRUB Legacy vs GRUB2
- GRUB Legacy:老版本,配置文件
/boot/grub/grub.conf - GRUB2:现代版本,配置文件
/boot/grub2/grub.cfg(自动生成,不手工改) - GRUB2 模板:
/etc/default/grub、/etc/grub.d/* - 修改后必须
grub2-mkconfig -o /boot/grub2/grub.cfg(CentOS/RHEL)或 update-grub(Debian/Ubuntu)
3.4 内核与 initramfs
- initramfs:
/boot/initramfs-*.img(RHEL)或 /boot/initrd.img-*(Debian) - initramfs 是一个 cpio 压缩包,内含启动初期所需的所有驱动和工具
- dracut(RHEL 系)vs initramfs-tools(Debian 系):生成 initramfs 的工具
- 命令:
dracut -f、update-initramfs -u
3.5 init 与 systemd
- SysVinit:传统 init,按顺序执行
/etc/rc.d/rc?.d/S??* - systemd:现代 init,按依赖图并行启动 unit
- 配置文件:
/etc/systemd/system/(高优先级)、/usr/lib/systemd/system/(发行版默认) - unit 类型:service、target、mount、socket、timer、path、swap、device
3.6 target 与 runlevel 对应
runlevel 0 → poweroff.target
runlevel 1 → rescue.target
runlevel 2 → multi-user.target(Debian 下含 GUI)
runlevel 3 → multi-user.target
runlevel 5 → graphical.target
runlevel 6 → reboot.target
3.7 启动过程中关键文件
/etc/fstab/etc/crypttab/etc/mdadm.conf/etc/lvm/lvm.conf/etc/default/grub/etc/systemd/system/default.target/etc/systemd/system/*.service
3.8 内核参数
常用:
rhgb quietnomodeset:禁用内核 mode setting(黑屏时排查用)systemd.unit=rescue.targetsystemd.unit=emergency.targetrd.break:在 initramfs 末尾打断,给 shellinit=/bin/bashroot=/dev/sda1ro
四、整体排查或实施思路
启动故障按阶段反向推:
- 机器能否开机自检(屏幕有无输出、IPMI 是否能进)
每个阶段都有"症状 → 文件 → 命令 → 修复"对应关系:
- 卡 GRUB 菜单:检查
/boot/grub2/grub.cfg、EFI 分区 - 卡 initramfs:检查 dracut 配置、磁盘驱动是否在内核
- 卡 fstab:检查
/etc/fstab UUID、设备名 - 卡 systemd:检查
journalctl -xb、systemctl list-units --failed - 卡 service:检查
systemctl status <svc>、journalctl -u <svc>
五、实战步骤
5.1 现象:服务器开机黑屏
按电源后风扇转、硬盘灯闪,但屏幕无显示,IPMI 能进。
5.1.1 初步判断
- 是否有输出到 IPMI console?登录 BMC 看 sol 输出
- 是否键盘灯亮但屏幕黑?说明 POST 过了、显示初始化失败
5.1.2 命令检查
ipmitool -I lanplus -H <bmc_ip> -U admin -P xxx sol activate
预期:能进入 BIOS 或 GRUB 串口输出。
5.1.3 关键指标
5.1.4 根因
常见:
5.1.5 修复
5.1.6 验证
5.2 现象:GRUB 菜单不出现
机器开机直接黑屏或跳到下一个设备。
5.2.1 初步判断
预期输出:能看到 Boot0001* Centos 类似的条目。
5.2.2 检查 EFI 分区
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
mount | grep /boot/efi
判断:/boot/efi 是否存在、UUID 是否变化、EFI 文件是否被删。
5.2.3 重建 GRUB
grub2-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=centos
grub2-mkconfig -o /boot/grub2/grub.cfg
注意:grub2-install 只写 EFI 启动项,不写 grub.cfg。
5.2.4 BIOS 模式修复
MBR 模式:
UEFI 模式:
grub2-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=centos
5.2.5 验证
重启,看 GRUB 菜单是否回来。
5.3 现象:内核加载后卡死
GRUB 选完内核,进入 initramfs 阶段卡住。
5.3.1 去掉 quiet 看输出
编辑 GRUB 内核命令行,去掉 rhgb quiet:
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
改为:
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap"
然后 grub2-mkconfig -o /boot/grub2/grub.cfg。
重启后会看到详细启动日志。
5.3.2 看卡在哪一步
- 卡在
Loading xfs module:根盘是 XFS 但 initramfs 没带 - 卡在
Waiting for device ...:磁盘设备未出现 - 卡在
Starting dracut initqueue hook:驱动没加载完 - 卡在
Starting Plymouth:显示服务问题
5.3.3 修复
更新 initramfs:
dracut -f /boot/initramfs-$(uname -r).img $(uname -r)
强制包含驱动:
dracut --force --add-drivers "nvme ahci megaraid_sas" /boot/initramfs-$(uname -r).img $(uname -r)
5.4 现象:根文件系统挂不上
错误:You are now being dropped into an emergency shell,或 Failed to mount /sysroot。
5.4.1 检查 fstab UUID
预期:能看到每个分区的 UUID 和 FSTYPE。
5.4.2 对比 /etc/fstab
判断:UUID 是否一致、设备名是否存在。
5.4.3 修复
mount -o remount,rw /
vi /etc/fstab
把错误 UUID 改成 blkid 输出的 UUID。
或注释掉暂时不需要的挂载点。
5.4.4 重启验证
systemctl daemon-reload
mount -a
无报错即修复。
5.5 现象:systemd 卡启动
卡在某个 service,A start job is running for ... 倒计时。
5.5.1 看卡哪个 unit
开机时按 e 进入 GRUB 编辑,在内核行加 systemd.log_level=debug systemd.log_target=console。
5.5.2 进入 emergency
GRUB 内核行加 systemd.unit=emergency.target 或 rd.break。
5.5.3 修复
mount -o remount,rw /
systemctl disable <hang_service>
systemctl mask <hang_service>
或编辑 /etc/systemd/system/<svc>.service 把 TimeoutStartSec 调小。
5.5.4 验证
systemctl daemon-reload
systemctl default
5.6 现象:忘记 root 密码
5.6.1 救援模式
GRUB 编辑内核行,加 rd.break。
5.6.2 切根
mount -o remount,rw /sysroot
chroot /sysroot
passwd root
touch /.autorelabel
exit
reboot
5.6.3 SELinux 注意
改了 /etc/shadow 后必须 touch /.autorelabel,否则下次 SELinux 会把 shadow 标错。
5.7 现象:systemd 单元启动失败循环
5.7.1 看失败单元
5.7.2 看日志
journalctl -u <svc> -n 200 --no-pager
5.7.3 看依赖
systemctl list-dependencies <svc>
5.7.4 临时停掉
systemctl stop <svc>
systemctl disable <svc>
排查后修复,再 enable。
5.8 现象:图形界面起不来
5.8.1 切字符界面
systemctl set-default multi-user.target
5.8.2 排查显示管理器
systemctl status gdm
systemctl status sddm
systemctl status lightdm
5.9 现象:内核升级后机器起不来
5.9.1 GRUB 选旧内核
开机时长按 Shift(BIOS)或 Esc(UEFI),选旧内核。
5.9.2 卸载新内核
或:
dnf remove kernel-5.14.0-xxx
5.9.3 重启
5.10 现象:initramfs 缺失
5.10.1 救援模式
用 LiveCD 或 LiveUSB 启动,挂载根分区。
mount /dev/sda2 /mnt
mount /dev/sda1 /mnt/boot
mount /dev/sda3 /mnt/boot/efi
chroot /mnt
dracut -f
exit
reboot
5.10.2 dracut 选项
dracut --kver $(uname -r) --force
判断:dracut 重新生成 initramfs 后重启即可。
六、常用命令
| | |
|---|
systemctl | | status、start、stop、enable、disable、mask |
journalctl | | -b |
dmesg | | -T |
systemd-analyze | | blame |
systemctl list-dependencies | | --before |
systemctl list-unit-files | | --state=enabled |
systemctl get-default | | |
systemctl set-default | | <target> |
grub2-mkconfig | | -o /boot/grub2/grub.cfg |
grub2-install | | --target=x86_64-efi |
efibootmgr | | -v |
dracut | | -f |
update-initramfs | | -u |
lsblk | | -f、-o NAME,SIZE,FSTYPE,UUID |
blkid | | -s UUID |
findmnt | | TARGET |
mount | | -o remount,rw |
ipmitool | | sol activate |
mkinitrd | | |
uname | | -r |
hostnamectl | | status |
localectl | | status |
timedatectl | | status |
6.1 systemctl 完整命令链
systemctl status nginx
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx
systemctl enable nginx
systemctl disable nginx
systemctl mask nginx
systemctl unmask nginx
systemctl is-active nginx
systemctl is-enabled nginx
systemctl is-failed nginx
判断:先 status,再 start;reload 优先于 restart(不停服务);mask 阻止自动和手动启动。
6.2 journalctl 实战命令
journalctl -b
journalctl -b -1
journalctl -u nginx -n 200
journalctl -p err -b
journalctl -f
journalctl --since "1 hour ago"
journalctl --since "2026-06-25 00:00" --until"2026-06-25 23:59"
journalctl -k
journalctl -t audit
6.3 systemd-analyze
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain nginx.service
systemd-analyze plot > /tmp/boot.svg
判断:blame 按启动耗时排序;critical-chain 看关键路径;plot 输出 SVG。
6.4 修改 GRUB
vi /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
注意:grub.cfg 由工具生成,不要手工改。
6.5 dracut 实战
dracut -f
dracut -f --kver 5.14.0-xxx
dracut --print-cmdline
lsinitrd /boot/initramfs.img
lsinitrd -f /boot/initramfs.img | less
6.6 EFI 启动项
efibootmgr -v
efibootmgr -b 0001 -B
efibootmgr -c -d /dev/sda -p 1 -L "CentOS" -l /EFI/centos/shimx64.efi
6.7 systemd unit 文件
systemctl cat nginx.service
systemctl edit nginx.service
systemctl revert nginx.service
判断:edit 会创建 override 文件,比直接改主 unit 干净。
6.8 启动日志抓取
journalctl -b -o short-monotonic --no-pager > /tmp/boot.log
判断:放进 /var/log/ 或上传到日志服务器,作为事后复盘材料。
6.9 看当前默认 target
systemctl get-default
ls -l /etc/systemd/system/default.target
判断:default.target 通常是 multi-user.target 或 graphical.target 的软链。
6.10 查看系统启动时间
systemd-analyze
who -b
last reboot
七、配置示例
7.1 /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
判断:默认 5 秒等待;启用 saved(上次选的内核);recovery 关闭(生产环境)。
7.2 /etc/fstab 标准写法
UUID=xxxxx-xxx-xxx / xfs defaults 0 1
UUID=xxxxx-xxx-xxx /boot ext4 defaults 1 2
UUID=xxxxx-xxx-xxx /boot/efi vfat umask=0077 0 1
UUID=xxxxx-xxx-xxx /data xfs defaults,noatime 0 2
UUID=xxxxx-xxx-xxx swap swap defaults 0 0
判断:用 UUID 而非设备名;dump 通常 0;passno 根分区 1,其他 2,swap 0。
7.3 /etc/crypttab(LUKS 加密)
luks-data /dev/sdb1 /etc/luks-keys/data.key
判断:data.key 文件必须 0400,属主 root。
7.4 /etc/lvm/lvm.conf 关键配置
use_lvmetad = 1
obtain_device_list_from_udev = 1
7.5 /etc/mdadm.conf(软 RAID)
ARRAY /dev/md0 metadata=1.2 UUID=xxx:xxx:xxx
MAILADDR root@localhost
7.6 /etc/systemd/system.conf
[Manager]
DefaultTimeoutStartSec=90s
DefaultTimeoutStopSec=90s
DefaultRestartSec=100ms
判断:默认启动超时 90 秒,避免某个服务卡死导致整体卡启动。
7.7 自定义 service 示例
[Unit]
Description=My Application Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myapp
Restart=on-failure
RestartSec=5
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=/etc/myapp/myapp.env
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
判断:Type=simple 是默认;Restart=on-failure 让异常退出自动重启;WantedBy=multi-user.target 让 enable 时自动加入启动链。
7.8 timer 替代 cron 示例
[Unit]
Description=Daily backup
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
判断:OnCalendar 比 cron 直观;Persistent=true 让错过的时间补跑。
7.9 systemd socket activation 示例
# myapp.socket
[Unit]
Description=My app socket
[Socket]
ListenStream=/run/myapp.sock
SocketUser=myapp
SocketMode=0660
[Install]
WantedBy=sockets.target
判断:socket activation 让服务按需启动,减少常驻进程。
7.10 /etc/systemd/logind.conf
[Login]
HandlePowerKey=poweroff
HandleSuspendKey=suspend
HandleHibernateKey=hibernate
HandleLidSwitch=ignore
判断:笔记本盖子合上不睡眠(外接显示器场景)。
7.11 /etc/systemd/journald.conf
[Journal]
Storage=persistent
SystemMaxUse=2G
SystemKeepFree=200M
MaxRetentionSec=30day
判断:日志持久化、最大 2G、保留 30 天。
7.12 dracut 配置
# /etc/dracut.conf.d/my-drivers.conf
add_drivers+="nvme ahci megaraid_sas mlx5_core"
force_drivers+="dm-multipath"
判断:把生产必须的驱动硬塞进 initramfs,避免重启后磁盘看不见。
7.13 /etc/sysctl.d/ 持久化
# /etc/sysctl.d/99-custom.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 1
fs.file-max = 200000
判断:sysctl 重启后会自动加载。
7.14 内核模块黑名单
# /etc/modprobe.d/blacklist.conf
blacklist nouveau
install nouveau /bin/false
判断:禁用 nouveau 后系统自动加载 nvidia。
7.15 systemd 启动分析脚本
#!/bin/bash
# analyze-boot.sh
echo"=== Boot time ==="
systemd-analyze | head
echo"=== Top 10 slow units ==="
systemd-analyze blame | head -10
echo"=== Failed units ==="
systemctl --failed --no-pager
echo"=== Critical chain ==="
systemd-analyze critical-chain | head -20
echo"=== Last boot logs ==="
journalctl -b -p err --no-pager | head -50
判断:把脚本放进 cron,每周跑一次,长期跟踪启动时间。
八、日志或指标观察方法
8.1 启动日志
journalctl -b
journalctl -b -p err
journalctl -k -b
判断:第一次启动失败后再启动时,会留下两条记录,对比两条差异。
8.2 内核日志
dmesg -T | less
dmesg -T -l err,crit,alert,emerg
判断:内核 panic、I/O error、driver load fail 都在这里。
8.3 启动耗时
预期输出:
Startup finished in 1.234s (kernel) + 5.678s (initrd) + 12.345s (userspace) = 19.257s
判断:userspace 阶段耗时超过 30 秒说明服务启动慢。
8.4 服务启动耗时排行
systemd-analyze blame | head -20
判断:network.service、firewalld.service、NetworkManager-wait-online.service 经常是耗时大头。
8.5 关键路径
systemd-analyze critical-chain network-online.target
判断:能看清"为什么 network-online 起得慢"的依赖图。
8.6 失败 unit
判断:长期保持空列表。出现一个就要查。
8.7 启动事件流
journalctl -b -o short-precise --no-pager | head -200
判断:能看到每条日志的精确时间(毫秒),用于按时间定位卡点。
8.8 EFI 启动日志
journalctl -u systemd-boot
journalctl -u grub2-common
8.9 服务依赖图
systemd-analyze dot | dot -Tsvg > /tmp/dep.svg
判断:SVG 可视化依赖图。
8.10 启动失败的 unit 自动重启次数
systemctl show <svc> | grep NRestarts
判断:Restarts=0 是健康;>0 说明服务一直在跳。
九、排查路径
9.1 “开机卡黑屏”
- 是否键盘亮但屏幕无显示(POST 过了,显卡或显示输出问题)
- 是否卡在 BIOS LOGO(Secure Boot 失败)
9.2 “卡 GRUB 菜单”
- vmlinuz、initramfs 是否在 /boot
9.3 “卡 initramfs”
9.4 “卡 emergency shell”
- 是否 systemd 服务启动失败进入 emergency
9.5 “卡 systemd 启动”
systemctl --failedjournalctl -b -p errsystemd-analyze critical-chain
9.6 “卡图形界面”
systemctl status gdm
9.7 “卡网络启动”
NetworkManager-wait-online.service
9.8 “卡磁盘挂载”
9.9 “卡防火墙”
9.10 “卡 SELinux”
十、风险提醒
- 修改 GRUB 配置后未
grub2-mkconfig:下次开机 GRUB 菜单丢失或参数错误 - 修改
/etc/fstab 写错 UUID:机器起不来 - 修改
/etc/default/grub 加了 init=/bin/bash:内核找不到 /sbin/init - 误删
/boot/vmlinuz-*:机器无法启动 - 误删
/boot/initramfs-*:initramfs 阶段卡死 - 误删
/boot/efi/EFI/*:EFI 启动项丢失 - 修改 SELinux 模式从 enforcing → permissive:导致合规检查失败
- 修改 systemd 默认 target → rescue.target:机器开机进救援
- 修改
/etc/crypttab 后没 dracut -f:重启后找不到加密盘 - 误改
/etc/lvm/lvm.conf:LVM 激活异常 - 修改内核参数
nomodeset 长期保留:性能变差 systemctl mask- Secure Boot 关闭后再开:自签名内核需要重新签名
- 修改
DefaultTimeoutStartSec=0:某个服务卡死直接拖垮启动 - 把 systemd service 改成
Type=oneshot 但没 RemainAfterExit=yes:状态显示 inactive systemctl disable
十一、验证方式
systemd-analyzesystemctl --failedjournalctl -b -p errsystemctl list-unit-files --state=enabledsystemctl is-active <svc>dmesg -T -l err
十二、回滚方案
12.1 GRUB 配置回滚
cp /etc/default/grub.bak /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
12.2 fstab 回滚
cp /etc/fstab.bak /etc/fstab
systemctl daemon-reload
mount -a
12.3 内核回滚
dnf remove kernel-5.14.0-new
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
12.4 initramfs 重建
dracut -f --regenerate-all
12.5 service 回滚
systemctl revert myapp.service
systemctl daemon-reload
systemctl restart myapp
12.6 target 回滚
systemctl set-default graphical.target
reboot
12.7 SELinux 回滚
12.8 EFI 启动项回滚
efibootmgr -b 0001 -B
efibootmgr -c -d /dev/sda -p 1 -L "CentOS" -l /EFI/centos/shimx64.efi
12.9 crypttab 回滚
cp /etc/crypttab.bak /etc/crypttab
dracut -f
12.10 完整启动快照与回滚
cp /etc/default/grub /backup/grub.$(date +%F)
cp /etc/fstab /backup/fstab.$(date +%F)
cp /etc/crypttab /backup/crypttab.$(date +%F)
cp -r /etc/systemd/system /backup/systemd.$(date +%F)
rsync -a /backup/systemd.2026-06-26/ /etc/systemd/system/
systemctl daemon-reload
十三、生产环境注意事项
- 备份:变更前必须备份 /etc/default/grub、/etc/fstab、/etc/crypttab、关键 unit
- 知识:每个工程师必须会进 rescue.target 和 emergency.target
- 自动化:用 Ansible 统一推送 GRUB 和 fstab
- 镜像:装机镜像固化 GRUB、initramfs、fstab 模板
- 性能:userspace 启动 < 30 秒为正常
- DNS:systemd-resolved 与 NetworkManager 冲突要避免
- Network:网络相关 unit 不要过早 enable
- Security:Secure Boot 默认开启,禁用要明确理由
十四、总结
Linux 启动流程看似"按一下电源"那么简单,实际上贯穿 BIOS/UEFI、GRUB、内核、initramfs、systemd 五大阶段,每个阶段都有自己的故障模式。90% 的初级运维答不全,是因为:
真正的内功:
- 能从 BIOS 一直讲到 systemd unit
- 能用 systemd-analyze 分析启动耗时
- 能进 emergency.target 改 fstab
记住一句话:启动故障往往发生在你睡觉的时候,而排查时间是有限的。把每条启动路径练熟,把每次变更留底,把每个 unit 备份到位。
最后给一个口诀:
- 卡网络:NetworkManager-wait-online
十五、进阶:systemd 单元类型深入
15.1 service 类型
- simple:默认,ExecStart 启动后立即认为成功
- forking:ExecStart fork 后父进程退出,子进程是主进程
15.2 mount 类型
systemd 接管 /etc/fstab 后会自动生成 mount unit。可用 systemctl cat tmp.mount 查看。
15.3 socket 类型
socket activation 让 socket 监听先启动,服务按需启动。Redis、sshd 都支持。
15.4 timer 类型
替代 cron。常用:
15.5 path 类型
监控文件/目录变化触发服务。
15.6 swap 类型
管理 swap 空间。
15.7 slice 类型
cgroup 分组。systemd 默认有 user.slice、system.slice、machine.slice。
15.8 scope 类型
外部进程的管理单元,由 systemd-run 创建。
15.9 单元依赖关系
- BindsTo:更强 Requires,目标消失则当前停止
十六、UEFI 与 Secure Boot 实战
16.1 查看 Secure Boot 状态
判断:SecureBoot enabled 表示开启。
16.2 自签名内核模块
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -days 3650 -subj "/CN=MyCompany/"
mokutil --import MOK.crt
16.3 查看 EFI 变量
efivar -l
efivar -p -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-BootCurrent
16.4 切换 BIOS/UEFI 模式
大部分服务器支持切换,但需要:
- UEFI 模式需要 ESP 分区(FAT32,挂到 /boot/efi)
- BIOS 模式需要 MBR + bios_grub 分区
十七、initramfs 详解
17.1 initramfs 的内容
initramfs 包含:
- /lib/modules/$(uname -r) 下的驱动
17.2 看 initramfs 内容
lsinitrd /boot/initramfs-$(uname -r).img
lsinitrd -f /boot/initramfs-$(uname -r).img
17.3 强制加驱动
dracut --force --add-drivers "nvme ahci megaraid_sas" /boot/initramfs-$(uname -r).img $(uname -r)
17.4 强制减驱动
dracut --force --omit-drivers "firewire" /boot/initramfs-$(uname -r).img $(uname -r)
17.5 initramfs 调试
GRUB 内核行加 rd.debug loglevel=7,能看到详细日志。
17.6 切换回传统 initrd
dracut --no-kernel --force
仅在不支持 initramfs 的旧硬件才考虑。
十八、救援模式完整步骤
18.1 LiveUSB 启动
18.2 挂载原系统
mount /dev/sda2 /mnt
mount /dev/sda1 /mnt/boot
mount /dev/sda3 /mnt/boot/efi
mount -o bind /dev /mnt/dev
mount -o bind /proc /mnt/proc
mount -o bind /sys /mnt/sys
chroot /mnt
18.3 修复操作
vi /etc/fstab
dracut -f
grub2-install /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg
passwd root
exit
reboot
18.4 退出救援
umount /mnt/dev /mnt/proc /mnt/sys /mnt/boot/efi /mnt/boot /mnt
reboot
十九、内核参数调优示例
19.1 I/O 优化
GRUB_CMDLINE_LINUX="... elevator=none"
或:
GRUB_CMDLINE_LINUX="... elevator=bfq"
19.2 透明大页
GRUB_CMDLINE_LINUX="... transparent_hugepage=never"
19.3 审计
GRUB_CMDLINE_LINUX="... audit=1"
19.4 启动早期 console
GRUB_CMDLINE_LINUX="... console=ttyS0,115200 console=tty0"
判断:服务器场景用串口方便抓日志。
19.5 crashkernel
GRUB_CMDLINE_LINUX="... crashkernel=auto"
判断:预留 kdump 内存。
二十、性能与监控建议
- 把 systemd-analyze 周期跑,趋势监控启动时间
- 把
systemctl --failed 接入监控 - 把
journalctl -b -p err 接入告警 - 用 Prometheus 抓 node_exporter 的 systemd unit 指标
二十一、常见误区
- “启动慢是磁盘慢”——不一定是,可能是 service 卡 timeout
- “删了 vmlinuz 还能开机”——下次关机就开不了
- “重装系统前一定要备份 /boot”——没错,但 /boot/efi 也要备份
- “systemd 比 SysVinit 快很多”——不一定,看配置
- “disable 一个服务就 OK”——可能还依赖 socket,需要 mask
- “mask 后再 unmask 一定能恢复”——配置可能已经被覆盖
- “dracut -f 就够了”——没指定内核版本可能搞错
- “rd.break 一定能改 root 密码”——如果 fstab 错,先修 fstab
二十二、面试问答清单
面试官常问的:
BIOS 和 UEFI 区别?BIOS 是 Legacy,MBR,2TB 上限;UEFI 是 GPT,支持 Secure Boot。
GRUB Legacy 和 GRUB2 区别?Legacy 是 0.x 系列,配置文件 /boot/grub/grub.conf;GRUB2 是现代版本,/boot/grub2/grub.cfg 由工具生成。
initramfs 是什么?启动初期的 cpio 包,含驱动和工具。
systemd 启动顺序?按依赖图并行启动,可并行启动多个 unit。
如何进救援模式?GRUB 内核行加 systemd.unit=rescue.target 或 rd.break。
如何找回 root 密码?rd.break → 切根 → passwd → autorelabel → 重启。
systemd target 和 runlevel 关系?target 是 unit 概念,runlevel 是 SysVinit 概念,通过符号链接兼容。
fstab 字段含义?设备 挂载点 文件系统 参数 dump passno。
如何修改默认启动 target?systemctl set-default <target>。
systemd-analyze 的关键指标?kernel、initrd、userspace 阶段耗时。
dracut 是什么?生成 initramfs 的工具。
怎么调试启动慢?systemd-analyze blame、critical-chain、plot。
systemd unit 加载顺序?/etc/systemd/system 优先于 /usr/lib/systemd/system,再 /run/systemd/system。
service 和 target 区别?service 是单个服务,target 是 unit 集合,target 不做事只引用其他 unit。
systemd-resolved 有什么用?本地 DNS 缓存与转发,部分发行版默认开启。
把这些问题答全,面试官会知道你不是只听过 systemd 这个词。
二十三、生产启动时间基线示例
下面给一个常见业务服务的启动时间基线:
- initramfs 阶段:2-8 秒(含 dracut 加载驱动、LVM 激活、磁盘挂载)
- systemd 启动 multi-user:5-15 秒
- 关键服务(mysql、redis、nginx、java 应用):合计 10-30 秒
超过 60 秒通常有问题。超过 90 秒建议排查:
- NetworkManager-wait-online 是否卡
二十四、并行启动与依赖优化
24.1 减少 After 链
如果服务 A 不依赖 B,把 A 的 After=B.target 去掉。
24.2 用 socket activation
让服务按需启动而非常驻,减少启动链。
24.3 用 path/socket/dbus 触发
替代 After=network.target 这种粗粒度依赖。
24.4 关闭不必要的 enable
每个 enabled unit 都会拉起一串依赖。定期 systemctl list-unit-files --state=enabled 巡检。
24.5 配置 DefaultDependencies=no
[Unit]
DefaultDependencies=no
After=
Requires=
判断:让某些一次性脚本不参与默认依赖图。
24.6 用 drop-in 覆盖
systemctl edit myapp.service
会创建 /etc/systemd/system/myapp.service.d/override.conf,比改主 unit 干净。
24.7 合并多个 service
如果有 10 个相互依赖的小服务,考虑合并成一个 myapp.service + 内部守护进程。
二十五、systemd 与 cgroup
25.1 cgroup v1 vs v2
- v2:统一 hierarchy,systemd 269+ 默认
25.2 看进程在哪个 slice
systemd-cgls
systemctl status myapp.service
25.3 限制资源
[Service]
MemoryMax=2G
CPUQuota=200%
IOWeight=100
25.4 隔离进程组
systemd-run --unit=batch-job --slice=batch.slice /usr/local/bin/batch.sh
二十六、systemd 与日志
26.1 journald 的存储
- 配置:
/etc/systemd/journald.conf
26.2 rsyslog 转发
# /etc/rsyslog.d/journald.conf
module(load="imjournal")
26.3 日志归档
journalctl --vacuum-size=1G
journalctl --vacuum-time=30days
26.4 实时跟踪启动
二十七、systemd 与网络
27.1 network-online.target 等待
[Unit]
After=network-online.target
Wants=network-online.target
判断:等网络就绪后才启动。
27.2 NetworkManager 与传统 network 冲突
两个同时启用会冲突。建议:
systemctl disable network
systemctl enable NetworkManager
27.3 systemd-networkd
轻量级网络管理,容器场景常用。
27.4 systemd-resolved
DNS 解析,部分发行版默认开启。
二十八、systemd 与安全
28.1 DynamicUser
[Service]
DynamicUser=yes
StateDirectory=myapp
判断:systemd 自动分配 UID,服务停止时清理。
28.2 ProtectSystem
[Service]
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
NoNewPrivileges=yes
判断:让服务看不到 /home、/boot、/usr。
28.3 ReadWritePaths
[Service]
ReadWritePaths=/var/lib/myapp /var/log/myapp
判断:ProtectSystem=strict 后还需要可写的目录。
28.4 SystemCallFilter
[Service]
SystemCallArchitectures=native
SystemCallFilter=@system-service
判断:白名单系统调用,被 systemd 保护。
28.5 CapabilityBoundingSet
[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
判断:只给必要的能力。
二十九、systemd 与容器
29.1 Quadlet
systemd 270+ 支持在 unit 文件里直接写容器定义:
# /etc/containers/systemd/myapp.container
[Unit]
Description=My app container
[Container]
Image=myapp:1.0
Exec=myapp --port 8080
PublishPort=8080:8080
Volume=/var/lib/myapp:/var/lib/myapp
[Install]
WantedBy=multi-user.target
判断:比 docker-compose + systemd unit 更简洁。
29.2 nspawn
systemd-nspawn -D /var/lib/machines/centos9 -b
判断:systemd 原生容器。
29.3 machinectl
machinectl list
machinectl shell myapp
三十、与启动相关的常见面试加分项
- 能讲清楚 dracut 的 hostonly mode 与 full mode 区别
- 能讲清楚 systemd unit 的 4 个目录加载顺序
- 能讲清楚 system.slice / machine.slice 的关系
- 能讲清楚 cgroup v2 与 systemd 的结合
- 能讲清楚 socket activation 的实现
- 能讲清楚 generator 在 systemd 中的角色
三十一、kexec 与快速重启
31.1 什么是 kexec
跳过 BIOS/UEFI 直接加载新内核,从运行中的内核重启。适合:
31.2 安装 kexec-tools
31.3 加载新内核
kexec -l /boot/vmlinuz-$(uname -r) --initrd=/boot/initramfs-$(uname -r).img --command-line="root=UUID=xxx ro"
31.4 触发重启
判断:kexec -e 会直接跳到新内核,不经过 BIOS/UEFI。
31.5 风险
三十二、kdump 与 crash 排查
32.1 kdump 是什么
预留一块内存,在内核崩溃时自动捕获 vmcore,用于事后 crash 分析。
32.2 开启 kdump
systemctl enable kdump
systemctl start kdump
判断:crashkernel=auto 必须在内核命令行。
32.3 看 vmcore
crash /var/crash/<date>/vmcore /usr/lib/debug/lib/modules/$(uname -r)/vmlinux
32.4 常用 crash 命令
判断:crash 是定位内核 panic 的关键工具。
三十三、systemd 故障案例库
33.1 案例:mysql 启动慢
现象:mysql.service 启动 60 秒。
systemd-analyze blame | grep mysql
判断:mysqld 在等磁盘 I/O。
修复:
- 加
After=remote-fs.target 等异步挂载 - 把 mysql.service 的 TimeoutStartSec 调大
33.2 案例:docker 服务起不来
现象:docker.service failed。
journalctl -u docker --no-pager
判断:通常因为 iptables 模块未加载或 storage driver 错。
33.3 案例:kubelet 起不来
现象:kubelet.service 重启循环。
journalctl -u kubelet --no-pager
判断:通常因为 swap 没关、cgroup driver 不匹配。
33.4 案例:firewalld 卡启动
现象:firewalld.service 卡 30 秒。
systemd-analyze blame | grep firewall
判断:通常因为 nftables 模块未加载。
33.5 案例:systemd-journald 满
现象:日志写不进去。
journalctl --vacuum-size=1G
33.6 案例:NetworkManager-wait-online 超时
现象:机器启动卡 5 分钟。
systemctl disable NetworkManager-wait-online.service
或:
systemctl edit NetworkManager-wait-online.service
[Service]
TimeoutStartSec=10s
三十四、init 与 systemd 切换
34.1 查看当前 PID 1
判断:systemd 或 init。
34.2 从 init 切换到 systemd
yum install systemd
systemctl preset-all
reboot
34.3 从 systemd 切换回 init(不推荐)
需要安装 SysVinit 包,并禁用 systemd-sysv:
不推荐生产环境执行。
三十五、systemd 与 sysctl 持久化
35.1 sysctl 命令
sysctl -w net.ipv4.ip_forward=1
判断:临时生效,重启失效。
35.2 持久化
echo"net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-custom.conf
sysctl -p /etc/sysctl.d/99-custom.conf
35.3 看生效情况
sysctl net.ipv4.ip_forward
三十六、systemd 与 tmpfiles
36.1 /usr/lib/tmpfiles.d/ 与 /etc/tmpfiles.d/
systemd-tmpfiles 管理临时文件。
36.2 配置示例
# /etc/tmpfiles.d/myapp.conf
d /run/myapp 0755 myapp myapp -
判断:启动时创建 /run/myapp 目录。
36.3 手动执行
systemd-tmpfiles --create
三十七、systemd 与 logind
37.1 用户会话管理
logind 管理用户登录会话、自动挂起等。
37.2 关闭自动挂起
# /etc/systemd/logind.conf
HandleSuspendKey=ignore
HandleLidSwitch=ignore
37.3 看用户会话
loginctl list-sessions
loginctl session-status <sid>
三十八、systemd 与 timedatectl
38.1 同步时间
timedatectl set-ntp true
timedatectl status
38.2 改时区
timedatectl set-timezone Asia/Shanghai
38.3 改时间
timedatectl set-time "2026-06-26 16:00:00"
判断:启用 NTP 后改时间会被覆盖。
三十九、systemd 与 hostnamectl
hostnamectl set-hostname web01.example.com
hostnamectl status
判断:会同步更新 /etc/hostname。
四十、systemd 与 localectl
localectl set-locale LANG=en_US.UTF-8
localectl set-keymap us
四十一、systemd 与 oomd
systemd 249+ 引入了 oomd,可在系统内存压力下杀进程。
[Slice]
ManagedOOMSwap=kill
ManagedOOMMemoryPressure=auto
四十二、systemd 与 homed
systemd-homed 提供便携用户家目录,类似 macOS 用户。
homectl create alice --disk-size=20G
四十三、本章总结
Linux 启动流程是运维的基本功。能讲清楚从 BIOS 到 systemd 的每一段、能用正确命令排查每种卡启动场景、能进救援模式改任何配置、能优化启动时间、能看懂 systemd 单元之间的依赖——这些是把运维从"装系统 + 启服务"提升到"系统级工程师"的关键。
把这一篇收藏好,遇到启动问题按章节走,比查 Google 比看博客高效得多。
四十四、附录:常用 unit 文件位置速查
- 发行版默认:/usr/lib/systemd/system/
- 系统管理员:/etc/systemd/system/
- 用户:/etc/systemd/system/.service.d/ 或 ~/.config/systemd/user/
- Drop-in 覆盖:/etc/systemd/system/.service.d/override.conf
加载顺序:/etc/systemd/system > /run/systemd/system > /usr/lib/systemd/system。
四十五、附录:常用挂载点与文件
- /var/log/journal:systemd 日志
四十六、附录:紧急救援流程速查
- 机器卡启动 → GRUB 编辑加
rd.break - 进 shell →
mount -o remount,rw /sysroot → chroot /sysroot - 启动到 emergency →
mount -o remount,rw / → 修 /etc/fstab - 启动卡 service →
systemctl --failed → journalctl -u <svc> - 启动慢 →
systemd-analyze blame - 启动卡 initramfs → 改 dracut 配置或加驱动
四十七、写在最后
启动流程看起来"基础",但能真正讲清每一个字节、每一行日志、每一个 unit、每一段依赖的运维,绝对不是初级。把这一篇里的命令和排查步骤多跑几遍,面试和现场都能用上。