启动序列(使用 systemd 来管理启动项)

启动顺序(使用systemd管理启动项目)

启动序列(使用 systemd 来管理启动项)

了解systemd如何确定服务启动顺序,即使它本质上是一个并行系统。

近在设置Linux系统的时候,想知道在这些服务和依赖它们的单元启动之前,如何保证服务和其他单元之间的依赖关系已经启动并运行。我需要更多关于systemd如何管理启动程序的知识,特别是如何在本质上决定并行系统中服务的启动顺序。

您可能知道,SystemV(systemd的systemd前身,我在本系列的一篇文章中解释过)通过用Sxx前缀命名启动脚本来确定启动顺序。xx是从00到99的数字。然后SystemV按文件名排序,然后根据需要的运行级别执行队列中的每个启动脚本。

但是,systemd使用单元文件来定义子程序,这些子程序可以由系统管理员创建或编辑。这些文件不仅可以用于初始化,还可以用于日常操作。在本系列的三篇文章中,我解释了如何创建装载单元文件。在五篇文章中,我解释了如何创建一个不同的单元文件——一个在启动时执行程序的服务单元文件。您也可以修改设备文件中的一些配置,然后通过systemd日志检查您的修改在启动序列中的位置。

准备工作/即将工作

确保您已经在/etc/default/grub文件的GRUB_CMDLINE_LINUX=行中删除了rhgb和quiet,正如我在本系列的二篇文章中所展示的那样。这允许您查看Linux启动信息流,这是您在本文的一些实验中需要的。

程序

在本教程中,您将创建一个简单的程序,以便在主控制台和后续的systemd日志中查看启动信息。

创建一个shell程序/usr/local/bin/hello.sh并添加以下内容。为了确保执行结果在启动时可见,您可以很容易地在systemd日志中找到它。你将使用一个带有一些方块的“你好世界”程序版本,这样它将会脱颖而出。为了确保该文件是可执行的,并且为了安全起见,它需要root和700权限的用户和组所有权。

#!/usr/bin/bash#Simpleprogramtousefortestingstartupconfigurations#withsystemd.#ByDidBoth#LicensedunderGPLV2#echo"###############################"echo"#########HelloWorld!########"echo"###############################"

在命令行上执行这个程序,检查它是否正常工作。

[root@testvm1~]#hello.sh########################################HelloWorld!#######################################[root@testvm1~]#

这个程序可以用任何脚本或编译语言实现。hello.sh程序可以放在Linux文件系统层次结构的任何地方(FHS)。我把它放在/usr/local/bin目录下,这样它就可以直接在命令行上执行,而不必在键入命令之前带一个路径。我发现我创建的许多shell程序需要从命令行和其他工具(如systemd)运行。

服务单元文件

创建服务单元文件/etc/systemd/system/hello . service,并编写以下内容。这个文件不必是可执行的,但是为了安全起见,它需要root的用户和组所有权以及644或640权限。

#Simpleserviceunitfiletousefortesting#startupconfigurationswithsystemd.#ByDidBoth#LicensedunderGPLV2#[Unit]Description=Myhelloshellscript[Service]Type=oneshotExecStart=/usr/local/bin/hello.sh[Install]WantedBy=multi-user.target

检查服务状态以确认服务单元文件可以按计划运行。如果有语法问题,这里会显示错误。

[root@testvm1~]#systemctlstatushello.service●hello.service-MyhelloshellscriptLoaded:loaded(/etc/systemd/system/hello.service;disabled;vendorpreset:disabled)Active:inactive(dead)[root@testvm1~]#

您可以多次运行这种“oneshot”类型的服务,没有任何问题。这种服务适用于由服务单元文件启动的程序是主进程,并且必须在systemd启动任何相关进程之前完成的服务。

有7种服务类型,您可以在systemd.service(5)的手册页上找到每种类型的详细说明(以及服务单元文件的其他部分)。(也可以在文末的资料中找到更多信息。)

出于好奇,想看看错误是什么样子的。所以我删除了Type=oneshot行中的字母“o”,现在看起来是这样的。Type=neshot,现在再次执行命令:

[root@testvm1~]#systemctlstatushello.service●hello.service-MyhelloshellscriptLoaded:loaded(/etc/systemd/system/hello.service;disabled;vendorpreset:disabled)Active:inactive(dead)May0608:50:09testvm1.both.orgsystemd[1]:/etc/systemd/system/hello.service:12:Failedtoparseservicetype,ignoring:neshot[root@testvm1~]#

