Systemd 使用教程(六):使用 systemctl 管理操作系统

本教程将由浅入深的介绍 linux 中 Systemd 的知识和相关使用(同时也方便自己后续查阅)

以下是对 “使用 systemctl 管理操作系统” 内容的完善和补充,包含常见操作场景、命令示例及说明:

六、使用 systemctl 管理操作系统

systemd 是 Linux 系统的系统和服务管理器,systemctl 作为其核心工具,不仅能管理服务(Service),还能实现系统状态查询、电源控制、日志管理、系统快照等高级操作。

6.1 系统操作:关机、重启、休眠与唤醒

# 立即关机(需 root)
systemctl poweroff

# 立即重启(需 root)
systemctl reboot

# 进入睡眠(S3 休眠,内存供电)
systemctl suspend

# 进入休眠(S4 休眠,数据写入硬盘,唤醒速度较慢)
systemctl hibernate

# 混合休眠(同时写入硬盘并保持内存供电,需内核支持)
systemctl hybrid-sleep

以上操作支持定时(某些旧的版本并不支持),例如

# 10 分钟后关机
systemctl poweroff --delay=600

# 2AM 执行重启
systemctl reboot --scheduled="02:00"

6.2 查看和操作当前系统运行目标(Target)

运行目标(Target)介绍

systemd 的 “运行目标” 像是一个系统启动时的 “开机剧本”。导演(systemd)按剧本(运行目标)喊开始,灯光组(网络服务)、道具组(数据库)、演员(图形界面)按顺序上台。

比如 “家庭影院剧本” 会先开投影仪(图形),再启动音响(声音服务);而 “省电剧本” 则只保留台灯(基础服务)。

我们知道 systemd 管理了非常多的功能,运行目标实际上可以定义其中一个功能的子集进行开机启动,并且这些开机启动的功能子集是已经定义好了依赖关系的。

运行目标替代了传统 Linux 系统中 System Vinit 的运行级别(Runlevel)。早期系统通过/etc/inittab定义runlevel 0-6(如 0 关机、3 文本模式、5 图形模式),而 systemd 通过更灵活的.target 文件(如multi-user.target对应传统 runlevel 3,graphical.target对应 runlevel 5)实现相同功能,同时支持更复杂的依赖管理和并行启动。

linux 常用的运行目标有:

  • graphical.target(默认):启动图形界面,依赖 multi-user.target,加载显示管理器(如 GDM/KDM)和桌面环境服务;
  • multi-user.target:多用户文本模式,启动网络、SSH、本地服务(如数据库),无图形界面;
  • rescue.target:救援模式,挂载根目录为读写,启动键盘 / 磁盘 / 基础网络(如 SSH),允许多用户通过命令行修复系统(如修复磁盘坏道);
  • emergency.target:紧急模式,仅激活内核和最小系统,根目录为只读,用于系统无法启动时的底层修复;
  • shutdown.target:关机流程目标,负责终止所有用户进程,最终依赖 poweroff.target 或 halt.target 实现断电

此外,目标之前还可以创建类似于 依赖关系,根据依赖关系可以实现 “套娃式” 启动,例如

graphical.target → multi-user.target → basic.target → sysinit.target

用户还可根据需求自定义运行目标,实现特定场景的服务组合(如嵌入式设备定制启动、服务器专项功能子集等),在这里就不进行展开介绍了。

命令

使用 systemctl 操作运行目标的常用命令如下:

# 显示当前目标(如 graphical.target、multi-user.target)
systemctl get-default
# 设置默认运行目标
systemctl set-default <target>
# 查看所有的运行目标
systemctl list-targets  # 不知道为什么我找了好几个系统这个命令都不成功???
systemctl list-units --all --type=target
# 临时切换运行目标,非破坏性的
systemctl start <target>
# 切换至指定目标,破坏性的(终止所有与目标无关的服务)
systemctl isolate <target>
# 兼容传统运行级别(如 runlevel 3 对应 multi-user.target)
systemctl telinit 3  # 等价于 systemctl isolate multi-user.target

6.3 系统状态查询与分析

systemctl status

输出如下

