Systemd - 当计时器触发另一个一次性服务时,如何自动重新加载单元?

Ale*_*bes 6 systemd

我有两个单元,nginx.service 和 certbot.service,由它们各自的 Debian 软件包提供:

nginx.服务:

[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

certbot.服务:

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true
Run Code Online (Sandbox Code Playgroud)

还有一个计时器 certbot.timer (也由 certbot deb 包提供):

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)

这些都工作正常。

问题是,当计时器触发时,我需要重新加载 nginx,以便 nginx 看到新证书 ( systemctl reload nginx)。

我知道我可以做systemctl edit certbot.service,并添加:

[Service]
ExecStartPost=/bin/systemctl reload nginx
Run Code Online (Sandbox Code Playgroud)

事实上,这就是我所做的,但这是一个拼凑。有没有办法通过本机 systemd 依赖项来实现这一点?棘手的事情是仅触发重新加载,而不是完全重新启动。

Mic*_*ton 2

您可以直接将部署挂钩(不是后挂钩;仅在部署了证书时才需要执行此操作)直接添加到您的域的 certbot 配置中,在/etc/letsencrypt/renewal/example.com.conf.

[renewal]部分中,添加一行,例如:

deploy_hook = systemctl reload nginx
Run Code Online (Sandbox Code Playgroud)

就这些。您不需要对 systemd 单元做奇怪的事情。

  • 我们在这里陷入了一场哲学辩论,但我所说的“某种事情”是指将服务耦合在一起。Systemd 绝对是声明服务依赖关系的正确位置。这是它存在的主要原因之一。我认为这实际上是一个有趣的辩论,但这个评论领域太有限了,所以当我有更多时间时,我将把我对何时使用通用解决方案与特定领域解决方案的想法分解成一篇博客文章。我将链接到这里,对您的想法感兴趣! (3认同)
  • https://blog.al4.co.nz/2019/04/domain-expert-vs-generalist/ (2认同)