首页 > 服务器学习 > Linux > systemd中的配置文件
2018
05-28

systemd中的配置文件

每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit 。

Systemd 默认从目录/etc/systemd/system/读取配置文件。里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在那个目录。

设置开机启动systemctl enable命令实际上就是在上面两个目录之间,建立符号链接关系。

也就是说不管是不是开机启动的Unit,配置文件全部要存放在/usr/lib/systemd/system/目录中,开机时Systemd只执行/etc/systemd/system目录里面的配置文件。这也意味着,如果把修改后的配置文件放在该目录,就可以达到覆盖原始配置的效果。当然也可以直接复制一份配置文件到/etc/systemd/system目录而不是建立软连接,也可以达到开机启动的目的。

systemctl enable httpd.service命令等同于

ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'

与之对应的,撤销开机启动命令systemctl disable命令实际上就是在两个目录之间撤销符号链接关系。

配置文件的后缀名,就是该 Unit 的种类,比如sshd.socket。如果省略,Systemd 默认后缀名为.service,所以sshd会被理解成sshd.service。

一、配置文件的自启动状态

列出所有配置文件:systemctl list-unit-files

列出指定类型的配置文件:systemctl list-unit-files --type=service

命令会输出一个列表,显示每个配置文件的启动链接状态,一共有四种。

enabled:已建立启动链接

disabled:没建立启动链接

static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖

masked:该配置文件被禁止建立启动链接

二、配置文件的格式

配置文件就是普通的文本文件,可以用文本编辑器打开,systemctl cat命令可以查看配置文件的内容。如systemctl cat sshd.service

配置文件内容分成几个区块。每个区块的第一行,是用方括号表示的区别名,比如[Unit],每个区块内部是一些等号连接的键值对。注意,配置文件的区块名和字段名,都是大小写敏感的,并且键值对的等号两侧不能有空格。

三、配置文件的区块

[Unit]区块通常是配置文件的第一个区块,用来定义Unit的元数据,以及配置启动顺序与依赖关系。它的主要字段如下。

Description:简短描述

Documentation:文档位置

Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败

Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败

BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行

Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动,只涉及启动顺序不涉及依赖关系

After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动,只涉及启动顺序不涉及依赖关系

Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行

Condition...:当前 Unit 运行必须满足的条件,否则不会运行

Assert...:当前 Unit 运行必须满足的条件,否则会报启动失败

[Service]区块只有 Service 类型的 Unit 才有这个区块,定义如何启动当前服务。它的主要字段如下。

Type:定义启动时的进程行为。它有以下几种值。

Type=simple:默认值,执行ExecStart指定的命令,启动主进程

Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出,子进程将成为主进程

Type=oneshot:一次性进程,类似于simple,但只执行一次,Systemd 会等当前服务退出,再继续往下执行

Type=dbus:当前服务通过D-Bus启动,类似于simple,但会等待 D-Bus 信号后启动

Type=notify:当前服务启动完毕,会发出通知信号通知Systemd,然后 Systemd 再继续启动其他服务

Type=idle:类似于simple,但是要等到其他任务都执行完毕,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合

ExecStart:启动当前服务的命令

ExecStartPre:启动当前服务之前执行的命令

ExecStartPost:启动当前服务之后执行的命令

ExecReload:重启当前服务时执行的命令

ExecStop:停止当前服务时执行的命令

ExecStopPost:停止当其服务之后执行的命令

KillMode:定义如何停止服务。KillMode字段可以设置的值如下control-group(默认值):当前控制组里面的所有子进程,都会被杀掉;process:只杀主进程;mixed:主进程将收到SIGTERM信号,子进程收到SIGKILL信号;none:没有进程会被杀掉,只是执行服务的stop命令。如ssh服务将KillMode设为process,不停止任何sshd子进程,即子进程打开的SSH session仍然保持连接,这个设置不太常见,但对 sshd 很重要,否则你停止服务的时候,会连自己打开的 SSH session一起杀掉。

RestartSec:自动重启当前服务等待的秒数

Restart:定义了当前服务退出后,Systemd的重启方式,可能的值包括no(默认值):退出后不会重启;always:不管是什么退出原因,总是重启;on-success:只有正常退出时(退出状态码为0),才会重启;on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启;on-abnormal:只有被信号终止和超时,才会重启;on-abort:只有在收到没有捕捉到的信号终止时,才会重启;on-watchdog:超时退出,才会重启,如ssh服务设置为on-failure,表示任何意外的失败,就将重启sshd。如果sshd正常停止(比如执行systemctl stop命令),它就不会重启。

RemainAfterExit:值为yes或no,表示进程退出以后,服务仍然保持执行。这样的话,一旦使用systemctl stop命令停止服务,ExecStop指定的命令就会执行

TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数

Environment:指定当前服务的环境变量

EnvironmentFile:指定当前服务的环境参数文件,该文件的key=value键值对,可以用$key的形式,在当前配置文件中获取

所有的启动设置都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行。比如,EnvironmentFile=-/etc/sysconfig/sshd,表示即使/etc/sysconfig/sshd文件不存在,也不会抛出错误。

[Install]通常是配置文件的最后一个区块,定义如何安装这个配置文件,以及开机启动。它的主要字段如下。

WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中

RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中

Alias:当前 Unit 可用于启动的别名

Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

Target 的配置文件

Target也有自己的配置文件,比如:systemctl cat multi-user.target

[Unit]

Description=Multi-User System

Documentation=man:systemd.special(7)

Requires=basic.target

Conflicts=rescue.service rescue.target

After=basic.target rescue.service rescue.target

AllowIsolate=yes

注意,Target 配置文件里面没有启动命令。

上面输出结果中,主要字段含义如下。

Requires字段:要求basic.target一起运行。

Conflicts字段:冲突字段。如果rescue.service或rescue.target正在运行,multi-user.target就不能运行,反之亦然。

After:表示multi-user.target在basic.target 、 rescue.service、 rescue.target之后启动,如果它们有启动的话。

AllowIsolate:允许使用systemctl isolate命令切换到multi-user.target。

最后编辑:
作者:qingheluo
这个作者貌似有点懒,什么都没有留下。