执行结果清楚地告诉我错误在哪里,所以解决错误变得非常容易。

请注意,即使在以原始形式保存hello.service文件后,错误仍然存在。虽然重启机器可以消除这种错误,但你不必这样,所以我去想办法清理这种持续存在的错误。我遇到了一些错误,需要systemctl daemon-reload命令来重置错误状态,但是在这个例子中它不起作用。可以用这个命令修复的错误似乎总是有这样的声明,所以你知道运行它。

但是,在修改或创建新的单元文件后执行systemctl daemon-reload确实是一种推荐的做法。它提醒系统已经发生了修改,并且它可以防止一些与管理服务或单元相关的问题。所以继续执行这个命令。

更正服务单元文件中的拼写错误后,一个简单的systemctl restart hello.service命令可以清除这些错误。让我们试着看看通过向hello.service文件中添加一些其他错误可以得到什么。

开始服务。

现在您已经准备好启动这项新服务,请检查状态以查看结果。虽然您以前可能已经重新启动过它,但您仍然可以随时启动或重新启动这个单一服务,因为它只运行一次,然后退出。

继续启动此服务(如下所示),然后检查状态。你的结果可能和我的不同,这取决于你做过多少次试错实验。

[root@testvm1~]#systemctlstarthello.service[root@testvm1~]#systemctlstatushello.service●hello.service-MyhelloshellscriptLoaded:loaded(/etc/systemd/system/hello.service;disabled;vendorpreset:disabled)Active:inactive(dead)May1010:37:49testvm1.both.orghello.sh[842]:#########HelloWorld!########May1010:37:49testvm1.both.orghello.sh[842]:###############################May1010:37:49testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:37:49testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.May1010:54:45testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orghello.sh[1380]:#########HelloWorld!########May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:54:45testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.[root@testvm1~]#

从status check命令的输出中,我们可以看到systemd日志指示hello.sh启动,然后服务结束。您还可以看到脚本的输出。输出是根据服务近一次调用的日志记录生成的。尝试启动服务几次,然后查看status命令的输出,了解我所说的内容。

您还应该直接检查日志的内容。有很多方法可以做到这一点。一种方法是指定记录类型标识符,在本例中是shell脚本的名称。它显示以前重新启动和当前会话的日志。如你所见,我为这篇文章做了相当长时间的研究和测试。

[root@testvm1~]#journalctl-thello.sh–Reboot–May0815:55:47testvm1.both.orghello.sh[840]:###############################May0815:55:47testvm1.both.orghello.sh[840]:#########HelloWorld!########May0815:55:47testvm1.both.orghello.sh[840]:###############################–Reboot–May0816:01:51testvm1.both.orghello.sh[840]:###############################May0816:01:51testvm1.both.orghello.sh[840]:#########HelloWorld!########May0816:01:51testvm1.both.orghello.sh[840]:###############################–Reboot–May1010:37:49testvm1.both.orghello.sh[842]:###############################May1010:37:49testvm1.both.orghello.sh[842]:#########HelloWorld!########May1010:37:49testvm1.both.orghello.sh[842]:###############################May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orghello.sh[1380]:#########HelloWorld!########May1010:54:45testvm1.both.orghello.sh[1380]:###############################[root@testvm1~]#

要查找hello.service unit的systemd记录,您可以在systemd中搜索。您可以使用G+Enter将页面翻到日志记录的末尾,然后使用回滚找到您感兴趣的日志。使用-b选项仅显示近开始的记录。

[root@testvm1~]#journalctl-b-tsystemdMay1010:37:49testvm1.both.orgsystemd[1]:StartingSYSV:Lateinitscriptforliveimage….May1010:37:49testvm1.both.orgsystemd[1]:StartedSYSV:Lateinitscriptforliveimage..May1010:37:49testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:37:49testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.May1010:37:50testvm1.both.orgsystemd[1]:StartingD-BusSystemMessageBus…May1010:37:50testvm1.both.orgsystemd[1]:StartedD-BusSystemMessageBus.

