systemd

Systemd是一个系统管理守护进程、工具和库的集合,用于取代System V初始进程。Systemd的功能是用于集中管理和配置类UNIX系统。

Systemd通常是所有其它守护进程的父进程,systemd对应的进程管理命令是systemctl。Systemd具有以下特点:

  • 启动系统时并行启动
  • 按需激活systemd管理的服务
  • 服务快照
  • 服务依赖定义

Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面。

Systemd 系统相关命令:

命令 作用
systemctl reboot 重启系统
systemctl poweroff 关闭系统
systemctl halt CPU停止工作
systemctl suspend 暂停系统
systemctl hibernate 系统进入交互式休眠状态
systemctl rescue 启动进入救援状态(单用户状态)
systemd-analyze 查看启动耗时
systemd-analyze blame 查看每个服务的启动耗时
systemd-analyze critical-chain 显示瀑布状的启动过程流
systemd-analyze critical-chain atd.service 显示指定服务的启动流
hostnamectl 显示当前主机的信息
localectl set-locale LANG=en_GB.utf8 设置本地化参数。
timedatectl 查看当前时区设置
timedatectl list-timezones 显示所有可用的时区
timedatectl set-timezone America/New_York 设置当前时区
timedatectl set-time YYYY-MM-DD 设置当前日期
timedatectl set-time HH:MM:SS 设置当前时间
loginctl list-sessions 列出当前session
loginctl list-users 列出当前登录用户
loginctl show-user ruanyf 列出显示指定用户的信息

unit

配置文件

Systemd 可以管理所有系统资源。不同的资源统称为 Unit(单位)。

每个unit都有一个配置文件,告诉systemd怎么启动这个服务单元。系统启动时,systemd会读取/etc/systemd/system 下的unit配置,即开机启动,其他配置目录在开启开机启动时,会创建一个符号链接在/etc/systemd/system中。

目录 作用
/etc/systemd/system 开机启动的服务单元配置
/run/systemd/system 运行时的服务单元配置,一般很少修改
/lib/systemd/system 本地的服务单元配置
/usr/lib/systemd/system 第三方软件安装的服务单元配置

单元类型

类型 名称作用
.service 封装守护进程的启动、停止、重启和重载操作,是最常见的一种 unit 类型
.target 用于对 unit 进行逻辑分组,引导其他 unit 的执行
.device 对应/dev目录下设备,主要用于定义设备之间的依赖关系
.mount 定义系统结构层次中的一个挂载点,可以替代过去的 /etc/fstab 配置文件
.automount 用于控制自动挂载文件系统。自动挂载即当某一目录被访问时系统自动挂载该目录,这类unit取代了传统Linux系统的autofs相应功能
.path 用于监控指定目录变化,并触发其他unit运行
.scope 这类 unit 文件不是用户创建的,而是 Systemd 运行时自己产生的,描述一些系统服务的分组信息
.slice 用于描述 cgroup 的一些信息,极少使用到
.snapshot 这种 unit 其实是 systemctl snapshot 命令创建的一个描述 Systemd unit 运行状态的快照
.socket 监控系统或互联网中的 socket 消息,用于实现基于网络数据自动触发服务启动
.swap 定义一个用于做虚拟内存的交换分区
.timer 封装由system的里面由时间触发的动作, 替代了 crontab 的功能

Unit 相关命令:

命令 作用
systemctl list-units 列出正在运行的 Unit
systemctl list-units --all 列出所有Unit,包括没有找到配置文件的或者启动失败的
systemctl list-units --all --state=inactive 列出所有没有运行的 Unit
systemctl list-units --failed 列出所有加载失败的 Unit
systemctl list-units --type=service 列出所有正在运行的、类型为 service 的 Unit
systemctl status 显示系统状态

对于用户来说,最常用的Unit命令是关于service的命令。

命令 作用
sysystemctl status bluetooth.service 显示单个 Unit 的状态
systemctl -H root@rhel7.example.com status httpd.service 显示远程主机的某个 Unit 的状态
systemctl is-active application.service 显示某个 Unit 是否正在运行
systemctl is-failed application.service 显示某个 Unit 是否处于启动失败状态
systemctl is-enabled application.service 显示某个 Unit 服务是否建立了启动链接
systemctl start apache.service 立即启动一个服务
systemctl stop apache.service 立即停止一个服务
systemctl restart apache.service 重启一个服务
systemctl kill apache.service 杀死一个服务的所有子进程
ystemctl reload apache.service 重新加载一个服务的配置文件
systemctl daemon-reload 重载所有修改过的配置文件
systemctl show httpd.service 显示某个 Unit 的所有底层参数
systemctl show -p CPUShares httpd.service 显示某个 Unit 的指定属性的值
systemctl set-property httpd.service CPUShares=500 设置某个 Unit 的指定属性
systemctl list-dependencies nginx.service 列出一个 Unit 的所有依赖
systemctl list-dependencies --all nginx.service 列出一个 Unit 的所有依赖,并展开 Target
systemctl list-unit-files 列出所有配置文件
systemctl list-unit-files --type=service 列出指定类型的配置文件

