Systemd的Unit配置详解,unit文件位置和优先级,unit文件类型,unit文件字段详解,[Unit]字段,[Service]字段,[Install]字段,添加服务,创建.service 文件,配置文件,加载启动服务。


unit

概念

  • unit(单元|服务等)
    Systemd 可以管理所有系统资源,将每个系统资源称为一个 Unit。Unit 是 Systemd 管理系统资源的基本单位,使用一个 Unit File 作为 Unit 的单元文件,Systemd 通过单元文件控制 Unit 的启动.
    例如,Httpd服务被 Systemd 视为一个 Unit,使用一个 httpd.service 作为启动配置文件

  • Unit File(单元文件|配置文件)
    单元文件中包含该单元的描述、属性、启动命令等

unit文件位置和优先级

路径 说明 优先级
/etc/systemd/system 系统或用户提供的配置文件
/run/systemd/system 软件运行时生成的配置文件
/usr/lib/systemd/system 系统或第三方软件安装时添加的配置文件

注意: 当这几个目录中有同名文件时,会使用优先级最高目录的文件。

通常我们是在/etc/systemd/system/ 目录下进行新增文件。

[root@shuge ~]# ls /etc/systemd/system/
basic.target.wants/                         default.target.wants/                       network-online.target.wants/
dbus-org.fedoraproject.FirewallD1.service   getty.target.wants/                         sysinit.target.wants/
dbus-org.freedesktop.nm-dispatcher.service  local-fs.target.wants/                      system-update.target.wants/
default.target                              multi-user.target.wants/                    vmtoolsd.service.requires/

unit文件类型

Systemd 将系统资源划分为12类,对应12种类型的单元文件

系统资源类型 单元文件扩展名 单元文件描述
Service .service 最常见Unit 文件类型,封装守护进程的启动、停止、重启和重载操作,也就是一直讲的服务
Target .target 定义 target 信息及依赖关系,一般仅包含 Unit 段
Device .device 对于 /dev 目录下的硬件设备,主要用于定义设备之间的依赖关系
Mount .mount 定义文件系统的挂载点,可以替代过去的 /etc/fstab 配置文件
Automount .automount 用于控制自动挂载文件系统,相当于 SysV-init 的 autofs 服务
Path .path 用于监控指定目录或文件的变化,并触发其它 Unit 运行
Scope .scope 这种 Unit 文件不是用户创建的,而是 Systemd 运行时产生的,描述一些系统服务的分组信息
Slice .slice 用于表示一个 CGroup 的树
Snapshot .snapshot 用于表示一个由 systemctl snapshot 命令创建的 Systemd Units 运行状态快照,可以切回某个快照
Socket .socket 监控来自于系统或网络的数据消息
Swap .swap 定义一个用户做虚拟内存的交换分区
Timer .timer 用于配置在特定时间触发的任务,替代了 Crontab 的功能

注意:

  • 如果缺省扩展名,则默认.service扩展名
  • 执行target相关命令,则默认生成.target扩展名
unit文件字段详解

sshd.service文件的输出内容输出如下,可以看到分为三个部分[Unit],[Service],[Install]。

[root@shuge system]# cat sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

[Unit]字段详解

该部分主要对服务进行说明。

  • Description
    描述信息,自定义即可。

  • Documentation
    介绍这个服务的文档的地址,可以是url,也可以是其他地址。

  • Requires
    依赖的其他 Unit 列表,列在其中的 Unit 模块会在这个服务启动的同时被启动,并且如果其中有任意一个服务启动失败,这个服务也会被终止。

  • Wants
    与 Requires 相似,但只是在被配置的这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模块启动是否成功。

  • After
    与 Requires 相似,但会在后面列出的所有模块全部启动完成以后,才会启动当前的服务。

  • Before
    与 After 相反,在启动指定的任一个模块之前,都会首先确保当前服务已经运行。

  • BindsTo
    与 Requires 相似,但是一种更强的关联。启动这个服务时会同时启动列出的所有模块,当有模块启动失败时终止当前服务。反之,只要列出的模块全部启动以后,也会自动启动当前服务。并且这些模块中有任意一个出现意外结束或重启,这个服务会跟着终止或重启。

  • PartOf
    这是一个 BindTo 作用的子集,仅在列出的任何模块失败或重启时,终止或重启当前服务,而不会随列出模块的启动而启动。

  • OnFailure
    当这个模块启动失败时,就自动启动列出的每个模块。

  • Conflicts
    与这个模块有冲突的模块,如果列出模块中有已经在运行的,这个服务就不能启动,反之亦然。