我复制了一些其他的日志记录,让你知道你可能会发现什么。这个命令弹出所有属于systemd的日志内容——当我写这个的时候,它有109,183行。这是需要整理的大量数据。你可以使用页面的搜索功能,通常更少或者你可以使用内置的grep功能。-g(或-grep =)选项可以使用与Perl兼容的正则表达式。

[root@testvm1~]#journalctl-b-tsystemd-g"hello"[root@testvm1~]#journalctl-b-tsystemd-g"hello"–LogsbeginatTue2020-05-0518:11:49EDT,endatSun2020-05-1011:01:01EDT.–May1010:37:49testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…May1010:37:49testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:37:49testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.May1010:54:45testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…May1010:54:45testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:54:45testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.[root@testvm1~]#

您可以使用标准的GNUgrep命令,但这不会显示日志一行的元数据。

如果您只想查看包含hello服务的日志记录,可以指定一个时间来缩小范围。例如,我将在我的测试虚拟机上的10:54:00开始,这是上述日志记录开始的分钟数。注意-自=的选项必须加引号,这个选项也可以写成-S“在某个时间”。

您的计算机上的日期和时间可能不同,因此请确保使用与日志中的时间相匹配的时间戳。

[root@testvm1~]#journalctl–since="2020-05-1010:54:00"May1010:54:35testvm1.both.orgaudit:BPFprog-id=54op=LOADMay1010:54:35testvm1.both.orgaudit:BPFprog-id=55op=LOADMay1010:54:45testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orghello.sh[1380]:#########HelloWorld!########May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:54:45testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.May1010:54:45testvm1.both.orgaudit[1]:SERVICE_STARTpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd"'May1010:54:45testvm1.both.orgaudit[1]:SERVICE_STOPpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd/"'May1010:56:00testvm1.both.orgNetworkManager[840]:

由于选项会跳过指定时间点的所有记录,但在此时间点之后仍有许多记录不需要。您也可以使用直到选项在您感兴趣的时间之后剪切记录。我只想在事发时间附近呆一分钟,别无他求:

[root@testvm1~]#journalctl–since="2020-05-1010:54:35"–until="2020-05-1010:55:00"–LogsbeginatTue2020-05-0518:11:49EDT,endatSun2020-05-1011:04:59EDT.–May1010:54:35testvm1.both.orgsystemd[1]:Reloading.May1010:54:35testvm1.both.orgaudit:BPFprog-id=27op=UNLOADMay1010:54:35testvm1.both.orgaudit:BPFprog-id=26op=UNLOADay1010:54:35testvm1.both.orgaudit:BPFprog-id=55op=LOADMay1010:54:45testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orghello.sh[1380]:#########HelloWorld!########May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:54:45testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.May1010:54:45testvm1.both.orgaudit[1]:SERVICE_STARTpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd>May1010:54:45testvm1.both.orgaudit[1]:SERVICE_STOPpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd/>lines1-46/46(END)

如果此时间段内仍有大量活动,您可以使用以下选项进一步缩小结果数据流:

[root@testvm1~]#journalctl–since="2020-05-1010:54:35"–until="2020-05-1010:55:00"-t"hello.sh"–LogsbeginatTue2020-05-0518:11:49EDT,endatSun2020-05-1011:10:41EDT.–May1010:54:45testvm1.both.orghello.sh[1380]:###############################May1010:54:45testvm1.both.orghello.sh[1380]:#########HelloWorld!########May1010:54:45testvm1.both.orghello.sh[1380]:###############################[root@testvm1~]#

你的结果应该和我的差不多。从这一系列实验中可以看出,该服务运行正常。

重启-或者到此为止。

到目前为止,您还没有重新启动安装了该服务的机器。所以现在重启,因为毕竟这个教程是关于程序在启动阶段的运行。首先,您需要在启动序列中启用该服务。

[root@testvm1~]#systemctlenablehello.serviceCreatedsymlink/etc/systemd/system/multi-user.target.wants/hello.service→/etc/systemd/system/hello.service.[root@testvm1~]#

请注意,此软链接是在/etc/systemd/system/multi-user . target . wants目录中创建的。这是因为服务单元文件指定多用户“需要”该服务。

重启机器,确保在启动阶段可以观察到数据流,这样就可以看到“Hello world”的消息。等待…你看到了吗?是的,我看到了。虽然很快就被刷掉了,但我确实看到systemd的信息显示它启动了hello.service服务。

