如何使用 Systemctl 管理 Systemd 服务和单元

介绍

「systemd」是一个 init 系统和系统管理器,已经广泛成为Linux发行版的新标准。由于其广泛采用,熟悉「systemd」是值得的麻烦,因为它将使管理服务器变得更容易。了解和使用包括「systemd」在内的工具和恶魔,将有助于您更好地欣赏它提供的力量,灵活性和功能,或者至少有助于您以更少的麻烦完成工作。

在本指南中,我们将讨论systemctl命令,该命令是控制 init 系统的中央管理工具,我们将介绍如何管理服务,检查状态,更改系统状态,以及处理配置文件。

请注意,虽然systemd已成为许多Linux发行版的默认 init系统,但它并非在所有发行版中普遍实施。当您通过本教程时,如果您的终端输出错误bash: systemctl未安装,那么您的机器可能安装了不同的 init系统。

服务管理

init 系统的基本目的是在启动 Linux 内核后必须启动的组件(传统上称为userland组件)的初始化, init 系统还用于在系统运行时随时为服务器管理服务和 daemons。

systemd中,大多数操作的目标是单位,这些是systemd知道如何管理的资源。单位按它们所代表的资源类型进行分类,并通过被称为单元文件的文件来定义。

对于服务管理任务,目标单元将是服务单元,这些单元文件具有.service字符串,但对于大多数服务管理命令,您实际上可以放弃.service字符串,因为systemd足够聪明,以便知道在使用服务管理命令时,您可能希望在服务上运行。

启动和停止服务

要启动systemd服务,在服务的单元文件中执行指令,请使用start命令. 如果您作为非 root 用户运行,则必须使用sudo,因为这会影响操作系统的状态:

1sudo systemctl start application.service