[Service]字段详解

这部分内容是仅针对 “.service” 文件,在配置服务的时候,这部分内容是最重要的。

  • Type
    Type=simple:默认值,ExecStart字段启动的进程为主进程,服务进程不会 fork,如果该服务要启动其他服务,不要使用此类型启动。
    Type=forking:ExecStart字段将以fork()方式从父进程创建子进程启动,创建后父进程会立即退出,子进程成为主进程。通常需要指定PIDFile字段,以便 Systemd 能够跟踪服务的主进程
    对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可
    Type=oneshot:只执行一次,Systemd 会等当前服务退出,再继续往下执行。适用于只执行一项任务、随后立即退出的服务。通常需要指定RemainAfterExit=yes字段,使得 Systemd 在服务进程退出之后仍然认为服务处于激活状态
    Type=dbus:当前服务通过 D-Bus 信号启动。当指定的 BusName 出现在 DBus 系统总线上时,Systemd认为服务就绪
    Type=notify:当前服务启动完毕会发出通知信号,通知 Systemd,然后 Systemd 再启动其他服务
    Type=idle:Systemd 会等到其他任务都执行完,才会启动该服务。

  • RemainAfterExit
    当前服务的所有进程都退出的时候,Systemd 仍认为该服务是激活状态。这个配置主要是提供给一些并非常驻内存,而是启动注册后立即退出,然后等待消息按需启动的特殊类型服务使用的

  • ExecStart
    启动当前服务的命令

ExecStart=/bin/echo execstart1
ExecStart=
ExecStart=/bin/echo execstart2
  • ExecStartPre
    启动当前服务之前执行的命令

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

  • TimeoutStartSec
    定义 Systemd 停止当前服务之前等待的秒数。

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

  • ExecStopPost
    停止当前服务之后执行的命令

  • KillMode:定义 Systemd 如何停止服务,可能的值包括:
    control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
    process:只杀主进程(sshd 服务,推荐值)
    mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
    none:没有进程会被杀掉,只是执行服务的 stop 命令。

  • TimeoutStopSec
    停止服务时的等待的秒数,如果超过这个时间服务仍然没有停止,systemd 会使用 SIGKILL 信号强行杀死服务的进程。

  • Restart
    no(默认值):退出后不会重启
    on-success:只有正常退出时(退出状态码为0),才会重启
    on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启(守护进程,推荐值)
    on-abnormal:只有被信号终止和超时,才会重启(对于允许发生错误退出的服务,推荐值)
    on-abort:只有在收到没有捕捉到的信号终止时,才会重启
    on-watchdog:超时退出,才会重启
    always:不管是什么退出原因,总是重启

  • PIDFile:指向当前服务 PID file 的绝对路径。

  • RestartSec
    Systemd 重启当前服务间隔的秒数

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

  • Environment
    为服务添加环境变量,如前面的第一个例子中所示。

  • EnvironmentFile
    指定加载一个包含服务所需的环境变量列表的文件,文件中的每一行都是一个环境变量的定义。

  • Nice
    服务的进程优先级,值越小优先级越高,默认为0。-20为最高优先级,19为最低优先级。

  • WorkingDirectory
    指定服务的工作目录。

  • RootDirectory
    指定服务进程的根目录( / 目录),如果配置了这个参数后,服务将无法访问指定目录以外的任何文件。

  • User
    指定运行服务的用户

  • Group
    指定运行服务的用户组

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

  • LimitCPU / LimitSTACK / LimitNOFILE / LimitNPROC 等
    限制特定服务可用的系统资源量,例如 CPU,程序堆栈,文件句柄数量,子进程数量

[Install]字段详解

