systemd 教程 / Target 与启动流程
Target 与启动流程
一、Target 概念
Target 是 systemd 中用于分组管理 Unit 的一种 Unit 类型,替代传统 System V init 的 runlevel 概念:
- 一个 Target 可以包含多个服务
- 一个服务可以属于多个 Target
- Target 之间可以有依赖关系
- 可以自定义 Target
1.1 Runlevel 到 Target 映射
| SysVinit Runlevel | systemd Target | 说明 |
|---|---|---|
| 0 | poweroff.target | 关机 |
| 1 | rescue.target | 单用户救援模式 |
| 3 | multi-user.target | 多用户命令行 |
| 5 | graphical.target | 图形界面 |
| 6 | reboot.target | 重启 |
💡 提示:Target 不等同于 runlevel。一个服务可以属于多个 Target(通过多个 WantedBy),而 runlevel 限制每个服务只能属于一个级别。
# 查看当前 Target
systemctl get-default
# 输出: graphical.target
# 兼容方式查看 runlevel
runlevel
# 输出: N 5
二、常用 Target
| Target | 说明 |
|---|---|
default.target | 默认启动目标(符号链接) |
multi-user.target | 多用户命令行模式 |
graphical.target | 图形桌面模式 |
rescue.target | 单用户救援模式 |
emergency.target | 紧急模式(最小系统) |
poweroff.target | 关机 |
reboot.target | 重启 |
network.target | 网络可用 |
network-online.target | 网络完全就绪 |
remote-fs.target | 远程文件系统已挂载 |
local-fs.target | 本地文件系统已挂载 |
basic.target | 基础系统就绪 |
sysinit.target | 系统初始化完成 |
2.1 Target 依赖关系
graphical.target
└── multi-user.target
├── basic.target
│ ├── sockets.target
│ ├── timers.target
│ └── paths.target
├── network.target
├── network-online.target
└── remote-fs.target
rescue.target
└── sysinit.target
├── local-fs.target
└── swap.target
# 查看 Target 的依赖树
systemctl list-dependencies graphical.target
# 只显示 service 类型
systemctl list-dependencies graphical.target --type=service
# 反向查看
systemctl list-dependencies multi-user.target --reverse
三、默认 Target 管理
# 查看默认 Target
systemctl get-default
# 设置默认为命令行模式
systemctl set-default multi-user.target
# 设置默认为图形模式
systemctl set-default graphical.target
# 临时切换(不影响默认值)
systemctl isolate graphical.target
# 进入救援模式
systemctl isolate rescue.target
⚠️ 注意:isolate 会停止不在目标 Target 中的所有服务。切换到 rescue.target 会停止大部分服务,远程操作需谨慎。
四、Linux 启动流程
┌─────────┐
│ BIOS/ │ 上电自检
│ UEFI │
└────┬────┘
▼
┌─────────┐
│ GRUB │ 选择内核和 initrd
│引导加载器│
└────┬────┘
▼
┌─────────┐
│ Kernel │ 初始化硬件
└────┬────┘
▼
┌──────────────┐
│ initrd │ 加载驱动,挂载根分区
│ (initramfs) │
└──────┬───────┘
▼
┌──────────────┐
│ systemd │ PID 1,初始化系统
└──────┬───────┘
▼
┌──────────────┐
│ default.target│ 启动所有关联服务
└──────────────┘
4.1 systemd 启动阶段
| 阶段 | Target | 说明 |
|---|---|---|
| 1 | sysinit.target | 加载模块、挂载文件系统 |
| 2 | basic.target | Socket、定时器、路径 |
| 3 | network.target | 网络服务可用 |
| 4 | multi-user.target | 大部分服务启动 |
| 5 | graphical.target | 图形界面(可选) |
4.2 启动分析工具
# 总体启动时间
systemd-analyze
# 输出: Startup finished in 2.345s (kernel) + 5.678s (initrd) + 12.345s (userspace) = 20.368s
# 各服务启动耗时排序
systemd-analyze blame
# 关键路径分析
systemd-analyze critical-chain
# 生成启动图(SVG)
systemd-analyze plot > /tmp/boot.svg
systemd-analyze blame 输出示例:
8.234s NetworkManager-wait-online.service
3.456s dev-sda1.device
2.345s accounts-daemon.service
890ms udisks2.service
345ms ssh.service
234ms nginx.service
五、自定义 Target
5.1 创建自定义 Target
/etc/systemd/system/myapp.target:
[Unit]
Description=My Application Stack
Requires=multi-user.target
After=multi-user.target
AllowIsolate=yes
5.2 将服务关联到自定义 Target
# myapp.service 的 [Install] 段
[Install]
WantedBy=myapp.target
# 启用服务到自定义 Target
systemctl enable myapp.service
# 切换到自定义 Target
systemctl isolate myapp.target
六、服务在 Target 中的依赖
# WantedBy — 启用时在 Target 的 .wants 目录创建符号链接
[Install]
WantedBy=multi-user.target
# RequiredBy — 更强依赖(服务失败则 Target 也失败)
[Install]
RequiredBy=graphical.target
# Also — 启用本服务时同时启用其他服务
[Install]
Also=myapp-log.service
# enable 创建的符号链接
systemctl enable nginx.service
# 创建: /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service
七、rescue.target 与 emergency.target
| 特性 | rescue.target | emergency.target |
|---|---|---|
| 文件系统 | 全部挂载 | 仅根(只读) |
| 网络 | ❌ | ❌ |
| 适用场景 | 服务配置错误、忘记密码 | 根分区损坏、fstab 错误 |
# 进入救援模式
systemctl isolate rescue.target
# 进入紧急模式
systemctl isolate emergency.target
通过 GRUB 进入不同 Target
在 GRUB 菜单按 e 编辑启动项,在 linux 行末尾添加:
systemd.unit=rescue.target # 救援模式
systemd.unit=emergency.target # 紧急模式
systemd.debug-shell=1 # tty9 debug shell
八、GRUB 与 systemd-boot
# 编辑 GRUB 默认内核参数
sudo vim /etc/default/grub
# GRUB_CMDLINE_LINUX_DEFAULT="quiet splash systemd.unit=multi-user.target"
# 应用修改
sudo update-grub
# systemd-boot 状态
bootctl status
九、生产场景
场景 1:服务器启动缓慢排查
# 1. 查看总体启动时间
systemd-analyze
# 2. 找出最慢的服务
systemd-analyze blame | head -10
# 3. 分析关键路径
systemd-analyze critical-chain
# 4. 优化:禁用不需要的服务
systemctl disable bluetooth.service cups.service
systemctl disable NetworkManager-wait-online.service
场景 2:远程服务器忘记 root 密码
1. 重启,在 GRUB 菜单按 'e'
2. 找到 linux 行,将 ro 改为 rw
3. 行末添加: init=/bin/bash
4. Ctrl+X 启动
5. mount -o remount,rw /
6. passwd root
7. sync && exec /sbin/init
场景 3:多环境 Target 管理
#!/bin/bash
# switch-env.sh — 切换应用环境
ENV=$1
case $ENV in
production)
systemctl set-default production.target
echo "已切换到生产环境" ;;
staging)
systemctl set-default staging.target
echo "已切换到预发布环境" ;;
*)
echo "用法: $0 {production|staging}"; exit 1 ;;
esac
echo "重启后生效: systemctl reboot"