如何建立虛擬 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]

相關內容