如何创建虚拟 systemd 服务来一起停止/启动多个实例?

如何创建虚拟 systemd 服务来一起停止/启动多个实例?

我计划为使用systemd.我希望能够stop使用start每个客户实例systemd,并将整个客户实例集合视为可以一起停止和启动的单个服务。

systemd似乎提供了我需要使用的构建块PartOf和模板单元文件,但是当我停止父服务时,子客户服务并未停止。我怎样才能使这个与 systemd 一起工作?这是我到目前为止所拥有的。

父单元文件,app.service

[Unit]
Description=App Web Service

[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal

名为 的单元模板文件[email protected],用于创建客户实例:

[Unit]
Description=%I Instance of App Web Service

[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal

我的app-poc.sh脚本(仅循环打印到日志文件的概念证明):

#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
  echo "The App PoC loop for $@"
  sleep 2;
done

为了证明概念,我将 systemd 单元文件放在~/.config/systemd/user.

然后,我启动父级和基于模板的实例(之后systemctl --user daemon-reload):

systemctl --user start app
systemctl --user start [email protected]

从使用中journalctl -f我可以看到两者都已启动并且客户实例继续运行。现在我预计关闭父母会阻止孩子(因为我用过PartOf),但事实并非如此。此外,启动父进程也没有按预期启动子进程。

systemctl --user stop app

谢谢!

(我使用的是 Ubuntu 16.04 和 systemd 229)。

答案1

我了解到这就是 systemd“目标单元”的用途。通过使用目标单元,我可以获得我想要的好处,而无需创建[Service]上面的假部分。一个工作示例“目标单元”文件如下所示:

# named like app.target
[Unit]
Description=App Web Service

# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target

然后,每个客户实例都应包含PartOf在该[Unit]部分中(如 @meuh 所指出的),并且还应该有一个[Install]部分,以便enabledisable能够处理特定的服务:

# In a file name like [email protected]
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target

[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal

# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp

# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target

要启动客户实例并使其在目标启动时启动,请使用以下一次性启用命令:

 systemctl enable app

现在,我可以对特定实例使用 和 ,或者我可以使用和stop一起停止所有应用程序。startapp@customerstart appstop app

答案2

你需要移动线路

PartOf=app.service

出入[Service][Unit]部分,并添加到要启动的客户列表[Unit]中,例如app.service

[email protected] [email protected]

或者正如 Sourcejedi 在评论中所说,Requires=同样的事情。您可以保留PartOf上面列表中没有的手动启动的停止服务,例如.systemctl --user start [email protected]

相关内容