Linux

systemd 噩夢 - 訂購我的服務,使其在啟動時啟動並在需要時重新啟動

  • January 13, 2022

我無法圍繞 systemd 單元文件。

這是我的場景,我有一個名為:my.service

my.service需要在啟動後的某個時間啟動,只要其他一切準備就緒,不要著急。

my.service啟動一個 docker 容器,所以我想在啟動my.service之前啟動docker.service(我的系統上可能禁用了docker.service)。

每當重新啟動docker.service和/或management.service時,我希望my.service也重新啟動(在 docker 和管理之後)。

my.service需要在management.service之後啟動

現在我在 Requires=, After=, Wants= BindsTo= ReloadPropagatedFrom= 等之間很困惑…我一直在使用它們的組合,但它似乎沒有啟動docker.servicemy.service

[Unit]
Description=test
Requires=management.service
After=multi-user.target
Wants=docker.service management.service multi-user.target
BindsTo=docker.service management.service
ReloadPropagatedFrom=docker.service

[Service]
ExecStartPre=/usr/bin/start.sh
ExecStop=/usr/bin/stop.sh
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target

我究竟做錯了什麼?

查看systemd.unit手冊頁以查看描述,我已將它們包含在下面,但會盡力解釋。

Requires是強依賴。如果my.service被啟動,那麼之後列出的任何內容Requires=也會被啟動。如果後面列出的單元之一Requires=明確停止,那麼my.service也被停止。如果沒有Before=After=用於設置排序my.service和後面列出的單元,Requires=則它們將同時啟動。

Wants是較弱的依賴。如果已啟動,則後面列出的單元Wants=my.service啟動。但是,如果列出的單元在啟動時出現問題,那麼它確實會停止my.service啟動。

BindsTo是比 Requires 更強的依賴。這就像需要,但是如果出於任何原因在BindsTo=停止之後列出的服務my.service也將被停止。

After並且Before都用於指定訂單。它們是、 和的獨立設置Requires,但可以與它們一起使用來指定服務的啟動順序。Wants``BindsTo

PropagatesReloadToPropagatesReloadFrom用於在多個單元中排隊重新載入。如果my.service指定PropagatesReloadTo=docker.service,則重新載入my.service也會重新載入docker.service。如果my.service指定PropagatesReloadFrom=docker.service,則重新載入docker.service也會重新載入my.service

或多或少建議Wants在可能的情況下使用Requiresor BindsTo

不要與WantsRequires和重疊服務BindsTo。確定哪個適合您要指定的單元文件的服務需求並使用它。

每當重新啟動 docker.service 和/或 management.service 時,我希望 my.service 也重新啟動(在 docker 和管理之後)。

如果您想在另一個服務重新啟動時重新啟動一個服務,那麼您可以PartOf=使用Requires.

PartOf= 配置與 Requires= 類似的依賴項,但僅限於停止和重新啟動單元。當 systemd 停止或重新啟動此處列出的單元時,該操作將傳播到該單元。請注意,這是一種單向依賴——對此單元的更改不會影響列出的單元。

my.service 啟動一個 docker 容器,所以我想在啟動 my.service 之前啟動 docker.service(我的系統上可能禁用了 docker.service)。

After=docker.service management.service設置my.service為在之後啟動docker.servicemanagement.service因為您希望按照上面列出的方式重新啟動,請使用PartOf=docker.service management.service. 如果您不需要傳播重啟,那麼您可能會在 、 和 之間Wants做出Requires決定BindsTo。不過盡量不要創建不必要的強依賴關係。

然後

需要=
配置對其他單元的需求依賴。如果這個單位被啟動,這裡列出的單位也將被啟動。如果其他單元之一未能啟動,並且排序依賴 After= 在
設置失敗單元,該單元將不會啟動。此外,無論是否指定 After=,如果其他單元之一被顯式停止,則該單元將停止。此選項可以指定多次或
可以在一個選項中指定多個空格分隔的單元,在這種情況下,將為所有列出的名稱創建需求依賴項。請注意,需求依賴關係不會影響服務的順序
啟動或停止。這必須使用 After= 或 Before= 選項獨立配置。如果單元 foo.service 需要一個單元 bar.service 配置為 Requires= 並且沒有排序配置為
After= 或 Before=,如果 foo.service 被啟動,那麼兩個單元將同時啟動並且它們之間沒有任何延遲。通常,使用 Wants= 而不是 Requires= 是更好的選擇,以實現
在處理失敗的服務時更健壯的系統。

