systemd服务配置文件编写(1)

systemd服务配置文件编写(1)

systemd服务配置文件编写(1)

systemd service:简介

Systemd Service是systemd提供的用于管理服务启动、停止和相关操作的功能,它极大的简化了服务管理的配置过程,用户只需要配置几项指令即可。相比于SysV的服务管理脚本,用户不需要去编写服务的启动、停止、重启、状态查看等等一系列复杂且有重复造轮子嫌疑的脚本代码了,相信写过SysV服务管理脚本的人都深有体会。所以,Systemd Service是面向所有用户的,即使对于新手用户来说,配置门槛也非常低。

systemd service是systemd所管理的其中一项内容。实际上,systemd service是Systemd Unit的一种,除了Service,systemd还有其他几种类型的unit,比如socket、slice、scope、target等等。在这里,暂时了解两项内容:

Service类型,定义服务程序的启动、停止、重启等操作和进程相关属性

Target类型,主要目的是对Service(也可以是其它Unit)进行分组、归类,可以包含一个或多个Service Unit(也可以是其它Unit)

此外,Systemd作为管家,还将一些功能集成到了Systemd Service中,个人觉得比较出彩的两个集成功能是:

用户可以直接在Service配置文件中定义CGroup相关指令来对该服务程序做资源限制。在以前,对服务程序做CGroup资源控制的步骤是比较繁琐的

用户可以选择Journal日志而非采用rsyslog,这意味着用户可以不用单独去配置rsyslog,而且可以直接通过systemctl或journalctl命令来查看某服务的日志信息。当然,该功能并不适用于所有情况,比如用户需要管理日志时

Systemd Service还有其它一些特性,比如可以动态修改服务管理配置文件,比如可以并行启动非依赖的服务,从而加速开机过程,等等。例如,使用systemd-analyze blame可分析开机启动各服务占用的时长:

$ systemd-analyze blame

3.557s network.service

1.567s lvm2-pvscan@8:2.service

1.060s lvm2-monitor.service

1.046s dev-mapper-centos\x2droot.device

630ms cgconfig.service

581ms tuned.service

488ms mysqld.service

270ms postfix.service

138ms auditd.service

91ms polkit.service

66ms boot.mount

43ms systemd-logind.service

......

# 从内核启动开始至开机结束所花时间

$ systemd-analyze time

Startup finished in 818ms (kernel) + 2.228s (initrd) + 3.325s (userspace) = 6.372s

multi-user.target reached after 2.214s in userspace

systemd服务配置文件存放路径

如果用户需要,可以将服务配置文件手动存放至用户配置目录/etc/systemd/system下。该目录下的服务配置文件可以是普通.service文件,也可以是链接至/usr/lib/systemd/system目录下服务配置文件的软链接。

例如:

# 位于/usr/lib/systemd/system下的服务配置文件

# 注意带有`@`符号的文件名,它有特殊意义

