Systemd-服务启动顺序

Systemd-服务启动顺序

systemd各种服务都统一在一个成为target的分类集合下,各个target有特定的依赖顺序,例如NTP服务应该依赖network-online.target即网络服务启动完成后再启动,否则有可能服务无法启动。

在systemd管理下各个target的启动顺序如下:

System Manager Bootup

引导时,OS镜像上的系统管理器负责初始化系统运行所需的必需文件系统,服务和驱动程序。在systemd系统上,此过程分为多个离散步骤,这些步骤作为目标单元(target unit)公开。

启动过程高度并行化,因此无法确定达到特定目标单元的顺序,但是仍然遵循限定的顺序结构。

At boot, the system manager on the OS image is responsible for initializing the required file systems, services and drivers that are necessary for operation of the system. On systemd(1) systems, this process is split up in various discrete steps which are exposed as target units. (See systemd.target(5) for detailed information about target units.) The boot-up process is highly parallelized so that the order in which specific target units are reached is not deterministic, but still adheres to a limited amount of ordering structure.

cryptsetup-pre.target veritysetup-pre.target
                                                  |
(various low-level                                v
 API VFS mounts:             (various cryptsetup/veritysetup devices...)
 mqueue, configfs,                                |    |
 debugfs, ...)                                    v    |
 |                                  cryptsetup.target  |
 |  (various swap                                 |    |    remote-fs-pre.target
 |   devices...)                                  |    |     |        |
 |    |                                           |    |     |        v
 |    v                       local-fs-pre.target |    |     |  (network file systems)
 |  swap.target                       |           |    v     v                 |
 |    |                               v           |  remote-cryptsetup.target  |
 |    |  (various low-level  (various mounts and  |  remote-veritysetup.target |
 |    |   services: udevd,    fsck services...)   |             |    remote-fs.target
 |    |   tmpfiles, random            |           |             |             /
 |    |   seed, sysctl, ...)          v           |             |            /
 |    |      |                 local-fs.target    |             |           /
 |    |      |                        |           |             |          /
 \____|______|_______________   ______|___________/             |         /
                             \ /                                |        /
                              v                                 |       /
                       sysinit.target                           |      /
                              |                                 |     /
       ______________________/|\_____________________           |    /
      /              |        |      |               \          |   /
      |              |        |      |               |          |  /
      v              v        |      v               |          | /
 (various       (various      |  (various            |          |/
  timers...)      paths...)   |   sockets...)        |          |
      |              |        |      |               |          |
      v              v        |      v               |          |
timers.target  paths.target   |  sockets.target      |          |
      |              |        |      |               v          |
      v              \_______ | _____/         rescue.service   |
                             \|/                     |          |
                              v                      v          |
                          basic.target         rescue.target    |
                              |                                 |
                      ________v____________________             |
                     /              |              \            |
                     |              |              |            |
                     v              v              v            |
                 display-    (various system   (various system  |
             manager.service     services        services)      |
                     |         required for        |            |
                     |        graphical UIs)       v            v
                     |              |            multi-user.target
emergency.service    |              |              |
        |            \_____________ | _____________/
        v                          \|/
emergency.target                    v
                              graphical.target

复制

System Manager Shutdown

使用systemd进行系统关闭还包括各种目标单元,并应用了一些最小顺序结构:

                                  (conflicts with  (conflicts with
                                    all system     all file system
                                     services)     mounts, swaps,
                                         |           cryptsetup/
                                         |           veritysetup
                                         |          devices, ...)
                                         |                |
                                         v                v
                                  shutdown.target    umount.target
                                         |                |
                                         \_______   ______/
                                                 \ /
                                                  v
                                         (various low-level
                                              services)
                                                  |
                                                  v
                                            final.target
                                                  |
            _____________________________________/ \_________________________________
           /                         |                        |                      \
           |                         |                        |                      |
           v                         v                        v                      v
systemd-reboot.service   systemd-poweroff.service   systemd-halt.service   systemd-kexec.service
           |                         |                        |                      |
           v                         v                        v                      v
    reboot.target             poweroff.target            halt.target           kexec.target

复制

service 怎么设置依赖顺序

启动顺序的依赖在unit Section下面定义

Option Description
Description A short description of the unit.
Documentation A list of URIs referencing documentation.
Before, After The order in which units are started.
Requires If this unit gets activated, the units listed here will be activated as well. If one of the other units gets deactivated or fails, this unit will be deactivated.
Wants Configures weaker dependencies than Requires. If any of the listed units does not start successfully, it has no impact on the unit activation. This is the recommended way to establish custom unit dependencies.
Conflicts If a unit has a Conflicts setting on another unit, starting the former will stop the latter and vice versa.

例如,若一个服务需要在网络基础设置ready的情况下再执行启动,可以这样编写

[Unit]
Wants=network-online.target
After=network.target network-online.target

复制

这里wants指希望network-online.target能成功启动,一般非特殊情况很少使用到Requires强制依赖(即network-online.target一定要启动成功)

After指具体的顺序,服务在network.target network-online.target相关target启动完毕再进行启动

注意,network.target不能保证网络服务已经启动,正常情况应该依赖network-online.target,参考这里

官方文档建议,通过编写更健壮的程序,容忍网络的变化或者失败,才是最佳的解决方案(因为实际我们无法保证网络服务长期稳定不变的运行,在某个时段网络服务可能有一些变化,这个是比较普遍的想象)。

启动顺序依赖有多重要

没有systemd service应该认真考虑其启动顺序依赖,否则有可能出现一些无法预估的问题

举例说,ntp开机启动,有可能会失败,导致系统时间错乱。具体原因由于系统COMS电池没电,系统启动时使用硬件的时间同步时间,导致系统时间与正确时间相比相差数天,ntp在系统时间与实际时间相差大于一定程度时,不会启动

这时候,就需要手工强制同步校对一次系统时间,再启动ntp服务

sudo systemctl stop ntp
sudo /usr/sbin/ntpd -qg
sudo systemctl start ntp

复制

但如何开机时保证ntp.service启动成功呢?这里就可以编写一个oneshot service

[Unit]
Description=ntp force synchronization once
Before=ntp.service
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ntpd -qg
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

复制

这里unit section有3个关键的顺序依赖

  1. Before=ntp.service, 即需要在ntp服务之前启动
  2. Wants=network-online.target,希望网络相关服务能启动成功
  3. After=network.target network-online.target,这个oneshot service需要在网络ready以后才能启动
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片