Ubuntu 系统启动流程与服务管理机制

Ubuntu 系统启动流程与服务管理机制

Ubuntu 自 15.04 起全面转向 systemd 作为 PID 1 的 init 系统(Ubuntu 16.04 LTS 是最后一个还保留部分 Upstart 痕迹的版本),到 2026 年,Ubuntu 24.04 LTS 和即将主流的 26.04 LTS 都完全建立在 systemd 之上。

systemd 不仅仅是一个启动管理器,它是一个系统与服务管理器,负责启动顺序、依赖关系、并行启动、服务监督、重启策略、日志、挂载、网络等待、设备热插拔等几乎所有用户空间初始化与运行时管理任务。

1. 现代 Linux 启动全流程(从按电源键到登录提示)

启动过程可以分为五个主要阶段,每个阶段的职责边界清晰:

阶段执行主体主要职责输出形式 / 可观测点典型耗时占比(SSD + 现代硬件)
1固件(Firmware)POST、自检、硬件初始化、加载 UEFI 变量BIOS/UEFI 界面、蜂鸣声、LED 灯2–10 秒
2引导加载器(Bootloader)选择内核、加载 initramfs、传递内核参数GRUB 菜单(或 systemd-boot)1–5 秒
3内核(Kernel)解压 initramfs、驱动初始化、挂载根文件系统dmesg、黑屏或内核参数 quiet 隐藏3–15 秒
4init 用户空间(PID 1)systemd 初始化、激活 default.targetPlymouth 启动画面 / journalctl -b5–40 秒(最关键可优化部分)
5系统就绪登录提示 / 显示管理器 / getty控制台登录或图形桌面

2. 每个阶段的理论细节与关键机制

阶段 1:固件阶段(BIOS / UEFI)

  • UEFI 模式下:读取 EFI 系统分区(FAT32,通常 /boot/efi),加载 EFI 引导项(efibootmgr 管理)。
  • 寻找 Bootxxxx 变量中优先级最高的 .efi 文件(通常是 grubx64.efi)。
  • 安全启动(Secure Boot)启用时,只允许签名过的引导加载器和内核执行。

阶段 2:引导加载器(GRUB2 为主,少数用 systemd-boot)

  • GRUB 读取 /boot/grub/grub.cfg(由 update-grub 生成)。
  • 加载选中的内核(vmlinuz-x.x.x-generic)和对应的 initramfs(initrd.img)。
  • 传递内核命令行参数(/proc/cmdline):quiet splash、root=UUID=xxx、ro、systemd.unit=xxx 等。
  • Ubuntu Server 默认不显示 GRUB 菜单(GRUB_TIMEOUT=0),除非按 Shift 或 Esc。

阶段 3:内核初始化(Kernel + initramfs)

  • 内核解压 initramfs(微型根文件系统,包含必要模块、udev、busybox 等)。
  • initramfs 中的 /init 脚本(通常是 systemd 的早期版本或 dracut 生成的脚本)负责:
    • 加载模块(modprobe)
    • 激活 LVM / RAID / 加密(cryptsetup)
    • 挂载真实根文件系统(switch_root)
  • 内核参数 root= 指定真实根设备,rootfstype= 指定文件系统类型。
  • 成功 switch_root 后,内核执行 /sbin/init(符号链接 → /lib/systemd/systemd)。

阶段 4:systemd 初始化(PID 1 的世界)

systemd 作为 PID 1 启动后,立即进入并行依赖激活模式,不再是传统的顺序脚本执行。

核心概念:

  • Unit:systemd 的最小管理单元,共 11 种类型,最常见:
    • .service(服务)
    • .target(同步点 / 状态组)
    • .mount / .automount
    • .socket(socket 激活)
    • .timer(定时任务)
    • .path(路径监控触发)
  • Target:相当于旧 SysV 的 runlevel,但更灵活,是“目标状态”而非级别。
    • basic.target:最基础系统(所有服务 After=basic.target)
    • multi-user.target:无图形多用户模式(Server 默认)
    • graphical.target:带图形界面(桌面默认)
    • default.target:启动时实际激活的目标(通常软链接到 multi-user.target 或 graphical.target)

启动逻辑:

  1. systemd 读取 /etc/systemd/system/default.target(或内核参数 systemd.unit=)
  2. 递归解析依赖(Wants=、Requires=、After=、Before=)
  3. 并行启动所有非阻塞单元(大量服务同时启动)
  4. 等待所有 Required 依赖满足
  5. 达到 default.target → 视为开机完成

关键同步点(target):

  • sysinit.target → 基本系统初始化(fsck、swap、模块加载)
  • local-fs.target → 本地文件系统挂载完成
  • network.target → 网络配置完成(但不保证连通)
  • network-online.target → 网络真正可达(需 wait-online 服务)
  • multi-user.target → 命令行就绪
  • getty.target → 控制台登录提示

3. 服务管理机制的核心理论

systemd 的服务管理远超传统 init 的启动/停止脚本,它引入了现代化的特性:

  • 依赖类型
    • Wants=:弱依赖(失败不影响本单元)
    • Requires=:强依赖(失败则本单元也失败)
    • Requisite=:更严格(依赖已激活,否则本单元不启动)
    • BindsTo=:跟随依赖生死(依赖停止则本单元也停止)
  • 启动顺序
    • After= / Before=:纯顺序关系,不影响激活
    • 推荐使用 After= + Wants= / Requires= 的组合
  • 服务类型(Type=)
    • simple(默认):启动即认为就绪
    • forking:启动后 fork 子进程,父进程退出
    • oneshot:运行一次后结束(脚本常用)
    • notify:服务通过 sd_notify() 通知就绪
    • dbus:等待特定 D-Bus name 出现
  • 重启策略(Restart=)
    • no / on-success / on-failure / on-abnormal / on-watchdog / on-abort / always
  • 资源控制(cgroup v2):
    • CPUQuota=、MemoryMax=、IOWeight=、DeviceAllow= 等
    • ProtectSystem=、PrivateTmp=、NoNewPrivileges= 等安全沙箱
  • 激活方式
    • 传统:开机启动(WantedBy=multi-user.target)
    • socket 激活:有连接到来才启动(极致按需)
    • path 激活:文件/目录变化触发
    • timer 激活:定时 / 周期执行

4. 生产环境中理解与优化的关键点

  • 开机慢最常见元凶:network-online.target 等待不存在的接口、远程挂载超时、Plymouth 等待、phased updates 延迟服务。
  • 诊断启动瓶颈:systemd-analyze blame、systemd-analyze critical-chain、systemd-analyze plot > boot.svg
  • 禁用不必要服务:systemctl mask(而非 disable)防止被依赖拉起。
  • 自定义 target:可创建 mini.target 只启动特定服务,用于容器、嵌入式或快速恢复场景。
  • cgroups v2 + systemd:默认统一层级,资源隔离更精细,OOM killer 更可控。

理解 systemd 的依赖图和服务激活模型后,你就能从“重启后不知道为什么卡住”转变为“精准定位第几秒哪个单元在等什么”。

Telegram