Linux_Systemd_service自定义实践
[TOC]
区分 sevice 和 systemctl
service
脚本位置:
/etc/init.d脚本内容:常为
/bin/sh或者/bin/bash- function 部分,提供
start、stop等函数 - **main(case-swicth)**部分,根据
$1传入参数,调用前文定义好的func
- function 部分,提供
脚本举例,例子来自
/etc/init.d/dubs,为方便理解,内容有删减
### BEGIN INIT INFO
# Provides: dbus
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: D-Bus systemwide message bus
# Description: D-Bus is a simple interprocess messaging system, used
# for sending messages between applications.
### END INIT INFO
# -*- coding: utf-8 -*-
# Debian init.d script for D-BUS
# Copyright © 2003 Colin Walters <walters@debian.org>
# Copyright © 2005 Sjoerd Simons <sjoerd@debian.org>
# ..........................................................................................
set -e
DAEMON=/usr/bin/dbus-daemon
UUIDGEN=/usr/bin/dbus-uuidgen
UUIDGEN_OPTS=--ensure
NAME=dbus
DAEMONUSER=messagebus
PIDDIR=/var/run/dbus
PIDFILE=$PIDDIR/pid
DESC="system message bus"
# ................................ function part BEGIN .....................................
create_machineid() {
# Create machine-id file
if [ -x $UUIDGEN ]; then
$UUIDGEN $UUIDGEN_OPTS
fi
}
start_it_up()
{
if [ ! -d $PIDDIR ]; then
mkdir -p $PIDDIR
chown $DAEMONUSER $PIDDIR
chgrp $DAEMONUSER $PIDDIR
fi
if ! mountpoint -q /proc/ ; then
log_failure_msg "Can't start $DESC - /proc is not mounted"
return
fi
if [ -e $PIDFILE ]; then
if $0 status > /dev/null ; then
log_success_msg "$DESC already started; not starting."
return
else
log_success_msg "Removing stale PID file $PIDFILE."
rm -f $PIDFILE
fi
fi
create_machineid
log_daemon_msg "Starting $DESC" "$NAME"
start-stop-daemon --start --quiet --pidfile $PIDFILE \
--exec $DAEMON -- --system $PARAMS
log_end_msg $?
}
shut_it_down()
{
log_daemon_msg "Stopping $DESC" "$NAME"
start-stop-daemon --stop --retry 5 --quiet --oknodo --pidfile $PIDFILE \
--user $DAEMONUSER
# We no longer include these arguments so that start-stop-daemon
# can do its job even given that we may have been upgraded.
# We rely on the pidfile being sanely managed
# --exec $DAEMON -- --system $PARAMS
log_end_msg $?
rm -f $PIDFILE
}
reload_it()
{
create_machineid
log_action_begin_msg "Reloading $DESC config"
dbus-send --print-reply --system --type=method_call \
--dest=org.freedesktop.DBus \
/ org.freedesktop.DBus.ReloadConfig > /dev/null
# hopefully this is enough time for dbus to reload it's config file.
log_action_end_msg $?
}
# ................................ function part Over .....................................
# ............................... Main case-switch BEGIN .....................................
case "$1" in
start)
start_it_up
;;
stop)
shut_it_down
;;
reload|force-reload)
reload_it
;;
restart)
shut_it_down
start_it_up
;;
status)
status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|reload|restart|force-reload|status}" >&2
exit 2
;;
esac
# ............................... Main case-switch Over .....................................优缺点:
- 优点:方便,简单。其实就是,
service按指定格式访问用户自定义脚本。 - 优点:通用。因为
service是Linux发行版基本都有的,称得上是 Linux 核心能力了。 - 缺点:太简单,基本只能做到 start、stop、status 的统一管理,没啥别的能力了。
- 优点:方便,简单。其实就是,
systemctl
脚本位置:
/etc/systemd/system或者/usr/lib/systemd/system- 前缀是
/etc还是/usr/lib由发行版决定。据说 Ubuntu 是前者,Centos 是后者 - 其实
/etc/systemd就算是「模块根目录」了 - 不过
systemctl daemon-reload读取的还是/etc/systemd/system - 注意,
systemctl也是会读取/etc/init.d中的内容的。—— 这就是他俩的关系。
- 前缀是
脚本内容:
- 类 ini 格式,支持以
#开头的行注释 - 可以在 VSCode 找到
coolbear.systemd-unit-file扩展,体验其语法支持与关键字高亮 systemctl把注册文件称之为unit,后面细说。
- 类 ini 格式,支持以
脚本举例:
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
Alias=sshd.service优缺点:
其实是,systemd 和 systemctl
systemd 是 一个系统管理守护进程、工具和库的集合
systemctl 是 命令行用户接口
- 优点:systemctl 是 Linux 系统继 init.d 之后的一个 systemd 工具,主要负责控制 systemd 系统和管理系统服务
- 如果没什么比 service 优秀的,肯定就不会用它了啊
- 优点:设计目标是
- 提高系统的启动速度,尽可能启动较少的进程,尽可能更多进程并发启动。
- 抽象出 unit 的概念,方便用户将进程交付给系统来管理。
- systemctl 提供相当多的模块管理功能,甚至包括依赖的树状查询。其在服务的模块管理上,比简陋的 service 完备很多。
- 缺点:unit 的注册文件虽然比较简单,但毕竟还是有一定的学习成本
- 优点:systemctl 是 Linux 系统继 init.d 之后的一个 systemd 工具,主要负责控制 systemd 系统和管理系统服务
详解 systemctl - 常用 CLI
- 更详细更完整的详讯官方文档
man systemctl
systemctl < start | stop | status | restart > < UnitName > # 基础能力,不多赘述 |
- 基本格式
systemctl [command] [unit] command主要有:- start | stop | restart:启动 | 关闭 | 关闭了再启动
- reload:不关闭,但是重新载入配置文件
- enable:开机自启,其实就是在 wants 里面加了一个软链接
- disable:关闭开机自启
- status:打印状态和日志信息
- is-active:当前活着不
- is-enabled:当前是否是开机自启的
- kill :发送 kill 信号给 unit
- show:展示一下 unit 注册文件里的配置信息
- mask:注销指定 unit,注销后无法启动这个 unit 了
- unmask:取消指定 unit 的注销
详解 systemctl - unit File
- systemd 的 unit 文件详解,可以用
man systemd.unit查阅- 我在 CentOS8 Linux4.18 的服务器上
man systemd查到 unit 有十一种
- Service、Socket、Target、Device、Mount、Automount、Timer、Swap、Path、Slice、Scope
- 想查看他们的详细信息,可以
man systemd.service或者man systemd.scope这样子- 文件支持行注释,以
#开始的行将作为注释
.mount 文件
定义挂载点,仅有 Mount 一节
- [Mount]
- What
- Where
- Type
.service 文件
定义服务,分 Unit、Service、Install 三节
value 如果是数组,则数组元素间用空格隔开即可
- [Unit]
- Description
- Before
- After
- ConditionPathExists:执行条件。满足条件才会去start。
不写也行,我反正没用到过。
- [Service]
- EnvironmentFile:环境变量可以从这个文件导入
- Restart=always:失败后总是重启
- RestartSec=5:等5秒再重启
- StartLimitInterval=0:重启次数不限制
- Exec…
- ExecStart:必填
- ExecStop:必填
- …..
- ExecRestart:非必填
- ExecStatus:非必填
- [Install]
- Alias:别名
- WantedBy=multi-user.target:之后配置 enable,需要这个配置项
.target 文件
供 service 调用的,一般不需要用户编辑
.wants 文件夹
- 需要了解前置知识:Linux RunLevel
- multi-user 可以理解成就是服务器正常工作的时候,99% 都是在这个状态的。
- 这文件夹里面都是软链接,都是 service 的链接,在系统进入 multi-user 这个 level 的时候,会把这里的服务都启动一遍