避免關閉時關閉 systemd 用戶範圍

避免關閉時關閉 systemd 用戶範圍

我創建了一台 Debian Bookworm 機器作為 LXC 容器管理器。我使用透過 lxc-unpriv-start 命令啟動的非特權 LXC 容器來建立 systemd 使用者範圍。我創建了一項服務,該服務在伺服器啟動時啟動容器,並在服務停止時啟動乾淨關閉。每個容器可能需要 2 到 3 分鐘才能關閉。如果我手動停止主要服務,一切正常。當我關閉伺服器時,問題就出現了,因為我的服務正確地等待容器終止,但同時 systemd-logind 殺死了所有用戶會話,也殘酷地殺死了我的容器。

我模擬創建一個僅睡眠 shell 的情況並執行它

/usr/bin/systemd-run --user --scope -p "Delegate=yes" wait.sh &

它在關閉時被殺死。我怎樣才能避免這種殺戮?

答案1

靈兒應該能解決這個問題。

https://www.freedesktop.org/software/systemd/man/loginctl.html

啟用/停用一名或多名使用者的使用者延遲。如果為特定使用者啟用,則會在啟動時為該使用者產生使用者管理器,並在登出後保留。這允許未登入的用戶運行長時間運行的服務。採用一個或多個使用者名稱或數字 UID 作為參數。如果未指定參數,則為呼叫方會話的使用者啟用/停用延遲。

loginctl enable-linger <username>

為使用者工作階段啟用延遲將使您的容器即使在您登出後或系統關閉期間也能繼續運作。這應該可以防止 systemd-logind 強制終止使用者會話和關聯的容器,從而使它們有機會正常關閉。

答案2

假設容器停止命令「阻塞」(即容器停止後退出),您可以使用 systemd 使用者服務執行容器啟動命令,而不是直接從 shell 執行。假設需要啟動多個容器,可以編寫一個服務模板到$HOME/.config/systemd/user/.服務模板的檔案名稱@前面應該有.service(例如[email protected])。

這是一個供您參考的範例:

[Unit]
PartOf=%i.scope
After=%i.scope

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-run --user --scope -u %i sh -c 'sleep 1d &'
ExecStop=/usr/bin/sleep 1m

正如您所看到的,範圍名稱需要“已知”,而不是產生的名稱。

使用模板,您現在可以使用例如啟動容器systemctl --user start test@container-a。現在您應該看到對應的作用域仍然存在,直到其「代理」服務停止(即命令ExecStop=已退出)。

systemctl --user daemon-reload每當您對服務(模板)文件進行更改時,您可能都需要運行。

PS 顯然,如果您需要將額外的特定於容器的參數(與範圍名稱不同的字串)傳遞給容器啟動/停止命令,您可能必須編寫多個服務文件而不是使用模板。

相關內容