● xxx
    State: degraded
     Jobs: 0 queued
   Failed: 5 units
    Since: Thu 2025-04-03 02:02:15 UTC; 1 week 4 days ago
   CGroup: /
           ├─user.slice
           │ ├─user-1001.slice
           │ │ ├─session-126.scope
           │ │ │ ├─2529035 sudo su
           │ │ │ ├─2529747 sudo su
           │ │ │ ├─2529748 su
           │ │ │ ├─2529749 bash
           │ │ │ └─2618301 vppctl
           │ │ └─user@1001.service
           ... (更多内容)

输出的字段解释如下:

State

系统运行状态

  • degraded
    • 含义:系统功能部分受损,至少有一个关键单元(如服务、设备)失败,但系统仍可运行。
    • 典型场景:多个非关键服务失败(如用户输出中 5 个服务失败),系统未完全崩溃。
  • running
    • 含义:系统完全正常,所有关键单元处于活动状态(active)。
    • 典型场景:正常运行的服务器,无任何失败单元。
  • rescue
    • 含义:系统进入救援模式,仅启动最低限度服务(如 shell),用于手动修复故障。
    • 典型场景:根文件系统损坏、关键服务启动失败,需通过救援模式修复。
  • emergency
    • 含义:系统进入紧急模式,仅启动内核和基本驱动,几乎无法进行常规操作。
    • 典型场景:内核 panic、严重硬件故障或关键系统文件丢失,需强制恢复。
  • rebooting
    • 含义:系统正在执行重启操作(短暂过渡状态,稳定输出中较少显示)。
    • 典型场景:用户执行 reboot 命令后,系统处于重启过程中。
Jobs

systemd 每次动作都会有相应的 Job,例如当执行 systemctl start httpd.service 时,会生成一个 start 类型的 Job,任务完成后(服务启动成功或失败),该 Job 会被自动清除(任务完成后默认保留 10秒 即自动清除,非永久记录)。

这里整理了 systemctl statusJobs 字段的 6 种典型输出场景:

1. 输出:Jobs: 0 queued

  • 含义:当前无排队或执行中的 systemd 任务,系统处于稳定状态。
  • 排查建议: 无需操作,重点观察 StateFailed 字段确认系统健康(若 Statedegraded,需排查 Failed 单元)。
  • 补充说明: 此状态是系统无活跃任务的标志,但不排除历史故障(需结合 Failed 判断)。

2. 输出:Jobs: 1 running

  • 含义:有一个任务正在执行(如启动/停止服务),可能阻塞或超时。
  • 典型场景
    • 服务启动超时(如 httpd.service 因配置错误卡住,超过默认 90秒 超时阈值)。
    • 系统启动初期,关键服务正在加载(如内核模块、文件系统挂载)。
  • 排查建议
    1. 执行 systemctl list-jobs 查看任务详情(如 JOB 1 httpd.service start running)。
    2. 通过 journalctl -u <单元名> 追踪日志,定位阻塞原因(如依赖缺失、资源不足)。
  • 补充说明
    • 超时阈值可通过修改单元配置调整(如 systemctl edit httpd.service 中添加 TimeoutStartSec=300)。
    • 任务持续超过 10分钟 可能触发 State: degraded,需人工干预。

3. 输出:Jobs: 2 queued

  • 含义:多个任务按依赖顺序排队等待执行(后序任务需前序任务完成)。
  • 典型场景
    • 批量操作服务(如 systemctl restart *.service),任务按依赖关系排序。
    • 依赖链过长(如 A.service 依赖 B.serviceB 未启动导致 A 排队)。
  • 排查建议
    1. systemctl list-jobs --all 查看任务队列顺序(如 JOB 1 B.service start queued → JOB 2 A.service start queued)。
    2. 通过 systemctl show -p After= <单元名> 检查依赖配置(After= 表示该服务在谁之后启动)。
  • 补充说明
    • 排队是 systemd 的正常调度行为,不影响系统性能,无需过度干预。
    • 依赖关系定义在单元文件中(如 /etc/systemd/system/A.service 中的 After=B.service)。

