系统服务daemons
- 一. init管理时,服务的启动
- 二. 与init相比systemd的优点
- 三. systemd管理时,服务的启动
- 四. systemd的unit的分类
- 五. 用systemctl管理服务
- 六. 与 systemd 的 daemon 运行过程相关的目录简介
- 七. systemctl管理的类型为service 类型的unit的配置文件
一. init管理时,服务的启动
- 所有shell编写的daemons启动脚本放置在/etc/init.d/目录下。所以要启动、查看、停止某个daemons只需执行/etc/init.d daemon start|status|stop
- 系统分为0-6共七个执行等级,这个七个执行等级的启动脚本放置在/etc/rc.d/rc[0-6].d/目录下,这些目录下放置SXXdaemon 链接到 /etc/init.d/daemon , 链接文件名 (SXXdaemon) 的功能为: S 为启动该服务,XX是数字,为启动的顺序。由于有 SXX 的设置,因此在开机时可以“依序执行”所有需要的服务, 同时也能解决相依服务的问题。
- 要设置某个执行等级默认运行的daemon只需用
chkconfig daemon on
chkconfig daemon off
chkconfig --list daemon
系统会自动创建,删除符号链接 - 不同执行等级的切换 init n
二. 与init相比systemd的优点
- 没有依存关系的服务会同时启动,这样启动速度快
- 只需要systemd一个命令就能完成所有任务,如服务的启动关闭,把服务加入自启动等;init要用service,chkconfig,init多个命令
- 所有服务都称为unit,不同unit有分类(target,path,socket,timer,service等类别)
三. systemd管理时,服务的启动
- 所有服务unit的启动脚本都放置在/usr/lib/systemd/system/目录下
- 最终某个执行等级要启动的服务的启动脚本都以符合路径的形式放置在/etc/systemd/system/XXX.target.wants/目录下,连接的是/usr/lib/systemd/system/目录下真正的启动脚本
四. systemd的unit的分类
service:一般服务,包括本机服务和网络服务
socket:内部程序交换数据用
target:执行环境,一堆unit的集合
mount和automount:文件系统挂载相关的服务
五. 用systemctl管理服务
5.1 管理单一服务unit的启动、开机启动、观察状态
# systemctl [command] [unit]
command:
start: 立刻启动unit
stop:立刻停止unit
restart:
reload:
enable:
disable:
status:
is-active: 目前有没有正在运行
is-enabled:有没有开机默认启动
5.1.1 用systemctl status unit查看服务状态信息中第三行active的几种状态
active (running): 启动后常驻内存,如sshd
active (exited): 只使用时启动一次就退出,不常驻内存
active (waiting): 正在执行当中,不过还再等待其他的事件才能继续处理。举例来 说,打印的伫列相关服务就是这种状态! 虽然正在启动中,不过,也需要真的有伫列进 来 (打印工作) 这样他才会继续唤醒打印机服务来进行下一步打印的功能。
inactive (dead):正常用systemctl stop关闭的
failed (Result: signal): 用kill关闭的
5.1.2 用systemctl status unit查看服务状态信息中第二行的几种状态
enabled:这个 daemon 将在开机时被执行
disabled:这个 daemon 在开机时不会被执行
static:这个 daemon 不可以自己启动 (enable 不可),不过可能会被其他的 enabled 的服务来唤醒 (相依属性的服务)
mask:这个 daemon 无论如何都无法被启动!因为已经被强制注销 (非删除)。可通过 systemctl unmask 方式改回原本状态
mask状态:当执行systemctl mask atd时,会在/etc/systemd/system目录下为atd.service创建一个符号链接执行/dev/null, 不会删除/etc/systemd/system/multi-user.target.wants/atd.service这个符号链接,系统启动时会先找/etc/systemd/system这个目录下的atd.service,而不会找打/etc/systemd/system/multi-user.target.wants目录下的atd.service,atd服务自然就无法启动了。
[root@localhost ~]# systemctl mask atd.service
Created symlink /etc/systemd/system/atd.service → /dev/null.
[root@localhost ~]# systemctl unmask atd.service
Removed /etc/systemd/system/atd.service.
5.1.3 当多个服务之间有相依关系时尽管被依赖的服务没有设置开启启动也没有当前启动,但如果依赖的服务启动还是会自动把被依赖服务一起启动
比如:cups.socket会启动cups.service,我们把cups.service设置为开机和当前都不启动,但如果cups.socket启动在需要时还是会拉起cups.service
想要让一个服务不会被其他服务拉起有两种方法:
方法一:把cups.socket也关掉
方法二:把cups.service mask掉
5.2 用systemctl来查看系统中所有服务
5.2.1 命令格式
systemctl [command] [--type=TYPE] [--all]
command:
list-units: 根据unit列出系统中所有enable的unit。如果不加参数--all只显示enable并且已经启动的服务;加参数--all 才会列出没有启动的unit
list-unit-files: 根据/usr/lib/systemd/system目录中的文件,将所有文件列表出来
--type=TYPE: TYPE就是unit的类型,包括service、target、socket等
5.2.2 systemctl list-units查看所有系统已启动的服务
systemctl不加命令和systemctl list-units是一样的;
只显示enable的服务;
各个字段意义:
unit:服务名称
load:是否开机启动
active和sub:服务当前状态
5.2.3 systemctl list-unit-files查看所有系统已安装的服务(根据目录/usr/lib/systemd/system中的文件查看)
各个字段意义:
unit file:
state:开启是否启动的状态,包括enable,disable,static,mask
5.3 用systemctl管理不同的操作环境(target unit)
5.3.1 命令格式
systemctl [command] [unit.target]
command:
get-default :取得目前的 target
set-default :设置后面接的 target 成为默认的操作模式
isolate :切换到后面接的模式
5.3.2 用systemctl isolate加目标target来切换操作环境
systemctl isolate XXX.target
systemctl isolate shutdown.target
5.3.3 用systemctl 加快捷命令来切换操作环境
# systemctl poweroff 系统关机
# systemctl reboot 重新开机
# systemctl suspend 进入暂停模式
# systemctl hibernate 进入休眠模式
# systemctl rescue 强制进入救援模式
# systemctl emergency 强制进入紧急救援模式
5.4 通过 systemctl 分析各服务之间的相依性
5.4.1 查一个unit依赖哪些unit
systemctl list-dependencies //不加unit时是查询当前使用的环境unit依赖哪些unit
systemctl list-dependencies multi-user.target
systemctl list-dependencies cups.socket
systemctl list-dependencies cups.service
5.4.2 查一个unit被哪些unit依赖
systemctl list-dependencies --reverse //不加unit时是查询当前使用的环境unit被哪些unit依赖
systemctl list-dependencies --reverse multi-user.target
systemctl list-dependencies cups.service --reverse
systemctl list-dependencies cups.socket --reverse
六. 与 systemd 的 daemon 运行过程相关的目录简介
6.1 /usr/lib/systemd/system/目录
使用 CentOS 官方提供的软件安装后,默认的启动脚本配置文件都放在这里,这里的数据尽量不要修改~ 要修改时,请到 /etc/systemd/system 下面 修改较佳!
6.2 /etc/systemd/system/目录
- 管理员依据主机系统的需求所创建的执行脚本,其实这个目录有 点像以前 /etc/rc.d/rc5.d/Sxx 之类的功能!执行优先序又比 /run/systemd/system/ 高喔!
- 当某个daemon被enable时会在相应的运行环境.wants目录下创建一个指向/usr/lib/systemd/system/目录下启动脚本的符号链接;
[root@localhost ~]# systemctl enable vsftpd.service
Created symlink /etc/systemd/system/multi-user.target.wants/vsftpd.service → /usr/lib/systemd/system/vsftpd.service.
- 当某个daemon被注销时会在/etc/systemd/system目录下创建一个指向/dev/null的符号链接;
[root@localhost ~]# systemctl mask vsftpd.service
Created symlink /etc/systemd/system/vsftpd.service → /dev/null.
6.3 /etc/sysconfig/目录
几乎所有的服务都会将初始化的一些选项设置写入到这个目录下,举 例来说,mandb 所要更新的 man page 索引中,需要加入的参数就写入到此目录下的 man-db 当中喔!而网络的设置则写在 /etc/sysconfig/network-scripts/ 这个目录内。
6.4 /var/lib/目录
一些会产生数据的服务都会将他的数据写入到 /var/lib/ 目录中。举例来说,数 据库管理系统 Mariadb 的数据库默认就是写入 /var/lib/mysql/ 这个目录下
6.5 /run/目录
放置了好多 daemon 的暂存盘,包括 lock file 以及 PID file 等等。
6.7 查看systemd 里本机会用到的 socket 服务所产生socket file的存放位置
systemctl list-sockets
[root@localhost ~]# systemctl list-sockets
LISTEN UNIT ACTIVATES
/run/avahi-daemon/socket avahi-daemon.socket avahi-daemon.service
/run/dbus/system_bus_socket dbus.socket dbus.service
/run/dmeventd-client dm-event.socket dm-event.service
/run/dmeventd-server dm-event.socket dm-event.service
/run/initctl systemd-initctl.socket systemd-initctl.service
/run/lvm/lvmpolld.socket lvm2-lvmpolld.socket lvm2-lvmpolld.service
/run/rpcbind.sock rpcbind.socket rpcbind.service
/run/systemd/coredump systemd-coredump.socket
/run/systemd/journal/dev-log systemd-journald-dev-log.socket systemd-journald.service
/run/systemd/journal/socket systemd-journald.socket systemd-journald.service
/run/systemd/journal/stdout systemd-journald.socket systemd-journald.service
/run/udev/control systemd-udevd-control.socket systemd-udevd.service
/var/run/.heim_org.h5l.kcm-socket sssd-kcm.socket sssd-kcm.service
/var/run/cups/cups.sock cups.socket cups.service
/var/run/libvirt/virtlockd-sock virtlockd.socket virtlockd.service
/var/run/libvirt/virtlogd-sock virtlogd.socket virtlogd.service
/var/run/spice-vdagentd/spice-vdagent-sock spice-vdagentd.socket spice-vdagentd.service
0.0.0.0:111 rpcbind.socket rpcbind.service
0.0.0.0:111 rpcbind.socket rpcbind.service
@/org/kernel/linux/storage/multipathd multipathd.socket multipathd.service
@ISCSIADM_ABSTRACT_NAMESPACE iscsid.socket iscsid.service
@ISCSID_UIP_ABSTRACT_NAMESPACE iscsiuio.socket iscsiuio.service
[::]:111 rpcbind.socket rpcbind.service
[::]:111 rpcbind.socket rpcbind.service
kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
25 sockets listed.
Pass --all to see loaded but inactive sockets, too.
七. systemctl管理的类型为service 类型的unit的配置文件
7.1 service类型unit的配置文件存放目录
7.1.1 /usr/lib/systemd/system/vsftpd.service
官方释出的默认配置文件
7.1.2 /etc/systemd/system/vsftpd.service.d/custom.conf
在 /etc/systemd/system 下面创建与 配置文件相同文件名的目录,但是要加上 .d 的扩展名。然后在该目录下创建配置文件即 可。另外,配置文件最好附文件名取名为 .conf 较佳! 在这个目录下的文件会“累加其他设置”进入 /usr/lib/systemd/system/vsftpd.service
7.1.3 /etc/systemd/system/vsftpd.service.wants/目录下的配置文件
此目录内的文件为链接文件,设置相依服 务的链接。意思是启动了 vsftpd.service 之后,最好再加上这目录下面建议的服务。
7.1…4 /etc/systemd/system/vsftpd.service.requires/目录下的配置文件
此目录内的文件为链接文件,设置相依 服务的链接。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。
7.2 service类型unit的配置文件的内容详解
[root@localhost ~]# 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
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
配置文件内容分三个部分:Unit、Service、Install;
- [Unit]: unit 本身的说明,以及与其他相依 daemon 的设置,包括在什么服务之后才启动(After),以及他启动后还需要哪些unit 启动(Wants)的设置值;
# Description:就是当我们使用 systemctl list-units 时,会输出给管理员看的简易说 明!当然,使用 systemctl status 输出的此服务的说明,也是这个项 目!
# After:说明此 unit 是在哪个 daemon 启动之后才启动的意思!基本上仅是说 明服务启动的顺序而已,并没有强制要求里头的服务一定要启动后此 unit 才能启动。 以 sshd.service 的内容为例,该文件提到 After 后面 有 network.target 以及 sshd-keygen.service,但是若这两个 unit 没有 启动而强制启动 sshd.service 的话, 那么 sshd.service 应该还是能够 启动的!并且也不会去试图启动network.target 和 sshd-keygen.service。这与 Requires 的设置是有差异的喔!
# Requires:明确的定义此 unit 需要在哪个 daemon 启动后才能够启动!就是设置 相依服务啦!如果在此项设置的前导服务没有启动,那么此 unit 就先试图启动这个相依服务后再启动,如果这个相依服务无法启动此unit不会被启动!
# Wants:与 Requires 刚好相反,规范的是这个 unit 之后最好还要启动什么服务比较好的意思!不过,并没有明确的规范就是了!主要的目的是希望 创建让使用者比较好操作的环境。 因此,这个 Wants 后面接的服务在本uint启动后会试图去启动,如果启动不了也不会影响到这个 unit 本身!
# Before:与 After 的意义相反,是在什么服务启动前最好启动这个服务的意思。 不过这仅是规范服务启动的顺序,并非强制要求的意思。
# Conflicts:代表冲突的服务!亦即这个项目后面接的服务如果有启动,那么我们 这个 unit 本身就不能启动!我们 unit 有启动,则此项目后的服务就不 能启动! 反正就是冲突性的检查啦!系统会强制自动关闭冲突的unit。
- [Service], [Socket], [Timer], [Mount], [Path]…:不同的 unit type 就得要使用相对应的设置 项目。我们拿的是 sshd.service 来当范本,所以这边就使用 [Service] 来设置。 这个项目 内主要在规范服务启动的脚本、环境配置文件文件名、重新启动的方式等等;
# Type:说明这个 daemon 启动的方式,会影响到 ExecStart 喔!一般来说, 有下面几种类型 。
simple:默认值,这个 daemon 主要由 ExecStart 接 的指令串来启动,启动后常驻于内存中。
forking:由 ExecStart 启动 的程序通过 spawns 延伸出其他子程序来作为此 daemon 的主要服 务。原生的父程序在启动结束后就会终止运行。 传统的 unit 服务大 多属于这种项目,例如 httpd 这个 WWW 服务,当 httpd 的程序因为 运行过久因此即将终结了,则 systemd 会再重新生出另一个子程序持 续运行后, 再将父程序删除。据说这样的性能比较好!!
oneshot:与 simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在 内存中。
dbus:与 simple 类似,但这个 daemon 必须要在取得一个 D-Bus 的名称后,才会继续运行!因此设置这个项目时,通常也要设 置 BusName= 才行!
idle:与 simple 类似,意思是,要执行这个 daemon 必须要所有的工作都顺利执行完毕后才会执行。这类的 daemon 通常是开机到最后才执行即可的服务!
- [Install]:这个项目就是将此 unit 安装到哪个 target 里面去的意思
设置项的一些规则:
# 同一设置项可以有多个,但最后一个生效,比如有多个wants时,最后一个生效;
# 值为空就是reset这个值,比如wants=;
# 空行或以#开头或以;开头的行为注释行;
# 值是bool值时,用 1, yes, true, on 代 表启动,用 0, no, false, off 代表关闭
7.3 多重的重复设置方式: unit名@.service
7.3.1 格式为unit名@x.service的服务的启动过程
- 如果/usr/lib/systemd/system或/etc/systemd/system目录中有unit名@x.service就是直接执行,如果没有进入下一步
- 去/usr/lib/systemd/system和/etc/systemd/system目录找unit名@.service服务,然后将x作为unit名@.service这个文件的%i或%I值去启动服务
7.3.2 例如通过一个启动脚本和多个配置文件来启动多个不同端口的vsftpd服务
-
先确保/usr/lib/systemd/system或/etc/systemd/system目录中有vsftpd@.service这个启动脚本
[root@localhost ~]# ll /usr/lib/systemd/system |grep “vsftpd@”
-rw-r–r--. 1 root root 184 Apr 27 2020 vsftpd@.service -
发现这个文件中启动程序所用的配置文件的文件名为%i.conf, 这个%i就可以带人值了
-
在/etc/vsftpd目录下创建两个用不动端口的vsftpd配置文件叫做v1.conf和v2.confi
分别修改端口号为555和222
- 用命令启动他们
[root@localhost ~]# systemctl start vsftpd@v1.service
[root@localhost ~]# systemctl start vsftpd@v2.service
- 查看,确实用的v1.conf和v2.conf配置文件启动的
7.4 自制服务
- 写一个shell脚本作为服务的执行程序
[root@localhost ~]# cat backup.sh
#!/bin/bash
source="/etc /home /root /var/lib /var/spool/{cron,at,mail}"
target="/backups/backup-system-$(date +%Y-%m-%d).tar.gz"
[ ! -d /backups ] && mkdir /backups
tar -zcvf ${target} ${source} >> /backups/backup.log
[root@localhost ~]#
- 写一个backup.service 的启动脚本
cat /etc/systemd/system/backup.service
[Unit]
Description=backup my server
Requires=atd.service
[Service]
Type=simple
ExecStart=/bin/bash -c "echo /backups/backup.sh > at now"
[Install]
WantedBy=multi-user.target
# 因为 ExecStart 里面有用到 at 这个指令,因此, atd.service 就是一定要的服务!
- systemctl daemon-reload
[root@localhost ~]# systemctl daemon-reload
- 启动服务
[root@localhost ~]# systemctl start backup.service
[root@localhost ~]# systemctl status backup.service
● backup.service - backup my server
Loaded: loaded (/etc/systemd/system/backup.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Mar 05 23:56:26 localhost.localdomain systemd[1]: Started backup my server.
7.5 timer类型unit的配置文件的内容详解
有时候,某些服务你想要定期执行,或者是开机后执行,或者是什么服务启动多久后执行等 等的。在过去,我们大概都是使用 crond 这个服务来定期处理, 不过,既然现在有一直常驻 在内存当中的 systemd 这个好用的东西,加上这 systemd 有个协力服务,名为 timers.target 的家伙,这家伙可以协助定期处理各种任务!
7.5.1 要使用timer服务的三个条件
- 系统的timer.target要启动
- 有个x.service的服务要存在,他就是timer要执行的服务
- 配置一个x.timer来定时启动x.service服务
7.5.2 timer配置文件的配置项
设置参数 参数意义说明
OnActiveSec 当 timers.target 启动多久之后才执行这只 unit
OnBootSec 当开机完成后多久之后才执行
OnStartupSec 当 systemd 第一次启动之后过多久才执行
OnUnitActiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次启动后,隔 多久后再执行一次的意思
OnUnitInactiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次停止后,隔 多久再执行一次的意思。
OnCalendar 使用实际时间 (非循环时间) 的方式来启动服务的意思!至于时 间的格式后续再来谈。
Unit 一般来说不太需要设置,因此如同上面刚刚提到的,基本上我们设 置都是 sname.server + sname.timer,那如果你的 sname 并不相 同时,那在 .timer 的文件中, 就得要指定是哪一个 service unit 啰!
Persistent 当使用 OnCalendar 的设置时,指定该功能要不要持续进行的意 思。通常是设置为 yes ,比较能够满足类似 anacron 的功能喔!