Systemctl unit文件详解

Systemd 简介

Systemd 是一系列工具的集合,其作用也远远不仅是启动操作系统,它还接管了后台服务、结束、状态查询,以及日志归档、设备管理、电源管理、定时任务等许多职责,并支持通过特定事件(如插入特定 USB 设备)和特定端口数据触发的 On-demand(按需)任务。
Systemd 的后台服务还有一个特殊的身份——它是系统中 PID 值为 1 的进程。
Systemctl官方手册:https://www.freedesktop.org/software/systemd/man/systemctl.html#
Systemd官方手册:https://www.freedesktop.org/software/systemd/man/systemd.html#

systemd的优缺点

优点:

 按需启动进程,减少系统资源消耗
Systemd 提供了 服务按需启动 的能力,使得特定的服务只有在真定被请求时才启动。

 并行启动进程,提高系统启动速度
在 SysV-init 时代,将每个服务项目编号依次执行启动脚本。Ubuntu 的 Upstart 解决了没有直接依赖的启动之间的并行启动。而 Systemd 通过 Socket 缓存、DBus 缓存和建立临时挂载点等方法进一步解决了启动进程之间的依赖,做到了所有系统服务并发启动。对于用户自定义的服务,Systemd 允许配置其启动依赖项目,从而确保服务按必要的顺序运行。

 使用 CGroup 监视和管理进程的生命周期
在 Systemd 之间的主流应用管理服务都是使用 进程树 来跟踪应用的继承关系的,而进程的父子关系很容易通过 两次 fork 的方法脱离。
而 Systemd 则提供通过 CGroup 跟踪进程关系,引补了这个缺漏。通过 CGroup 不仅能够实现服务之间访问隔离,限制特定应用程序对系统资源的访问配额,还能更精确地管理服务的生命周期。

 统一管理服务日志
Systemd 是一系列工具的集合, 包括了一个专用的系统日志管理服务:Journald。这个服务的设计初衷是克服现有 Syslog 服务的日志内容易伪造和日志格式不统一等缺点,Journald 用 二进制格式 保存所有的日志信息,因而日志内容很难被手工伪造。Journald 还提供了一个 journalctl 命令来查看日志信息,这样就使得不同服务输出的日志具有相同的排版格式, 便于数据的二次处理。

 支持快照和系统恢复

缺点:

 过于复杂,与操作系统的其他部分强耦合,违反"keep simple, keep stupid"的Unix 哲学(“简单原则”----尽量用简单的方法解决问题----是"Unix哲学"的根本原则。这也就是著名的KISS(keep it simple, stupid),意思是"保持简单和笨拙"。)

systemd的配置文件目录

Unit 文件按照 Systemd 约定,应该被放置指定的三个系统目录之一中。这三个目录是有优先级的,如下所示,越靠后的优先级越高。因此,在三个目录中有同名文件的时候,只有优先级最高的目录里的那个文件会被使用。
/usr/lib/systemd/system/(centos),/etc/systemd/system(Ubuntu):每个服务最主要的启动脚本的配置放在这,有点类似以前的/etc/init.d;
/run/systemd/system/:系统执行过程中所产生的服务脚本所在目录,这些脚本的优先级要比/usr/lib/systemd/system/高;
/etc/systemd/system/:管理员根据主机系统的需求所创建的执行脚本所在目录,执行优先级比/run/systemd/system/高;
从上面的功能及优先级次序,我们可以知道,/etc/systemd/system/目录下的相关配置,决定系统了会不会执行某些服务,所以该目录下面一般放着一大堆链接文件,指向目录 /usr/lib/systemd/system/。而/usr/lib/systemd/system/下,则放着实际执行的systemd启动脚本配置文件。因此如果你想要修改某个服务启动的设置,应该去/usr/lib/systemd/system/下面修改。/etc/systemd/system/仅是链接到正确的执行脚本配置文件而已。所以想要看执行脚本设置,应该就得要到/usr/lib/systemd/system/去查阅。
/etc/default/ 这个目录中放置很多服务默认的配置文件。
/var/lib/ 一些会产生数据的服务都会将他的数据写入到 /var/lib/ 目录中,比如 docker 相关的数据文件就放在这个目录下。
/run/ 这个目录放置了好多服务运行时的临时数据,比如 lock file 以及 PID file 等等。