4. 输出:Jobs: 0 queued + State: degraded

  • 含义:任务已执行完毕(成功或失败),但至少有一个单元失败,导致系统功能退化。
  • 典型场景
    • 服务启动失败后,任务自动清除,但失败单元未修复(如 nginx.service 因端口被占用启动失败)。
    • 手动终止任务后,残留的失败单元未恢复(如配置错误未修正)。
  • 排查建议
    1. 执行 systemctl list-failed 列出所有失败单元(如 nginx.service)。
    2. journalctl -u <单元名> -b 查看本次启动日志(-b 表示当前启动会话)。
  • 补充说明
    • Jobs 不记录历史失败,仅 Failed 字段标记异常单元,需优先排查此处。
    • 修复后需重启失败单元(如 systemctl restart nginx.service)或重载配置。

5. 输出:Jobs: 1 running (deadline exceeded)

  • 含义:任务执行时间超过 自定义超时阈值(非默认90秒),进入“超时运行”状态。
  • 典型场景
    • 服务代码存在死循环,无法正常退出(如程序逻辑错误)。
    • 硬件故障导致 I/O 延迟(如磁盘损坏、网络中断)。
  • 排查建议
    1. 尝试优雅终止任务:systemctl kill --signal=SIGINT <单元名>(发送中断信号)。
    2. 若无效,强制终止:systemctl kill --signal=SIGKILL <单元名>,并检查进程状态(ps -ef | grep <单元名>)。
  • 补充说明
    • 该状态需人工干预,不会自动恢复,需修复代码或硬件问题。
    • 可临时延长超时时间(仅推荐测试环境):systemctl edit <单元名> 中添加 TimeoutStartSec=5min

6. 输出:Jobs: 0 queued + State: rebooting

  • 含义:系统正在执行重启操作,任务队列已清空(短暂过渡状态,极少在稳定输出中显示)。
  • 典型场景
    • 用户执行 rebootsystemctl reboot 命令后,系统进入重启流程。
  • 排查建议
    • 无需操作,等待重启完成即可(若需取消,在倒计时内执行 shutdown -c)。
  • 补充说明
    • 重启时 systemd 会强制清空 Jobs,避免未完成任务干扰重启过程。
    • 该状态持续时间极短(通常 <10秒),属正常现象。
Failed

指示了有多少 units 执行失败了,如果需要排查哪些单元失败了,执行如下命令查看失败的单元

systemctl --failed
# 或者
systemctl list-units --all --state=failed

结合 journalctl 命令查看具体失败日志,结合 systemctl cat 命令查看服务配置,综合这些信息来排查服务失败原因(可以将输出给 AI,自己排查太难了)

Since

系统进入当前状态(如 degraded)的时间

CGroup

/ 及其子层级表示 系统进程的资源隔离结构,用于追踪进程归属和资源使用

6.4 查看系统启动耗时分析

通过以下命令可以分析启动耗时,优化系统启动时间

# 总启动时间
systemd-analyze

# 各阶段启动耗时(固件/引导加载器/内核/用户空间)
systemd-analyze blame

# 可视化启动时间分布(需图形界面支持)
systemd-analyze plot > boot-time.svg

6.5 系统快照与紧急模式

systemd 快照主要用于恢复 systemd 管理的状态,而非磁盘快照。

分类回滚范围典型场景
systemd 管理的状态服务、挂载、资源限制等运行时配置服务误停、cgroups 配置混乱
非管理的状态文件内容、用户进程、硬件状态等文件误删、手动进程崩溃

# 创建系统运行时快照(保存当前服务状态)
systemctl snapshot my-snapshot

# 从快照恢复(需在 emergency/rescue 模式下执行)
systemctl revert my-snapshot

在系统运行出现严重异常时,紧急模式(Emergency Mode)是一种极简的故障恢复环境。它仅启动维持基本系统运行的最小服务集合(如必要的内核模块、终端驱动和 shell)

# 进入恢复模式(Rescue Mode,仅启动基本服务,允许 root 登录)
systemctl rescue

# 进入紧急模式(Emergency Mode,仅启动最小必要服务,仅支持 shell)
systemctl emergency

6.6 替代传统 cron:使用 systemd 定时任务