systemctl enable命令用于在/usr/lib/systemd/system//etc/systemd/system/两个目录之间,建立符号链接关系。

例如:

$ systemctl enable clamd@scan.service
# 等同于
$ ln -s '/usr/lib/systemd/system/clamd@scan.service' '/etc/systemd/system/multi-user.target.wants/clamd@scan.service'

如果配置文件里面设置了开机启动,systemctl enable命令相当于激活开机启动。

与之对应的,systemctl disable命令用于在两个目录之间,撤销符号链接关系,相当于撤销开机启动。

$ systemctl disable clamd@scan.service

systemctl list-unit-files这个命令会输出一个列表。

$ systemctl list-unit-files

UNIT FILE              STATE
chronyd.service        enabled
clamd@.service         static
clamd@scan.service     disabled

这个列表显示每个配置文件的状态,一共有四种。

  • enabled:已建立启动链接
  • disabled:没建立启动链接
  • static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖
  • masked:该配置文件被禁止建立启动链接

service配置

service配置包含三个部分UnitServiceInstall,字段表格中加粗的字段均可以多次出现配置。参考:https://www.freedesktop.org/software/systemd/man/systemd.unit.html

Unit

区块通常是配置文件的第一个区块,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系。它的主要字段如下。

字段 描述
Description 服务描述
Documentation 文档地址
Wants 当前服务需要其他unit配合,若其他unit未启动,不会启动失败
Requires 当前服务依赖的其他unit,依赖的unit停止或重启,当前服务也会停止或重启
Requisite 与Requires类似,若依赖的unit未启动,当前服务会立刻停止
BindsTo 与其他单元绑定,若其他unit停止,当前服务也会停止
PartOf 与Requires类似,若依赖单元重启或停止,当前服务也重启或停止
Upholds 与Wants类似,会持续重启依赖unit
Conflicts 当前服务不能与给定的unit同时运行
Before 当前服务必须在给定的unit之前启动
After 当前服务必须在给定的unit之后启动
Condition* 当前服务必须满足给定条件,否则不运行
Assert* 当前服务必须满足给定条件,否则启动失败

Service

service块配置,记录服务信息,环境变量、启动方式、工作目录等

字段 描述
Type 进程类型(参见下方类型介绍)
ExecStart 启动命令
ExecStartPre 启动前置命令
ExecStartPost 启动后置命令
ExecReload 重启命令
ExecStop 停止命令
ExecStopPost 停止后置命令
RestartSec 自动重启当前服务间隔的秒数
Restart 定义何种情况 Systemd 会自动重启当前服务
TimeoutSec 定义 Systemd 停止当前服务之前等待的秒数
Environment 环境变量
EnvironmentFile 指定加载一个包含服务所需的环境变量列表的文件,文件中的每一行都是一个环境变量的定义
Nice 服务的进程优先级,值越小优先级越高,默认为0。-20为最高优先级,19为最低优先级。
WorkingDirectory 工作目录
RootDirectory 指定服务进程的根目录( / 目录),如果配置了这个参数后,服务将无法访问指定目录以外的任何文件。
User 指定运行服务的用户,会影响服务对本地文件系统的访问权限。
Group 指定运行服务的用户组,会影响服务对本地文件系统的访问权限。
LimitCPU cpu资源限定
LimitSTACK 程序堆栈限定
LimitNOFILE 文件句柄数量限定
LimitNPROC 子进程数量限定

进程类型(Type)可选值

  • simple 即使二进制或者用户不存在启动会返回成功
  • exec 若二进制不存在或用户不存在启动会返回失败
  • forking 将ExecStart作为作为子进程执行,服务启动成功后主进程退出
  • oneshot 在主进程退出后启动服务单元
  • dbus 设置BusName或类型指定,总线释放,服务管理会尝试终止服务
  • notify 类似exec,在服务启动后发送通知消息
  • idle 类似simple,服务程序的实际执行会延迟

服务重启(Restart)可选值

  • no 不重启
  • always 所有异常情况都重启
  • on-success 仅当退出码或者退出信号正常时
  • on-failure 不满足on-success的其他异常情况
  • on-abnormal 非正常的退出信号、服务超时、看门狗超时
  • on-abort 非正常的退出信号
  • on-watchdog 看门狗超时

Install

用来定义如何启动,以及是否开机启动。