这个段中的配置与 Unit 有几分相似,但是这部分配置需要通过 systemctl enable 命令来激活,并且可以通过 systemctl disable 命令禁用。另外这部分配置的目标模块通常是特定启动级别的 .target 文件,用来使得服务在系统启动时自动运行。

  • WantedBy
    和[Unit]中的 Wants 作用相似,列出的是依赖当前服务的模块。它的值是一个或多个 target,执行enable命令时,符号链接会放入/etc/systemd/system目录下以 target 名 + .wants后缀构成的子目录中。
最常见的用法:WantedBy=multi-user.target,表明当系统以多用户方式(默认的运行级别)启动时,这个服务需要被自动运行。
  • RequiredBy
    和[Unit]的 Requires 作用相似,依赖当前服务的模块。它的值是一个或多个 target,执行enable命令时,符号链接会放入/etc/systemd/system目录下以 target 名 + .required后缀构成的子目录中

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

  • Also
    当这个服务被 enable/disable 时,将自动 enable/disable 后面列出的每个模块。

例:添加ohas服务

在centos/rhel 7当中在安装rac的时候,需要手工创建一个服务文件,我们就以这个案例进行讲解。

创建.service 文件

touch /usr/lib/systemd/system/ohasd.service  
chmod 777 /usr/lib/systemd/system/ohasd.service

配置文件

 vi /usr/lib/systemd/system/ohasd.service
[Unit]
Description=Oracle High Availability Services  //描述信息
After=syslog.target  //启动这个服务后,再启动当前配置的服务

[Service]
ExecStart=/etc/init.d/init.ohasd run >/dev/null 2>&1  // 执行的命令
Type=simple			//默认
Restart=always		// 无论何种原因退出,都重启这个服务

[Install]
WantedBy=multi-user.target   // 对应当前操作系统的启动级别,表明当系统以多用户方式(默认的运行级别)启动时,这个服务需要被自动运行。

加载,启动服务

  • 重新加载守护进程
systemctl daemon-reload
  • 设置守护进程自动启动
systemctl enable ohasd.service
  • 手工启动ohasd服务
systemctl start ohasd.service
例:添加mysql服务

创建service文件

[root@mdns ~]# touch /usr/lib/systemd/system/mysql.service
[root@mdns ~]# chmod 777 /usr/lib/systemd/system/mysql.service 
[root@mdns ~]# vi /usr/lib/systemd/system/mysql.service 
[root@mdns support-files]# cat /usr/lib/systemd/system/mysql.service 
[Unit]
Description=MySQL Server
After=network.target
SourcePath=/etc/init.d/mysqld
 
[Install]
WantedBy=multi-user.target
 
[Service]
Type=forking
TimeoutSec=0
PermissionsStartOnly=true
ExecStart=/etc/init.d/mysqld start
ExecStop=/etc/init.d/mysqld sop
LimitNOFILE = 65535
Restart=on-failure
RestartSec=3
RestartPreventExitStatus=1
PrivateTmp=false

启动加载服务

[root@mdns ~]# systemctl daemon-reload
[root@mdns ~]# systemctl enable mysql.service
[root@mdns support-files]# systemctl start mysql.service

查看服务状态

[root@mdns support-files]# systemctl status mysql.service
● mysql.service - MySQL Server
   Loaded: loaded (/etc/init.d/mysqld; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2022-01-05 22:08:54 CST; 6s ago
  Process: 3095 ExecStart=/etc/init.d/mysqld start (code=exited, status=0/SUCCESS)
 Main PID: 3103 (mysqld_safe)
   CGroup: /system.slice/mysql.service
           ├─3103 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --pid-file=/data/my...
           └─3255 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --plu...

Jan 05 22:08:53 mdns.zaishu.cn systemd[1]: Starting MySQL Server...
Jan 05 22:08:54 mdns.zaishu.cn mysqld[3095]: Starting MySQL. SUCCESS!
Jan 05 22:08:54 mdns.zaishu.cn systemd[1]: Started MySQL Server.

总结

Systemd的Unit配置详解,unit文件位置和优先级,unit文件类型,unit文件字段详解,[Unit]字段,[Service]字段,[Install]字段,添加服务,创建.service 文件,配置文件,加载启动服务。