我有一个在关机时运行的 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 是“包管理器”区域。)