0%

谈谈Linux的systemd服务管理

前言

项目中很多进程都是注册为服务,在系统启动的时候自动运行。抽空仔细的学习了一下systemd服务管理,在此做一个小结。

systemd 概述

之前在极客时间上面学习过一个专栏《趣谈Linux操作系统》, 有了解到系统的首个进程是init进程, 后续的进程都是通过init来起来的。服务基本上都是通过脚本启动,主要的脚本在/etc/init.d下面。服务主要有两类: 独立模式和托管模式。独立模式就是服务独立启动,常驻内存的, 托管模式就是通过inetd或者xinetdsocketport进行管理, 当用户有需求时再去唤醒相应的服务程序。

systemd基本上替代了旧的initd,实现了对服务的管理。有如下特点:

  • 平行处理所有的服务,加速了开机的流程。 init是串行的执行启动脚本,时间上会比较慢。systemd可以并发执行不相关的服务,启动速度更快。
  • 通过systemctl实现on-demand的启动方式。默认systemd是一个常驻内存的进程,通过执行systemctl的命令就可以快速的实现服务的管理。
  • 支持服务依赖的检查。systemd通过服务的文件描述了相关服务的依赖说明。systemd通过解析服务文件,自动进行服务启动的管理。省却了人工管理的麻烦。
  • 支持daemon的分类。systemdunit可以分成多种类型, service, socket, target, path, timer,snapshot等。
  • 相关的服务可以分组,就是有一个target类型的服务包含多个相关的其它类型的服务, 便于管理。
  • 兼容init的服务脚本。

systemd也有缺点,并不能实现对就有init功能的一一对应。但是为了启动更便捷,牺牲一些功能还是值得的。

配置文件

systemd的服务文件主要放在三个地方。

  • /lib/systemd/system/: 软件安装的时候配置文件安装的位置,默认是不需要修改的。
  • /run/systemd/system/: 系统执行过程中产生的服务脚本, 这个目录下的脚本内容可以覆盖上面那个脚本的内容。
  • /etc/systemd/system/: 这个是systemd实际运行的脚本。一般自动运行的服务都会在这里创建一个链接指向前面两个的位置,systemd启动的时候会依旧当前目录的文件依次启动服务。

还有几个相关的目录:

  • /etc/sysconfig/*: 存放一些初始化的参数配置
  • /var/lib: 一般存放产生的数据文件
  • /run/: 运行过程中产生的一些文件, 比如: lock文件, pid文件。 这些文件也可能存放在/run/下面

systemd的服务单元分类:

  • service。 一般的服务分类,主要是系统服务,进程服务。最常见的类型
  • socket. 内部交换的,主要进程间通信的吧, 具体还待深入了解, 不是很常用
  • target。 群组类型,可以执行一堆其他的服务。
  • mount. 执行文件系统挂载相关的服务。
  • path。 用于侦测特定目录文件的服务。
  • timer。 循环执行的服务。

服务管理

systemd使用systemctl指令对服务进行管理:

1
2
3
4
5
6
7
8
9
systemctl start xxx  启动服务
systemctl stop xxx 停止服务
systemctl restart xxx 重启服务
systemctl reload xxx 服务不关闭,重新载入配置,让配置生效。
systemctl enable xxx 设置服务自动启动,其实就是在/etc/systemd/system下面创建一个对应的链接
systemctl disable xxx 设置服务不自动启动 就是删除上面的链接
systemctl status xxx 查看服务的状态信息
systemctl list-units --type=service --all 查看所有service类型服务

服务只有通过systemctl管理,才可以被systemd监控到,手动执行的话就检测不到了。

还有一些小技巧。例如,切换图形界面graphical.target和命令行界面multi-user.target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
systemctl get-default  // 获取当前运行的target
systemctl set-default multi-user.target // 设置下次启动默认的模式
systemctl isolate graphical.target // 切换到图形界面模式

linux还提供快捷命令切换不同的模式

[root@study ~]# systemctl poweroff 系统关机
[root@study ~]# systemctl reboot 重新开机
[root@study ~]# systemctl suspend 进入暂停模式
[root@study ~]# systemctl hibernate 进入休眠模式
[root@study ~]# systemctl rescue 强制进入救援模式
[root@study ~]# systemctl emergency 强制进入紧急救援模式


systemctl list-dependencies [unit] [--reverse] // 查看某个unit依赖的服务, --reverse表示显示这个unit被谁依赖(使用)

服务文件的编写

下面是sshd.service文件的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat /usr/lib/systemd/system/sshd.service 

[Unit] # 这个项目与此 unit 的解释、执行服务相依性有关
Description=OpenSSH server daemon
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service] # 这个项目与实际执行的指令参数有关
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install] # 这个项目说明此 unit 要挂载哪个 target 下面
WantedBy=multi-user.target

大部分的service文件格式都是如上,就是一些相关的选项不一样,具体的可以参考网络文章学习一下。

多重服务实例

systemd还支持设置多个相同服务的不同实例, 这个主要是通过 xxx@.service实现的。带有@符号,表示这个service可以实现多个实例,然后里面会是一个带有参数%I的配置文件,根据参数的不同 最终实现不一样的服务实例。

1
2
原始文件:执行服务名称@.service
可执行文件案:执行服务名称@范例名称.service

比较常见的vtty、还有Ubuntu下面不同网络空间的服务程序。

systemd是一个原理简单,细节很多的一个服务管理程序。如果有需要使用到的话,还有待深入了解。一般使用的话,了解上面的那些命令及知识基本就足够了。

学习systemd这个知识的话,比较简单易读的还是鸟哥的Linux私房菜,虽然有一些实现有一点点出入,还有就是湾湾翻译的跟我们的习惯还是有点不一样。看书籍还是有好处的, 当然最好的材料还是英文文档。另外一个就是阮一峰的博客,这位老师的博文质量都是杠杠的。

另外, systemd是一个开源的程序,在github上面可以找到源代码,systemctl的实现跟一个dbus的程序相关,下一次聊一聊dbus服务,主要是项目中需要用到dbus服务实现一个功能,我也简单了解了一下。

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。