Linux-Systemd

1. Origin

In history,Linux's journeydirectly usedinitprogress.

The following command is used to start the service.

$ sudo /etc/init.d/apache2 start
# 或者
$ service apache2 start

This approach has two disadvantages.

First, the startup time is long. initThe process is started serially. The next process will not be started until the previous process is started.

Second, the startup script is complicated. initThe process just executes the startup script and does nothing else. The script needs to handle various situations on its own, which often makes the script very long.

2. Systemd Overview

Systemd was born to solve these problems. Its design goal is to provide a complete solution for system startup and management.

According to Linux convention, the lettersd are the abbreviations of daemon. The meaning of the name Systemd is that it protects the entire system.

If you use Systemd, you don't need to use init anymore. Systemd replaced initd and became the first process of the system (PID equal to 1), and other processes are its child processes.

$ systemctl --version

The above command checks the Systemd version.

The advantage of Systemd is that it is powerful and easy to use, but the disadvantage is that the system is huge and very complex. In fact, there are still many people who oppose the use of Systemd on the grounds that it is too complex, strongly coupled with other parts of the operating system, and violates the Unix philosophy of "keep simple, keep stupid".

(The picture above shows the Systemd architecture diagram)

3. System management

Systemd is not a command, but a set of commands that involves all aspects of system management.

3.1 systemctl

systemctlIt is the main command of Systemd and is used to manage the system.

重启系统
$ sudo systemctl reboot

# 关闭系统,切断电源
$ sudo systemctl poweroff

# CPU停止工作
$ sudo systemctl halt

# 暂停系统
$ sudo systemctl suspend

# 让系统进入冬眠状态
$ sudo systemctl hibernate

# 让系统进入交互式休眠状态
$ sudo systemctl hybrid-sleep

# 启动进入救援状态(单用户状态)
$ sudo systemctl rescue

3.2 systemd-analyze

systemd-analyzeThe command is used to check the startup time.

查看启动耗时
$ systemd-analyze                                                                                       

# 查看每个服务的启动耗时
$ systemd-analyze blame

# 显示瀑布状的启动过程流
$ systemd-analyze critical-chain

# 显示指定服务的启动流
$ systemd-analyze critical-chain atd.service

3.3 hostnamectl

hostnamectlThe command is used to view the information of the current host.

显示当前主机的信息
$ hostnamectl

# 设置主机名。
$ sudo hostnamectl set-hostname rhel7

3.4 localectl

localectlCommand is used to view localization settings.

查看本地化设置
$ localectl

# 设置本地化参数。
$ sudo localectl set-locale LANG=en_GB.utf8
$ sudo localectl set-keymap en_GB

3.5 timedatectl

timedatectlCommand is used to view the current time zone setting.

查看当前时区设置
$ timedatectl

# 显示所有可用的时区
$ timedatectl list-timezones                                                                                   

# 设置当前时区
$ sudo timedatectl set-timezone America/New_York
$ sudo timedatectl set-time YYYY-MM-DD
$ sudo timedatectl set-time HH:MM:SS

3.6 loginctl

loginctlThis command is used to view the currently logged in users.

列出当前session
$ loginctl list-sessions

# 列出当前登录用户
$ loginctl list-users

# 列出显示指定用户的信息
$ loginctl show-user ruanyf

4. Unit

4.1 Meaning

Systemd can manage all system resources. Different resources are collectively called Units.

Unit is divided into 12 types in total.

*   Service unit:系统服务
*   Target unit:多个 Unit 构成的一个组
*   Device Unit:硬件设备
*   Mount Unit:文件系统的挂载点
*   Automount Unit:自动挂载点
*   Path Unit:文件或路径
*   Scope Unit:不是由 Systemd 启动的外部进程
*   Slice Unit:进程组
*   Snapshot Unit:Systemd 快照,可以切回某个快照
*   Socket Unit:进程间通信的 socket
*   Swap Unit:swap 文件
*   Timer Unit:定时器

systemctl list-unitsThe command can view all Units in the current system.

列出正在运行的 Unit
$ systemctl list-units

# 列出所有Unit,包括没有找到配置文件的或者启动失败的
$ systemctl list-units --all

# 列出所有没有运行的 Unit
$ systemctl list-units --all --state=inactive

# 列出所有加载失败的 Unit
$ systemctl list-units --failed

# 列出所有正在运行的、类型为 service 的 Unit
$ systemctl list-units --type=service

4.2 Status of Unit

systemctl statusCommands are used to view the system status and the status of individual Units.

显示系统状态
$ systemctl status

# 显示单个 Unit 的状态
$ sysystemctl status bluetooth.service

# 显示远程主机的某个 Unit 的状态
$ systemctl -H [[email protected]](mailto:[email protected]) status httpd.service

In addition to the status command, systemctl also provides three simple methods for querying status, which are mainly used for judgment statements inside the script.

显示某个 Unit 是否正在运行
$ systemctl is-active application.service

# 显示某个 Unit 是否处于启动失败状态
$ systemctl is-failed application.service

# 显示某个 Unit 服务是否建立了启动链接
$ systemctl is-enabled application.service