正如我们上面提到的,‘systemd’ 知道为服务管理命令搜索 `*.service’ 文件,所以该命令可以这样键入:

1sudo systemctl start application

虽然您可以使用上述格式用于一般管理,但为了澄清,我们将为其余的命令使用.service字符串,以明确我们正在操作的目标。

要停止当前正在运行的服务,您可以使用停止命令:

1sudo systemctl stop application.service

重新启动和重新加载

要重新启动运行服务,您可以使用重新启动命令:

1sudo systemctl restart application.service

如果该应用程序能够重新加载其配置文件(没有重新启动),您可以发出重新加载命令来启动该过程:

1sudo systemctl reload application.service

如果您不确定该服务是否具有重新加载配置的功能,您可以发出重新加载或重新启动命令。

1sudo systemctl reload-or-restart application.service

允许和禁用服务

上面的命令有助于在当前会话中启动或停止服务. 要告诉systemd在启动时自动启动服务,您必须启用它们。

要在 boot 上启动服务,请使用启用命令:

1sudo systemctl enable application.service

这将从系统的服务文件副本(通常在/lib/systemd/system/etc/systemd/system)创建一个符号链接到磁盘上的位置,在那里systemd寻找自动启动文件(通常是/etc/systemd/system/some_target.target.wants

要禁用自动启动服务,您可以键入:

1sudo systemctl disable application.service

这将删除标志性链接,表示该服务应该自动启动。

请记住,启用服务不会在当前会话中启动它. 如果您希望启动该服务并在启动时启用它,则必须发出启动启用命令。

检查服务状态

要检查系统上的服务状态,您可以使用状态命令:

1systemctl status application.service

这将为您提供服务状态、cgroup 等级和前几行日志。

例如,当检查 Nginx 服务器的状态时,您可能会看到这样的输出:

 1[secondary_label Output]
 2 nginx.service - A high performance web server and a reverse proxy server
 3   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
 4   Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
 5 Main PID: 495 (nginx)
 6   CGroup: /system.slice/nginx.service
 7           ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
 8           └─496 nginx: worker process
 9Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server...
10Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

这为您提供了当前应用程序状态的良好概述,通知您任何问题和可能需要采取的任何行动。

例如,要检查一个单位是否目前处于活动状态(运行),您可以使用是活跃命令:

1systemctl is-active application.service

这将返回当前单元状态,通常是活跃不活跃。如果活跃,输出代码将是0,使结果更容易在壳脚本中解析。

要查看该单元是否已启用,您可以使用is-enabled命令:

1systemctl is-enabled application.service

这将输出服务是否启用禁用,并将输出代码重新设置为01,取决于对命令问题的答案。

第三個檢查是裝置是否處於失敗狀態,這表明有問題啟動該裝置:

1systemctl is-failed application.service

如果发生错误,该设备可能会返回未知不活跃0的输出状态表示出现了故障,而1的输出状态表示任何其他状态。

系统国家概述

到目前为止,这些命令对管理单个服务非常有用,但对于探索系统的当前状态并不太有用。

现有单位列表

要查看systemd知道的所有活跃单元的列表,我们可以使用list-units命令:

1systemctl list-units

这将向您显示所有目前在系统上活跃的systemd单元的列表,输出将看起来像这样:

1[secondary_label Output]
2UNIT LOAD ACTIVE SUB DESCRIPTION
3atd.service loaded active running ATD daemon
4avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
5dbus.service loaded active running D-Bus System Message Bus
6dcron.service loaded active running Periodic Command Scheduler
7dkms.service loaded active exited Dynamic Kernel Modules System
8getty@tty1.service loaded active running Getty on tty1
9. . .

输出有以下列:

  • UNIT: systemd 单元名称
  • LOAD:单元的配置是否已被 systemd 解析。被加载单元的配置保存在记忆中
  • ACTIVE:有关单元是否活跃的概述状态。这通常是一个相当基本的方式来判断单元是否成功启动
  • SUB:这是一个较低水平的状态,指示了有关单元的更详细信息。这通常因单元类型、状态和单元运行的实际方法而异。

由于list-units命令默认情况下只显示活跃单元,所以上面的所有条目都将显示在 LOAD 列中加载活跃在 ACTIVE 列中。

1systemctl

例如,要查看系统d 已加载(或试图加载)的所有单元,无论它们是否目前处于活动状态,您可以使用--all 标志,如下:

1systemctl list-units --all

这将显示任何systemd加载或试图加载的单元,无论其当前系统状态如何。

您可以使用其他标志来过滤这些结果. 例如,我们可以使用 --state= 标志来表示我们想要看到的 LOAD、ACTIVE 或 SUB 状态。

1systemctl list-units --all --state=inactive

另一个常见的过滤器是 --type= 过滤器. 我们可以说 `systemctl' 只显示我们感兴趣的类型单位。

1systemctl list-units --type=service

列出所有单元文件

「list-units」命令只显示了「systemd」试图解析并加载到内存的单元。由于「systemd」只会读取它认为需要的单元,这不一定包括系统上的所有可用单元。

1systemctl list-unit-files

由于systemd在本视图中不一定读过所有单位定义,它只会呈现有关文件本身的信息。

 1[secondary_label Output]
 2UNIT FILE STATE
 3proc-sys-fs-binfmt_misc.automount static
 4dev-hugepages.mount static
 5dev-mqueue.mount static
 6proc-fs-nfsd.mount static
 7proc-sys-fs-binfmt_misc.mount static
 8sys-fs-fuse-connections.mount static
 9sys-kernel-config.mount static
10sys-kernel-debug.mount static
11tmp.mount static
12var-lib-nfs-rpc_pipefs.mount static
13org.cups.cupsd.path enabled
14. . .

状态通常是启用,禁用,静态隐藏。在这种情况下,静态意味着单元文件不包含一个安装部分,用于启用单元。

我们将暂时覆盖伪装的含义。

单位管理

到目前为止,我们一直在与服务合作,并显示有关systemd知道的单元和单元文件的信息,然而,我们可以使用一些额外的命令找到有关单元的更具体信息。