字段 描述
Alias 额外别名unit
WantedBy 它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
RequiredBy 它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
Also 当前 Unit 激活(enable)时,会被同时激活的其他 Unit

Target

启动计算机的时候,需要启动大量的 Unit。如果每一次启动,都要一一写明本次启动需要哪些 Unit,显然非常不方便。Systemd 的解决方案就是 Target。

简单说,Target 就是一个 Unit 组,包含许多相关的 Unit 。启动某个 Target 的时候,Systemd 就会启动里面所有的 Unit。从这个意义上说,Target 这个概念类似于"状态点",启动某个 Target 就好比启动到某种状态。

传统的init启动模式里面,有 RunLevel 的概念,跟 Target 的作用很类似。不同的是,RunLevel 是互斥的,不可能多个 RunLevel 同时启动,但是多个 Target 可以同时启动。

命令 作用
systemctl list-unit-files --type=target 查看当前系统的所有 Target
systemctl list-dependencies multi-user.target 查看一个 Target 包含的所有 Unit
systemctl get-default 查看启动时的默认 Target
systemctl set-default multi-user.target 设置启动时的默认 Target
systemctl isolate multi-user.target ystemctl isolate multi-user.target

Target 与 传统 RunLevel 的对应关系如下。

Traditional runlevel New target name Symbolically linked to…
Runlevel 0 runlevel0.target poweroff.target
Runlevel 1 runlevel1.target rescue.target
Runlevel 2 runlevel2.target multi-user.target
Runlevel 3 runlevel3.target multi-user.target
Runlevel 4 runlevel4.target multi-user.target
Runlevel 5 runlevel5.target graphical.target
Runlevel 6 runlevel6.target reboot.target

它与init进程的主要差别如下。

  1. 默认的 RunLevel(在/etc/inittab文件设置)现在被默认的 Target 取代,位置是/etc/systemd/system/default.target,通常符号链接到graphical.target(图形界面)或者multi-user.target(多用户命令行)。
  2. 启动脚本的位置,以前是/etc/init.d目录,符号链接到不同的RunLevel目录 (比如/etc/rc3.d/etc/rc5.d等),现在则存放在/lib/systemd/system/etc/systemd/system目录。
  3. 配置文件的位置,以前init进程的配置文件是/etc/inittab,各种服务的配置文件存放在/etc/sysconfig目录。现在的配置文件主要存放在/lib/systemd目录,在/etc/systemd目录里面的修改可以覆盖原始设置。

日志管理

Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf

journalctl功能强大,用法非常多。

命令 作用
journalctl 查看所有日志(默认情况下 ,只保存本次启动的日志)
journalctl -k 查看内核日志(不显示应用日志)
journalctl -b 或 journalctl -b -0 查看系统本次启动的日志
journalctl -b -1 查看上一次启动的日志(需更改设置)
journalctl --since=“2012-10-30 18:17:16” 查看指定日期的日志
journalctl --since “20 min ago” 查看20分钟前的日志
journalctl --since yesterday 查看昨天前的日志
journalctl --since “2015-01-10” --until “2015-01-11 03:00” 查看指定日期的日志
journalctl --since 09:00 --until “1 hour ago” 查看9点到1小时前的日志
journalctl -n 显示尾部的最新10行日志
journalctl -n 20 显示尾部指定行数的日志
journalctl -f 实时滚动显示最新日志
journalctl /usr/lib/systemd/systemd 查看指定服务的日志
journalctl _PID=1 查看指定进程的日志
journalctl /usr/bin/bash 查看某个路径的脚本的日志
journalctl _UID=33 --since today 查看指定用户的日志
journalctl -u nginx.service 查看某个 Unit 的日志
journalctl -u nginx.service --since today 查看某个 Unit 今天的日志
journalctl -u nginx.service -f 实时滚动显示某个 Unit 的最新日志
journalctl -u nginx.service -u php-fpm.service --since today 合并显示多个 Unit 的日志
journalctl -p err -b 查看指定优先级(及其以上级别)的日志,共有8级
journalctl --no-pager 日志默认分页输出,–no-pager 改为正常的标准输出
journalctl -b -u nginx.service -o json 以 JSON 格式(单行)输出
journalctl -b -u nginx.service -o json-pretty 以 JSON 格式(多行)输出,可读性更好
journalctl --disk-usage 显示日志占据的硬盘空间
journalctl --vacuum-size=1G 指定日志文件占据的最大空间
journalctl --vacuum-time=1years 指定日志文件保存多久

注:journalctl -p err -b查看指定优先级(及其以上级别)的日志,共有8级
0: emerg
1: alert
2: crit
3: err
4: warning
5: notice
6: info
7: debug

参考:https://www.cnblogs.com/zwcry/p/9602756.html
https://www.xiehai.zone/2022-03-20-centos-7-systemd.html