学习爱上 systemd

https://opensource.com/article/20/4/systemd

systemd——是的,全部小写,甚至在句子的开头——是 init 和 SystemV init 脚本的现代替代品。它还有更多。

像大多数系统管理员一样,当我想到 init 程序和 SystemV 时,我想到的是 Linux 启动和关闭,而不是其他很多,比如在服务启动和运行后管理服务。与 init 一样,systemd 是所有进程之母,它负责将 Linux 主机提升到可以完成生产性工作的状态。systemd 承担的一些功能比旧的 init 程序要广泛得多,它管理正在运行的 Linux 主机的许多方面,包括挂载文件系统、管理硬件、处理计时器以及启动和管理所需的系统服务拥有一台高效的 Linux 主机。

本系列文章部分基于我的三卷 Linux 培训课程使用和管理 Linux:从零到 sysadmin 的摘录,探讨了 systemd 在启动时和启动完成后的功能。

Linux 启动

é完整的过程,需要一台Linux主机从关闭状态到运行状态是复杂的,但它是开放的和可知。在进入详细信息之前,我将快速概述从主机硬件打开到系统准备好供用户登录。 大多数时候,“引导过程”作为单个实体进行讨论,但这并不准确。事实上,完整的引导和启动过程包括三个主要部分:

  • 硬件启动:初始化系统硬件
  • Linux 启动:加载 Linux 内核,然后 systemd
  • Linux 启动: systemd 为生产性工作准备主机的地方

Linux 启动序列在内核加载 init 或 systemd 之后开始,具体取决于发行版是使用旧启动还是新启动。init 和 systemd 程序启动和管理所有其他进程,在各自的系统上都被称为“所有进程之母”。

将硬件引导与 Linux 引导与 Linux 启动分开并明确定义它们之间的分界点很重要。了解这些差异以及每个差异在使 Linux 系统达到可以高效运行的状态中所起的作用,可以管理这些进程并更好地确定在大多数人所说的“启动”期间出现问题的位置。

启动过程遵循三步引导过程,并使 Linux 计算机进入可用于生产性工作的运行状态。当内核将主机的控制权转移到 systemd 时,启动过程就开始了。

系统性争议

systemd 可以引起系统管理员和其他负责保持 Linux 系统正常运行的人员的广泛反应。systemd 在许多 Linux 系统中接管了如此多的任务,这一事实在某些开发人员和系统管理员群体中引起了反对和不和。

SystemV 和 systemd 是执行 Linux 启动序列的两种不同方法。SystemV 启动脚本和 init 程序是旧方法,而 systemd using targets 是新方法。尽管大多数现代 Linux 发行版都使用较新的 systemd 进行启动、关闭和进程管理,但仍有一些没有。一个原因是一些发行版维护者和一些系统管理员更喜欢旧的 SystemV 方法而不是新的 systemd。

我认为两者都有优点。

为什么我更喜欢 SystemV

我更喜欢 SystemV,因为它更开放。启动是使用 Bash 脚本完成的。在内核启动 init 程序(它是一个编译后的二进制文件)后,init 启动rc.sysinit脚本,该脚本执行许多系统初始化任务。之后rc.sysinit中完成,init将启动/etc/rc.d/rc脚本,这反过来又开始由SystemV定义的各种服务,在启动脚本/etc/rc.d/rcX.d,其中“X”是正在启动的运行级别的编号。

 

除了 init 程序本身,所有这些程序都是开放的且易于理解的脚本。通读这些脚本并准确了解整个启动过程中发生的事情是可能的,但我认为实际上并没有很多系统管理员这样做。每个启动脚本都有编号,以便它以特定顺序启动其预期服务。服务是串行启动的,一次只启动一个服务。

 