显示单元文件

要显示systemd已加载到其系统的单元文件,您可以使用cat命令(在systemd版本209中添加了该命令)。

1systemctl cat atd.service
1[secondary_label Output]
2[Unit]
3Description=ATD daemon
4[Service]
5Type=forking
6ExecStart=/usr/bin/atd
7[Install]
8WantedBy=multi-user.target

输出是目前正在运行的systemd过程中所知的单元文件,如果您最近修改了单元文件或在单元文件片段中超过某些选项,这可能很重要(我们稍后将讨论)。

显示依赖性

若要查看单位的依赖树,可以使用列表依赖命令:

1systemctl list-dependencies sshd.service

这将显示一个层次结构,描绘需要处理的依赖性,以便启动所涉及的单位。

 1[secondary_label Output]
 2sshd.service
 3├─system.slice
 4└─basic.target
 5  ├─microcode.service
 6  ├─rhel-autorelabel-mark.service
 7  ├─rhel-autorelabel.service
 8  ├─rhel-configure.service
 9  ├─rhel-dmesg.service
10  ├─rhel-loadmodules.service
11  ├─paths.target
12  ├─slices.target
13. . .

重复依赖只显示为 .target 单元,表示系统状态. 若要重复列出所有依赖,请包括 --all 旗帜。

若要显示反向依赖(取决于指定的单位的单位),您可以将反向旗帜添加到命令中。

检查单位财产

若要查看单元的低级属性,您可以使用显示命令. 这将显示使用关键=值格式为指定的单元设置的属性列表:

1systemctl show sshd.service
 1[secondary_label Output]
 2Id=sshd.service
 3Names=sshd.service
 4Requires=basic.target
 5Wants=system.slice
 6WantedBy=multi-user.target
 7Conflicts=shutdown.target
 8Before=shutdown.target multi-user.target
 9After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
10Description=OpenSSH server daemon
11. . .

如果您想要显示单个属性,您可以通过-p标志与属性名称。例如,要查看sshd.service单元的冲突,您可以键入:

1systemctl show sshd.service -p Conflicts
1[secondary_label Output]
2Conflicts=shutdown.target

面具和解面具单元

我们在服务管理部分中看到了如何停止或禁用服务,但systemd也有能力将一个单元标记为完全不可启动的,自动或手动,通过将其链接到/dev/null

1sudo systemctl mask nginx.service

这将防止 Nginx 服务自动或手动启动,只要它被掩盖。

如果你检查列表单元文件,你会看到该服务现在列为伪装:

1systemctl list-unit-files
 1[secondary_label Output]
 2. . .
 3kmod-static-nodes.service static
 4ldconfig.service static
 5mandb.service static
 6messagebus.service static
 7nginx.service masked
 8quotaon.service static
 9rc-local.service static
10rdisc.service disabled
11rescue.service static
12. . .

如果您尝试启动该服务,您将看到这样的消息:

1sudo systemctl start nginx.service
1[secondary_label Output]
2Failed to start nginx.service: Unit nginx.service is masked.

要解除一个单元,使其再次可用,请使用解除面具命令:

1sudo systemctl unmask nginx.service

这将使单元恢复到以前的状态,允许它启动或启动。

编辑单元文件

虽然单元文件的特定格式不在本教程的范围内,但systemctl提供了内置的编辑和修改单元文件的机制,如果需要进行调整。

默认情况下,编辑命令将为该单位打开一个单元文件片段:

1sudo systemctl edit nginx.service

