我有一个 systemd 服务,它具有:
[Unit]
After=network-online.target krb5-kdc.service krb5-admin-server.service
Wants=krb5-kdc.service network-online.target krb5-admin-server.service
除非网络堆栈已完全准备就绪/完全可用,并且 Kerberos 服务已启动,否则服务不应启动。(这就是我想要实现的,当这两者都不成立时,我的服务就不应该尝试启动)。
我的单元文件似乎可以正常使用。
重新启动时,从 grub2 菜单,如果我选择“*Ubuntu 的高级选项”,然后为我的内核选择“恢复模式”,然后打开 root shell,并且不运行“启用网络”,我可以看到我的服务尝试启动(并且随后失败,因为它需要完全运行的网络以及 kerberos 服务)。
我必须进行什么更改才能使服务在网络堆栈完全可用且 Kerberos 服务启动之前不会启动?
在恢复模式 root shell 中(没有“启用网络”):
systemctl list-units --type target
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
cryptsetup.target loaded active active Encrypted Volumes
friendly-recovery.target loaded active active Friendly Recovery Mode
local-fs-pre.target loaded active active Local File Systems (Pre)
local-fs.target loaded active active Local File Systems
network-online.target loaded active active Network is Online
network-pre.target loaded active active Network (Pre)
network.target loaded active active Network
paths.target loaded active active Paths
slices.target loaded active active Slices
sockets.target loaded active active Sockets
sound.target loaded active active Sound Card
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
time-sync.target loaded active active System Time Synchronized
timers.target loaded active active Timers
在上面的列表中,我没有看到任何 kerberos 服务,而且我不知道为什么目标 network.online 处于活动状态,它一定意味着与我的假设不同的东西。
在启动进入恢复模式期间,我还在控制台上看到:
[ DEPEND ] Dependency failed for Network Manager wait online
...
Reached Target Network is online
但是,网络无法正常运行:我无法 ping 通此主机名的静态 IP4 地址(结果: 网络不可达)。我无法引用本地网络上的任何其他计算机,尽管我可以 ping 127.0.0.1。因此,网络尚未完全运行,而这正是我想要避免的,即我希望我的服务仅在网络完全运行时启动。
似乎我还没有理解目标网络在线的真正含义?
当我的服务尝试启动时,它会超时,因为相关服务不可用,所以systemctl status myservice.service
显示
● myservice.service - description
Loaded: loaded (/etc/systemd/system/myservice.service; enabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: timeout) since Fri 2020-07-24 16:40:45 BST; 7s ago
Process: 1396 ExecStartPre=/usr/local/bin/get_kerberos_tickets.ksh (code=killed, signal=HUP)
Tasks: 0
Memory: 3.4M
CPU: 529ms
Jul 24 16:40:45 t7810 systemd[1]: myservice.service: Unit entered failed state.
Jul 24 16:40:45 t7810 systemd[1]: myservice.service: Failed with result 'timeout'.
如果我修改我的单元文件以添加multi-user.target
到 WANTS 和 AFTER 行,那么我的服务也会尝试启动,即使根 shell 显示systemctl list-units -target
有 multi-user.target“已加载非活动已死”。
答案1
这恢复模式在您的系统负载上network-online.target
。
运行命令
systemctl list-units --type target
列出在恢复模式下加载的目标。
线路
network-online.target loaded active active Network is Online
显示网络服务已加载。因此您的系统运行正常。
一个想法是使用Conflicts
,从systemd.units(7)
Conflicts= A space-separated list of unit names. Configures negative requirement dependencies. If a unit has a Conflicts= setting on another unit, starting the former will stop the latter and vice versa. Note that this setting does not imply an ordering dependency, similarly to the Wants= and Requires= dependencies described above. This means that to ensure that the conflicting unit is stopped before the other unit is started, an After= or Before= dependency must be declared. It doesn't matter which of the two ordering dependencies is used, because stop jobs are always ordered before start jobs, see the discussion in Before=/After= below. If unit A that conflicts with unit B is scheduled to be started at the same time as B, the transaction will either fail (in case both are required parts of the transaction) or be modified to be fixed (in case one or both jobs are not a required part of the transaction). In the latter case, the job that is not required will be removed, or in case both are not required, the unit that conflicts will be started and the unit that is conflicted is stopped.
当进入 grub 中的恢复模式时,systemd 开始到达 friendly-recovery.target。因此,尝试在您的服务单元中设置此语句:
Conflicts=friendly-recovery.target
这应该可以防止在恢复模式下启动您的服务。