systemd 由 Red Hat 的 Lennart Poettering 和 Kay Sievers 开发,是一个由大型编译二进制可执行文件组成的复杂系统,如果不访问源代码就无法理解。它是开源的,所以“访问源代码”并不难,只是不太方便。systemd 似乎代表了对 Linux 哲学多个原则的重大反驳。作为二进制文件,systemd 不会直接打开供系统管理员查看或轻松更改。systemd 尝试做所有事情,例如管理正在运行的服务,同时提供比 SystemV 多得多的状态信息。它还管理硬件、进程和进程组、文件系统挂载等等。systemd 几乎存在于现代 Linux 主机的各个方面,使其成为系统管理的一站式工具。

为什么我更喜欢 systemd

我更喜欢 systemd 作为我的启动机制,因为它会根据启动过程的当前阶段并行启动尽可能多的服务。这会加快整体启动速度,并使主机系统比 SystemV 更快地进入登录屏幕。

systemd 管理正在运行的 Linux 系统的几乎所有方面。它可以管理正在运行的服务,同时提供比 SystemV 多得多的状态信息。它还管理硬件、进程和进程组、文件系统挂载等等。systemd 几乎存在于现代 Linux 操作系统的各个方面,使其成为系统管理的一站式工具。(这听起来是不是很熟悉?)

systemd 工具是编译后的二进制文件,但工具套件是开放的,因为所有配置文件都是 ASCII 文本文件。启动配置可以通过各种GUI和命令行工具进行修改,也可以添加或修改各种配置文件,以适应特定本地计算环境的需要。

真正的问题

你认为我不能喜欢这两个启动系统吗?我愿意,而且我可以与任何一个一起工作。

在我看来,SystemV 和 systemd 之间大部分争议的真正问题和根本原因是在 sysadmin 级别上没有选择使用 SystemV 还是 systemd 的选择已经由各种发行版的开发人员、维护人员和打包人员做出——但有充分的理由。由于其极端的、侵入性的性质,挖出并替换 init 系统会产生很多后果,这些后果在发行版设计过程之外很难解决。

尽管这个选择是为我做出的,但我的 Linux 主机启动并工作,这是我通常最关心的。作为最终用户,甚至作为系统管理员,我最关心的是我是否能完成我的工作,比如写我的书和这篇文章、安装更新和编写脚本来自动化一切。只要我能做我的工作,我并不真正关心我的发行版上使用的启动顺序。

在启动或服务管理过程中出现问题时,我确实很在意。无论主机上使用哪种启动系统,我都知道足以按照事件顺序查找故障并修复它。

更换 SystemV

之前曾尝试用更现代的东西替换 SystemV。对于大约两个版本,Fedora 使用了一个叫做 Upstart 的东西来替换老化的 SystemV,但它没有替换 init 并且没有提供我注意到的任何变化。因为 Upstart 没有对围绕 SystemV 的问题做出重大改变,所以很快就放弃了朝这个方向发展的努力,转而支持 systemd。

尽管大多数 Linux 开发人员都同意替换旧的 SystemV 启动是个好主意,但许多开发人员和系统管理员不喜欢 systemd。与其重述人们使用 systemd 已经或曾经遇到的所有所谓问题,我将向您推荐两篇不错的文章,虽然有些陈旧,但它们应该涵盖大部分内容。Linux 内核的创建者 Linus Torvalds 似乎并不感兴趣。在 2014 年 ZDNet 的一篇文章中,Linus Torvalds 和其他人关于 Linux 的 systemd,Linus 清楚地表达了他的感受。

“我实际上对 systemd 本身并没有任何特别强烈的意见。我与一些核心开发人员有过问题,我认为他们对错误和兼容性过于傲慢,而且我认为一些设计细节很疯狂(我例如,不喜欢二进制日志),但这些都是细节,不是大问题。”

如果你对 Linus 不太了解,我可以告诉你,如果他不喜欢某样东西,他会非常直言不讳,直言不讳,而且很清楚那种不喜欢。他处理自己对事物的厌恶的方式在社会上变得更加可接受。

