百度百科对systemd的介绍
systemd即为systemd daemon,是Linux下的一个init软件,由Lennart Poettering带头开发,并在LGPL2.1及其后续版本许可证下开源发布,开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并以此来实现系统初始化时服务的并行启动,同时到达降低shell的系统开销的效果,最终代替常用的system V与BSD风格initial程序。
与其他发行版本的system V风格的init相比,systemd采用以下新技术:
熟悉linux的都知道init是centos6及6以前用来管理服务和软件的方式,从centos7到现在的redhat9(因为centos9还没出)都是使用的systemd来控制
init启动服务使用的是串方式
systemd使用的是并行的方式
init启动服务的种类有独立启动模式和超级守护进程两种类型
systemd使用的是systemctl命令来管理服务的,种类有service、socket、target、path、snapshot、time等等
centos6管理服务,例如设置服务的开机自启需要自行在/etc/rc.d/rc。load文件中写命令,或者在/etc/rc.d目录下编写启动脚本来实现开机自启
centos7则是使用systemctl命令来管理,来管理服务
init自启动时当前服务所依赖其他服务才能启动须,须自行解决
systemd则自行检查启动服务所依赖的服务
通过上面的区别我们也能看出systemd的优势所在
但是init也不是没有优势的,systemd使用systemctl命令来进行管理服务的,命令就以为的固定,但是init使用的shell脚本,我们可以根据自己的需求进行灵活的管理
对于某些支持systemd的服务而言,他们的service文件一般都放在/usr/lib/systemd/system目录下
如果我们设置了某个服务开机自启,那么系统就在/etc/systemd/system目录添加来一个符号链接(或者说软链接),指向/usr/lib/systemd/system里面对应服务service文件。
当你设置禁止开机自启的时候系统就会自动删除/etc/systemd/system/multi-user.target.wants目录下的链接文件
因为系统在开机时,systemd只执行/etc/systemd/system
例如:
// 我这里安装了一个docker,咱们可以看一下
[root@localhost multi-user.target.wants]# pwd
/etc/systemd/system/multi-user.target.wants
[root@localhost multi-user.target.wants]# ll | grep docker.service
lrwxrwxrwx 1 root root 38 Aug 29 18:40 docker.service -> /usr/lib/systemd/system/docker.service
// 查看服务状态
[root@localhost ~]# systemctl status docker.service
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2022-08-30 19:23:50 CST; 3h 3min ago
Docs: https://docs.docker.com
Main PID: 1308 (dockerd)
Tasks: 8
Memory: 118.1M
CGroup: /system.slice/docker.service
└─1308 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
loaded:配置文件所在位置,后面的一个参数表示是否为开机自启
Active:表示正在运行
Main PID:表示主进程的PID号
Status:由应用本身提供的软件当前状态,但是docker没有提供这个参数
CGroup:应用所有的子进程
CGroup下面的都是应用的日志信息
// 下面以sshd服务的配置文件作为案例
[root@localhost ~]# systemctl cat sshd.service // 此命令不仅可以查看service文件内容,而且可以看service文件位置
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
Description字段是当前服务的简单描述
Documentation字段给出命令帮助文档位置
After字段表示如果network.target或sshd-kegen.service需要启动,那么sshd.service要在他们之后启动。
Before字段定义sshd.service应该在哪些服务之前启动(这里没有,可以自行设置)
Wants字段表示sshd.service与sshd-keygen.service之间存在"弱依赖"关系,即如果sshd-keygen.service启动失败或停止运行,不影响sshd.service继续执行。
Requires字段表示"强依赖"关系,即如果该服务启动失败或异常退出,那么sshd.service也必须退出。
Wants字段与Requires字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动的。
BindsTo字段与Requires类似,它指定的unit如果退出,会导致当前unit停止运行
Conflicts:与此栏有冲突的模块,如果列出模块中有已经运行的,这个服务就不能启动,反之亦然。
OnFailure:当这个模块启动失败时,就自动启动列出的每个模块。
Assert字段:当前unit运行必须满足的条件,否则会报启动失败
systemd可以管理所有的系统资源。不同的资源统称为Unit,Unit一共分为12种,使用systemctl -t help命令
service 系统服务
socket 进程间通信的socket
target 多个unit构成的一个组
snapshot systemd快照,可以切回某个快照
device 硬件设备
mount 文件系统的挂载点
automount 自动挂载点
swap swap文件
timer 定时器
path 文件或路径
slice 进程组
scope 不是由systemd启动的外部进程
[root@localhost ~]# systemctl list-units //列出正在运行的unit
[root@localhost ~]# systemctl list-units --all //列出所有的unit
[root@localhost ~]# systemctl list-units --all --state=inactive //列出没有运行的unit
[root@localhost ~]# systemctl list-units --failed //列出启动失败的unit
[root@localhost ~]# systemctl list-units --type=service //列出所有正在运行的、类型为service的unit
[root@localhost ~]# systemctl status //显示系统状态
[root@localhost ~]# systemctl -H root@node1 status docker.service //显示远程主机node1上的unit状态
[root@localhost ~]# systemctl show docker.service //显示某个unit的所有底层参数
[root@localhost ~]# systemctl show -p CPUshares docker.service //显示某个unit的指定属性的值
[root@localhost ~]# systemctl set-property docker.service CPUshares=100 //设置某个unit的指定属性
unit之间存在依赖关系:A依赖B,这也就是说systemd启动A时,同时会去启动B
[root@localhost ~]# systemctl list-dependencies docker.service //列出某个unit的依赖关系
某些 target 类型,默认不会展开显示。如果要展开 target,就需要使用 --all 参数
[root@localhost ~]# systemctl list-dependencies --all docker.service
启动系统的时候,系统会启动大量的unit,若每次启动,都要申明此次要启动的所有unit,显然效率太低。systemd为了解决这个问题所以出现了:target
简单来说target就是一个unit组,启动某个target,systemd就会启动包含在这里target里的unit
[root@localhost ~]# systemctl list-units --type=target //查看当前系统中所有的target
[root@localhost ~]# systemctl set-default multi-user.target //设置默认的target
[root@localhost ~]# systemctl isolate multi-user.target //关闭一个target里面所有不属于后一个target的进程
[root@localhost ~]# systemctl list-dependencies multi-user.target //查看一个target包含的所有unit
常用的target:
名称 | 作用 |
---|---|
basic.target | 启动基本系统,该目标间接包含了所有的本地挂载点单元以及其他必须的系统初始化单元 |
default.target | 默认的启动目标,通常指向multi-user.target或graphical.target的目标 |
graphical.target | 专用于启动图形化登录界面的目标单元,其中包含multi-user.target单元 |
local-fs.target | 专用于集合本地文件系统挂载点的目标单元 |
multi-user.target | 专用于多用户命令行模式下启动的单元。所有在命令行多用户模式下启动的单元[install]栏都应加上WantedBy=multi-user.target |
timers.target | 专用于包含所有应该在系统启动时被启动的timer单元 |
sleep.target | 专用于进入休眠模式的目标单元 |
shutdown.target | 专用于关机过程中的所有单元 |
rescure.target | 专用于启动基本系统并打开一个救援shell时需要启动的单元 |
reboot.target | 专用于重启系统时需要启动的单元 |
halt.target | 专用于关闭系统但不切断电源时启动的单元 |
hibernate.target | 专用于系统休眠到硬盘时启动的单元 |
target和init进程的区别
systemd统一管理所有unit启动日志,好处是可以使用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志配置文件时/etc/systemd/journald.conf
[root@localhost ~]# journalctl //查看所有日志
[root@localhost ~]# journalctl -k //查看内核日志
//查看系统本次启动的日志
[root@localhost ~]# journalctl -b
[root@localhost ~]# journalctl -b -0
[root@localhost ~]# journalctl -b -1 //查看上一次启动的日志
//查看指定时间的日志
[root@localhost ~]# journalctl --since " 20 min ago"
[root@localhost ~]# journalctl --since="也可以写具体的年月日"
[root@localhost ~]# journalctl --since yesterday
[root@localhost ~]# journalctl -n 10 //查看最新的十条日志信息
[root@localhost ~]# journalctl -f //实时查看最新日志信息
[root@localhost ~]# journalctl /usr/lib/systemd/systemd //查看指定服务的日志信息
[root@localhost ~]# journalctl /usr/bin/bash //查看某个路径的脚本日志信息
[root@localhost ~]# journalctl _UID=0 --since today // 查看指定用户的日志
[root@localhost ~]# journalctl -u docker.service // 查看某个unit的日志
[root@localhost ~]# journalctl -u docker.service --since today
一个unit配置文件只能描述一种单元
系统提供两种级别的单元
systemd优先级如下:
系统单元目录 | 优先级 | 单元 |
---|---|---|
/lib/systemd/system | 高 | 本地配置的系统单元 |
/run/systemd/system | 中 | 运行时配置的系统单元 |
/usr/lib/systemd/system | 低 | 软件包安装的系统单元 |
EnvironmentFile字段:指定当前服务的环境参数文件。该文件内部的key=value键值对,可以用$key的形式,在当前配置文件中获取。
ExecStart字段:定义启动进程时执行的命令,在service文件中$OPTIONS变量表示的是EnvironmentFile字段指定的环境参数文件
ExecReload字段:重启服务时执行的命令,$MAINPID变量表示的服务主进程的PID号
ExecStop字段:停止服务时执行的命令
ExecStartPre字段:启动服务前执行的命令
ExecStopPost字段:停止服务后执行的命令
ExecStartPost字段:启动服务后执行的命令
RestartSec: 如果服务需要被重启,这个参数的值为服务被重启前的等待秒数。注意,该重启等待时间只针对Restart的参数值起作用时的重启才有效,因Unit段配置的关系或者人为使用systemctl restart命令导致该服务重启时,则无效。
TimeoutSec:定义systemd停止当前服务之前等待的秒数
Environment:指定环境变量
Nice:服务的进程优先级,值越小优先级越高,默认为0。-20为最高优先级,19为最低优先级
WorkingDirectory:指定服务的工作目录
RootDirectory:指定服务进程的根目录,如果配置了这个参数后,服务将无法访问指定目录以外的任何文件。
User:指定运行服务的用户,会影响服务对本地文件系统的访问权限。可使用root
Group:指定运行服务的用户组,会影响服务对本地文件系统的访问权限。
PrivateTmp:是否给服务分配独立的临时空间(tru/false)
Restart字段:指定什么情况下需要重启服务进程,这个不同的值表示哪些情况下,服务会被重新启动:
no:退出后不会重启
always:除了用systemctl stop或等价的服务停止操作命令,其他情况下都可以重启
on-success:只有正常退出时(退出状态码为0),才会重启
on-failure:非正常退出时(退出状态码不为0),包括被信号终止和超时,才会重启
on-abnormal:只有被信号终止和超时,才会重启(一般用用于允许发生错误的服务)
on-abort:只有在收到没有捕捉到的信号终止时,才会重启
on-watchdog:超时退出,才会重启
killMode字段:定义Systemd如何终止sshd服务
killMode设置为process表示为停止主进程,不会停止sshd的子进程,SSH session仍然保持
killMode可设置值如下:
control-group(默认值):当前控制组面的所有子进程,都会被杀掉
process:只杀主进程
mixed:主进程将收到SIGTERM信号,子进程收到SIGKILL信号
none:没有进程会被杀掉,只是执行服务的stop命令。
关键点:
所有的启动设置前,都可以加一个连词符"-",表示抑制错误,如如果发生错误,也部影响其他命令的执行 EnvironmentFile=-/etc/sysconfig/sshd表示即使/etc/sysconfig/sshd文件不存在,也不会输出错误信息
type字段定义启动类型。
simple(默认值):ExecStart字段启动的进程为主进程
forking:ExecStart字段将以fork()方式启动,此时父进程将退出,子进程将称成为主进程
oneshot:类似simple,但只执行一次,Systemd会等他执行完,才会启动其他服务
dbus:类似于simple,但会等待D-Bus信号后启动
notify:类似于simple,启动结束后会发出通知信号,然后Systemd再启动其他服务
idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为了让该服务的输出,不与其他服务的输出相混合
// 例子
ExecStart=/bin/bash test.sh
ExecStart=
//此时第二行的空值会覆盖掉一行的内容
WantedBy:表示该服务所在的Target。
Target表示的是服务组,表示一组服务。WantedBy=multi-user.target表示的是,sshd所在target是multi-user.target
因为systemctl命令执行开机自启时,会将sshd.service的软链接放在/etc/systemd/system目录下面的multi-user.target.wants目录下
[root@localhost system]# systemctl get-default //获取默认的target
multi-user.target
通过命令我们可以看到默认启动target时multi-user.target。在这个组里所有的服务,都将开机自启。着也就是为什么systemctl enable命令可以设置开机自启的原因
// 查看multi-user.target包含的所有服务
[root@localhost ~]# systemctl list-dependencies multi-user.target
multi-user.target
● ├─auditd.service
● ├─crond.service
● ├─dbus.service
● ├─docker.service
● ├─irqbalance.service
● ├─kdump.service
● ├─network.service
● ├─NetworkManager.service
此处省略N个。。。。。。
一般来说target有两个:一个是multi-user.target表示多用户命令行状态;另一个是graphical.target表示图形用户状态,它依赖于multi-user.target
[root@localhost ~]# systemctl cat multi-user.target
# /usr/lib/systemd/system/multi-user.target
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
主要字段的含义:
Requires字段:要求basic.target一起运行
Conflicts字段:冲突字段。如果rescue.service或rescue.target正在运行,multi-user.target就不能运行,反之。
After字段:表示multi-user.target在basic.target、rescue.service、rescue.target之后启动
AllowIsolate字段:允许使用systemctl isolate命令切换到multi-user.target
[root@localhost ~]# systemctl cat sshd.service // 查看服务的配置文件
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
// 以下命令只做了解,慎用
[root@localhost ~]# systemctl halt //停止cpu工作
[root@localhost ~]# systemctl suspend //暂停系统
[root@localhost ~]# systemctl hibernate //系统进入冬眠模式
[root@localhost ~]# systemctl rescue //进入救援模式(也就是常说的单用户模式)
// 重新加载系统中创建或修改过的配置文件
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl status sshd //查看你服务的状态
[root@localhost ~]# systemctl start sshd //开启sshd服务
[root@localhost ~]# systemctl stop sshd //关闭sshd服务
[root@localhost ~]# systemctl restart sshd //重启sshd服务
[root@localhost ~]# systemctl list-unit-files | grep enabled //列出系统中哪些服务设置了开机自启
[root@localhost ~]# systemctl kill sshd.service //杀掉sshd服务的所有进程,用于服务无法正常关闭的情况
[root@localhost ~]# systemctl is-enabled sshd //查看sshd服务是否设置了开机自启
enabled
[root@localhost ~]# systemctl is-failed sshd //查看sshd服务是否处于启动失败
[root@localhost ~]# systemctl is-active sshd //查看sshd服务是否活跃
[root@localhost ~]# systemctl --failed //列出启动失败的服务
[root@localhost ~]# systemctl list-units --type=service //列出所有已经启动的服务
[root@localhost ~]# systemctl list-unit-files --type=service //列出指定类型的配置文件
[root@localhost ~]# systemctl reset-failed docker.service // 移除标记为丢失的 Unit 文件
[root@localhost ~]# systemd-analyze //查看启动耗时
[root@localhost ~]# systemd-analyze blame
7.932s tuned.service
6.234s containerd.service
5.148s kdump.service
4.060s docker.service
3.885s postfix.service
3.606s lvm2-monitor.service
3.504s initrd-switch-root.service
3.226s dev-mapper-centos\x2droot.device
1.493s polkit.service
1.272s NetworkManager.service
1.161s lvm2-pvscan@8:2.service
此处省略N行。。。。。。。
// 显示瀑布的启动流程
[root@localhost ~]# systemd-analyze critical-chain
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.
multi-user.target @22.209s
└─docker.service @18.148s +4.060s
└─containerd.service @11.907s +6.234s
└─network.target @11.871s
└─network.service @11.213s +657ms
└─NetworkManager-wait-online.service @10.501s +706ms
└─NetworkManager.service @9.221s +1.272s
└─dbus.service @8.336s
└─basic.target @8.295s
└─sockets.target @8.295s
└─docker.socket @8.293s +1ms
└─sysinit.target @8.292s
└─systemd-update-utmp.service @8.242s +47ms
└─auditd.service @7.688s +548ms
└─systemd-tmpfiles-setup.service @7.639s +42ms
└─rhel-import-state.service @7.475s +157ms
└─local-fs.target @7.470s
└─home.mount @7.259s +210ms
└─dev-mapper-centos\x2dhome.device @7.255s
// 查看某个服务的启动流
[root@localhost ~]# systemd-analyze critical-chain sshd.service