systemd 噩梦 - 订购我的服务,以便它在启动时启动并在需要时重新启动

systemd 噩梦 - 订购我的服务,以便它在启动时启动并在需要时重新启动

我无法理解 systemd 单元文件。

这是我的场景,我有一个名为:我的服务

我的服务需要在启动后的某个时间启动,只要其他一切都准备好了,就不用着急。

我的服务启动一个 docker 容器,所以我想启动docker.service在开始之前我的服务(它可能是docker.service在我的系统上被禁用)。

每当docker.service和/或当管理.服务已重新启动,我想要我的服务也要重新启动(在 docker 和管理之后)。

我的服务需要在之后启动管理.服务

现在我对 Requires=、After=、Wants= BindsTo= ReloadPropagatedFrom= 等之间感到很困惑...我一直在使用这些的组合,但它似乎没有开始docker.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

我究竟做错了什么?

答案1

查看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也将被停止。

AfterBefore都用于指定顺序。它们是独立于RequiresWants和 的设置BindsTo,但可以与它们一起使用来指定服务的启动顺序。

PropagatesReloadToPropagatesReloadFrom用于跨多个单元排队重新加载。如果my.service指定PropagatesReloadTo=docker.service,则重新加载my.service也会重新加载docker.service。如果my.service指定PropagatesReloadFrom=docker.service,则重新加载docker.service也会重新加载my.service

或多或少建议Wants在可能的情况下使用RequiresBindsTo

请勿将服务与WantsRequires、 和重叠BindsTo。确定哪个适合您要指定的单元文件的服务需求并使用它。

每当 docker.service 和/或 management.service 重新启动时,我希望 my.service 也重新启动(在 docker 和 management 之后)。

如果您想在另一个服务重新启动时重新启动一个服务,那么您可以使用PartOf=代替Requires

PartOf= 配置与 Requires= 类似的依赖关系,但仅限于停止和重新启动单元。当 systemd 停止或重新启动此处列出的单元时,操作将传播到该单元。请注意,这是一种单向依赖关系 - 对此单位的更改不会影响列出的单位。

my.service 启动一个 docker 容器,因此我想在启动 my.service 之前启动 docker.service (docker.service 可能在我的系统上被禁用)。

After=docker.service management.service设置为在和my.service之后启动因为您希望按照上面列出的方式重新启动,请使用.如果您不需要传播重新启动,那么您可能会在、和之间做出决定。但尽量不要创建不必要的强依赖关系。docker.servicemanagement.servicePartOf=docker.service management.serviceWantsRequiresBindsTo

然后

需要=
    配置对其他单元的需求依赖性。如果该单位被激活,此处列出的单位也将被激活。如果其他单元之一未能激活,并且排序依赖性 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= 并不重要。两者中哪一个被关闭也并不重要
    关闭,只要关闭一个并启动另一个即可。在所有情况下,关闭都是在启动之前命令的。如果两个单元之间没有顺序依赖性,则它们将被关闭或启动
    同时,并且不会发生任何排序。设备何时完成启动取决于设备类型。最重要的是,对于服务单位来说,启动被视为已完成,目的是
    Before=/After= 当其配置的所有启动命令都已被调用并且它们失败或报告启动成功时。
绑定到=
    配置需求依赖关系,风格与 Requires= 非常相似。然而,这种依赖类型更强:除了 Requires= 的效果之外,它还声明如果绑定到的单元停止,该单元将
    也被阻止。这意味着与突然进入非活动状态的另一个单元绑定的单元也将被停止。由于不同的原因,单元可能会突然、意外地进入非活动状态:服务的主进程
    单元可能会自行终止,设备单元的支持设备可能会被拔掉,或者安装单元的安装点可能会在系统和服务管理器不参与的情况下被卸载。

    当在同一单元上与 After= 结合使用时,BindsTo= 的行为甚至更强。在这种情况下,严格绑定的单元必须处于活动状态,该单元也处于活动状态。这不
    仅表示绑定到另一个单元的单元突然进入非活动状态,而且还表示绑定到另一个单元的单元由于条件检查失败而被跳过(例如 ConditionPathExists=,
    ConditionPathIsSymbolicLink=, ... — 见下文)如果正在运行,将被停止。因此,在许多情况下,最好将 BindsTo= 与 After= 结合起来。
PropagatesReloadTo=, ReloadPropagatedFrom=
    一个或多个单元的空格分隔列表,该单元上的重新加载请求将被传播到该单元,或者另一个单元上的重新加载请求将被传播到该单元。发出重新加载请求
    单元还将自动将重新加载请求排队到所有单元上,重新加载请求将通过这两个设置传播到这些单元。

相关内容