Unit

Unit(单元|服务):Systemd 可以管理所有系统资源,不同的资源统称为 Unit(单位)。
在 Systemd 的生态圈中,Unit 文件统一了过去各种不同系统资源配置格式,例如服务的启/停、定时任务、设备自动挂载、网络配置、虚拟内存配置等。而 Systemd 通过不同的文件后缀来区分这些配置文件。
将系统资源划分为12类,将每个系统资源称为一个 Unit。Unit 是 Systemd 管理系统资源的基本单位,使用一个 Unit File 作为 Unit 的单元文件,Systemd 通过单元文件控制 Unit 的启动,例如,MySQL服务被 Systemd 视为一个 Unit,使用一个 mysql.service 作为启动配置文件。

Unit 和 Target

Unit 是 Systemd 管理系统资源的基本单元,可以认为每个系统资源就是一个 Unit,并使用一个 Unit 文件定义。在 Unit 文件中需要包含相应服务的描述、属性以及需要运行的命令。
Target 是 Systemd 中用于指定系统资源启动组的方式,相当于 SysV-init 中的运行级别。
简单说,Target 就是一个 Unit 组,包含许多相关的 Unit 。启动某个 Target 的时候,Systemd 就会启动里面所有的 Unit。从这个意义上说,Target 这个概念类似于”状态点”,启动某个 Target 就好比启动到某种状态。

Unit File类型

Unit File(单元文件|配置文件):单元文件中包含该单元的描述、属性、启动命令等
Systemd 将系统资源划分为12类,对应12种类型的单元文件。
系统资源类型 单元文件扩展名 单元文件描述
Service .service 封装守护进程的启动、停止、重启和重载操作,是最常见的一种 Unit 文件, 为了与 SysV 兼容,我们不仅支持我们自己的服务配置文件,而且还能够读取经典的 SysV init 脚本,特别是我们解析 LSB 标头(如果存在)。
Target .target 定义 target 信息及依赖关系,一般仅包含 Unit 段。它本身并不实际做任何事情,它只是引用其他单元,从而可以一起控制。这方面的例子是:multi-user.target,它是一个在经典 SysV 系统上基本上扮演运行级别 5 角色的目标
Device .device 对于 /dev 目录下的硬件设备,主要用于定义设备之间的依赖关系, 如果设备通过 udev 规则为此标记,它将在 systemd 中作为device unit公开。使用udev设置的属性可用作配置源来设置设备单元的依赖关系。
Mount .mount 定义文件系统的挂载点,可以替代过去的 /etc/fstab 配置文件
Automount .automount 用于控制自动挂载文件系统,相当于 SysV-init 的 autofs 服务,每个自动挂载 单元都有一个匹配的挂载单元,一旦访问自动挂载目录,它就会启动(即挂载)。
Path .path 用于监控指定目录或文件的变化,并触发其它 Unit 运行
Scope .scope 这种 Unit 文件不是用户创建的,而是 Systemd 运行时产生的,描述一些系统服务的分组信息
Slice .slice 用于表示一个 CGroup 的树,通常用户不会自己创建这样的 Unit 文件
Snapshot .snapshot 用于表示一个由 systemctl snapshot 命令创建的 Systemd Units 运行状态快照,可以切回某个快照
Socket .socket 监控来自于系统或网络的数据消息,用于实现基于数据自动触发服务启动
Swap .swap 定义一个用户做虚拟内存的交换分区
Timer .timer 用于配置在特定时间触发的任务,替代了 Crontab 的功能

systemctl配置文件的设置

这里我们先查看一下service里面的内容,随便找了一个内容比较多的sshd.service,方便讲解,指令结果如下:
[root@desktop ~]# cat /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target