4.3 Unit Management

For users, the most commonly used commands are the following commands, which are used to start and stop Units (mainly services).

立即启动一个服务
$ sudo systemctl start apache.service

# 立即停止一个服务
$ sudo systemctl stop apache.service

# 重启一个服务
$ sudo systemctl restart apache.service

# 杀死一个服务的所有子进程
$ sudo systemctl kill apache.service

# 重新加载一个服务的配置文件
$ sudo systemctl reload apache.service

# 重载所有修改过的配置文件
$ sudo systemctl daemon-reload

# 显示某个 Unit 的所有底层参数
$ systemctl show httpd.service

# 显示某个 Unit 的指定属性的值
$ systemctl show -p CPUShares httpd.service

# 设置某个 Unit 的指定属性
$ sudo systemctl set-property httpd.service CPUShares=500

4.4 Dependencies

There is a dependency relationship between Units: A depends on B, which means that when Systemd starts A, it will also start B.

systemctl list-dependenciesThe command lists all dependencies of a Unit.

$ systemctl list-dependencies nginx.service

Among the output results of the above command, some dependencies are of Target type (see details below) and will not be expanded and displayed by default. If you want to expand Target, you need to use the --all parameter.

$ systemctl list-dependencies --all nginx.service

5. Unit configuration file

5.1 Overview

Each Unit has a configuration file that tells Systemd how to start the Unit.

Systemd reads configuration files from directory/etc/systemd/system/ by default. However, most of the files stored there are symbolic links pointing to the directory/usr/lib/systemd/system/, where the real configuration files are stored.

systemctl enableThe command is used to establish a symbolic link relationship between the above two directories.

$ sudo systemctl enable [email protected]
# 等同于
$ sudo ln -s '/usr/lib/systemd/system/[email protected]' '/etc/systemd/system/multi-user.target.wants/[email protected]'

If startup is set in the configuration file, the systemctl enable command is equivalent to activating startup.

Correspondingly, the systemctl disable command is used to cancel the symbolic link relationship between two directories, which is equivalent to canceling the startup.

$ sudo systemctl disable [email protected]

The suffix name of the configuration file is the type of Unit, such assshd.socket. If omitted, Systemd's default suffix is ​​.service, so sshd will be understood as sshd.service.

5.2 Status of configuration files

systemctl list-unit-filesCommand is used to list all configuration files.

列出所有配置文件
$ systemctl list-unit-files

# 列出指定类型的配置文件
$ systemctl list-unit-files --type=service

This command will output a list.

$ systemctl list-unit-files

UNIT FILE              STATE
chronyd.service        enabled
[email protected]         static
[email protected]     disabled

This list shows the status of each profile, of which there are four.

*   enabled:已建立启动链接
*   disabled:没建立启动链接
*   static:该配置文件没有`[Install]`部分(无法执行),只能作为其他配置文件的依赖
*   masked:该配置文件被禁止建立启动链接

Note that it is not possible to tell from the status of the configuration file whether the Unit is running. This must execute the previously mentioned systemctl status command.

$ systemctl status bluetooth.service

Once the configuration file is modified, SystemD must reload the configuration file and then restart, otherwise the modification will not take effect.

$ sudo systemctl daemon-reload
$ sudo systemctl restart httpd.service

5.3 Format of configuration file

Configuration files are ordinary text files that can be opened with a text editor.

systemctl catcommand to view the contents of the configuration file.

$ systemctl cat atd.service

[Unit]
Description=ATD daemon

[Service]
Type=forking
ExecStart=/usr/bin/atd

[Install]
WantedBy=multi-user.target

As you can see from the above output, the configuration file is divided into several blocks. The first line of each block is the distinguished name expressed in square brackets, such as [Unit]. Note that the block names and field names of the configuration file are case-sensitive.

Inside each block are some key-value pairs connected with an equal sign.

[Section]
Directive1=value
Directive2=value

. . .

Note that there cannot be spaces on either side of the equal sign in the key-value pair.

5.4 Sections of the configuration file

[Unit]The block is usually the first block in the configuration file and is used to define the metadata of the Unit and the relationship between the configuration and other Units. Its main fields are as follows.

*   `Description`:简短描述
*   `Documentation`:文档地址
*   `Requires`:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
*   `Wants`:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
*   `BindsTo`:与`Requires`类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
*   `Before`:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
*   `After`:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
*   `Conflicts`:这里指定的 Unit 不能与当前 Unit 同时运行
*   `Condition...`:当前 Unit 运行必须满足的条件,否则不会运行
*   `Assert...`:当前 Unit 运行必须满足的条件,否则会报启动失败

[Install]It is usually the last block of the configuration file and is used to define how to start and whether to start at boot. Its main fields are as follows.

*   `WantedBy`:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入`/etc/systemd/system`目录下面以 Target 名 + `.wants`后缀构成的子目录中
*   `RequiredBy`:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入`/etc/systemd/system`目录下面以 Target 名 + `.required`后缀构成的子目录中
*   `Alias`:当前 Unit 可用于启动的别名
*   `Also`:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

