systemd 服务配置及常用命令
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配置包含三个部分Unit
、Service
、Install
,字段表格中加粗的字段均可以多次出现配置。参考: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进程的主要差别如下。
- 默认的 RunLevel(在
/etc/inittab
文件设置)现在被默认的 Target 取代,位置是/etc/systemd/system/default.target
,通常符号链接到graphical.target
(图形界面)或者multi-user.target
(多用户命令行)。 - 启动脚本的位置,以前是
/etc/init.d
目录,符号链接到不同的RunLevel
目录 (比如/etc/rc3.d
、/etc/rc5.d
等),现在则存放在/lib/systemd/system
和/etc/systemd/system
目录。 - 配置文件的位置,以前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