systemd oneshot 服务在几周后停止运行

systemd oneshot 服务在几周后停止运行

我有一个在关机时运行的 systemd 服务。如果主机的磁盘空间不足,它会运行一个脚本清除存储在 Ubuntu 22.04 AWS VM 上的所有 docker 镜像。

# cat /lib/systemd/system/purge-docker.service
[Unit]
Description=Purge all Docker files on reboot if we're running low on disk space
After=syslog.service network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=/usr/local/sbin/purge-docker.sh lowdisk
Restart=on-failure
RestartSec=1s

[Install]
WantedBy=multi-user.target

服务已启动并启用。它运行了几个星期,成功将输出记录到系统日志中:

-- Boot c39eb40835574e229dddde806da40539 --
Jun 11 15:30:43 i-023416ba5deadbeef systemd[1]: Finished Purge all Docker files on reboot if we're running low on disk space.
Jun 11 15:33:25 i-023416ba5deadbeef systemd[1]: Stopping Purge all Docker files on reboot if we're running low on disk space...
Jun 11 15:33:25 i-023416ba5deadbeef purge-docker.sh[35434]: Plenty of free space, not purging docker files
Jun 11 15:33:27 i-023416ba5deadbeef systemd[1]: purge-docker.service: Deactivated successfully.
Jun 11 15:33:27 i-023416ba5deadbeef systemd[1]: Stopped Purge all Docker files on reboot if we're running low on disk space.

它运行良好几个星期,在 AWS 实例重新启动或关闭时执行其应该执行的操作,然后停止工作并停止将任何内容记录到系统日志中。systemctl status显示:

# systemctl status purge-docker
○ purge-docker.service - Purge all Docker files on reboot if we're running low on disk space
     Loaded: loaded (/lib/systemd/system/purge-docker.service; enabled; vendor preset: enabled)
     Active: inactive (dead)

因此它已启用但处于非活动状态。由于它已启用,我希望它在下次启动 VM 时重新启动,但它永远不会再次启动。已启用服务的符号链接/etc/systemd/system/multi-user.target.wants/purge-docker.service已消失,而符号链接是导致 systemd 在启动时启动已启用服务的原因。

如果我输入systemctl enable purge-docker它会重新添加丢失的链接到服务文件:

# systemctl enable purge-docker
Created symlink /etc/systemd/system/multi-user.target.wants/purge-docker.service → /lib/systemd/system/purge-docker.service.

之后状态仍然显示相同的内容(已启用),但现在它实际上已启用:

# systemctl status purge-docker
○ purge-docker.service - Purge all Docker files on reboot if we're running low on disk space
     Loaded: loaded (/lib/systemd/system/purge-docker.service; enabled; vendor preset: enabled)
     Active: inactive (dead)

更奇怪的是:如果我disable随后enable执行服务,disable删除与创建(multi-user.target.wants)不同的符号链接(shutdown.target.wants enable):

# systemctl disable purge-docker
Removed /etc/systemd/system/shutdown.target.wants/purge-docker.service.
# systemctl enable purge-docker
Created symlink /etc/systemd/system/multi-user.target.wants/purge-docker.service → /lib/systemd/system/purge-docker.service.

我的问题是:

  • 符号链接为什么消失了?
  • 为什么即使缺少符号链接,systemd 也会说服务已启用?
  • 为什么shutdown.target.wants当出现故障时,虚拟机上会出现符号链接?

答案1

符号链接为什么消失了?

有东西正在删除它。

如果 Ubuntu 具有内核审计支持,请添加审计规则来跟踪文件的任何更改 -auditctl直接使用(非持久性)或将其添加到/etc/audit/audit.rules(持久性):

-a always,exit -w /etc/systemd/system/multi-user.target.wants/purge-docker.service -S all

然后,您的dmesg(或 下的日志_TRANSPORT=audit)将包含触及此文件的每个系统调用的条目,记录程序的命令行和所有内容。不过,以下内容对于解码 dmesg 中的消息很有用:

perl -pe 's/(?<=proctitle=)([0-9A-F]+)/join(" ", map {"\"$_\""} split("\0", $1 =~ s![0-9A-F]{2}!chr hex $&!ger))/ge'

为什么即使缺少符号链接,systemd 也会说服务已启用?

检查依据是任何.wants/unit (或任何 .target?)在或下具有该服务的符号链接.requires/,但不一定是否与 [Install] 部分完全匹配。

为什么当出现故障时,虚拟机上会出现 shutdown.target.wants 符号链接?

我不知道,但我的荒野猜测可能是同事将其移到那里。


(此外,您的自定义单元文件最好位于 /etc 中,而不是 /lib 中。通常 /lib 是“包管理器”区域。)

相关内容