Last updated on:February 11, 2023 pm

编写systemd服务脚本

如何编写systemd服务脚本来实现服务的自启动,启动,停止和重启管理

1 背景介绍

  • RHEL6/CentOS6采用/etc/init.d/xxx脚本进行服务管理,但是7+版本之后由init管理升级为了由systemd管理,相应地服务管理方式也变更为由systemctl管理的service

  • RHEL7/CentOS7的/etc/rc.d/rc.local建议创建自己的systemd服务或udev规则来进行开机自启脚本管理,建议如下:

#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
  • 因此我们应该顺应时代(工具)的变迁,学习systemd的用法🐕

2 服务脚本写法

  • CentOS7的service脚本一般存放在/etc/systemd/, /usr/lib/systemd路径下,前者包含着多个*.target.wantsmulti-user.target.wants等;而后者为安装软件生成service的目录,一般编写自己的service可以放在此目录下。目录下又有systemuser之分:
    • **/usr/lib/systemd/system/**,系统服务,开机不需要用户登录即可运行的服务
    • **/usr/lib/system/user/**,用户服务,需要用户登录后才能运行的服务
  • 每一个服务脚本文件以.service结尾,由三个区块组成: [Unit], [Service]和[Install],以下是一个编写样例:
[Unit]   
Description=test   		# 简单描述服务
After=network.target    # 描述服务类别,表示本服务需要在network服务启动后在启动
Before=xxx.service      # 表示需要在某些服务启动之前启动,After和Before字段只涉及启动顺序,不涉及依赖关系。

[Service] 
Type=forking     		# 设置服务的启动方式
User=USER        		# 设置服务运行的用户
Group=USER       		# 设置服务运行的用户组
WorkingDirectory=/PATH	# 设置服务运行的路径(cwd)
KillMode=control-group  # 定义systemd如何停止服务
Restart=no        		# 定义服务进程退出后,systemd的重启方式,默认是不重启
ExecStart=/start.sh    	# 服务启动命令,命令需要绝对路径(采用sh脚本启动其他进程时Type须为forking)
   
[Install]   
WantedBy=multi-user.target  # 多用户
  • 完成service脚本编写后,需要执行以下命令以重载生效:
# 重新加载所有的systemd服务
sudo systemctl daemon-reload

# 管理服务 [使能开启启动|启动|停止|重启|查看状态]
sudo systemctl [enable|start|stop|restart|status] xxx.service

3 区块参数解释

[Unit]区块:启动顺序与依赖关系

服务描述:

  • Description:给出当前服务的简单描述
  • Documentation:给出文档位置

启动顺序:

  • After:定义xxx.service应该在哪些target或service服务之后启动
  • Before:定义xxx.service应该在哪些target或service服务之前启动

依赖关系:

  • Wants:表示xxx.service与定义的服务存在“弱依赖”关系,即指定的服务启动失败或停止运行不影响xxx的允行
  • Requires:则表示”强依赖”关系,即指定服务启动失败或异常退出,那么xxx也必须退出;反之xxx启动则指定服务也会启动

[Service]区块:启动行为定义

启动命令:

  • EnvironmentFile:指定当前服务的环境参数文件(路径),如EnviromentFile=-/etc/sysconfig/xxx,连词号表示抑制错误,即发生错误时,不影响其他命令的执行
  • Environment:后面接多个不同的shell变量,如Environment=DATA_DIR=/dir/data
  • User:设置服务运行的用户
  • Group:设置服务运行的用户组
  • WorkingDirectory:设置服务运行的路径
  • Exec*:各种与执行相关的命令
    • ExecStart:定义启动服务时执行的命令
    • ExecStop:定义停止服务时执行的命令
    • ExecStartPre:定义启动服务前执行的命令
    • ExecStartPost:定义启动服务后执行的命令
    • ExecStopPost:定义停止服务后执行的命令
    • ExecReload:定义重启服务时执行的命令

启动类型:

  • Type:字段定义启动类型,可以设置的值如下
    • simple(默认值):ExecStart字段启动的进程为主进程,即直接启动服务进程
    • forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程(例如用shell脚本启动服务进程)
    • oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务
    • dbus:类似于simple,但会等待 D-Bus 信号后启动
    • notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务
    • idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合
  • RemainAfterExit:设为yes,表示进程退出以后,服务仍然保持执行

重启行为:

  • KillMode:定义 Systemd 如何停止服务,可以设置的值如下
    • control-group(default):当前控制组里面的所有子进程,都会被杀掉
    • process:只杀主进程
    • mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
    • none:没有进程会被杀掉,只是执行服务的 stop 命令
  • Restart:定义了服务退出后,Systemd 的重启方式,可以设置的值如下(对于守护进程,推荐设为on-failure。对于那些允许发生错误退出的服务,可以设为on-abnormal
    • no(default):退出后不会重启
    • on-success:只有正常退出时(退出状态码为0),才会重启
    • on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启
    • on-abnormal:只有被信号终止和超时,才会重启
    • on-abort:只有在收到没有捕捉到的信号终止时,才会重启
    • on-watchdog:超时退出,才会重启
    • always:不管是什么退出原因,总是重启
  • RestartSec:表示 Systemd 重启服务之前,需要等待的秒数

[Install]区块:服务安装定义

  • WantedBy:表示该服务所在的 Target

Target的含义是服务组,如WantedBy=multi-user.target指的是该服务所属于multi-user.target。当执行systemctl enable xxx.service命令时,xxx.service的符号链接就会被创建在/etc/systemd/system/multi-user.target目录下。

可以通过systemctl get-default命令查看系统默认启动的target,一般为multi-user或者是graphical。因此配置好相应的WantedBy字段,可以实现服务的开机启动。

4 参考文章

[1]【阮一峰的网络日志】Systemd 入门教程:实战篇

[2] Centos7 自定义systemctl服务脚本

[3] 编写systemd下服务脚本

[4] systemd Wiki简体中文


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

KVM的安装与使用 Previous
攻防世界-MISC新手区-Writeup Next

 TOC

载入天数... 载入时分秒...