2013 年,Poettering 写了一篇很长的博客文章,在其中他揭穿了有关 systemd神话,同时深入了解了创建它的一些原因。这是一本非常好的读物,我强烈推荐它。

系统任务

根据编译过程中使用的选项(本系列不考虑这些选项),systemd 可以有多达 69 个二进制可执行文件来执行以下任务,其中包括:

  • systemd 程序作为 PID 1 运行,并提供尽可能多的并行服务的系统启动,这作为一个副作用,加快了整体启动时间。它还管理关闭顺序。
  • systemctl 程序提供了用于服务管理的用户界面。
  • 为了向后兼容,提供了对 SystemV 和 LSB 启动脚本的支持。
  • 服务管理和报告提供比 SystemV 更多的服务状态数据。
  • 它包括用于基本系统配置的工具,例如主机名、日期、区域设置、登录用户列表、正在运行的容器和虚拟机、系统帐户、运行时目录和设置、管理简单网络配置的守护进程、网络时间同步、日志转发, 和名称解析。
  • 它提供套接字管理。
  • systemd 计时器提供了类似于 cron 的高级功能,包括在与系统启动、systemd 启动、计时器上次启动等相关的时间运行脚本。
  • 它提供了一个工具来分析计时器规范中使用的日期和时间。
  • 具有层次意识的文件系统的挂载和卸载允许更安全地级联已挂载的文件系统。
  • 它可以积极创建和管理临时文件,包括删除。
  • D-Bus 接口提供了在插入或移除设备时运行脚本的能力。这允许所有设备,无论是否可插拔,都被视为即插即用,这大大简化了设备处理。
  • 其分析启动顺序的工具可用于定位耗时最多的服务。
  • 它包括用于存储系统日志消息的日志和用于管理日志的工具。

建筑学

许多守护进程、控制程序和配置文件支持这些任务以及更多任务。图 1 显示了许多属于 systemd 的组件。这是一个旨在提供高级概述的简化图,因此它不包括所有单个程序或文件。它也没有提供对数据流的任何洞察,数据流是如此复杂,以至于在本系列文章的上下文中这将是无用的练习。

 

图 1:systemd 的架构,作者 Shmuel Csaba Otto Traian (CC BY-SA 3.0)

对 systemd 的完整阐述本身就需要一本书。您不需要了解图 1 中的 systemd 组件如何组合在一起的细节;了解能够管理各种 Linux 服务并处理日志文件和日志的程序和组件就足够了。但很明显,systemd 并不是它的一些批评者所声称的庞大的庞然大物。

systemd 作为 PID 1

systemd 是 PID 1。它的一些功能比旧的 SystemV3 init 程序要广泛得多,可以管理正在运行的 Linux 主机的许多方面,包括挂载文件系统以及启动和管理具有高效 Linux 主机所需的系统服务。任何与启动顺序无关的 systemd 任务都超出了本文的范围(但本系列稍后会探讨一些)。

首先,systemd 挂载由/etc/fstab定义的文件系统,包括任何交换文件或分区。此时,它可以访问位于/etc 中的配置文件,包括它自己的配置文件它使用其配置链接/etc/systemd/system/default.target来确定它应该将主机引导到哪个状态或目标。default.target文件是一个符号链接到真正的目标文件。对于桌面工作站,这通常是graphics.target,相当于 SystemV 中的运行级别 5。对于服务器,默认值更有可能是multi-user.target,类似于 SystemV 中的运行级别 3。emergency.target类似于单用户模式。目标和服务是系统单位。

下表(图 2)将 systemd 目标与旧的 SystemV 启动运行级别进行了比较。systemd 提供 systemd 目标别名以实现向后兼容性。目标别名允许脚本和许多系统管理员使用 SystemV 命令(如init 3)来更改运行级别。当然,SystemV 命令会转发给 systemd 进行解释和执行。

