注:
- Oracle 提供的免费实验室环境中提供了本教程。
- 它使用 Oracle Cloud Infrastructure 身份证明、租户和区间示例值。完成实验室后,请使用特定于您的云环境的这些值替换这些值。
在 Oracle Linux 上使用 systemd
简介
在本教程中,您将学习如何使用 systemctl 命令行实用程序管理和查看 systemd 控制的 systemd 单元。本教程以 Oracle Linux 8 或更高版本的用户为目标。
systemd 是引导时启动的第一个进程,是系统关闭时终止的最终进程。systemd 主要用于在引导时管理系统服务或进程以及系统初始化。但是,systemd 还能够处理许多其他任务和功能,包括事件记录、设备管理、用户登录、任务调度、时间同步和系统引导。systemd 中的许多功能未完全使用,因为用户可能更熟悉用于这些用途的替代软件,或者不同的 Linux 分发可能具有首选的系统配置方法。
在 systemd 单元中处理不同类型的行为或函数。例如,守护进程或系统服务作为服务单元运行,而系统状态通常定义为目标单元。可以定义计时器单元来调度任务,类似于使用系统 cron 服务的方式,并且可以使用挂载单元来配置挂载点,就像在系统 fstab 中配置挂载点的方式一样。
systemd 用于管理系统级进程和函数,但它也能够管理在用户空间中运行的进程。系统上的用户可以配置和管理自己的服务,甚至可以配置 systemd 以允许这些服务在用户终止其会话后继续运行。
目标
- 搜索不同的系统单元类型
- 使用 systemd 目标单元
- 了解常见的 systemctl 命令语法
- 在用户空间中创建您自己的 systemd 计时器单元
- 配置 systemd 以允许用户空间进程在注销后运行
需要做哪些准备?
- 安装了 Oracle Linux 8 的系统。
注意:使用免费实验室环境时,请参见 Oracle Linux Lab Basics 了解连接和其他使用情况说明。
了解 systemd 单元文件
连接到 Oracle Linux 8 实例后,可以开始尝试使用 systemctl 命令来了解可用的不同单元。
-
运行 systemctl 命令可列出当前由 systemd 装入的所有 systemd 单元:
systemctl使用键盘上的空格或 PgDn 键可遍历输出。
此命令相当于运行以下命令:
systemctl list-units输出显示 systemd 正在管理的所有当前活动配置单元。在输出中应注意,存在使用不同后缀命名的单位,包括使用 '.device'、'.mount'、'.service'、'.target' 和 '.timer' 后缀命名的单位。
单元在启动、运行、装载或插入时处于活动状态,具体取决于它们的用途。单元可以处于非活动状态,即停止、卸载或断开连接。如果要查看所有单位,而不管它们是否有效,可以运行:
systemctl list-units --all以下命令的输出显示了不同类型的 systemd 单元的选择:
automount:提供自动挂载功能,支持按需挂载文件系统和并行引导。mount:控制文件系统当前日期和时间显示中的挂载点。path:可以在文件系统路径信息发生更改时激活服务。scope:与服务单元类似,但管理外部进程而不是启动它们。service:启动和控制守护进程及其包含的进程。slice:用于对分层 cgroup 树中的系统进程(如服务单元和范围单元)进行分组以用于资源管理。socket:封装系统中的本地进程间通信 (Interprocess Communication, IPC) 或网络套接字,这对于基于套接字的激活非常有用。target:用于在引导期间对单元进行分组或提供已知的同步点。timer:用于触发使用计时器激活其他单位。这些选项提供了替代以前可能已使用 cron 服务管理的任务。device:在 systemd 中公开内核设备,还可以用于实现基于设备的激活。swap:封装内存交换分区或交换文件。
-
使用
--type选项将单元列表限制为特定的单元类型。-
使用
systemctl list-units --type services命令列出系统上的当前活动服务单元。systemctl list-units --type service -
再次运行同一命令,但包括
--all选项以查看所有装入的单元,包括处于非活动状态(如果有)。systemctl list-units --type service --all
-
您可以对可用的每种服务类型重复这些命令,以便仅将信息限制为您随时感兴趣的类型。
使用系统化目标单元
目标单位用于将不同的单位组合在一起,以使系统处于特定状态,以便它可以用于特定目的。
-
列出可用的
target单元。systemctl list-units --type target单元可以要求加载其他单元,也可以配置为与特定单元冲突。例如,
multi-user.target要求basic.target正常运行,它也与rescue.service和rescue.target单元冲突。单位还指定要加载以能够运行的其他单位。通过这种方式,可以将目标链接在一起以设置特定状态,但其模块化程度也足以重用于触发替代状态。
-
查看默认目标单元。
缺省目标单元定义引导后的缺省系统状态。
-
使用
systemctl get-default命令查看缺省情况下使用的目标单元。默认目标单元由/etc/systemd/system/default.target文件表示。systemctl get-default -
使用
ls -l命令可列出有关/etc/systemd/system/default.target文件的信息。ls -l /etc/systemd/system/default.target注意:
default.target文件是指向当前默认目标单元文件的符号链接。
-
-
更改默认目标单元。
-
使用
systemctl set-default命令将缺省目标单元更改为graphical.target单元。systemctl set-default graphical.target -
使用
ls –l命令确认default.target文件现在是指向graphical.target文件的符号链接。ls -l /etc/systemd/system/default.target注意:更改默认目标单元将删除现有的
default.target符号链接并重新创建指向新的默认目标单元的符号链接。
-
-
浏览目标以了解更多信息。
-
使用
systemctl show命令可获取有关任何特定目标的更多信息。systemctl show multi-user.target输出显示您指定的目标的所有参数。请注意,您可以确定目标需要、希望和冲突的单位,并且还可以查看此目标必须在之前和之后运行的单位。
-
使用
systemctl list-dependencies命令显示特定目标达到其状态所需的或需要的依赖项的树:systemctl list-dependencies default.target此命令显示启动默认目标时启动的所有单元。单位链以递归方式呈现到树中,从而可以全面评估目标在启动时取得的成绩。如果已将
graphical.target设置为默认目标,则可以看到系统希望运行display-manager.service来加载图形显示,但还会运行multi-user.target来执行运行图形显示之前所需的所有操作。
-
使用 systemctl 启用、禁用和屏蔽单元
可以禁用或启用单元,还可以对其进行屏蔽,以便从不在任何情况下运行单元。有些单位是静态的,因为它们始终可用,通常是因为它们是其他要工作的单位的依赖项。systemctl list-units 命令只能用于显示系统中处于活动状态或不活动的单元。
-
列出系统上可用的所有单元及其状态:
systemctl list-unit-files许多可用的单元是静态的。启用的单元在引导时启动。已禁用的单元是系统上可用但未配置为引导时启动的单元。屏蔽的单元在系统中可用,但是已主动设置为根本无法启动它们的状态。
-
使用
systemctl status命令查看有关nfs-server.service单元的详细信息。systemctl status nfs-server.servicesystemctl命令允许您在引用服务单元时删除.service扩展。状态命令指示某个单元是启用、活动、不活动、已禁用还是已屏蔽。
对于脚本化解决方案,
systemctl提供了一行输出状态的简短命令:-
使用
systemctl is-active命令检查nfs-server服务是正在运行(活动)还是未运行(不活动)。systemctl is-active nfs-server -
使用
systemctl is-enabled命令检查nfs-server服务是否已启用或禁用。启用服务后,服务将在系统重新引导时启动。systemctl is-enabled nfs-server
-
-
允许服务在引导时启动。
可以使用
systemctl enable命令启用nfs-server服务。sudo systemctl enable --now nfs-server如果命令更改系统状态或配置,则必须使用管理员权限运行
systemctl命令。可以使用--now选项在启用服务的同时另外启动服务。注意:该命令通过为服务启动的最低级别系统状态目标创建符号链接来启用服务。在输出中,该命令为
multi-user目标创建了符号链接nfs-server.service。使用
systemctl status command确认nfs-server服务现在已启用且正在运行。systemctl status nfs-server -
禁用和停止服务。
可以使用
systemctl disable命令禁用nfs-server服务。另请注意,systemctl disable命令删除服务的 systemctl 链接。sudo systemctl disable nfs-server使用
systemctl stop命令停止nfs-server服务。sudo systemctl stop nfs-server在禁用服务时,可以使用
--now选项组合这些步骤。 -
屏蔽和取消屏蔽单元。
在某些情况下,您可能希望禁用从头开始的单位。通常,如果特定单元与系统上的某些其他功能冲突,或者由于策略原因,您可以执行此操作。
使用
systemctl mask命令屏蔽nfs-server服务:sudo systemctl mask nfs-server创建符号链接以确保 systemd 单元配置指向 /dev/null。这将阻止启用或启动服务。
确认在屏蔽 nfs-server 单元时无法启动该单元:
sudo systemctl start nfs-server服务无法启动,返回错误以指示服务已屏蔽。
取消屏蔽单元以将其返回到其原始状态,并允许用户启动或启用该服务。
sudo systemctl unmask nfs-server
为用户空间单位设置 systemd
通常,systemd 用于在系统级别管理单元。用户需要对系统进行管理员级别访问,以管理以这种方式配置的 systemd 单元。在某些环境和某些单元类型中,用户可能希望使用 systemd 在用户空间内运行单元的能力。例如,用户可能希望使用 systemd 的计时器单元功能来调度任务;或者用户可能希望将特定的应用程序或服务作为不需要 root 级别权限才能运行的服务单元运行。
systemd 在登录时为用户启动一个 systemd 用户进程。对于用户,将按以下顺序处理位于以下目录中的单元:
/usr/lib/systemd/user/:已安装软件包提供的用户空间单元$HOME/.local/share/systemd/user/:主目录中安装的软件包的用户空间单元/etc/systemd/user/:应在用户空间中为所有用户运行的全局系统范围用户单元$HOME/.config/systemd/user/:用户创建的单位
通过对任何 systemd 命令使用 --user 选项,可以向 systemd 指示您在用户空间中工作。
-
列出用户当前可用的单元文件。
systemctl --user list-unit-files请注意,可用单元列表大大短于发出不带
--user选项的同一命令时。这些单元文件的大多数位于新系统上的
/usr/lib/systemd/user中。列出此目录中的文件以查看位于以下位置的单元:ls -la /usr/lib/systemd/user/ -
创建用于托管您自己的 systemd 单元文件的目录。
mkdir -p $HOME/.config/systemd/user -
创建您自己的 systemd 服务单元。
cat << EOF > $HOME/.config/systemd/user/uptime.service [Unit] Description="Logs system uptime and load average" Wants=uptime.timer [Service] ExecStart=/usr/bin/uptime [Install] WantedBy=default.target EOF此服务单元提供三个配置部分。
Unit部分提供了单元的说明以及任何要求。在这种情况下,Wants条目定义尚不存在的计时器单元的弱要求。列为Wants条目的单位在可用时运行,但不阻止父单元在找不到或无法运行时运行。Service部分定义此特定服务单元在运行时的行为。我们在此处依赖多个可用选项的缺省值,并且仅指定ExecStartline,该行指定启动服务时运行的命令。在这种情况下,将运行uptime命令来记录系统正常运行时间和负载值。Install部分定义启用服务后应如何将其安装到系统中。值得注意的是,该服务添加为WantedBy为 "default.target" 的服务。这意味着服务是作为此用户的默认目标的一部分启用的。 -
运行 systemd 单元并检查其输出。
由于您已添加新单元,因此在尝试运行该服务之前重新加载系统配置通常是个好主意:
systemctl --user daemon-reload现在启动新单元。
systemctl --user start uptime检查命令是否按预期运行。您可以通过检查服务的状态来检查服务是否已运行:
systemctl --user status uptime注意:这些命令使用
--user选项在用户空间内运行。要检查所运行的
uptime命令的输出,请使用journalctl命令查看日志并指定标记选项来查看特定于该命令的日志:journalctl -t uptime您可以启用此服务,使其在用户首次登录到系统时启动。
systemctl --user enable uptime请注意,服务在用户首次登录到系统时运行。它不会在系统引导时自动启动。通常,在用户空间中运行的服务在用户注销或终止所有用户会话后终止。本教程稍后将讨论用户服务的启用持久性。
使用系统化计时器单元
在本练习中,您将在前面的练习的基础上再接再厉,以创建并允许计时器单元定期在特定时间或间隔运行另一个 systemd 单元。计时器单位可以在系统级别和用户级别定义,可用于定义 systemd 应何时运行其他单位。计时器单元对已调度事件提供细粒度控制,并可替代使用 cron 守护进程处理更多子配置。
许多系统服务都包括计时器单元以控制运行时间。dnf-automatic 软件包中提供了一个计时器单元的极佳示例,可用于使系统保持最新状态,以便系统自动执行常规 dnf 更新。要在系统级别执行此操作,请安装软件包并启用计时器单元:
sudo dnf install -y dnf-automatic
sudo systemctl enable dnf-automatic.timer
您可以查看单元文件来了解该单元的配置方式:
cat /usr/lib/systemd/system/dnf-automatic.timer
此单元中的重要内容包括 Wants 行,该行需要满足 network-online.target。配置的 Timer 部分中的 OnCalendar 条目表明此操作每天都在 06h00 运行。同样值得注意的是 RandomizedDelaySec 条目,该条目可以帮助防止计时器单元完全同时触发,并突然推送系统负载。
此处提供的示例属于更复杂的一组单元。要更好地了解计时器单元的工作原理,请在用户空间中添加计时器单元,以调度您在上一个练习中创建的 uptime.service,使其以固定间隔运行。
-
创建计时器单元文件。
cat <<EOF > $HOME/.config/systemd/user/uptime.timer [Unit] Description=Timer for the uptime service that logs uptime Requires=uptime.service [Timer] Unit=uptime.service OnCalendar=*-*-* *:*:00 [Install] WantedBy=timers.target此文件指定要运行此计时器单元需要
uptime.service。这是一个比Wants定义中定义的要求强得多的要求,如果不符合要求,则单元不运行。Timer部分定义它使用OnCalendar项装入uptime.service单元。OnCalendar项与 crontab 定义中的选项类似,但提供了更精细的功能。在这种情况下,单位定义为每分钟 00 秒运行一次。 -
由于您修改了 systemd 配置,因此请重新加载 systemd 守护进程并重新启动运行时间服务,以便它可以选取新的计时器单元:
systemctl --user daemon-reload systemctl --user restart uptime -
列出单元以检查
uptime.service和uptime.timer单元是否正在运行。systemctl --user list-units -
监视日志中的日志输出,以便查看每分钟运行正常运行时间服务触发的正常运行时间输出。
journalctl -f -t uptime几分钟之后,应显示多行输出。如果您十分关注,您可能会注意到 uptime 命令并非始终在分钟内触发。这是系统化计时器功能中的有意功能。计时器作业由一个随机器触发,该随机器允许任务延迟多达一分钟。这有助于防止计时器同时发生所有触发。通过将以下配置条目添加到计时器单元
Timer部分,可以强制计时器具有不可思议的准确性,方法是在调度事件的纳秒内:AccuracySec=1us但是,对于大多数任务,允许某种程度的不准确性是明智的做法,可以防止任务太同步地运行。
完成监视后,您可以使用 Ctrl-C 组合键退出日记账。
配置用户空间进程以在注销后继续
默认情况下,当用户注销或用户的所有会话都已终止时,由用户启动和拥有的服务和进程将终止。您可以使用多种方法在 systemd 中更改此默认行为。此处介绍了两个选项。
使用 loginctl 命令启用 systemd linger 用户
可以使用 loginctl 命令更改特定用户的缺省行为,并在用户会话终止后将该用户的进程启用到 "linger"。
-
使用 loginctl 实用程序为特定用户启用 linger。在此实例中,为“oracle”用户启用 systemd 锁定程序行为:
sudo loginctl enable-linger oracle -
要验证设置是否已应用,请检查
/var/lib/systemd/linger目录中与用户同名的文件。ls /var/lib/systemd/linger/oracle该命令应验证该文件是否存在。
编辑 systemd logind.conf 文件
Systemd 管理用户登录事件并提供一个配置文件,可以对其进行编辑以设置与用户会话相关的不同事件的缺省行为。此配置文件位于 /etc/systemd/logind.conf。
-
将位于
/etc/systemd/logind.conf的现有配置的内容转储到屏幕以查看:cat /etc/systemd/logind.conf注释掉大部分选项,但显示编译时默认值。此文件中有三个选项,可以控制当用户的会话终止时,Systemd 处理在用户空间中运行的进程的方式。
KillUserProcesses:此选项可以控制用户进程在会话结束时是否默认终止。将此选项设置为“否”将允许在用户从系统注销后运行用户进程。KillExcludeUsers:如果启用了KillUserProcesses选项,则此选项允许您指定一个以空格分隔的用户列表,该列表允许进程在会话终止后继续运行。将用户名添加到此列表的行为与使用 loginctl 命令将用户添加到 systemd linger 组的行为类似。KillOnlyUsers:如果禁用了KillUserProcesses选项,则此参数可用于指定进程在注销后应终止的用户的空格分隔列表。
视频演示
如果需要有关在 Oracle Linux 8 上使用 systemd 的更多信息,可以在 https://www.youtube.com/watch?v=9uDvnZKhU8A 和 https://www.youtube.com/watch?v=Tkxs-wfZrnw 中提供 systemd 上的视频演示。
Oracle Linux 8 上的 systemd 系统和服务管理器
Oracle Linux 8 上的 systemd 目标单元
更多信息
- 系统文档:https://systemd.io/
systemd(1)手册页systemctl(1)手册页journalctl(1)手册页systemd.unit(5)手册页logind.conf(5)手册页- Oracle Linux 8:管理核心系统配置
- Oracle Linux 文档
更多学习资源
在 docs.oracle.com/learn 上浏览其他实验室,或者在 Oracle Learning YouTube 渠道上访问更多免费学习内容。此外,访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。