文章目录
- 一、systemd 的由来
- (一)常用的 init 系统
- (二)init 程序的缺点
- (三)systemd 简介
- (四)systemd 架构图
- 二、服务管理
- 三、unit 配置文件
- (一)概述
- (二)配置文件状态
- (三)配置文件格式
- 1. unit 配置文件格式
- 2.[Unit] 常用选项
- 3.[Service] 常用的选项
- 4.[Install] 常用选项
- 四、Target
- (一)Target命令
- (二)Target与传统 RunLevel 的对应关系
- (三)它与init进程的主要差别
- 五、日志管理
- (一)命令 journalctl 用法
- (二)查看指定优先级(及其以上级别)的日志,共有8级
一、systemd 的由来
(一)常用的 init 系统
- Centos 5 Sys V init 是启动速度最慢的,串行启动进程,无论进程相互之间有无依赖关系。
- Centos6 Upstart init 相对启动速度快一点有所改进。有依赖的进程之间依次启动而其他与之没有依赖关系的则并行同步启动。
(二)init 程序的缺点
- 启动时间长。Init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。(这也是Centos5的主要特征)
- 启动脚本复杂。Init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这使得脚本变得很长而且复杂。
(三)systemd 简介
systemd 与以上都不同。systemd为了解决上文的问题而诞生。它的目标是,为系统的启动和管理提供一套完整的解决方案。所有进程无论有无依赖关系都是并行启动(当然很多时候进程没有真正启动而是只有一个信号或者说是标记而已,在真正利用的时候才会真正启动。)根据linux惯例,字母d是守护进程(daemon) 的缩写。systemd名字的含义就是守护整个系统。
Centos 7里systemd代替了init,成为了系统的第一个进程(PID为1),其他所有的进程都是它的子进程。systemd 的优点是功能强大,使用方便,缺点是体系庞大,非常复杂。事实上,现在还有很多人反对使用 systemd,理由就是它过于复杂,与操作系统的其他部分强耦合,违反"keep simple, keep stupid"的Unix 哲学。
(四)systemd 架构图
二、服务管理
命令 systemctl 的使用
三、unit 配置文件
(一)概述
每一个 Unit 都有一个配置文件,告诉 systemd 怎么启动这个 Unit 。
systemd 默认从目录 /etc/systemd/system/
读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录 /usr/lib/systemd/system/,真正的配置文件存放在那个目录。
systemctl enable httpd.service
命令用于在上面两个目录之间,建立符号链接关系。(Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
)等同于 ln -s /usr/lib/systemd/system/httpd.service /etc/systemd/system/multi-user.target.wants/httpd.service
。当然 systemdctl disable httpd.service
则相当于删除这个软连接。
/usr/lib/system/system
:系统默认的单元文件安装目录,每个服务最主要的启动脚本存放在该目录下,类似于之前的 /etc/init.d/
。
/run/system/system
:存放系统单元执行过程中所产生的脚本,比安装目录优先运行。
/etc/systemd/system
:存放系统管理员建立的执行脚本,这是系统管理员管理的单元目录,类似于 /etc/rc.d/rcN.d/Sxx
的功能,比上面目录优先运行,优先级别最高。
(二)配置文件状态
systemctl list-unit-files
命令用于列出所有配置文件。
列出所有配置文件
# systemctl list-unit-files
列出指定类型的配置文件
# systemctl list-unit-files --type=service
systemctl list-unit-files
该命令会输出一个列表,从中可以看到每个配置文件的状态。
Unit config file status
lvm2-lvmetad.service disabled
lvm2-lvmetad.socket enabled
lvm2-lvmpolld.service disabled
lvm2-lvmpolld.socket enabled
这个列表显示每个配置文件的状态,一共有四种:
enabled:已建立启动链接
disabled:没建立启动链接
static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖
masked:该配置文件被禁止建立启动链接
注意,从配置文件的状态无法看出,该 Unit 是否正在运行。这必须执行前面提到的systemctl status
命令。
# systemctl status httpd.service
(三)配置文件格式
1. unit 配置文件格式
[Unit]
Description=backup /etc
Requires=atd.service
[Service]
Type=simple
ExecStart=/bin/bash -c "echo /testdir/bak.sh|at now"
[Install]
WantedBy=multi-user.target
[Unit] :定义与Unit类型无关的通用选项,用于提供unit的描述信息、 unit行为及依赖关系等
[Service]:与特定类型相关的专用选项,此处为Service类型
[Install]:定义由“ systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项
2.[Unit] 常用选项
Description:描述信息
After:定义unit的启动次序,表示当前unit应该晚于哪些
unit启动,其功能与Before相反
Requires:依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激活
Wants:依赖到的其它units,弱依赖
Conflicts:定义units间的冲突关系
BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
Condition…:当前 Unit 运行必须满足的条件,否则不会运行
Assert…:当前 Unit 运行必须满足的条件,否则会报启动失败
3.[Service] 常用的选项
Type:定义影响ExecStart及相关参数的功能的unit进程启动类型
simple:默认值,这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
forking:由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务。原生父程序在启动结束后就会终止。
oneshot:与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中
dbus:与simple类似,但这个daemon必须要在取得一个D-Bus的名称后,才会继续运作.因此通常也要同时设定BusNname= 才行
notify:在启动完成后会发送一个通知消息。还需要配合NotifyAccess 来让 systemd 接收消息
idle:与simple类似,要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行。这类的daemon通常是开机到最后才执行即可的服务。
EnvironmentFile:环境配置文件
ExecStart:指明启动unit要运行命令或脚本的绝对路径
ExecStartPre: ExecStart前运行
ExecStartPost: ExecStart后运行
ExecRsload: 重启当前服务时执行的命令
ExecStopPost:停止当前服务之后执行的命令
ExecStartSec:自动重启当前服务间隔的秒数
ExecStop:指明停止unit要运行的命令或脚本
Restart:当设定Restart=1 时,则当次daemon服务意外终止后,会再次自动启动此服务。
TimeoutSec:定义 systemd 停止当前服务之前等待的秒数。
Environment:指定环境变量。
4.[Install] 常用选项
Alias:别名,可使用systemctl command Alias.service
RequiredBy:被哪些units所依赖,强依赖
WantedBy:被哪些units所依赖,弱依赖
Also:安装本服务的时候还要安装别的相关服务
注意:对于新创建的unit文件,或者修改了的unit文件,要通知systemd重载此配置文件,而后可以选择重启。
# systemctl daemon-reload
# systemctl restart httpd.service
更加详细的 unit 配置文件格式请参考官方文档
https://www.freedesktop.org/software/systemd/man/systemd.unit.html
四、Target
启动计算机的时候,需要启动大量的 Unit。如果每一次启动,都要一一写明本次启动需要哪些 Unit,显然非常不方便。systemd 的解决方案就是 Target。
简单说,Target 就是一个 Unit 组,包含许多相关的 Unit 。启动某个 Target 的时候,systemd 就会启动里面所有的 Unit。从这个意义上说,Target 这个概念类似于"状态点",启动某个 Target 就好比启动到某种状态。
传统的init启动模式里面,有 RunLevel 的概念,跟 Target 的作用很类似。不同的是,RunLevel 是互斥的,不可能多个 RunLevel 同时启动,但是多个 Target 可以同时启动。
(一)Target命令
查看当前系统的所有 Target
# systemctl list-unit-files --type=target
查看一个 Target 包含的所有 Unit
# systemctl list-dependencies multi-user.target
查看启动时的默认 Target
# systemctl get-default
设置启动时的默认 Target
# systemctl set-default multi-user.target
切换 Target 时,默认不关闭前一个 Target 启动的进程, systemctl isolate 命令改变这种行为,
关闭前一个 Target 里面所有不属于后一个 Target 的进程 systemctl isolate multi-user.target
(二)Target与传统 RunLevel 的对应关系
Traditional runlevel New target name Symbolically linked to…
Runlevel 0 | runlevel0.target -> poweroff.target
Runlevel 1 | runlevel1.target -> rescue.target
Runlevel 2 | runlevel2.target -> multi-user.target
Runlevel 3 | runlevel3.target -> multi-user.target
Runlevel 4 | runlevel4.target -> multi-user.target
Runlevel 5 | runlevel5.target -> graphical.target
Runlevel 6 | runlevel6.target -> reboot.target
(三)它与init进程的主要差别
(1)默认的 RunLevel(在/etc/inittab文件设置)现在被默认的 Target 取代,位置是/etc/systemd/system/default.target,通常符号链接到graphical.target(图形界面)或者multi-user.target(多用户命令行)。
(2)启动脚本的位置,以前是/etc/init.d目录,符号链接到不同的 RunLevel 目录 (比如/etc/rc3.d、/etc/rc5.d等),现在则存放在/lib/systemd/system和/etc/systemd/system目录。
(3)配置文件的位置,以前init进程的配置文件是/etc/inittab,各种服务的配置文件存放在/etc/sysconfig目录。现在的配置文件主要存放在/lib/systemd目录,在/etc/systemd目录里面的修改可以覆盖原始设置。
五、日志管理
systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf。
(一)命令 journalctl 用法
查看所有日志(默认情况下 ,只保存本次启动的日志)
# journalctl
查看内核日志(不显示应用日志)
# journalctl -k
查看系统本次启动的日志
# journalctl -b
# journalctl -b -0
查看上一次启动的日志(需更改设置)
# journalctl -b -1
查看指定时间的日志
# journalctl --since="2012-10-30 18:17:16"
# journalctl --since "20 min ago"
# journalctl --since yesterday
# journalctl --since "2015-01-10" --until "2015-01-11 03:00"
# journalctl --since 09:00 --until "1 hour ago"
显示尾部的最新10行日志
# journalctl -n
显示尾部指定行数的日志
# journalctl -n 20
实时滚动显示最新日志
# journalctl -f
查看指定服务的日志
# journalctl /usr/lib/systemd/systemd
查看指定进程的日志
# journalctl _PID=1
查看某个路径的脚本的日志
# journalctl /usr/bin/bash
查看指定用户的日志
# journalctl _UID=33 --since today
查看某个 Unit 的日志
# journalctl -u nginx.service
# journalctl -u nginx.service --since today
实时滚动显示某个 Unit 的最新日志
# journalctl -u nginx.service -f
合并显示多个 Unit 的日志
# journalctl -u nginx.service -u php-fpm.service --since today
(二)查看指定优先级(及其以上级别)的日志,共有8级
0: emerg
1: alert
2: crit
3: err
4: warning
5: notice
6: info
7: debug
# journalctl -p err -b
日志默认分页输出,–no-pager 改为正常的标准输出
# journalctl --no-pager
以JSON格式(单行)输出
# journalctl -b -u httpd.service -o json
以JSON格式(多行)输出,可读性更好,建议选择多行输出
# journalctl -b -u httpd.service -o json-pretty
显示日志占据的硬盘空间
# journalctl --disk-usage
指定日志文件占据的最大空间
# journalctl --vacuum-size=1G
指定日志文件保存多久
# journalctl --vacuum-time=1years