systemd配置文件及管理方法

systemd 配置路径

systemd 配置文件存在于以下三个文件夹中:          

  • /etc/systemd/system  存放系统启动的默认级别及启动的unit的软连接,优先级最高。
  • /run/systemd/system 系统执行过程中产生的服务脚本,优先级次之。
  • /usr/lib/systemd/system 存放系统上所有的启动文件。优先级最低

 systemd文件分类

systemd的定义文件可以根据其后缀名称识别其定义的类型,可以使用systemctl -t help 查看。

文件后缀名 说明
.service 定义了系统服务的启动
.target 定义了系统启动的级别标签,systemd 没有运行级别的概念,创建标签只是为了兼容老版本。
.socket 定义了进程通信用到的套接字,套接字与进程是分离的
.device 定义了系统启动时内核识别的文件,systemd提供了设备的管理功能,/dev 下的设备由/etc/udev/下的配置文件与.device共同定制
.mount 定义了系统的文件系统的挂载点
.snapshop 系统快照
.swap 用于标识swap设备
.automount 文件系统的自动挂载点
.path 用于定义文件系统中的一个文件或目录使用。常用于文件系统发生变化时,延迟激活服务。
.busname
.snapshot
.timer
.slice
.scope

systemd 文件内容格式

通常由3段组成:分别是unit段,类型段,install段

1
2
3
4
5
6
7
8
9
# Unit段
[Unit]
xxx=

# 类型段
[类型] 如Service、Path等,和unit分类中的后缀名对应

# Install 段
[Install]

Unit 段

[Unit] :不属于第二个标签的定义都放在这里,或存放不属于unit类型的定义,描述信息,依赖的unit

关键字 说明
Description 描述信息
After 表明需要依赖的服务,作用决定启动顺序
Before 表明被依赖的服务
Requles 依赖到的其他unit ,强依赖,即依赖的unit启动失败。该unit不启动。
Wants 依赖到的其他unit,弱依赖,即依赖的unit 启动失败。该unit继续启动
Conflicts 定义冲突关系

[类型] 段:

类型段根据systemd文件分类中定义的服务类型来确定具体的关键字,如.service文件则此段为[Service], .timer文件此段为[Timer] 等

Service段 关键字说明如下