可以通过 systemd.timer 管理定时任务(替代传统 cron)

利用 systemd 创建的定时器,需要两个配置文件,即 xxx.servicexxx.timer,systemd 将自动将二者建立关联关系。

  • xxx.service:用于配置这个定时任务要执行的具体工作,和其他服务定义没有明显差别,类型比较适合 oneshot比较适合,推荐) 或者 simple
  • xxx.timer:定义执行计划

timer 单元配置的要点

  • [Timer] 选项
    • OnCalendar:指定执行计划,例如 Daily 03:00(每天三点) 或者 *-*-* *:00(整点)
    • OnUnitActiveSec:基于上次执行完成时间的相对时间设定执行计划,类似于传统的每隔多少秒(支持秒、分钟、小时、天等时间单位)
    • OnStartupSec:系统启动后多长时间执行(支持秒、分钟、小时、天等时间单位)
    • RandomizedDelaySec:触发时间随机偏移(避免大量任务同时执行)
    • AccuracySec:允许的触发时间误差(减少 CPU 唤醒频率)
    • Persistent:错过触发时是否补执行(例如关机造成错过执行计划),默认情况下 Persistent=no
    • Unit:如果 timer 和 service 的名字不一样,可以通过这个配置显示的指定绑定的服务
  • WantedBy=timers.target

timer 的常见操作(启停、状态查询等)和其他单元的操作类似,这里不做赘述,示例:

# 列出所有定时器
systemctl list-timers

# 启用(开机启动)并启动一个定时器
systemctl enable --now my-cleanup.timer
Calendar 的具体格式

可以通过命令 man systemd.time 查看,我截取了比较有用的一些如下

       The following special expressions may be used as shorthands for longer normalized forms:

               minutely → *-*-* *:*:00
                 hourly → *-*-* *:00:00
                  daily → *-*-* 00:00:00
                monthly → *-*-01 00:00:00
                 weekly → Mon *-*-* 00:00:00
                 yearly → *-01-01 00:00:00
              quarterly → *-01,04,07,10-01 00:00:00
           semiannually → *-01,07-01 00:00:00

       Examples for valid timestamps and their normalized form:

             Sat,Thu,Mon..Wed,Sat..Sun → Mon..Thu,Sat,Sun *-*-* 00:00:00
                 Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00
                               Wed *-1 → Wed *-*-01 00:00:00
                      Wed..Wed,Wed *-1 → Wed *-*-01 00:00:00
                            Wed, 17:48 → Wed *-*-* 17:48:00
           Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
                           *-*-7 0:0:0 → *-*-07 00:00:00
                                 10-15 → *-10-15 00:00:00
                   monday *-12-* 17:00 → Mon *-12-* 17:00:00
             Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45
                  12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00
                       12..14:10,20,30 → *-*-* 12..14:10,20,30:00
             mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45
                        03-05 08:05:40 → *-03-05 08:05:40
                              08:05:40 → *-*-* 08:05:40
                                 05:40 → *-*-* 05:40:00
                Sat,Sun 12-05 08:05:40 → Sat,Sun *-12-05 08:05:40
                      Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40
                      2003-03-05 05:40 → 2003-03-05 05:40:00
            05:40:23.4200004/3.1700005 → *-*-* 05:40:23.420000/3.170001
                        2003-02..04-05 → 2003-02..04-05 00:00:00
                  2003-03-05 05:40 UTC → 2003-03-05 05:40:00 UTC
                            2003-03-05 → 2003-03-05 00:00:00
                                 03-05 → *-03-05 00:00:00
                                hourly → *-*-* *:00:00
                                 daily → *-*-* 00:00:00
                             daily UTC → *-*-* 00:00:00 UTC
                               monthly → *-*-01 00:00:00
                                weekly → Mon *-*-* 00:00:00
               weekly Pacific/Auckland → Mon *-*-* 00:00:00 Pacific/Auckland
                                yearly → *-01-01 00:00:00
                              annually → *-01-01 00:00:00
                                 *:2/3 → *-*-* *:02/3:00

可以通过如下命令,校验一个 Calendar 配置是否合法

systemd-analyze calendar "Daily 03:00"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值