請注意,這種依賴類型並不意味著當該單元執行時另一個單元必須始終處於活動狀態。具體來說:條件檢查失敗(例如 ConditionPathExists=,
ConditionPathIsSymbolicLink=, ... — 見下文)不會導致具有 Requires= 依賴項的單元的啟動作業失敗。此外,某些單元類型可能會自行停用(例如,服務程序可能會決定
乾淨地退出,或者使用者可能會拔下設備),這不會傳播到具有 Requires= 依賴項的單元。將 BindsTo= 依賴類型與 After= 一起使用,以確保一個單元永遠不會在
沒有特定其他單元的活動狀態也處於活動狀態(見下文)。
想要=
Requires= 的弱版本。如果配置單元是,則將啟動此選項中列出的單元。但是,如果列出的單位未能啟動或無法添加到交易中,則不影響有效性
交易的整體。這是將一個單元的啟動與另一單元的啟動掛鉤的推薦方法。
之前=,之後=
這兩個設置需要一個以空格分隔的單位名稱列表。它們配置單元之間的排序依賴關係。如果一個單元 foo.service 包含一個設置 Before=bar.service 並且兩個單元都正在啟動,
bar.service 的啟動會延遲到 foo.service 完成啟動。請注意,此設置獨立於並正交於由 Requires=、Wants= 或 BindsTo= 配置的需求依賴關係。這是
在 After= 和 Requires= 選項中包含單元名稱的常見模式,在這種情況下,列出的單元將在配置有這些選項的單元之前啟動。這個選項可以指定更多
不止一次,在這種情況下,會為所有列出的名稱創建排序依賴項。After= 是 Before= 的倒數,即 After= 確保配置的單元在列出的單元完成啟動後啟動
up, Before= 確保相反的情況,即配置的單元在列出的單元啟動之前完全啟動。請注意,當兩個具有順序依賴關係的單元關閉時,
應用啟動順序。即,如果一個單元在另一個單元上配置了 After=,如果兩者都關閉,則前者在後者之前停止。給定兩個單元,它們之間有任何排序依賴關係,如果一個單元
一個是關機,另一個是開機,關機是在開機前命令的。在這種情況下,排序依賴項是 After= 還是 Before= 都沒有關係。兩者中的哪一個關閉也沒關係
down,只要一個關閉,另一個啟動。在所有情況下,在啟動之前都會下令關閉。如果兩個單元之間沒有順序依賴關係,則將它們關閉或啟動
同時,並且沒有排序發生。當一個單元精確地完成啟動時,這取決於單元類型。最重要的是,對於服務單元來說,啟動被認為是完成的目的
Before=/After= 當其所有配置的啟動命令都已被呼叫並且它們失敗或報告啟動成功時。
綁定到 =
配置需求依賴,風格與 Requires= 非常相似。但是,這種依賴類型更強:除了 Requires= 的效果外,它聲明如果綁定到的單元停止,該單元將
也被阻止。這意味著綁定到另一個單元的單元突然進入非活動狀態也將被停止。單元可能由於不同的原因突然、意外地進入非活動狀態:服務的主程序
單元可能會自行終止,設備單元的備份設備可能會被拔出,或者安裝單元的安裝點可能會在系統和服務管理器不參與的情況下被解除安裝。

當在同一單元上與 After= 結合使用時,BindsTo= 的行為會更加強大。在這種情況下,嚴格綁定到的單元必須處於活動狀態才能使該單元也處於活動狀態。這不
僅表示綁定到另一個單元的單元突然進入非活動狀態,還表示綁定到另一個單元由於條件檢查失敗而被跳過(例如 ConditionPathExists=,
ConditionPathIsSymbolicLink=, ... — 見下文)將被停止,如果它正在執行。因此,在許多情況下,最好將 BindsTo= 與 After= 結合使用。
PropagatesReloadTo=, ReloadPropagatedFrom=
一個或多個單元的空格分隔列表,該單元上的重新載入請求將被傳播到該單元,或者另一個單元上的重新載入請求將分別傳播到該單元。發出重新載入請求
unit 還將自動將重新載入請求排入所有單元上,重新載入請求應通過這兩個設置傳播到。

引用自:https://unix.stackexchange.com/questions/686096