查看上次系统启动后的日志。你可以少用页面搜索工具找“你好”或者“你好”。我切掉了很多数据,但是留下了附近的日志记录,这样您就可以在本地感受到与您的服务相关的日志记录是什么样子:

[root@testvm1~]#journalctl-bMay1010:37:49testvm1.both.orgsystemd[1]:ListeningonSSSDKerberosCacheManagerrespondersocket.May1010:37:49testvm1.both.orgsystemd[1]:ReachedtargetSockets.May1010:37:49testvm1.both.orgsystemd[1]:ReachedtargetBasicSystem.May1010:37:49testvm1.both.orgsystemd[1]:StartingModemManager…May1010:37:49testvm1.both.orgsystemd[1]:StartingNetworkManager…May1010:37:49testvm1.both.orgsystemd[1]:StartingahimDNS/DNS-SDStack…May1010:37:49testvm1.both.orgsystemd[1]:ConditioncheckresultedinSecureBootDBX(blacklist)updaterbeingskipped.May1010:37:49testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…May1010:37:49testvm1.both.orgsystemd[1]:StartingIPv4firewallwithiptables…May1010:37:49testvm1.both.orgsystemd[1]:Startedirqbalancedaemon.May1010:37:49testvm1.both.orgaudit[1]:SERVICE_STARTpid=1uid=0auid=4294967295ses=4294967295msg='unit=irqbalancecomm="systemd"exe="/usr/lib/sy>"'May1010:37:49testvm1.both.orgsystemd[1]:StartingLSB:Initscriptforliveimage….May1010:37:49testvm1.both.orgsystemd[1]:StartingHardwareMonitoringSensors…May1010:37:49testvm1.both.orgsystemd[1]:StartingNTPclient/server…May1010:37:49testvm1.both.orgsystemd[1]:StartingSYSV:Lateinitscriptforliveimage….May1010:37:49testvm1.both.orgsystemd[1]:StartedSYSV:Lateinitscriptforliveimage..May1010:37:49testvm1.both.orgaudit[1]:SERVICE_STARTpid=1uid=0auid=4294967295ses=4294967295msg='unit=livesys-latecomm="systemd"exe="/usr/lib/>"'May1010:37:49testvm1.both.orghello.sh[842]:###############################May1010:37:49testvm1.both.orghello.sh[842]:#########HelloWorld!########May1010:37:49testvm1.both.orghello.sh[842]:###############################May1010:37:49testvm1.both.orgsystemd[1]:hello.service:Succeeded.May1010:37:49testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.May1010:37:49testvm1.both.orgaudit[1]:SERVICE_STARTpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd>"'May1010:37:49testvm1.both.orgaudit[1]:SERVICE_STOPpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd/>May1010:37:50testvm1.both.orgaudit:BPFprog-id=28op=LOAD

您可以看到systemd启动了hello.service单元,该单元执行hello.sh脚本并将输出记录在日志中。如果您可以在启动阶段捕捉到它,您还应该看到systemd消息指示它正在启动脚本,另一条消息指示服务成功。通过观察上述数据流中的一条systemd消息,您会发现systemd在达到基本系统目标后很快就会启动您的服务。

但我想看到创业阶段印出来的信息。有一种方法可以做到这一点:在hello.service文件的[Service]部分添加以下行:

StandardOutput=journal+console

hello.service文件如下所示:

#Simpleserviceunitfiletousefortesting#startupconfigurationswithsystemd.#ByDidBoth#LicensedunderGPLV2#[Unit]Description=Myhelloshellscript[Service]Type=oneshotExecStart=/usr/local/bin/hello.shStandardOutput=journal+console[Install]WantedBy=multi-user.target

添加此行后,重启系统,启动时观察显示屏上的数据流滚动。你应该在它的小盒子里看到信息。启动序列完成后,您可以查看的启动日志,然后找到新服务的日志记录。

修改顺序

现在您的服务可用了,您可以看到它在启动序列中的开始位置,并尝试修改它。请记住,systemd倾向于在每个主目标(basic.target、多用户. target和graphical)中并行启动尽可能多的服务和其他单元类型。* *目标)。你应该刚刚读了上次引导的日志记录。它应该类似于我上面的日志。

