Systemd简介CentOS 7 使用 Systemd 替换了SysV Ubuntu 从 15.04 开始使用 Systemd Systemd 是 Linux 系统工具,用来启动守护进程,已成为大多数发行版的标准配置 特点优点:
缺点:
架构图Unit(单元|服务)Systemd 可以管理所有系统资源:
Unit File(单元文件|配置文件)单元文件中包含该单元的描述、属性、启动命令等 类型Systemd 将系统资源划分为12类,对应12种类型的单元文件
语法单元文件的语法来源于 XDG桌面入口配置文件 Unit 文件可以分为三个配置区段:
Unit 段主要字段如下:
Install 段主要字段如下:
Service 段主要字段如下: 【启动类型】
【启动行为】
【重启行为】
【上下文】
占位符在 Unit 文件中,有时会需要使用到一些与运行环境有关的信息,例如节点 ID、运行服务的用户等。这些信息可以使用占位符来表示,然后在实际运行中动态地替换为实际的值。 模板在现实中,往往有一些应用需要被复制多份运行,就会用到模板文件 模板文件的写法与普通单元文件基本相同,只是模板文件名是以 @ 符号结尾。例如:apache@.service 通过模板文件启动服务实例时,需要在其文件名的 @ 字符后面附加一个用于区分服务实例的参数字符串,通常这个参数是用于监控的端口号或控制台 TTY 编译号
Systemd 在运行服务时,首先寻找跟单元名完全匹配的单元文件,如果没有找到,才会尝试选择匹配模板 例如上面的命令,System 首先会在约定的目录下寻找名为 apache@8080.service 的单元文件,如果没有找到,而文件名中包含 @ 字符,它就会尝试去掉后缀参数匹配模板文件。对于 apache@8080.service,Systemd 会找到 apache@.service 模板文件,并通过这个模板文件将服务实例化。 状态
示例
Systemd 内建命令
|
动作 | SysV Init 指令 | Systemd 指令 |
---|---|---|
启动某服务 | service httpd start | systemctl start httpd |
停止某服务 | service httpd stop | systemctl stop httpd |
重启某服务 | service httpd restart | systemctl restart httpd |
检查服务状态 | service httpd status | systemctl status httpd |
删除某服务 | chkconfig --del httpd | 停掉应用,删除其配置文件 |
使服务开机自启动 | chkconfig --level 5 httpd on | systemctl enable httpd |
使服务开机不自启动 | chkconfig --level 5 httpd off | systemctl disable httpd |
查询服务是否开机自启 | chkconfig --list | grep httpd | systemctl is-enabled httpd |
加入自定义服务 | chkconfig --add test | systemctl load test |
显示所有已启动的服务 | chkconfig --list | systemctl list-unit-files | grep enabled |
--all
显示加载到内存的所有单元
--type
-t
--type=
显示指定类型(12种类型)的单元
--state
--state=
显示指定状态的单元或单元文件
单元状态
输入
systemctl list-units --state
按Tab
键,显示所有可用的值单元文件状态
另外还可以用 enabled static disabled 等
systemctl list-unit-files
显示的状态
--failed
--state=failed
显示加载失败的单元
systemctl --failed
--version
打印 Systemd 版本
lfp@legion:/lib/systemd/system$ systemctl --version
Systemd 237
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
我的理解
- systemd 对单元的管理,不涉及单元文件自身属性和内容
list-units
相当于systemctl
列出当前已加载的单元(内存)
默认情况下仅显示处于激活状态(正在运行)的单元
UNIT 单元名
LOAD 加载状态
ACTIVE SUB 执行状态(大状态 子状态)
DESCRIPTION 描述
start
启动单元
systemctl start mysql.service
stop
停止单元
systemctl stop mysql.service
kill
杀掉单元进程
systemctl kill mysql.service
reload
不终止单元,重新加载 针对该单元的 运行配置文件,而不是 针对 systemd的 该单元的启动配置文件
例如启动 MySQL 服务,reload 可以在不停止服务的情况下重载 MySQL 的配置文件
my.cnf
restart
重启单元
该单元在重启之前拥有的资源不会被完全清空,比如文件描述符存储设施
systemctl reload mysql.service
status
status [unit | PID]
显示单元或进程所属单元的运行信息
systemctl status mysql.service
Loaded
行:配置文件的位置,是否设为开机启动
Active
行:表示正在运行
Main PID
行:主进程ID
CGroup
块:应用的所有子进程日志块:应用的日志
is-active
判断指定的单元是否处于激活状态
# 默认会打印当前单元的状态,可以通过 --quiet 参数取消打印
lfp@legion:~$ systemctl is-active mysql
active
is-failed
判断指定的单元是否处于启动失败状态
lfp@legion:~$ systemctl is-failed mysql
active
list-dependencies
查看单元之间的依赖关系
systemctl list-dependencies graphical.target
systemctl list-dependencies mysql.service
show
show --property= Unit
⇐=> show -p Unit
显示单元所有底层参数
lfp@legion:~$ systemctl show -p MainPID mysql
MainPID=1061
set-property
在单元启动的时候设置运行时的某个属性,立即生效,并保存在磁盘中作为启动配置
如果添加了--runtime
则重启后失效
并非所有的属性都可以设置,只是 systemd.resource-control 包含的属性
isolate
切换到某个 target(系统状态),立即停止该 target 未包含的单元进程。也可以理解为切换 runlevel
如果没有指定扩展名,则默认.target
只有当.target单元文件中的AllowIsolate=yes
时,才能使用 isolate 切换;也可以用IgnoreOnIsolate=yes
字段来拒绝使用 isolate 切换
systemctl isolate multi-user.target
cat
显示单元配置文件的备份文件,包括插入式配置drop-ins
,可以完整的看到单元服务的配置。注意这里打印的依据是磁盘的上内容,如果用户修改了配置文件(磁盘已修改)但是未执行daemon-reload
命令(内存中未更新),那么该命令显示的配置和实际执行情况有出入
lfp@legion:~$ systemctl cat mysql.service
# /lib/systemd/system/mysql.service
# MySQL Systemd service file
[Unit]
Description=MySQL Community Server
...
[Install]
WantedBy=multi-user.target
[Service]
Type=forking
...
# 这段就显示的是 插入式配置 drop-in 的内容
# /etc/systemd/system/mysql.service.d/mysql.conf
# MySQL Systemd service file
[Unit]
# Description=MySQL Community Server conf
[Service]
# ExecStartPost=/home/lfp/bin/espeak.sh
我的理解
- systemd 对单元文件自身属性和内容的管理
list-unit-files
列出所有已安装的单元文件和它们的启用状态
和
list-units
的区别是
- list-units 仅显示当前已加载到内存中的单元
- list-unit-files 会读取单元文件内容,列出所有单元,包括存在于硬盘未加载进内存的单元
实际测试结果:
systemctl list-unit-files 显示“348 Unit files listed”
systemctl list-units --all 显示“405 loaded units listed”
systemctl list-units 显示 “232 loaded units listed”
enable
使某个单元开机自启动
这会根据单元文件内容中的[Install]
指定的 target 组,创建一个软链接
lfp@legion:/etc/systemd/system$ vim v2rayL.service # 文件内容 [Install] 段 ...... [Install] WantedBy=multi-user.target ...... lfp@legion:/etc/systemd/system$ systemctl is-enabled v2rayL.service disabled lfp@legion:/etc/systemd/system$ systemctl enable v2rayL.service # 根据 [Install] 段指定的组,添加软链接 Created symlink /etc/systemd/system/multi-user.target.wants/v2rayL.service → /etc/systemd/system/v2rayL.service. lfp@legion:/etc/systemd/system$ systemctl is-enabled v2rayL.service enabled
disable
取消某个单元开机自启动设置,删除软链接
这会删除所有指向该单元文件的软链接,不仅仅是 enable 操作创建的
reenable
disable 和 enable 的结合,根据单元文件内容中的 [Install] 段,重置软链接
is-enabled
检查某个单元是否是开机自启动的(建立的启动链接)
lfp@legion:~$ systemctl is-enabled mysql
enabled
get-default
获取默认启动 target,default-target 是指向该 target 的软链接
set-default
设置默认启动 target,同时修改 default-target 指向设定的 target
systemctl set-default multi-user.target
daemon-reload
重新加载所有的单元文件和依赖关系
对单元文件有修改的时候,需要执行该命令重新加载文件内容
reboot
systemctl reboot
重启系统(异步操作)
it will return after the reboot operation is enqueued, without waiting for it to complete
poweroff
关闭系统,切断电源(异步操作)
halt
仅CPU停止工作,其他硬件仍处于开机状态(异步操作)
suspend
暂停系统(异步操作)
将触发执行suspend.target
hibernate
让系统进入冬眠状态(异步操作)
将触发执行hibernate.target
/run/systemd/system/
单元(服务)运行时生成的配置文件所在目录
/etc/systemd/system/
系统或用户自定义的配置文件,初始化过程中Systemd
只执行/etc/systemd/system
目录里面的配置文件
/lib/systemd/system/
软件安装时添加的配置文件,类似于 /etc/init.d/
对于支持 Systemd 的程序,安装的时候,会自动的在 /lib/systemd/system
目录添加一个配置文件
其他目录都是软链接
/etc/systemd/system/default.target
Systemd 执行的第一个单元文件,符号链接到默认启动 target 对应的 .target
单元文件
SysV 的启动脚本放在/etc/init.d
目录下
Systemd 的单元文件放在/etc/systemd/system
和 /lib/systemd/system
目录下
当一个程序在3个目录下都存在启动方式时,优先级是/etc/systemd/system --> /lib/systemd/system --> /etc/init.d
lfp@legion:/etc/init.d$ ll
-rwxr-xr-x 1 root root 5650 5月 19 22:09 mysql*
lfp@legion:/etc/systemd/system$ ll
-rw-r--r-- 1 root root 511 5月 20 01:42 mysql.service
lfp@legion:/lib/systemd/system$ ll
-rw-r--r-- 1 root root 499 5月 20 01:20 mysql.service
/etc/systemd/system
里面的同名service会覆盖/lib/systemd/system
里面的
注意查看文件信息,该同名文件不能是指向 /lib/systemd/system 的软链接
软链接不会覆盖而会同步
如果某个程序不存在Systemd 单元文件,那么会执行/etc/init.d
里面的启动脚本
根据启动过程,
/etc/systemd/system/multi-user.target.wants/
目录下是很多指向/lib/systemd/system/
目录的软链接,所以两个目录下的单元文件会互相同步。如果
/etc/systemd/system/
和/etc/systemd/system/multi-user.target.wants/
同时存在单元文件,测试发现,不管是手动启动还是开机自启动,使用的都是/etc/systemd/system/
目录下的service单元文件
/etc/init.d
目录下的脚本mysql 修改 mysql.service
为mysql.service.bak
然后通过service mysql restart
启动/etc/init.d/mysql
脚本
下面是启动后的一些信息
注:在恢复
mysql.service
之前,需要先通过service mysql stop
利用/etc/init.d/mysql
脚本中的stop
结束上面的进程,否则一旦恢复,service mysql stop
执行的操作就不是/etc/init.d/mysql
脚本中的stop
,无法结束上面的进程,出现命令无法正常执行的情况
结束上面的进程,恢复mysql.service
,重新启动
/etc/systemd/system
覆盖测试未修改前,查看MySQL的状态
lfp@legion:~$ service mysql status
● mysql.service - MySQL Community Server
# 可以发现这里的 mysql.service 是在 /lib/systemd/system 下面
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: en
Active: active (running) since Sat 2020-04-25 18:34:30 CST; 5h 33min ago
Main PID: 988 (mysqld)
Tasks: 28 (limit: 4915)
CGroup: /system.slice/mysql.service
└─988 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
4月 25 18:34:30 legion Systemd[1]: Starting MySQL Community Server...
4月 25 18:34:30 legion Systemd[1]: Started MySQL Community Server.
将 /lib/systemd/system 下面的文件复制到 /etc/systemd/system/
下面
sudo cp /lib/systemd/system/mysql.service /etc/systemd/system/
修改 mysql.service
sudo vim /etc/systemd/system/mysql.service
重启 mysql.service ,系统提示需要重新加载
lfp@legion:~$ systemctl restart mysql.service
Warning: The Unit file, source configuration file or drop-ins of mysql.service changed on disk.
Run 'systemctl daemon-reload' to reload units.
lfp@legion:~$ systemctl daemon-reload# 重新加载
lfp@legion:~$ systemctl restart mysql.service # 重启
lfp@legion:~$ systemctl status mysql.service
● mysql.service - MySQL Community Server hahahaha# 发现这里是修改之后的,覆盖了 /lib/systemd/lib 中的
# 这里也可以看到加载路径
Loaded: loaded (/etc/systemd/system/mysql.service; enabled; vendor preset: en
Active: active (running) since Sun 【2020-04-26】 00:47:02 CST; 5s ago
Process: 21590 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/m
Process: 21581 ExecStartPre=/usr/share/mysql/mysql-Systemd-start pre (code=exi
Main PID: 21592 (mysqld)
Tasks: 27 (limit: 4915)
CGroup: /system.slice/mysql.service
└─21592 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pi
4月 26 00:47:02 legion Systemd[1]: Starting MySQL Community Server hahahaha...
4月 26 00:47:02 legion Systemd[1
两个含义
系统的某个状态称为一个 target(类似于"状态点")
达到某个系统状态,所需的一个或多个资源(Unit)称为一个 target(一个 Unit 组)
target是一个抽象的系统资源,不像MySQL有实体
如果一个target只包含一个Unit,那么该 target,没有对应的目录,指的就是这个 Unit
例如
hibernate.target
只包含systemd-hibernate.service
一个Unit如果一个target包含多个Unit,那么该target,有对应的 xxx.target.wants 目录,指的是目录里面所有的Unit
例如
multi-user.target
包含位于/etc/systemd/system/multi-user.target.wants
目录下的多个 Unit
target也是一个 Target 类型的系统资源,有对应的单元文件 xxx.target
Systemd 使用 target 来划分和管理资源(Unit),启动(激活)某个 xxx.target 单元文件,通过执行该 target 包含的 Unit,使系统达到某种状态
对于状态点的理解:
例如,执行
systemd suspend
命令让系统暂停,会触发启动suspend.target
,然后执行里面的systemd-suspend.service
Unit,使系统达到一个暂停的状态
传统的init
启动模式里面,有 RunLevel 的概念,跟 Target 的作用很类似。不同的是,RunLevel 是互斥的,不可能多个 RunLevel 同时启动,但是多个 Target 可以同时启动
runlevel是 SysV init 初始化系统中的概念,在Systemd初始化系统中使用的是 Target,他们之间的映射关系是
Runlevel | Target | 说明 |
---|---|---|
0 | poweroff.target | 关闭系统 |
1 | rescue.target | 维护模式 |
2,3,4 | multi-user.target | 多用户,无图形系统(命令行界面) |
5 | graphical.target | 多用户,图形化系统(图形用户界面) |
6 | reboot.target | 重启系统 |
读入 /boot
目录下的内核文件
内核文件加载完之后,开始执行第一个程序/sbin/init
初始化进程,由 Systemd 初始化系统引导,完成相关的初始化工作
Systemd 执行default.target
,获知设定的启动 target
实际上
default.target
是指向设定的启动 target 的软链接
Systemd 执行启动 target 对应的单元文件。根据单元文件中定义的依赖关系,传递控制权,依次执行其他 target 单元文件,同时启动每个 target 包含的单元
对于图形化界面,默认 target 是 graphical,Systemd 执行位于
/lib/systemd/system/
目录下的 graphical.target 单元文件,根据 target 单元文件中定义的依赖关系,依次启动其他 target 单元文件以及各个 target 包含的位于/etc/systemd/system/
目录下的单元例如: graphical.target 的依赖关系是
[Unit] Description=Graphical Interface Documentation=man:systemd.special(7) Requires=multi-user.target # Wants=display-manager.service # Conflicts=rescue.service rescue.target After=multi-user.target rescue.service rescue.target display-manager.service # AllowIsolate=yes
因此,依次启动 multi-user.target --> basic.target --> sysinit.target --> local-fs.target -->local-fs-pre.target --> ...
同时启动每个 target 包含的位于
/etc/systemd/system/
目录下的UnitSysV对应的 rc5.d --> /etc/init.d 目录下的指定的脚本就不会在开机的时候执行了
systemctl get-default
lfp@legion:~$ runlevel
N 5
lfp@legion:~$ systemctl get-default
graphical.target
systemctl set-default [xxx.target]
# Ubuntu18.04
# 图形用户界面 切换 命令行界面
sudo systemctl set-default multi-user.target
# 命令行界面 切换 图形用户界面
systemctl set-default graphical.target
reboot
# 命令行界面 想进入 图形用户界面(仅进入一次,重启系统后仍然会进入命令行模式)
sudo systemctl start lightdm
直接修改/lib/systemd/system
目录下的单元文件
如果软件包更新,修改会被丢弃
将/lib/systemd/system
中的单元文件复制到/etc/systemd/system/
如果软件包更新,不会同步更新
在/etc/systemd/system/
中添加配置(推荐)
步骤:
/etc/systemd/system/
目录下新建<单元名>.d
目录<单元名>.d
目录下,新建<单元名>.conf
文件<单元名>.conf
文件中修改配置测试:
创建目录及文件
# /mysql.service.d
lfp@legion:/etc/systemd/system/mysql.service.d$ ls
mysql.conf
修改配置
# MySQL Systemd service config file
# 不需要所有的组,仅添加需要修改的组及选项
[Unit]
Description=MySQL Community Server config test
[Service]
ExecStartPost=/home/lfp/bin/espeak.sh
重启测试
lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl daemon-reload
lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl restart mysql.service
lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl status mysql.service
lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl status mysql.service
# 描述已经被修改
● mysql.service - MySQL Community Server config test
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
# 加入了配置文件
Drop-In: /etc/systemd/system/mysql.service.d
└─mysql.conf
Active: active (running) since Thu 2020-05-21 20:18:02 CST; 12min ago
# 新增的动作执行成功
Process: 4703 ExecStartPost=/home/lfp/bin/espeak.sh (code=exited, status=0/SUCCESS)
Process: 4672 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS)
Process: 4663 ExecStartPre=/usr/share/mysql/mysql-Systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 4674 (mysqld)
Tasks: 27 (limit: 4915)
CGroup: /system.slice/mysql.service
└─4674 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
5月 21 20:18:02 legion espeak.sh[4703]: ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
rc.local
文件/lib/systemd/rc.local.service
# 如果存在,就自动添加到 multi-user.target
# This Unit gets pulled automatically into multi-user.target by
# Systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
创建 rc.local 文件,赋予可执行权限,即可添加启动命令
sudo touch /etc/rc.local
chmod 755 /etc/rc.local
lfp@legion:/etc$ vim rc.local
#!/bin/sh -e
echo "test rc.local" > /usr/local/rclocal.log
echo "rc.local `date +%Y-%m-%d-%H:%M:%S`" >/home/lfp/log/rclocal.log
exit 0
hostnamectl status
Show current system hostname and related information
lfp@legion:/lib/systemd/system$ hostnamectl status
Static hostname: legion
Icon name: computer-laptop
Chassis: laptop
Machine ID: b28xxxxxxxx2ecafa29e
Boot ID: 21xxxxxxxxxxxx1d3a47504d
Operating System: Ubuntu 18.04.4 LTS
Kernel: Linux 5.3.0-51-generic
Architecture: x86-64
Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl
一个命令,查看所有日志(内核日志和应用日志)。
配置文件
/etc/systemd/journald.conf
日志保存目录
/var/log/journal/
默认日志最大限制为所在文件系统容量的 10%,可通过 /etc/systemd/journald.conf
中的 SystemMaxUse 字段来指定
该目录是 systemd 软件包的一部分。若被删除,systemd 不会自动创建它,直到下次升级软件包时重建该目录。如果该目录缺失,systemd 会将日志记录写入 /run/systemd/journal。这意味着,系统重启后日志将丢失。
journalctl -u [服务名]
查看指定单元的日志
journalctl -b
http://manpages./manpages/bionic/en/man1/systemctl.1.html
http://manpages./manpages/bionic/en/man5/systemd.unit.5.html
https://www.cnblogs.com/yingsong/p/6012180.html
https://www.cnblogs.com/sparkdev/p/8472711.html
http://www./blog/2016/03/systemd-tutorial-commands.html
http://www./blog/2016/03/systemd-tutorial-part-two.html
https:///linux-how-to/systemd-boot-process/
https://cloud.tencent.com/developer/article/1516125
https://www.cnblogs.com/sparkdev/p/8472711.html
https://www.ibm.com/developerworks/cn/linux/1407_liuming_init3/index.html?ca=drs-
|