[Service]The block is used for Service configuration. Only Units of Service type have this block. Its main fields are as follows.

*   `Type`:定义启动时的进程行为。它有以下几种值。
*   `Type=simple`:默认值,执行`ExecStart`指定的命令,启动主进程
*   `Type=forking`:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
*   `Type=oneshot`:一次性进程,Systemd 会等当前服务退出,再继续往下执行
*   `Type=dbus`:当前服务通过D-Bus启动
*   `Type=notify`:当前服务启动完毕,会通知`Systemd`,再继续往下执行
*   `Type=idle`:若有其他任务执行完毕,当前服务才会运行
*   `ExecStart`:启动当前服务的命令
*   `ExecStartPre`:启动当前服务之前执行的命令
*   `ExecStartPost`:启动当前服务之后执行的命令
*   `ExecReload`:重启当前服务时执行的命令
*   `ExecStop`:停止当前服务时执行的命令
*   `ExecStopPost`:停止当其服务之后执行的命令
*   `RestartSec`:自动重启当前服务间隔的秒数
*   `Restart`:定义何种情况 Systemd 会自动重启当前服务,可能的值包括`always`(总是重启)、`on-success`、`on-failure`、`on-abnormal`、`on-abort`、`on-watchdog
`*   `TimeoutSec`:定义 Systemd 停止当前服务之前等待的秒数
*   `Environment`:指定环境变量

For the complete field list of the Unit configuration file, please refer tothe official documentation.

6. Target

When starting the computer, a large number of Units need to be started. It would obviously be very inconvenient if every time you start, you have to specify which Units are needed for this start. Systemd's solution is Target.

Simply put, Target is a Unit group that contains many related Units. When a Target is started, Systemd will start all Units in it. In this sense, the concept of Target is similar to "state point". Starting a Target is like starting a certain state.

TraditionalinitIn startup mode, there is the concept of RunLevel, which is very similar to Target. The difference is that RunLevel is mutually exclusive. It is impossible for multiple RunLevel to be started at the same time, but multiple Targets can be started at the same time.

查看当前系统的所有 Target
$ systemctl list-unit-files --type=target

# 查看一个 Target 包含的所有 Unit
$ systemctl list-dependencies multi-user.target

# 查看启动时的默认 Target
$ systemctl get-default

# 设置启动时的默认 Target
$ sudo systemctl set-default multi-user.target

# 切换 Target 时,默认不关闭前一个 Target 启动的进程,
# systemctl isolate 命令改变这种行为,
# 关闭前一个 Target 里面所有不属于后一个 Target 的进程
$ sudo systemctl isolate multi-user.target

The corresponding relationship between Target and traditional RunLevel is as follows.


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

The main differences from theinit process are as follows.

**(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`目录里面的修改可以覆盖原始设置。

7. Log management

Systemd centrally manages the startup logs of all Units. The advantage is that you can view all logs (kernel logs and application logs) with just one command. The log configuration file is. journalctl/etc/systemd/journald.conf

journalctlIt has powerful functions and many uses.

查看所有日志(默认情况下 ,只保存本次启动的日志)
$ sudo journalctl

# 查看内核日志(不显示应用日志)
$ sudo journalctl -k

# 查看系统本次启动的日志
$ sudo journalctl -b
$ sudo journalctl -b -0

# 查看上一次启动的日志(需更改设置)
$ sudo journalctl -b -1

# 查看指定时间的日志
$ sudo journalctl --since="2012-10-30 18:17:16"
$ sudo journalctl --since "20 min ago"
$ sudo journalctl --since yesterday
$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$ sudo journalctl --since 09:00 --until "1 hour ago"

# 显示尾部的最新10行日志
$ sudo journalctl -n

# 显示尾部指定行数的日志
$ sudo journalctl -n 20

# 实时滚动显示最新日志
$ sudo journalctl -f

# 查看指定服务的日志
$ sudo journalctl /usr/lib/systemd/systemd

# 查看指定进程的日志
$ sudo journalctl _PID=1

# 查看某个路径的脚本的日志
$ sudo journalctl /usr/bin/bash

# 查看指定用户的日志
$ sudo journalctl _UID=33 --since today

# 查看某个 Unit 的日志
$ sudo journalctl -u nginx.service
$ sudo journalctl -u nginx.service --since today

# 实时滚动显示某个 Unit 的最新日志
$ sudo 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
$ sudo journalctl -p err -b

# 日志默认分页输出,--no-pager 改为正常的标准输出
$ sudo journalctl --no-pager

# 以 JSON 格式(单行)输出
$ sudo journalctl -b -u nginx.service -o json

# 以 JSON 格式(多行)输出,可读性更好
$ sudo journalctl -b -u nginx.serviceqq
-o json-pretty

# 显示日志占据的硬盘空间
$ sudo journalctl --disk-usage

# 指定日志文件占据的最大空间
$ sudo journalctl --vacuum-size=1G

# 指定日志文件保存多久
$ sudo journalctl --vacuum-time=1years

Guess you like

Origin blog.csdn.net/qq_45707966/article/details/133999031