Ubuntu Server 启动流程详解
Ubuntu Server(以 24.04 LTS Noble Numbat 系列及后续版本为主)启动流程是一个高度结构化的多阶段过程,从按下电源键到出现登录提示符(或进入 ssh 可访问状态),涉及固件、引导加载器、内核、初始 RAM 磁盘和用户空间初始化系统。整个流程的核心目标是从硬件初始化 → 加载内核 → 挂载根文件系统 → 启动核心服务 → 达到可操作状态。
Ubuntu Server 自 15.04 起全面采用 systemd 作为 PID 1 初始化系统,取代了传统的 SysV init。以下按时间顺序详细拆解每个阶段的技术原理与关键组件(基于 2024–2026 年主流实现)。
阶段 1:固件初始化(Firmware / BIOS 或 UEFI)
- 触发:按下电源键或远程电源管理(IPMI / Redfish)
- 执行主体:主板固件(UEFI 已成为 2020 年后服务器主流,BIOS 仅在极老旧硬件残留)
- 主要工作:
- Power-On Self-Test (POST):检查 CPU、内存、PCIe 设备、存储控制器等基本硬件完整性
- 初始化最低硬件环境(时钟、内存控制器、基本 I/O)
- 读取 NVRAM / EFI 变量,确定引导顺序(Boot Order)
- 定位 EFI System Partition (ESP,通常 FAT32) 或传统 MBR 中的引导代码
- 输出:加载引导程序(Bootloader)的第一阶段代码
关键变化:现代服务器几乎全部使用 UEFI + Secure Boot(Canonical 官方镜像支持),Secure Boot 会验证引导链签名,防止 rootkit 篡改 bootloader 或内核。
阶段 2:引导加载器(Bootloader) — GRUB2(主流)
Ubuntu Server 默认使用 GRUB2(GRand Unified Bootloader 2)。
- 加载位置:
- UEFI:ESP 分区中的 /EFI/ubuntu/grubx64.efi
- BIOS:MBR + /boot/grub 中的核心映像
- 主要工作:
- 读取 /boot/grub/grub.cfg(由 update-grub 生成)
- 显示引导菜单(默认超时 0–10 秒,Server 常设为 0)
- 用户(或默认)选择内核版本 + initrd
- 加载选中的内核映像(vmlinuz-x.x.x-generic)到内存
- 加载对应的 initrd(initial ramdisk)到内存
- 传递内核命令行参数(cmdline),常见参数包括:
- root=UUID=xxx 或 root=/dev/sda1
- ro(只读挂载根)
- quiet splash(减少内核日志输出)
- 云环境常见:cloud-init=...、ds=nocloud 等
- 执行 boot 指令,将控制权交给内核
2024–2026 趋势:部分实验性安装支持 systemd-boot(更轻量、更快),但 GRUB2 仍是 Ubuntu Server 官方默认和最广泛使用的引导器。
阶段 3:内核启动 + initrd(Initial RAM Filesystem)
- 内核解压并执行:内核映像(vmlinuz)被解压到内存,成为第一个真正运行的代码。
- 早期内核阶段:
- 初始化 CPU、内存管理、IRQ、中断控制器
- 加载内置驱动(内置于内核映像的模块)
- 挂载 initrd(tmpfs 中的压缩 cpio 归档)作为临时的根文件系统
- initrd 的核心作用(这是服务器启动最关键的“桥梁”阶段):
- 包含必要驱动(NVMe、RAID 控制器、LUKS 加密、文件系统如 ext4/xfs/zfs/btrfs)
- 包含 udev(动态设备管理)
- 包含最基础工具(busybox 或自定义 mini-root)
- 执行 /init 脚本(通常是 systemd 或 dracut 生成的脚本)
- 主要任务:
- 探测并加载存储驱动
- 解锁加密磁盘(如果有 passphrase 或 TPM 自动解锁)
- 挂载真正的根文件系统(switch_root)
- 切换控制权到真实根下的 /sbin/init(即 systemd)
典型服务器 initrd 包含:LVM、mdadm(软 RAID)、cryptsetup、virtio 驱动、云元数据挂载支持等。
阶段 4:systemd 初始化(PID 1,用户空间起点)
内核挂载真实根文件系统并执行 /sbin/init(符号链接到 systemd)后,进入用户空间。
- systemd 作为 PID 1:
- 挂载 /sys、/proc、/dev 等伪文件系统
- 应用 sysctl 参数(/etc/sysctl.conf / /etc/sysctl.d/)
- 初始化日志(journald)
- 读取单元文件(/lib/systemd/system/、/etc/systemd/system/)
- 并行启动服务(依赖关系驱动,而非顺序执行)
- 核心目标(targets):
- basic.target → 最基础系统就绪
- multi-user.target → 命令行多用户模式(Server 默认目标)
- cloud-init.target(云镜像常见)→ 等待云初始化完成
- graphical.target(桌面版才有)
- 启动顺序大致(并行执行,依赖决定先后):
- systemd-udev → 设备探测与命名
- systemd-journald → 日志系统
- systemd-networkd 或 NetworkManager → 网络配置(Server 默认 networkd + Netplan)
- cloud-init(云环境)→ 从元数据服务获取 hostname、SSH 密钥、用户数据、运行脚本
- ssh.service → OpenSSH 服务启动
- snapd、docker、nginx 等自定义服务(按依赖)
- systemd 启动特点:
- 并行化 → 开机时间显著缩短
- socket 激活 → 按需启动服务(例如 docker.socket)
- cgroups v2 → 资源隔离与限制
- journal 日志 → 二进制、结构化、可查询
阶段 5:云环境特有 — cloud-init
在 AWS、Azure、GCP、后浪云等公有云的 Ubuntu Server 镜像中,cloud-init 是启动后期关键组件。
- 运行阶段:
- init-local(最早,网络前)
- init(网络可用后)
- config(配置用户、SSH、软件源等)
- final(最后运行用户脚本)
- 数据来源:云厂商元数据服务
- 典型作用:设置主机名、导入 SSH 公钥、扩展磁盘、运行 user-data 脚本
阶段 6:达到登录就绪状态
- multi-user.target 完成
- getty@test.service 启动控制台登录提示
- sshd 监听端口(默认 22)
- 系统进入稳定运行状态,可接受 SSH 登录
总结:启动流程层级一览
- 固件(UEFI/BIOS) → POST + 加载 bootloader
- GRUB2 → 选择内核 + initrd + 传递 cmdline
- 内核 → 解压 + 初始化硬件 + 挂载 initrd
- initrd → 加载驱动 → 挂载真实根 → switch_root
- systemd (PID 1) → 并行启动服务 → 达到 multi-user.target
- cloud-init(云环境) → 个性化配置
- getty / sshd → 登录提示 / 远程访问可用
调试技巧:
- GRUB 菜单按 'e' 编辑内核参数,加 systemd.debug-shell=1 可在启动早期获得 root shell
- 加 rd.break 进入 initrd 调试
- systemd.unit=emergency.target 进入紧急模式
- journalctl -b -1 查看上一次启动日志
理解这个流程后,遇到开机卡住、黑屏、initramfs 掉进 busybox、systemd 依赖死锁等问题时,就能快速定位到具体阶段,极大提升服务器故障诊断效率。