关键字 说明
Type 启动时关系的定义
RemainAfterExit 可设为”yes”或”no”(默认值),表示当该服务的所有进程全部退出之后,是否依然将此服务视为活动(active)状态
PIDFile 守护进程的PID文件,必须是绝对路径。强烈建议在 Type=forking 的情况下明确设置此选项。 systemd 将会在此服务启动后从此文件中读取主守护进程的PID 。systemd 不会写入此文件,但会在此服务停止后删除它(若存在)。
GuessMainPID 可设为”yes”(默认值)或”no”,表示在无法明确定位该服务的主进程的情况下,systemd 是否应该猜测主进程的PID(可能不正确)。 该选项仅在设置了 Type=forking 但未设置 PIDFile= 的情况下有意义。如果PID猜测错误,那么该服务的失败检测与自动重启功能将失效。
EnvironmentFile 需要使用到的变量的定义文件
ExecStart 在启动该服务时需要执行的命令行(命令+参数)。有关命令行的更多细节可参见后文的”命令行”小节。 仅在设置了 Type=oneshot 的情况下,才可以设置任意个命令行(包括零个),否则必须且只能设置一个命令行。 多个命令行既可以在同一个 ExecStart= 中设置,也可以通过设置多个 ExecStart= 来达到相同的效果。 如果设为一个空字符串,那么先前设置的所有命令行都将被清空。 如果不设置任何 ExecStart= 指令,那么必须确保设置了 RemainAfterExit=yes 指令。 命令行必须以一个绝对路径表示的可执行文件开始,并且其后的那些参数将依次作为”argv[1] argv[2] …”传递给被执行的进程。 如果在绝对路径前加上可选的”@”前缀,那么其后的那些参数将依次作为”argv[0] argv[1] argv[2] …”传递给被执行的进程。 如果在绝对路径前加上可选的”-“前缀,那么即使该进程以失败状态(例如非零的返回值或者出现异常)退出,也会被视为成功退出。 可以同时使用”-“与”@”前缀,且顺序任意。 如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。 如果某个无”-“前缀的命令行执行失败,那么剩余的命令行将不会被执行,同时该单元将变为失败(failed)状态。 当未设置 Type=forking 时,这里设置的命令行所启动的进程将被视为该服务的主守护进程。
ExecReload 这是一个可选的指令,用于设置当该服务被要求重新载入配置时所执行的命令行。语法规则与 ExecStart= 完全相同。 另外,还有一个特殊的环境变量 $MAINPID 可以用于表示主进程的PID,例如可以这样使用: /bin/kill -HUP $MAINPID 注意,像上例那样,通过向守护进程发送复位信号,强制其重新加载配置文件,并不是一个好习惯。 因为这是一个异步操作,所以不适用于需要按照特定顺序重新加载配置文件的服务。 我们强烈建议将 ExecReload= 设置为一个能够确保重新加载配置文件的操作同步完成的命令行。
ExecStop 这是一个可选的指令,用于设置当该服务被要求停止时所执行的命令行。语法规则与 ExecStart= 完全相同。 执行完此处设置的命令行之后,该服务所有剩余的进程将会根据 KillMode= 的设置被杀死(参见 systemd.kill(5) 手册)。 如果未设置此选项,那么当此服务被停止时,该服务的所有进程都将会根据 KillMode= 的设置被立即全部杀死。 与 ExecReload= 一样,也有一个特殊的环境变量 $MAINPID 可以用于表示主进程的PID 一般来说,仅仅设置一个结束服务的命令,而不等待其完成,是不够的。 因为当此处设置的命令执行完之后,剩余的进程会被 SIGKILL 信号立即杀死,这可能会导致数据丢失。 因此,这里设置的命令必须是同步操作,而不能是异步操作。
ExecStopPost 这是一个可选的指令,用于设置该服务停止之后所执行的命令行。语法规则与 ExecStart= 完全相同。 无论此服务是正常停止,还是异常退出,此处的设置都适用。 RestartSec= 设定在重启服务(Restart=)前暂停多长时间。默认值是100毫秒(100ms)。 如果未指定时间单位,那么将视为以秒为单位。例如设为”20”等价于设为”20s”。
ExecStartPre、ExecStartPost 设置在执行 ExecStart= 之前/后执行的命令行。语法规则与 ExecStart= 完全相同。 如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。 如果某个无”-“前缀的命令行执行失败,那么剩余的命令行将不会被执行,同时该单元将变为失败(failed)状态。 仅在所有无”-“前缀的 ExecStartPre= 命令全部执行成功的前提下,才会继续执行 ExecStart= 命令。 ExecStartPost= 命令仅在服务已经被成功启动之后才会运行,判断的标准基于 Type= 选项。 具体说来,对于 Type=simple 或 Type=idle 就是主进程已经成功启动;对于 Type=oneshot 来说就是主进程已经成功退出; 对于 Type=forking 来说就是初始进程已经成功退出;对于 Type=notify 来说就是已经发送了”READY=1”; 对于 Type=dbus 来说就是已经取得了 BusName= 中设置的总线名称。 注意,不可将 ExecStartPre= 用于需要长时间执行的进程。 因为所有由 ExecStartPre= 派生的子进程都会在启动 ExecStart= 服务进程之前被杀死。
TimeoutStartSec 设定该服务允许的最大启动时长。如果守护进程未能在限定的时长内发出”启动完毕”的信号,那么该服务将被视为启动失败,并会被关闭。 如果未指定时间单位,那么将视为以秒为单位。例如设为”20”等价于设为”20s”。设为”0”则表示永不超时。 当 Type=oneshot 时,默认值为”0”,否则默认值等于 DefaultTimeoutStartSec= 的值(参见 systemd-system.conf(5) 手册)。
TimeoutStopSec 设定该服务允许的最大停止时长。如果该服务未能在限定的时长内成功停止,那么将会被强制使用 SIGTERM 信号关闭, 如果依然未能在相同的时长内成功停止,那么将会被强制使用 SIGKILL 信号关闭(参见 systemd.kill(5) 手册中的 KillMode= 选项)。 如果未指定时间单位,那么将视为以秒为单位。例如设为”20”等价于设为”20s”。设为”0”则表示永不超时。 默认值等于 DefaultTimeoutStartSec= 的值(参见 systemd-system.conf(5) 手册)。
TimeoutSec 一个同时设置 TimeoutStartSec= 与 TimeoutStopSec= 的快捷方式。
Restart 当服务进程正常退出、异常退出、被杀死、超时的时候,是否重新启动该服务。 “服务进程”是指 ExecStart=, ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost=, ExecReload= 中设置的进程。 当进程是由于 systemd 的正常操作(例如 systemctl stop restart)而被停止时,该服务不会被重新启动。 “超时”可以是看门狗的”keep-alive ping”超时,也可以是 systemct start /reload/stop 操作超时。
该选项可以取下列值之一:no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always “no”(默认值)表示不会被重启。”always”表示会被无条件的重启。 “on-success”表示仅在服务进程正常退出时重启,所谓”正常退出”是指: 退出码为”0”,或者进程收到 SIGHUP, SIGINT, SIGTERM, SIGPIPE 信号并且退出码符合 SuccessExitStatus= 的设置。 “on-failure”表示仅在服务进程异常退出时重启,所谓”异常退出”是指: 退出码不为”0”,或者进程被强制杀死(包括”core dump”以及收到 SIGHUP, SIGINT, SIGTERM, SIGPIPE 之外的其他信号), 或者进程由于看门狗或者 systemd 的操作超时而被杀死。 对于 on-failure, on-abnormal, on-abort, on-watchdog 的分别适用于哪种异常退出,见下表:
注意如下两个例外情况: (1) RestartPreventExitStatus= 中列出的退出码或者信号永远不会导致该服务被重启。 (2) RestartForceExitStatus= 中列出的退出码或者信号将会无条件的导致该服务被重启。 对于需要长期持续运行的守护进程,推荐设为”on-failure”以增强可用性。 对于自身可以自主选择何时退出的服务,推荐设为”on-abnormal”。
RestartSec
BusName 设置与此服务通信所使用的 D-Bus 名称。在 Type=dbus 的情况下必须明确设置此选项。
BusPolicy 如果设置了此项,那么 systemd 将会创建一个自定义的kdbus端点(endpoint),并将其安装为该服务默认的总线节点(bus node)。 这个自定义的端点可以拥有它自己的策略规则。端点的名称就是其所服务的单元的名称。 端点的节点(node)将被绑定挂载到默认的总线节点的位置,这样该服务就只能通过它自己的端点访问总线。 注意,自定义端点的默认策略是’拒绝所有’,因此,你必须在 BusPolicy= 中明确的添加必要的允许策略。 这个选项的值由两部分组成:总线名+访问级别,中间以空格分隔。 访问级别必须是 see, talk, own 之一,并且 talk 隐含了 see ,而 own 隐含了 talk 与 see 。 如果对同一个总线名称多次指定了访问级别,那么将以拥有最大权限的那个为准。 例如: BusPolicy=org.freedesktop.systemd1 talk BusPolicy=org.foo.bar see 该选项仅在内核开启了kdbus(即将并入官方内核)支持的情况下有意义。