请注意,systemd在您的测试服务达到基本系统目标后不久就启动了它。这正是您在服务单元文件的WantedBy行中指定的内容,因此是正确的。在进行更改之前,请列出目录/etc/systemd/system/multi-user . target . wants中的内容,您将看到一个指向服务单元文件的软链接。服务单元文件的[安装]部分指定哪个目标将启动服务,执行systemctl enablehlo.service命令将在适当的targets.wants路径下创建一个软链接。

hello.service->/etc/systemd/system/hello.service

有些服务需要在basic.target阶段启动,而有些则不需要,除非系统正在启动graphical.target。本实验中的服务不会在basic.target阶段启动。假设您在graphical.target阶段之前不需要它启动。然后修改所需的行:

WantedBy=graphical.target

在重新启用hello.service之前,请务必禁用它,这样您就可以删除旧链接并在目录中创建新链接。graphic . targets . wants我注意到,如果在修改服务所需的目标之前忘记禁用该服务,我可以运行systemctl disable命令,该链接将从两个目标中删除。wants目录。之后,我只需要重新启用该服务并重新启动计算机。

在图形目标下启动服务时需要注意一点。如果计算机启动到多用户目标阶段,此服务将不会自动启动。如果这个服务需要GUI桌面界面,可能是你想要的,但也可能不是你想要的。

使用-o短单调选项查看graphical.target和multi-user.target的日志,并在内核启动几秒钟后显示日志,精确度为微秒:

[root@testvm1~]#journalctl-b-oshort-monotonic

多用户的部分日志。目标:

[17.264730]testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…[17.265561]testvm1.both.orgsystemd[1]:StartingIPv4firewallwithiptables…[19.478468]testvm1.both.orgsystemd[1]:StartingLSB:Initscriptforliveimage….[19.507359]testvm1.both.orgiptables.init[844]:iptables:Applyingfirewallrules:[OK][19.507835]testvm1.both.orghello.sh[843]:###############################[19.507835]testvm1.both.orghello.sh[843]:#########HelloWorld!########[19.507835]testvm1.both.orghello.sh[843]:###############################[21.482481]testvm1.both.orgsystemd[1]:hello.service:Succeeded.[21.482550]testvm1.both.orgsmartd[856]:Openedconfigurationfile/etc/smartmontools/smartd.conf[21.482605]testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.

还有一些图形目标的日志:

[19.436815]testvm1.both.orgsystemd[1]:StartingMyhelloshellscript…[19.437070]testvm1.both.orgsystemd[1]:StartingIPv4firewallwithiptables…[19.612614]testvm1.both.orghello.sh[841]:###############################[19.612614]testvm1.both.orghello.sh[841]:#########HelloWorld!########[19.612614]testvm1.both.orghello.sh[841]:###############################[19.629455]testvm1.both.orgaudit[1]:SERVICE_STARTpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd/systemd"hostname=?addr=?terminal=?res=success'[19.629569]testvm1.both.orgaudit[1]:SERVICE_STOPpid=1uid=0auid=4294967295ses=4294967295msg='unit=hellocomm="systemd"exe="/usr/lib/systemd/systemd"hostname=?addr=?terminal=?res=success'[19.629682]testvm1.both.orgsystemd[1]:hello.service:Succeeded.[19.629782]testvm1.both.orgsystemd[1]:FinishedMyhelloshellscript.

虽然单元文件的WantedBy部分包含graphical.target,但是hello.service单元在启动后大约运行19.5或19.6秒。但是,hello.service在多用户. target中启动时间为17.24秒,在图形target中为19.43秒。

这是什么意思?查看链接/etc/system d/system/default . target..文件显示systemd首先启动了默认目标graphic . target,然后graphic . target触发了多用户. target..

[root@testvm1system]#catdefault.target#SPDX-License-Identifier:LGPL-2.1+##Thisfileispartofsystemd.##systemdisfreesoftware;youcanredistributeitand/ormodifyit#underthetermsoftheGNULesserGeneralPublicLicenseaspublishedby#theFreeSoftwareFoundation;eitherversion2.1oftheLicense,or#(atyouroption)anylaterversion.[Unit]Description=GraphicalInterfaceDocumentation=man:systemd.special(7)Requires=multi-user.targetWants=display-manager.serviceConflicts=rescue.servicerescue.targetAfter=multi-user.targetrescue.servicerescue.targetdisplay-manager.serviceAllowIsolate=yes[root@testvm1system]#