这将是一个空格的文件,可以用来翻译或添加指令到单位定义中。在 /etc/systemd/system 目录中将创建一个目录,其中包含该单位的名称,附加了 `.d。

在该目录中,将创建一个名为override.conf的片段。当该单元被加载时,systemd将在内存中将该片段合并到完整的单元文件中。

如果您想编辑完整的单元文件,而不是创建一个片段,您可以通过--full旗帜:

1sudo systemctl edit --full nginx.service

当编辑器退出时,更改的文件将被写入 /etc/systemd/system,这将优先于系统的单位定义(通常在 /lib/systemd/system中找到)。

要删除你所做的任何添加,要么删除设备的 .d 配置目录,要么从 /etc/systemd/system 中删除修改后的服务文件。

1sudo rm -r /etc/systemd/system/nginx.service.d

要删除完整的修改单元文件,我们会键入:

1sudo rm /etc/systemd/system/nginx.service

删除文件或目录后,您应该重新加载systemd过程,以便它不再试图引用这些文件,然后返回使用系统副本。

1sudo systemctl daemon-reload

通过目标调整系统状态(运行级别)

目标是描述系统状态或同步点的特殊单元文件. 与其他单元一样,定义目标的文件可以通过其尾声来识别,在这种情况下是.target

这可以用来将系统带到某些状态,就像其他 init 系统使用运行级别一样,它们被用作某些函数可用时的参考,允许您指定所需的状态,而不是生产该状态所需的单个单位。

例如,有一个swap.target用于表示,swap 已准备好使用. 作为这个过程的一部分的单位可以通过在配置中表示它们是WantedBy=RequiredBy=swap.target来同步这个目标。

获取和设置默认目标

这个systemd过程有一个默认目标,它在启动系统时使用它. 满足这个单一目标的依赖范围将使系统进入所需状态。

1systemctl get-default
1[secondary_label Output]
2multi-user.target

如果您想要设置不同的默认目标,您可以使用默认设置。例如,如果您安装了图形桌面,并且您希望系统默认启动,您可以相应地更改默认目标:

1sudo systemctl set-default graphical.target

可用目标列表

您可以通过键入系统上可用的目标列表:

1systemctl list-unit-files --type=target

与运行级别不同,多个目标可以同时活跃。一个活跃的目标表示systemd试图启动与目标绑定的所有单元,并且没有试图再次打破它们。

1systemctl list-units --type=target

孤立目标

可以启动与目标相关的所有单元,并停止所有不属于依赖树的一部分单元。我们需要这样做的命令被称为适当的隔离

例如,如果您在graphical.target活跃的图形环境中运行,则可以关闭图形系统并将系统放入多用户命令行状态,以隔离multi-user.target

您可能想看看您正在隔离的目标的依赖性,然后执行此程序,以确保您不会停止重要的服务:

1systemctl list-dependencies multi-user.target

当你对将保持活跃的单元感到满意时,你可以通过键入来隔离目标:

1sudo systemctl isolate multi-user.target

在重要事件中使用快捷方式

对于重要的事件,如停电或重新启动,有定义的目标,但是,‘systemctl’也有一些快捷的步骤,增加了一些额外的功能。

例如,若要将系统放入救援(单用户)模式,可以使用救援命令而不是隔离 rescue.target:

1sudo systemctl rescue

这将提供通知所有登录的用户有关事件的额外功能。

要停止系统,您可以使用停止命令:

1sudo systemctl halt

要启动完全关闭,您可以使用poweroff命令:

1sudo systemctl poweroff

重启可以用重启命令开始:

1sudo systemctl reboot

所有这些警告都记录在用户中,该事件正在发生,而仅仅运行或隔离目标将不会发生。

例如,要重新启动系统,您通常可以键入:

1sudo reboot

结论

到目前为止,您应该熟悉systemctl命令的一些基本功能,允许您与systemd实例进行交互和控制。

虽然systemctl主要通过核心systemd过程运作,但systemd生态系统的其他组件由其他实用程序控制。 其他功能,如日志管理和用户会话,由单独的戴蒙和管理实用程序(分别为journald/journalctllogind/loginctl)来处理。

Published At
Categories with 技术
Tagged with
comments powered by Disqus