[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target
单元文件的语法来源于 XDG桌面入口配置文件.desktop文件
Unit 文件可以分为三个配置区段:
Unit 段:所有 Unit 文件通用,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系
Install 段:所有 Unit 文件通用,用来定义如何启动,以及是否开机启动
Service 段:服务(Service)类型的 Unit 文件(后缀为 .service)特有的,用于定义服务的具体管理和执行动作
单元文件中的区段名和字段名大小写敏感
每个区段内都是一些等号连接的键值对(键值对的等号两侧不能有空格)

其中三个部分分别是:
[Unit]:unit本身的说明,以及与其他相关联daemon的设置,包括在什么服务之后才启动此unit之类的设置值;
[Service],[Socket],[Timer],[Mount],[Path]等等:不同的unit type就得要使用相对应的设置项目,我们拿的是sshd.service来举例,所以这边就使用[Service]来设置。这个项目内主要在规范服务启动的脚本、环境配置文件文件名、重新启动的方式等等;
[Install]:这个项目就是将此unit安装到哪个target里面去;

至于配置文件内有些设置规则还是得要说明一下:
 设置项目通常是可以重复的,例如我可以重复设置两个After在配置文件中,不过,后面的设置会取代前面的,因此,如果你想要将设置值归零,可以使用类似“After=”的设置,即该项目的等号后面什么都没有,就将该设置归零了(reset);
 如果设置参数需要有“是/否”的项目(布尔值,boolean),你可以使用1,yes,true,on代表启动,用0,no,false,off代表关闭!随你喜好选择;
 空白行、开头为#或;的那一行,都代表注解;

Service段

用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块。
【启动类型】
说明这个 daemon 启动的方式,会影响到 ExecStart, 一般来说,有下面几种类型:
1、Type=simple :默认值,这个 daemon 主要由 ExecStart 接的指令串来启动,启动的进程为主进程 。启动后常驻于内存中。
服务进程不会 fork,如果该服务要启动其他服务,不要使用此类型启动,除非该服务是 socket 激活型。
2、Type=forking :ExecStart字段将以fork()方式从父进程创建子进程启动,创建后父进程会立即退出,子进程成为主进程。
通常需要指定PIDFile字段,以便 Systemd 能够跟踪服务的主进程。
对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。
由 ExecStart 启动的程序通过spawns 延伸出其他子程序来作为此 daemon 的主要服务。原生的父程序在启动结束后就会终止运行。传统的unit 服务大多属于这种项目,例如httpd 这个 WWW 服务,当 httpd 的程序因为运行过久因此即将终结了,则systemd 会再重新生出另一个子程序持续运行后,再将父程序删除。
3、Type=oneshot :与simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中。
适用于只执行一项任务、随后立即退出的服务
通常需要指定RemainAfterExit=yes字段,使得 Systemd 在服务进程退出之后仍然认为服务处于激活状态
4、Type=dbus :与 simple 类似,但这个 daemon 必须要在取得一个D-Bus的名称后,才会继续运行!因此设置这个项目时,通常也要设置BusName= 才行!
5、Type=notify:当前服务启动完毕会发出通知信号,通知 Systemd,然后 Systemd 再启动其他服务。
6、Type=idle :与 simple 类似,意思是,要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行。这类的 daemon通常是开机到最后才执行即可的服务!比较重要的项目大概是simple,forking 与 oneshot 了!毕竟很多服务需要子程序(forking ),而有更多的动作只需要在开机的时候执行一次(oneshot ),例如文件系统的检查与挂载啊等等的。
【启动行为】
1、ExecStart:启动当前服务的命令,可以指定启动脚本的环境配置文件!例如 sshd.service 的配置文件写入到/etc/sysconfig/sshd 当中!你也可以使用 Environment= 后面接多个不同的Shell 变量来给予设置!
ExecStart=/bin/echo execstart1
ExecStart=
ExecStart=/bin/echo execstart2
顺序执行设定的命令,把字段置空,表示清除之前的值
2、ExecStartPre:启动当前服务之前执行的命令
3、ExecStartPost:启动当前服务之后执行的命令
4、ExecReload:重启当前服务时执行的命令,,与 systemctl reload 有关的指令行为
5、ExecStop:停止当前服务时执行的命令,与 systemctl stop 的执行有关,关闭此服务时所进行的指令。
6、ExecStopPost:停止当前服务之后执行的命令
7、RemainAfterExit:当前服务的所有进程都退出的时候,Systemd 仍认为该服务是激活状态。当设置为 RemainAfterExit=1 时,则当这个 daemon 所属的所有程序都终止之后,此服务会再尝试启动。这对于Type=oneshot 的服务很有帮助!
这个配置主要是提供给一些并非常驻内存,而是启动注册后立即退出,然后等待消息按需启动的特殊类型服务使用的
8、TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数,若这个服务在启动或者是关闭时,因为某些缘故导致无法顺利 “ 正常启动或正常结束” 的情况下,则我们要等多久才进入 “ 强制结束 ” 的状态!
注:所有的启动设置之前,都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行。比如,EnvironmentFile=-/etc/sysconfig/sshd(注意等号后面的那个连词号),就表示即使/etc/sysconfig/sshd文件不存在,也不会抛出错误。
【重启行为】
RestartSec:Systemd 重启当前服务间隔的秒数,与 Restart 有点相关性,如果这个服务被关闭,然后需要重新启动时,大概要sleep 多少时间再重新启动的意思。默认是 100ms (毫秒)。
KillMode:定义 Systemd 如何停止服务,可以是 process,control-group,none 的其中一种,如果是 process则daemon 终止时,只会终止主要的程序( ExecStart 接的后面那串指令),如果是control-group 时,则由此 daemon 所产生的其他control-group的程序,也都会被关闭。如果是 none 的话,则没有程序会被关闭喔!可能的值包括:
 control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
 process:只杀主进程(sshd 服务,推荐值)
 mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
 none:没有进程会被杀掉,只是执行服务的 stop 命令。
Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括:
 no(默认值):退出后不会重启
 on-success:只有正常退出时(退出状态码为0),才会重启
 on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启(守护进程,推荐值)
 on-abnormal:只有被信号终止和超时,才会重启(对于允许发生错误退出的服务,推荐值)
 on-abort:只有在收到没有捕捉到的信号终止时,才会重启
 on-watchdog:超时退出,才会重启
 always:不管是什么退出原因,总是重启
【上下文】
PIDFile:指向当前服务 PID file 的绝对路径。
User:指定运行服务的用户
Group:指定运行服务的用户组
EnvironmentFile:指定当前服务的环境参数文件。该文件内部的key=value键值对,可以用$key的形式,在当前配置文件中获取,例如 sshd.service 的配置文件写入到/etc/sysconfig/sshd 当中!你也可以使用 Environment= 后面接多个不同的Shell 变量来给予设置!

自定义服务

在 /usr/lib/systemd/system 下新建服务脚本
vim /usr/lib/systemd/system/zdy.service

[Unit]
Description=描述
Environment=环境变量或参数(系统环境变量此时无法使用)
After=network.target

[Service]
Type=forking
EnvironmentFile=所需环境变量文件或参数文件
ExecStart=启动命令(需指定全路径)
ExecStop=停止命令(需指定全路径)
User=以什么用户执行命令

[Install]
WantedBy=multi-user.target
新建完成后设置自启动
#添加或修改配置文件后,需要重新加载
systemctl daemon-reload

#设置自启动,实质就是在 /etc/systemd/system/multi-user.target.wants/ 添加服务文件的链接
systemctl enable zdy
举例:
在安装新服务包后,进入安装包路径查找.service单位文件
#find . -name service
#cp unitservice.service /usr/lib/systemd/system/
#chmod 644 /usr/lib/systemd/system/unitservice.service
#systemctl list-unit-files |grep unitservice
#systemctl enable unitservice && systemctl start unitservice

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太极淘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值