系统目标 SystemV 运行级别 目标别名 描述
默认目标     这个目标总是与一个符号链接走样multi-user.targetgraphical.targetsystemd 总是使用default.target来启动系统。default.target不应该被混淆为halt.targetpoweroff.target,或reboot.target
图形目标 5 运行级别5.target Multi-user.target使用GUI
  4 运行级别4.target 没用过。运行级别 4 与 SystemV 世界中的运行级别 3 相同。可以创建和自定义此目标以启动本地服务,而无需更改默认multi-user.target
多用户目标 3 运行级别3.target 所有服务都在运行,但仅限命令行界面 (CLI)
  2 运行级别2.target 多用户,没有 NFS,但所有其他非 GUI 服务正在运行
救援目标 1 运行级别1.target 一个基本系统,包括挂载仅运行最基本服务的文件系统和主控制台上的救援外壳
紧急目标   单用户模式——没有服务正在运行;未挂载文件系统。这是最基本的操作级别,仅在主控制台上运行一个紧急外壳,供用户与系统交互。
停止目标     在不关闭电源的情况下暂停系统
重启目标 6 运行级别6.target 重启
关机目标 0 运行级别0.target 停止系统并关闭电源

图 2:SystemV 运行级别与 systemd 目标和一些目标别名的比较

每个目标都有一组在其配置文件中描述的依赖项。systemd 启动所需的依赖项,这些依赖项是在特定功能级别运行 Linux 主机所需的服务。当目标配置文件中列出的所有依赖项都加载并运行时,系统就在该目标级别上运行。在图 2 中,功能最多的目标位于表格顶部,功能向表格底部递减。

systemd 还会查看旧的 SystemV init 目录,以查看那里是否存在任何启动文件。如果是这样,systemd 将它们用作配置文件来启动文件所描述的服务。弃用的网络服务就是一个很好的例子,它仍然使用 Fedora 中的 SystemV 启动文件。

图 3(下图)是直接从启动手册页复制而来的。它显示了 systemd 启动期间的一般事件序列图以及确保成功启动的基本排序要求。

                                         cryptsetup-pre.target
                                                   |
 (各种低级 v
     API VFS 挂载:(各种 cryptsetup 设备...)
  mqueue、configfs、| |
  debugfs、...) v |
  | cryptsetup.target |
  | (各种交换 | | remote-fs-pre.target
  | 设备...) | |
  | v
  | v local-fs-pre.target | (网络文件系统)
  | 交换目标| v v |
  | v | 远程cryptsetup.target |
  | (各种低级(各种挂载和 | | |
  | 服务:udevd、fsck 服务...)| | remote-fs.target
  | | tmpfiles、随机 | | /
  | | 种子、sysctl、...) v | /
  | 本地fs.target | /
  | /
  \____|______|_______________ ______|___________/ | /
                              \ / | /
                               v | /
                        sysinit.target | /
                               | /
        ____________/|\___________ | /
       / | \ | /
       | /
       v v | v | /
  (各种(各种|(各种||/
   计时器...) 路径...) | 插座...) | |
       | |
       v v | v | |
 timers.target 路径.target | sockets.target | |
       | v |
       v \_______ | _____/rescue.service |
                              \|/ | |
                               v v |
                           basic.target 救援.target |
                               | |
                       ________v____________________ |
                      / | \ |
                      | |
                      v v v |
                  display-(各种系统(各种系统 |
              manager.service services services)|
                      | 需要 | |
                      | 图形用户界面) v v
                      | 多用户目标
 紧急服务| |
         | \_____________ | _____________/
         v \|
 /emergency.target v
                              graphics.target

图 3:systemd 启动图

sysinit.targetbasic.target目标可以考虑在启动过程中的检查点。尽管 systemd 的设计目标之一是并行启动系统服务,但必须先启动某些服务和功能目标,然后才能启动其他服务和目标。在完成该检查点所需的所有服务和目标之前,无法通过这些检查点。