$ ls -1 /usr/lib/systemd/system/*.service | head

/usr/lib/systemd/system/arp-ethers.service

/usr/lib/systemd/system/auditd.service

/usr/lib/systemd/system/[email protected]

/usr/lib/systemd/system/blk-availability.service

/usr/lib/systemd/system/brandbot.service

/usr/lib/systemd/system/cgconfig.service

/usr/lib/systemd/system/cgred.service

/usr/lib/systemd/system/console-getty.service

/usr/lib/systemd/system/console-shell.service

/usr/lib/systemd/system/[email protected]

# 下面这些目录(*.target.wants)定义各种类型下需要运行的服务

# 如:

# sysinit.target.wants目录下的是系统初始化过程运行的服务

# getty.target.wants目录下的是开机后启动虚拟终端时运行的服务

# multi-user.target.wants目录下的是多用户模式(对应运行级别2、3、4)下运行的服务

$ ls -1dF /etc/systemd/system/*

/etc/systemd/system/basic.target.wants/

/etc/systemd/system/default.target

/etc/systemd/system/default.target.wants/

/etc/systemd/system/getty.target.wants/

/etc/systemd/system/local-fs.target.wants/

/etc/systemd/system/multi-user.target.wants/

/etc/systemd/system/nginx.service.d/

/etc/systemd/system/sockets.target.wants/

/etc/systemd/system/sysinit.target.wants/

/etc/systemd/system/system-update.target.wants/

# /etc/systemd/system/multi-user.target.wants下的服务配置文件,几乎都是软链接

$ ls -l /etc/systemd/system/multi-user.target.wants/ | awk '{print $9,$10,$11}'

auditd.service -> /usr/lib/systemd/system/auditd.service

crond.service -> /usr/lib/systemd/system/crond.service

irqbalance.service -> /usr/lib/systemd/system/irqbalance.service

mysqld.service -> /usr/lib/systemd/system/mysqld.service

postfix.service -> /usr/lib/systemd/system/postfix.service

remote-fs.target -> /usr/lib/systemd/system/remote-fs.target

rhel-configure.service -> /usr/lib/systemd/system/rhel-configure.service

rsyslog.service -> /usr/lib/systemd/system/rsyslog.service

sshd.service -> /usr/lib/systemd/system/sshd.service

tuned.service -> /usr/lib/systemd/system/tuned.service

systemd service文件格式说明

一个Systemd Service的服务配置文件大概长这样:

[Unit]

Description = some descriptions

Documentation = man:xxx(8) man:xxx_config(5)

Requires = xxx1.target xxx2.target

After = yyy1.target yyy2.target

[Service]

Type =

ExecStart =

ExecStop =

ExecReload =

Restart =

RestartSec =

[Install]

WantedBy = xxx.target yy.target

一个.Service配置文件分为三部分:

Unit:定义该服务作为Unit角色时相关的属性

Service:定义本服务相关的属性

Install:定义本服务在设置服务开机自启动时相关的属性。换句话说,只有在创建/移除服务配置文件的软链接时,Install段才会派上用场。这一配置段不是必须的,当未配置[Install]时,设置开机自启动或禁止开机自启动的操作将无任何效果

[Unit]和[Install]段的配置指令都来自于man systemd.unit,这些指令都用于描述作为Unit时的属性,[Service]段则专属于.Service服务配置文件。

这里先介绍一些常见的[Unit]和[Install]相关的指令(虽然支持的配置指令很多,但只需熟悉几个即可),之后再专门介绍Service段落的配置指令。

[Unit]段落指令

Unit指令含义

DescriptionUnit的描述信息

Documentation本Unit的man文档路径

After本服务在哪些服务启动之后启动,仅定义启动顺序,不定义服务依赖关系,即使要求先启动的服务启动失败,本服务也依然会启动

Before本服务在哪些服务启动之前启动,仅定义启动顺序,不定义服务依赖关系。通常用于定义在关机前要关闭的服务,如Before=shutdown.target

Wants本服务在哪些服务启动之后启动,定义服务依赖关系,不定义服务启动顺序。启动本服务时,如果被依赖服务未启动,则也会启动被依赖服务。如果被依赖服务启动失败,本服务不会受之影响,因此本服务会继续启动。如果未结合After使用,则本服务和被依赖服务同时启动。当配置在[Install]段落中时,systemctl enable操作将会将本服务安装到对应的.wants目录下(在该目录下创建一个软链接),在开机自启动时,.wants目录中的服务会被隐式添加至目标Unit的Wants指令后。

Requires本服务在哪些服务启动之后启动,定义服务强依赖关系,不定义服务启动顺序。启动本服务时,如果被依赖服务未启动,则也会启动被依赖服务。如果结合了After,当存在非active状态的被依赖服务时,本服务不会启动。且当被依赖服务被手动停止时,本服务也会被停止,但有例外。如果要保证两服务之间状态必须一致,使用BindsTo指令。当配置在[Install]段落中时,systemctl enable操作将会将本服务安装到对应的.requires目录下(在该目录下创建一个软链接),在开机自启动时,.requires目录中的服务会被隐式添加至目标Unit的Requires指令后。

Requisite本服务在哪些服务启动之后启动,定义服务依赖关系,不定义服务启动顺序。启动本服务时,如果被依赖服务处于尚未启动状态,则不会主动去启动这些服务,所以本服务直接启动失败。该指令一般结合After一起使用,以便保证启动顺序。

BindsTo绑定两个服务,两服务的状态保证一致。如服务1为active,则本服务也一定为active。

PartOf本服务是其它服务的一部分,定义了单向的依赖关系,且只对stop和restart操作有效。当被依赖服务执行stop或restart操作时,本服务也会执行操作,但本服务执行这些操作,不会影响被依赖服务。一般用于组合target使用,比如a.service和b.service都配置PartOf=c.target,那么stop c的时候,也会同时stop a和b。

Conflicts定义冲突的服务,本服务和被冲突服务的状态必须相反。当本服务要启动时,将会停止目标服务,当启动目标服务时,将会停止本服务。启动和停止的操作同时进行,所以,如果想要让本服务在目标服务启动之前就已经处于停止状态,则必须定义After/Before。

OnFailure当本服务处于failed时,将启动目标服务。如果本服务配置了Restart重启指令,则在耗尽重启次数之后,本服务才会进入failed。有时候这是非常有用的,一个典型用法是本服务失败时调用定义了邮件发送功能的service来发送邮件,特别地,可以结合systemd.timer定时任务实现cron的MAILTO功能。

RefuseManualStart, RefuseManualStop本服务不允许手动启动和手动停止,只能被依赖时的启动和停止,如果手动启动或停止,则会报错。有些特殊的服务非常关键,或者某服务作为一个大服务的一部分,为了保证安全,都可以使用该特性。例如,系统审计服务auditd.service中配置了不允许手动停止指令RefuseManualStop,network.target中配置了不允许手动启动指令RefuseManualStart。

AllowIsolated允许使用systemctl isolate切换到本服务,只配置在target中。一般来说,用户服务是绝不可能用到这一项的。

ConditionPathExists, AssertPathExists要求给定的绝对路径文件已经存在,否则不做任何事(condition)或进入failed状态(assert),可在路径前使用!表示条件取反,即不存在时才启动服务。

ConditionPathIsDirectory, AssertPathIsDirectory如上,路径存在且是目录时启动。

ConditionPathIsReadWrite, AssertPathIsReadWrite如上,路径存在且可读可写时启动。

ConditionDirectoryNotEmpty, AssertDirectoryNotEmpty如上,路径存在且是非空目录时启动。

ConditionFileNotEmpty, AssertFileNotEmpty如上,路径存在且是非空文件时启动。

ConditionFileIsExecutable, AssertFileIsExecutable如上,路径存在且是可执行普通文件时启动。

对于自定义的服务配置文件来说,需要定义的常见指令包括Description、After、Wants及可能需要的条件判断类指令。所以,Unit段落是非常简单的。

[Install]段落指令

下面是[Install]段落相关的指令,它们只在systemctl enable/disable操作时有效。如果期望服务开机自启动,一般只配置一个WantedBy指令,如果不期望服务开机自启动,则Install段落通常省略。

Install指令含义

WantedBy本服务设置开机自启动时,在被依赖目标的.wants目录下创建本服务的软链接。例如WantedBy = multi-user.target时,将在/etc/systemd/multi-user.target.wants目录下创建本服务的软链接。

RequiredBy类似WantedBy,但是是在.requires目录下创建软链接。

Alias指定创建软链接时链接至本服务配置文件的别名文件。例如reboot.target中配置了Alias=ctrl-alt-del.target,当执行enable时,将创建/etc/systemd/system/ctrl-alt-del.service软链接并指向reboot.target。

DefaultInstance当是一个模板服务配置文件时(即文件名为[email protected]),该指令指定该模板的默认实例。例如[email protected]中配置了DefaultInstall=server时,systemctl enable [email protected]时将创建名为[email protected]的软链接。

例如,下面是sshd的服务配置文件/usr/lib/systemd/system/sshd.service,只看Unit段落和Install段落,是否很简单?

再来一个auditd.service的配置文件示例:

$ cat /usr/lib/systemd/system/auditd.service

[Unit]

Description=Security Auditing Service

DefaultDependencies=no

After=local-fs.target systemd-tmpfiles-setup.service

Before=sysinit.target shutdown.target # 关机前先停止服务

Conflicts=shutdown.target # 确保关机时,auditd已停止成功

RefuseManualStop=yes # 禁止手动systemctl stop auditd操作

ConditionKernelCommandLine=!audit=0

Documentation=man:auditd(8)

[Service]

......

[Install]

WantedBy=multi-user.target

[Service]段配置

Systemd Service配置文件中的[Service]段落可配置的指令很多,可配置在此段落中的指令来源有多处,包括:

例如,/usr/lib/systemd/system/rsyslog.service文件的内容:

[Service]

EnvironmentFile=-/etc/sysconfig/rsyslog # 来自systemd.exec

UMask=0066 # 来自systemd.exec

StandardOutput=null # 来自systemd.exec

Type=notify # 来自systemd.service

ExecStart=/usr/sbin/rsyslogd -n $SYSLOGD_OPTIONS # 来自systemd.service

Restart=on-failure # 来自systemd.service

再比如,想要限制一个服务最多允许使用300M内存(比如512M的vps主机运行一个比较耗内存的博客系统时,可设置内存使用限制),最多30%CPU时间:

[Service]

MemoryLimit=300M

CPUQuota=30%

ExecStart=xxx

此外还需要了解systemd的一项功能,systemctl set-property,它可以在线修改已启动服务的属性。例如

# 直接限制,且写入配置文件,所以下次启动服务也会被限制

systemctl set-property nginx MemoryLimit=100M

# 直接限制,不写入配置文件,所以下次启动服务不会被限制

systemctl set-property nginx MemoryLimit=100M --runtime

目前来说,可以不用过多关注来自其它位置的指令,应该给予重点关注的是来自systemd.service自身的指令,比如:

Type:指定服务的管理类型

ExecStart:指定启动服务时执行的命令行

ExecStop:指定停止服务时运行的命令

ExecReload:指定重载服务进程时运行的命令

Restart:指定systemd是否要自动重启服务进程以及什么情况下重启

特别是Type指令,它直接影响[Service]段中的多项配置方式。

下面将从Type指令开始引入Service段的配置方式。

根据man systemd.service,Type指令支持多种值:

simple

exec

forking

oneshot

dbus

notify

idle

如果配置的是服务进程,Type的值很可能是forking或simple,如果是普通命令的进程,Type的值可能是simple、oneshot。而dbus类型一般情况下用不上,notify要求服务程序中使用代码对systemd notify进行支持,所以多数情况下可能也用不上。

关于Type,内容较长,见下一篇文章systemd service之:服务配置文件编写(2)。

相关推荐

零基础学英语:快速入门高效提升攻略
www.365bet.com亚洲版

零基础学英语:快速入门高效提升攻略

📅 11-22 ⭐ 2540
能潜水的蛇鹈,因为与鸬鹚有个不同点,避免了被人类驯养的命运!
断医断药,疫情危机之下的慢病患者将何去何从?
www.365bet.com亚洲版

断医断药,疫情危机之下的慢病患者将何去何从?

📅 09-06 ⭐ 7632
dnf激光卢克 DNF卢克副本光暗卢克怎么打 要注意什么
十万个为什么
365bet中文客服

十万个为什么

📅 07-11 ⭐ 225
三次决赛都浪费单刀 伊瓜因只能怪自己球技不精
office365输入账号

三次决赛都浪费单刀 伊瓜因只能怪自己球技不精

📅 12-23 ⭐ 3997
推荐阅读 ❤️