Restart设置及对应的退出原因

Restart no always on-success on-failure on-abnormal on-abort on-watchdog
正常退出 × ×
退出码不为0 × ×
进程被强制杀死 × × × ×
systemd操作超时 × × ×
看门狗超时 × × × ×

Type 关键字说明

关键字 说明
simple 表示 ExecStart= 所设定的进程就是该服务的主进程。 如果此进程需要为其他进程提供服务,那么必须在该进程启动之前先建立好通信渠道(例如套接字),以加快后继单元的启动速度
forking 如果设为”forking”,那么表示 ExecStart= 所设定的进程将会在启动过程中使用 fork() 系统调用。这是传统UNIX守护进程的经典做法。 也就是当所有的通信渠道都已建好、启动亦已成功之后,父进程将会退出,而子进程将作为该服务的主进程继续运行。 对于此种进程,建议同时设置 PIDFile= 选项,以帮助 systemd 准确定位该服务的主进程,进而加快后继单元的启动速度。
ontshot “oneshot”(未设置 ExecStart= 时的默认值)与”simple”类似,不同之处在于该进程必须在 systemd 启动后继单元之前退出。 此种类型通常需要设置 RemainAfterExit= 选项
dbus “dbus”(设置了 ExecStart= 与 BusName= 时的默认值)与”simple”类似,不同之处在于该进程需要在 D-Bus 上获得一个由 BusName= 指定的名称。 systemd 将会在启动后继单元之前,首先确保该进程已经成功的获取了指定的 D-Bus 名称。设置为此类型相当于隐含的依赖于 dbus.socket 单元
notify “notify”与”simple”类似,不同之处在于该进程将会在启动完成之后通过 sd_notify(3) 之类的接口发送一个通知消息。 systemd 将会在启动后继单元之前,首先确保该进程已经成功的发送了这个消息。 如果设置为此类型,那么 NotifyAccess= 将只能设置为”all”或者”main”(默认)。 注意,目前 Type=notify 尚不能在 PrivateNetwork=yes 的情况下正常工作。
ldle “idle”与”simple”类似,不同之处在于该进程将会被延迟到所有的操作都完成之后再执行。 这样可以避免控制台上的状态信息与 shell 脚本的输出混杂在一起。