sysinit.target当所有这取决于单位完成为止。所有这些单元、安装文件系统、设置交换文件、启动 udev、设置随机生成器种子、启动低级服务和设置加密服务(如果一个或多个文件系统被加密),都必须完成,但是,在sysinit.target,这些任务可以并行执行。

sysinit.target启动所有的系统所需要的低层次服务和单位是轻微的功能和所需要的使移动到basic.target

完成sysinit.target,systemd 将启动完成下一个目标所需的所有单元。基本目标通过启动所有下一个目标所需的单元来提供一些附加功能。其中包括设置各种可执行目录的路径、通信套接字和计时器等内容。

最后,用户级别的目标,multi-user.targetgraphical.target,可以初始化。multi-user.target必须要达到的目标图形依赖可以得到满足之前。图 3 中带下划线的目标是通常的启动目标。当达到这些目标之一时,启动已完成。如果multi-user.target是默认值,那么您应该会在控制台上看到文本模式登录。如果graphics.target是默认的,那么你应该会看到一个图形登录;您看到的特定 GUI 登录屏幕取决于您的默认显示管理器。

启动手册页还描述并提供了启动到初始 RAM 磁盘和 systemd 关闭过程的映射。

systemd 还提供了一个工具,用于列出完整启动或指定单元的依赖项。单元是一个可控的 systemd 资源实体,范围可以从特定服务(例如 httpd 或 sshd)到计时器、挂载、套接字等。尝试以下命令并滚动查看结果。

systemctl list-dependencies graphical.target

请注意,这完全扩展了使系统进入图形目标运行模式所需的顶级目标单元列表。使用--all选项也可以扩展所有其他单位。

systemctl list-dependencies --all graphical.target

您可以使用less命令的搜索工具搜索诸如“target”、“slice”和“socket”之类的字符串

所以现在,请尝试以下操作。

systemctl list-dependencies multi-user.target

systemctl list-dependencies rescue.target

systemctl list-dependencies local-fs.target

systemctl list-dependencies dbus.service

这个工具帮助我可视化我正在处理的主机的启动依赖项的细节。继续花一些时间探索一台或多台 Linux 主机的启动树。但要小心,因为 systemctl 手册页包含以下说明:

"请注意,此命令仅列出服务管理器当前加载到内存中的单元。特别是,此命令不适合获取特定单元的所有反向依赖项的完整列表,因为它不会列出单元声明的依赖项当前未加载。”

最后的想法

甚至在深入了解 systemd 之前,很明显它既强大又复杂。很明显,systemd 不是一个单一的、巨大的、单一的、不可知的二进制文件。相反,它由许多旨在执行特定任务的较小组件和子命令组成。

本系列的下一篇文章将更详细地探讨 systemd 启动,以及 systemd 配置文件、更改默认目标以及如何创建简单的服务单元。

资源

互联网上有大量关于 systemd 的信息,但很多都是简明扼要的,甚至是误导性的。除了本文中提到的资源外,以下网页还提供了有关 systemd 启动的更详细和可靠的信息。

  • Fedora 项目有一个很好的、实用的systemd指南 它拥有使用 systemd 配置、管理和维护 Fedora 计算机所需的几乎所有知识。
  • Fedora 项目还有一个很好的备忘单,可以将旧的 SystemV 命令与类似的 systemd 命令进行交叉引用。
  • 有关 systemd 的详细技术信息及其创建原因,请查看Freedesktop.org对 systemd描述
  • Linux.com的“More systemd fun”提供了更高级的 systemd信息和技巧

systemd 的设计师和主要开发人员 Lennart Poettering 还为 Linux 系统管理员撰写了一系列深入的技术文章。这些文章写于 2010 年 4 月至 2011 年 9 月之间,但它们现在和当时一样具有相关性。很多关于 systemd 及其生态系统的好文章都基于这些论文。

posted @ 2021-07-02 11:24  CharyGao  阅读(197)  评论(0编辑  收藏  举报