为什么大多数 systemd 示例都包含 WantedBy=multi-user.target?

Car*_*arl 72 systemd

我已经阅读了什么是 multi-user.targetsystemd 文档,其中指出 multi-user.target 是一个特殊的目标。此外,许多systemd 示例都包含该行。

  1. 为什么这么多示例服务都包含该行?
  2. 如果它们不包含 WantedBy=multi-user.target 会发生什么?
  3. 您能给我举个例子,说明什么时候实际上最好不要在服务文件定义中包含该行?
  4. 同样,什么时候保持这条线是个好主意?

tel*_*coM 88

1.)multi-user.target基本上是经典 SysVinit 运行级别 3 的最接近等价物systemd。当systemd系统启动时,systemd试图使系统状态与指定的状态匹配default.target- 通常是graphical.target或的别名multi-user.target

multi-user.target通常定义一个系统状态,其中所有网络服务都已启动,系统将接受登录,但未启动本地 GUI。这是服务器系统的典型默认系统状态,服务器系统可能是远程服务器机房中的机架式无外设系统。

graphical.target是另一个可能的别名default.target。通常它被定义为 的超集multi-user.target:它包括所做的一切multi-user.target,加上本地 GUI 登录的激活。有点像经典 SysVinit 中的运行级别 5。

WantedBy=multi-user.target服务中的行本质上与在 SysVinit 系统中指定“此服务应在运行级别 3、4 和 5 中启动”相同:它告诉systemd此服务应作为正常系统启动的一部分启动,无论是否为本地GUI 处于活动状态。

但是,WantedBy与启用/禁用状态是分开的:所以从另一种意义上说,它是一种“预设”:它确定在什么条件下可能会发生自动启动,但前提是首先启用服务。

2.) 如果您省略该WantedBy=multi-user.target行并且没有其他启用的服务在其服务定义中包含Requires=your.serviceWants=your.service,则您的服务将不会自动启动。

systemd适用于依赖项,并且在启动时,如果没有RequiresWants您的服务,即使启用了该服务,它也不会启动。

当然,您可以编辑您要在启动时启动的任何服务的default.target添加或删除RequiresWants行 - 但这样您就可以将新的服务文件放入系统并使其在默认情况下工作(这使得软件的事情变得非常容易包管理器),systemd具有WantedByRequiredBy关键字,可用于从“另一端”插入WantsRequires类型依赖项(分别)。

3.) 如果您希望该服务在启动时自动启动,或者该服务是您明确定义的依赖项链的一部分,则应省略该行。

例如,您可能正在重构服务器应用程序 A,并且出于某种原因决定将某些可选功能拆分为单独的服务 B,以允许用户在不需要时选择不安装它。然后,您可以将服务 B设为单独的service-B.rpm,并定义B.servicewithWantedBy=A.servicesystemd在服务 A 启动时自动启动服务 B - 但仅在service-B.rpm实际安装时。

请注意, a WantsorWantedBy仅表示每当另一个服务或目标也启动时,系统应该启动一个服务,但它根本没有指定关于启动/关闭顺序的任何内容。如果您需要在服务 A 启动时服务 B 已经在运行,则需要Before=A.serviceB.service文件中添加以明确指定启动顺序依赖项。

4.) 任何时候您确实希望该服务具有在启动时自动启动的能力,并且没有已经定义的其他依赖项。

  • 这是一个非常彻底的答案。你甚至澄清了为什么同时有 `Wants` 和 `WantedBy`,这一直让我感到困惑,因为我不知道我应该在什么时候使用。 (2认同)
  • 它掩盖了 `WantedBy` 在你启用服务之前什么都不做。当您安装基于 Debian Linux 的软件包时,它们会自动启用服务。但是大多数基于 Fedora 的软件包都没有。如果您编写自己的服务,它不会自动启用。您必须将 `systemctl enable ...` 作为单独的步骤运行。 (2认同)
  • 凉爽的!这里有很多好信息。“请注意,Wants 或 WantedBy 仅表示系统应在另一项服务 *[edit:] 或 target* 启动时启动一项服务,但它根本没有指定任何有关启动/关闭顺序的信息。” - 不幸的是编辑不太正确,它更复杂。`man systemd.target` 表示当*目标*需要您时,您也会自动排在目标之前。这解释了为什么日志显示 `graphical.target` 仅在所有服务启动后才“启动”。除非想要的单元(或目标?)有“DefaultDependency=no”。 (2认同)

sou*_*edi 6

如果您删除WantedBy=multi-user.targetsystemctl enable your-example-here则将(嘈杂地)无法执行任何操作。

图形目标

如果从源安装纯 systemd,它引导到的“默认目标”是graphical.target.

开始graphical.target开始multi-user.target,加上提供图形用户界面所需的任何单元。这种额外的复杂性是为了模拟遗留的“运行级别”而安排的。

真的应该忽略/掩盖“运行级别”模拟;无论如何它都不能正常工作。对不起!我想历史上强调“图形”与“多用户”的原因是图形软件 1) 不像系统的其他部分那样健壮和成熟,2) 需要大量资源。

通常只有少数单位是特定于graphical.target. GUI 本身有一个单一的服务,例如gdm.target. 这里也有一些主要由 GUI 使用的支持服务。

编辑:谷歌搜索建议,如果您没有安装 GUI,但“默认目标”已保留为graphical.target,则 systemd 可能会记录警告。“无法为单元 display-manager.service 添加依赖作业,忽略:单元 display-manager.service 加载失败:没有这样的文件或目录。” 我们希望避免用不必要的警告乱扔日志。因此,如果您没有安装 GUI,最好使用systemctl set-default multi-user. 尽管您的操作系统的安装系统可能已经为您解决了这个问题。除此之外,我强烈支持在这件事上冷漠:-)。

系统初始化目标

一些服务和其他类型的单元“参与了早期启动”。它们被定义为Before=sysinit.target直接或间接开始。大多数服务只是启动After=sysinit.target- 这是自动的情况,除非服务设置DefaultDependencies=no.

多用户目标

大多数示例服务不属于上述任一类别,因此我们将它们附加到multi-user.target. 这包括大多数网络服务(例如 Web 服务器),它们是原型系统服务。

动态激活服务

您可能会看到的另一种可能性是服务单元在启动时不会自动启动。所以就不需要了WantedBy=multi-user.target。该服务可以由其他东西触发或“激活”。

这方面的一个例子是 dbus 激活的服务。当对服务进行 dbus 调用时,可以将 Dbus 配置为按需启动服务。

对于网络服务,您可以使用套接字激活服务。这可能更容易找到详细信息,因为所有配置都以 systemd 为单位。例如sshd.socketssh.socket通常可用于激活ssh@.servicesshd@.service。虽然,我认为在启动时启动 sshd 服务更为常见。


与往常一样,上述内容简化并省略了似乎不需要的细节。