Timer 段关键字说明如下

关键字 说明
aa aa

Mount 段关键字说明如下

关键字 说明
aa aa

[Install] 段:

服务启动或禁用时的一些选项,有以下配置选项

关键字 说明
Alias
RequlredBy 被那些unit所依赖,
WanteBy 被那些unit所依赖

注意:修改了的unit文件 需要重载。systemctl daemon-reload

管理工具systemctl

centos7 的程序管理基本上都是由工具systemctl完成,systemctl的控制命令是固定不变的。systemd 兼容init文件夹下的启动脚本。

systemctl的管理服务通过的service的unit文件实现的。

.service 的配置文件对应的服务提供一下服务命令

命令 说明
systemctl start name.service 启动服务:
systemctl stop name.service 停止服务
systemctl restart name.service 重启服务
systemctl status name.service 查看状态
ystemctl try-restart name.service 条件式重启,即服务之前是启动的则进行重启,如果服务没有启动则不进行操作
systemctl reload-or-restart name.service 重载或重启,首先进行重载,如果重载不成功则进行重启
systemctl reload-or-try-restart name.service 重载或条件式重启:
systemctl unmask name.service 设置服务可以被用户设置开机启动状态
systemctl mask name.service 禁止服务可以被用户设置开机启动状态
systemctl is-active name.service 查看服务的当前激活状态
0 服务已经启动
非0 命令未启动
systemctl disable 服务名称unit 设置服务开机不启动
systemctl is-enabled name.service 查看服务是否开机自启
systemctl list-dependencies name.service 察看服务的依赖关系
systemctl list-depebdencies 察看服务的依赖关系
systemctl daemon-reload 重载服务:
systemctl kill 进程名 杀掉进程:

参考


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!