无论服务是用graphical.target还是多用户. target启动,hello.service单元都会在启动后19.5秒或19.6秒启动。基于这个事实和日志结果(尤其是输出单调的日志),您将知道这些目标是并行启动的。看看日志里的另一件事:

[28.397330]testvm1.both.orgsystemd[1]:ReachedtargetMulti-UserSystem.[28.397431]testvm1.both.orgsystemd[1]:ReachedtargetGraphicalInterface.

这两个目标几乎同时完成。这和理论是一致的,因为图形化的. target触发了多用户. target,在多用户. target到来之前不会完成(也就是完成)。但是hello.service完成得比这次早得多。

这一切都说明这两个目标几乎是并行开始的。如果您查看日志,您会发现来自这些主目标的各种目标和服务大多是并行启动的。显然,多用户目标没有必要在图形目标启动之前完成。因此,简单地使用这些主要目标并不能很好地对启动序列进行排序,尽管这对于确保只有在图形目标需要时才启动单元非常有用

继续之前,请将hello.service unit文件回滚到WantedBy=multi-user.target(如果尚未完成)。

确保服务在网络运行后启动。

常见的启动问题是确保设备在网络启动并运行后重新启动。Freedesktop.org的文章《网络启动后运行服务》提到,网络什么时候算“启动”还没有真正的共识。然而,本文提供了三种选择,而满足完全可用网络要求的是network-online.target。需要注意的是,network.target是在关机阶段使用的,不是启动阶段,所以对你有序启动没有帮助。

在进行任何更改之前,请务必检查日志,以确保在网络可用之前,hello.service单元可以正确启动。您可以在日志中找到network-online.target进行确认。

你的服务其实并不需要网络服务,但你可以把它当成需要网络。

因为设置需要=图形。target不保证服务会在网络可用时启动,您需要其他方法来做到这一点。幸运的是,有一个简单的方法。将以下两行代码添加到hello.service单元文件的[Unit]部分:

After=network-online.targetWants=network-online.target

这两个字段都需要生效。重新启动机器,并在日志中找到服务记录:

[26.083121]testvm1.both.orgNetworkManager[842]:

这确认了hello.service单元将在网络联机后启动。目标这正是您想要的。您可能已经在启动阶段看到“Hello World”消息。还需要注意的是,开机录制的时间戳比之前晚了6秒左右。

定义启动顺序的方式。

本文详细讨论了Linux启动过程中systemd、单元文件和日志的细节,发现单元文件引入错误会发生什么。作为一名系统管理员,我发现这种实验有助于我理解程序或服务失败时的行为,在安全的环境下故意破坏是一种很好的学习方式。

本文的实验结果证明,仅向多用户目标或图形目标添加服务单元不能确定其在启动序列中的位置。它仅确定一个单元是否作为图形环境的一部分启动。实际上,启动目标多用户、目标和图形目标以及它们的所有需求几乎是并行启动的。确保单元在特定位置启动的方法是确定它依赖于哪个单元,并将新单元配置为“想要”和“在它依赖之后”。

资源

网上有很多关于systemd的参考资料,但大多数都有点简短、晦涩,甚至会产生误导。除了本文中提到的材料之外,以下网页还提供了关于如何开始使用systemd的更可靠和详细的信息。

Fedora项目对systemd有一个实用的介绍,其中包含了您需要了解的关于如何使用systemd来配置、管理和维护Fedora计算机的几乎所有信息。

Fedora项目也有一个很好的备忘录,它交叉引用了过去的SystemV命令和systemd命令进行比较。

有关systemd的技术细节和创建本项目的原因,请查看Freedesktop.org系统的描述。

Linux.com的“更系统的乐趣”专栏提供了更高级的系统信息和技能。

此外,还有一系列由systemd的设计者和主要开发者Lennart Poettering为Linux系统管理员撰写的深度技术文章。这些文章写于2010年4月至2011年9月,但和当时一样现实。关于systemd及其生态的许多其他好文章都是基于这些文章:

版权声明:《启动序列(使用 systemd 来管理启动项)》文章主要来源于网络,不代表本网站立场,不承担相关法律责任,如涉及版权问题,请发送邮件至[dcseo8@163 。com]举报,我们会在第一时间进行处理。本文文章链接:https://www.dcseo.cn/41793.html
(0)

相关推荐