强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

systemd 教程 / Target 与启动流程

Target 与启动流程

一、Target 概念

Target 是 systemd 中用于分组管理 Unit 的一种 Unit 类型,替代传统 System V init 的 runlevel 概念:

  • 一个 Target 可以包含多个服务
  • 一个服务可以属于多个 Target
  • Target 之间可以有依赖关系
  • 可以自定义 Target

1.1 Runlevel 到 Target 映射

SysVinit Runlevelsystemd Target说明
0poweroff.target关机
1rescue.target单用户救援模式
3multi-user.target多用户命令行
5graphical.target图形界面
6reboot.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说明
1sysinit.target加载模块、挂载文件系统
2basic.targetSocket、定时器、路径
3network.target网络服务可用
4multi-user.target大部分服务启动
5graphical.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.targetemergency.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"

十、扩展阅读