2、目标单元(Target)基础:什么是Target单元,Target与传统运行级别的对应关系

2.1 Target单元的定义与作用

在systemd体系中,Target单元(目标单元)是一种特殊的单元类型,用于将其他单元(如服务单元、套接字单元、挂载单元等)逻辑地分组,形成一个同步点或系统状态快照。Target单元本身不执行任何操作,它只通过依赖关系(Wants、Requires、After、Before)来协调一组单元的启动顺序和并行度。

Target单元的核心作用包括:

  • 状态聚合:将多个服务单元聚合为一个逻辑状态(如“网络就绪”、“图形界面就绪”)。
  • 启动同步:确保在进入某个目标之前,其依赖的所有单元都已成功启动。
  • 系统切换:通过切换默认Target(如从multi-user.target切换到graphical.target),实现运行级别的动态变更。
  • 故障隔离:当某个关键服务启动失败时,Target单元可以阻止系统进入更高层次的状态,从而暴露问题。
关键理解: Target单元类似于“里程碑”或“检查点”。系统启动过程就是从一个Target过渡到下一个Target,直到达到默认的启动目标。每个Target代表系统的一个特定功能层级。

2.2 Target与传统运行级别的对应关系

在SysVinit时代,运行级别(Runlevel)用数字0-6表示系统的不同状态。systemd使用Target单元替代了运行级别,但保留了向后兼容性。下表展示了传统运行级别与systemd Target的精确对应关系:

传统运行级别 SysVinit描述 对应的systemd Target systemd Target描述
0 关机(Halt) poweroff.target 关闭系统并切断电源
1 单用户模式(Single-user) rescue.target 最小化环境,挂载根文件系统,仅启动基本服务,用于维护和修复
2 多用户模式(无网络) multi-user.target 多用户文本模式,启动所有非图形服务,包括网络服务
3 多用户模式(有网络) multi-user.target 与运行级别2相同,systemd将2、3、4统一映射到multi-user.target
4 保留/自定义 multi-user.target 与运行级别2、3相同,通常不单独使用
5 图形界面模式(X11) graphical.target 在multi-user.target基础上启动显示管理器和桌面环境
6 重启(Reboot) reboot.target 重新启动系统
重要差异: SysVinit的运行级别是互斥的(一次只能处于一个级别),而systemd的Target单元可以同时激活多个。例如,graphical.target会通过依赖关系自动激活multi-user.target,形成层级叠加。此外,systemd允许创建自定义Target,灵活性远超传统运行级别。

2.3 Target单元的层级结构与依赖关系

Target单元之间通过依赖关系形成层级结构。系统启动时,systemd按照依赖顺序依次激活各个Target。下图展示了从系统启动到图形界面的典型Target层级:

systemd Target单元层级结构图 systemd Target单元层级结构(从启动到图形界面) local-fs.target sysinit.target basic.target multi-user.target graphical.target sshd.service network.service gdm.service Xorg.service 依赖(Requires) 说明: • 箭头方向表示依赖关系:下层Target是上层Target的前提条件。 • graphical.target 通过 Requires 依赖 multi-user.target,因此启动 graphical.target 会自动激活 multi-user.target。

2.4 默认Target的查看与设置

系统启动时,systemd会读取默认Target(default target),并激活该Target及其所有依赖。默认Target通常是一个符号链接,指向/etc/systemd/system/default.target。

常用命令:

# 查看当前默认Target
systemctl get-default

# 设置默认Target为多用户模式(文本界面)
sudo systemctl set-default multi-user.target

# 设置默认Target为图形界面模式
sudo systemctl set-default graphical.target

# 查看当前系统正在运行的Target(激活状态)
systemctl list-units --type=target --state=active

# 查看所有可用的Target单元
systemctl list-units --type=target --all
故障排查提示: 如果系统启动后无法进入图形界面,首先检查默认Target是否为graphical.target。使用systemctl get-default确认。如果默认Target正确,再检查graphical.target的依赖是否完整:systemctl list-dependencies graphical.target。常见问题包括显示管理器(如gdm、lightdm)服务未启用或启动失败。

2.5 Target单元的配置文件结构

每个Target单元对应一个配置文件,通常位于/usr/lib/systemd/system/(系统默认)或/etc/systemd/system/(用户自定义覆盖)。配置文件以.target为后缀。

示例:graphical.target 配置文件

# /usr/lib/systemd/system/graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
After=multi-user.target
Conflicts=rescue.target
AllowIsolate=yes

关键指令说明:

指令 含义 在Target中的典型用法
Requires= 强依赖:如果依赖单元启动失败,本Target也会失败 graphical.target 依赖 multi-user.target
Wants= 弱依赖:依赖单元启动失败不影响本Target graphical.target 希望启动 display-manager.service
After= 排序约束:本Target在指定单元之后启动 graphical.target 在 multi-user.target 之后启动
Conflicts= 冲突关系:本Target与指定单元不能同时激活 graphical.target 与 rescue.target 冲突
AllowIsolate= 是否允许通过 systemctl isolate 切换到此Target 通常设置为 yes,允许动态切换运行级别

2.6 Target单元在故障排查中的价值

在systemd初始化阶段故障排查中,Target单元是定位问题的关键锚点。以下是基于Target的排查思路:

  1. 确定故障发生的层级:使用 systemctl list-dependencies <target> 查看某个Target的依赖链,找出哪个服务单元启动失败。
  2. 检查Target激活状态:systemctl status <target> 可以查看Target是否成功激活,以及其依赖中是否有失败的服务。
  3. 逐步隔离测试:通过 systemctl isolate rescue.target 进入救援模式,然后逐步切换到 multi-user.target,观察哪个步骤失败。
  4. 分析依赖循环:使用 systemd-analyze verify 检查Target配置中是否存在循环依赖。
实战案例: 某服务器启动后卡在“A start job is running for wait for network to be configured”超时。排查步骤:
1. 运行 systemctl list-dependencies network-online.target 查看依赖。
2. 发现 systemd-networkd-wait-online.service 配置了超时时间过长。
3. 修改该服务的 TimeoutStartSec 参数,或禁用 network-online.target 的等待依赖,问题解决。

2.7 自定义Target的创建方法

在实际运维中,有时需要创建自定义Target来管理一组特定的服务。例如,创建一个 myapp.target 来统一管理某业务应用的所有服务。

创建步骤:

# 1. 创建自定义Target配置文件
sudo vim /etc/systemd/system/myapp.target

# 文件内容:
[Unit]
Description=My Application Target
Requires=myapp-database.service myapp-web.service
After=network.target
AllowIsolate=yes

# 2. 重新加载systemd配置
sudo systemctl daemon-reload

# 3. 启用自定义Target(可选,设置为默认启动目标)
sudo systemctl enable myapp.target

# 4. 手动切换到自定义Target
sudo systemctl isolate myapp.target
最佳实践: 自定义Target应放在 /etc/systemd/system/ 目录下,避免与系统默认Target冲突。命名建议使用 <应用名>.target 格式,便于识别。在Target中尽量使用 Wants= 而非 Requires=,避免因单个服务故障导致整个Target无法激活。