systemd:源自红帽的系统初始化和服务管理套件

目录

概述

历史

设计

核心组件和库

辅助组件

systemd的配置

配置文件的层级结构

采纳情况

与其他软件的集成

接受情况

分支版本和替代实现

eudev

elogind

uselessd

systembsd

consolekit2

loginkit

notsystemd

s6


概述

systemd是一个软件套件,它为Linux操作系统提供一系列系统组件。

它的主要目的是将所有Linux发行版的服务配置和行为统一起来。systemd的主要组件是一个“系统和服务管理器”(system and service manager),这是一个初始化(init)系统,被用于引导(bootstrap)用户空间和管理用户进程。它同时还为很多守护进程(daemon)和工具软件提供了替代品,包括:

  • 设备管理(device management)
  • 登录管理(login management)
  • 网络连接管理(network connection management)
  • 事件日志(event logging)

 

其名称“systemd”遵循了Unix的关于守护进程(daemons)的命名,即在名称之后加上字母“d”。另外,它还在这里玩了一个文字游戏,读起来是“System D”,是指一个人快速适应和即兴发挥而解决问题的能力(这个词汇源自法语,形容一个人在面对挑战时总是能突发奇想、脑洞大开、灵光一闪,解决问题)。

从2015年开始,主要的Linux发行版都已经采用了systemd,替代了其他的系统管理机制,包括UNIX系统V和BSD的初始化(init)系统。systemd面临着来自Linux用户的复杂感受,他们常常评论说,systemd常常遭遇到任务蠕涨(creep)和肿胀(bloat),以及对各种软件(例如GNOME桌面系统)向其他类Unix操作系统添加对systemd的令人沮丧的兼容性。

 

历史

在红帽公司(Red Hat)工作的莱恩纳特·波特林(Lennart Poettering)和凯·西沃斯(Kay Sievers)发起了对systemd的开发,并于2010年启动了开发systemd的项目。他们寻求通过多种方式来超越初始化守护进程(init daemon)的效率。他们想要改进用于表示依赖关系的软件框架(software framework for expressing dependencies),从而在系统启动时,允许更多的进程可以并发执行,并降低shell的计算固定开销(computational overhead)。

2011年05月,Fedora称为了首个默认启用systemd的主流Linux发行版。在2013年10月到2014年02月之间,德卞技术委员会(Debian Technical Committee)在德卞邮件列表中出现了一次长久的争论,讨论应该使用哪个初始化系统(init system)作为德卞8“杰西”(jessie)的默认初始化系统,并最终决定支持systemd。在讨论过程中,这个辩论的内容被广泛地公开。2014年02月,在德卞做出决定后,马克·夏特尔沃斯(Mark Shuttleworth)在他的博客中宣布,乌班图(Ubuntu)会跟随实现systemd。

2014年11月,德卞开发者乔伊·海斯(Joey Hess)、德卞技术委员会成员拉斯·阿尔伯利(Russ Allbery)和伊恩·杰克逊(Ian Jackson),以及systemd软件包维护者托勒夫·福格·海恩(Tollef Fog Heen)辞去他们的职位。他们四位都在德卞邮件组和个人博客中对他们的决定说明了理由,提到了他们暴露在持续的关于将systemd集成到德卞的持续争论的巨大压力中,以及开源社区呈现常规维护几乎是不可能的。

2015年08月,systemd开始提供登录shell,可以通过machinectl shell来调用。

2016年09月,一个安全性漏洞被发现,它允许任何没有权限的用户对systemd执行拒绝服务式攻击。musl的开发者里奇·菲尔克(Rich Felker)表示,这个漏洞揭示了一个重要的“系统开发设计瑕疵”。2017年,systemd又被发现了另一个安全性漏洞,被称为CVE-2017-9445,它允许一台“恶意DNS服务器”能够“破坏服务”。

 

设计

波特林将systemd的开发工作描述为“永远结束不了,永远完成不了,但是一直跟着技术的发展”。2014年05月,波特林进一步将systemd描述为,通过提供如下三个一般功能,统一了“各个发行版之间数不清的差异”:

  • 一个系统和服务管理器(同时管理服务——通过应用各种不同的配置——以及它们的服务)
  • 一个软件平台(作为开发其他软件的基础)
  • 应用程序和内核之间的粘合剂(提供各种接口,暴露内核提供的各种功能)

 

systemd包含的功能有(例如):

  • 按需启动守护进程(on-demand starting of daemons)
  • 支持快照(snapshot support)
  • 进程跟踪(process tracking)
  • 缓止器锁(Inhibitor Locks)

 

systemd不仅仅是初始化守护进程(init daemon)的名字,而是指包括systemd以及环绕在它周围的整个软件集合,这里面包含的东西,除了systemd初始化守护进程之外,还有其他的守护进程,包括:

  • journald
  • logind
  • networkd
  • 另外,还有其他很多底层组件。

 

2013年01月,波特林将systemd描述为不仅仅是一个程序,而是一个巨大的软件套件,包括69个独立的二进制文件。作为一个集成的软件套件,systemd替代了由传统的init守护进程控制的启动序列(startup sequences)和运行级别(runlevel),以及在它控制下的shell脚本的执行。systemd还集成了很多其他的服务,它们在Linux系统中都很常见,包括:

  • 处理用户登录
  • 处理系统控制台
  • 设备热插拔(udev)
  • 调度执行(scheduled execution,替换cron)
  • 日志
  • 主机名
  • 区域设置(如时区、当地法律规定的夏令时等)

 

与很多初始化守护进程(init daemon)一样,systemd是一个管理其他守护进程的守护进程。守护进程,包括systemd自身,都是后台进程。systemd是在引导期间第一个启动的进程,也是在关机期间最后一个结束的进程。systemd是作为用户空间进程树的根节点存在的。在Unix系统中,第一个进程(进程号,也就是PID,为1)具有特殊的地位,因为当一个进程的原始父进程结束的时候,它就替代那个父进程,变成这个进程的父进程。因此,第一个进程就尤其适合用于监视其他的守护进程。

systemd是并行执行它的的启动序列中的各项内容(elements of its startup sequence)的,理论上,这样会比传统的启动序列方式要更快。对于进程间通信(Inter-Process Communication,简称IPC),systemd提供了Unix域套接字(sockets)和D-Bus来运行守护进程。systemd自身的状态也可以被保存(preserve)在一个快照中,以便以后回溯(recall)

 

核心组件和库

根据它的“集成性”的思路,systemd还为很多守护进程和实用工具提供了替代品,包括:

  • 启动shell脚本
  • pm-utils,即Perl Module
  • inetd,即InterNet Service Daemon,负责网络通信,源自UNIX
  • acpid
  • syslog
  • watchdog
  • cron,负责定时任务
  • atd

 

systemd的核心组件包括下面几部分:

  • systemd,它是一个用于Linux操作系统的“系统和服务管理器”。
  • systemctl,它是一个命令,用于对systemd“系统和服务管理器”的状态进行内省(introspect)和控制。注意,它和sysctl不是一回事。
  • systemd-analyze,它可以被用于确定系统启动性能指标,以及从“系统和服务管理器”获取其他的状态信息和跟踪日志信息。

 

systemd使用Linux内核的“cgroups子系统”而不是“进程标识符”(Process IDentifiers,简称PIDs)来跟踪进程。因此,守护进程无法“逃脱”systemd,及时进行双重进程复制(double-forking)也做不到。此外,systemd并不只是单纯地使用cgroups,还会使用systemd-nspawn和machinectl——两个实用工具程序,帮助Linux容器(containers)的创建和管理——来为cgroups提供参量(augments)。从第205版开始,systemd还提供了ControlGroupInterface,这是一个用于访问Linux内核cgroups的API。Linux内核cgroups为支持kernfs而做了适配,并且被修改以支持一个统一的层级结构。

 

辅助组件

除了“提供一个Linux初始化(init)系统”这一主要目的之外,systemd套件还可以提供一些额外的功能,也就是“辅助组件”(ancillary components),包括如下的组件:

  • journald

systemd-journald是一个守护进程(daemon),负责事件日志,使用“只追加”(append-only)的二进制文件作为其日志文件。系统管理员可以选择使用systemd-journald、syslog-ng或rsyslog来记录系统事件的日志。该二进制格式的潜在的“腐化”的可能性(potential for corruption)导致了很多激烈的争论。

  • logind

systemd-logind是一个守护进程(daemon),它通过多种方式来管理登录和席位(logins and seats)。它是一个集成的登录管理器,提供多席位(multiseat)改进,并代替了ConsoleKit,后者已经不再维护。对于X11显示管理器,如果要迁移到logind的话,只需要很小的移植性改动。在第30版中,它被集成到systemd中。

  • resolved
  • timesyncd
  • networkd

networkd是一个守护进程(daemon),它管理网络接口的配置。它在第209版中首次被集成进来,当时限制在只支持静态分配的地址,以及对桥接配置的基本支持。2014年06月,systemd第215版发布,增加了新的功能,例如用于IPv4主机的DHCP服务器,以及对VXLAN的支持。可以使用networkctl来查看网络链接的状态,它看到的内容与systemd-networkd所看到的是相同的。新接口的配置被添加到/lib/systemd/network/目录下,放在一个以.network扩展名结尾的新文件中。

  • tmpfiles

systemd-tmpfiles是一个实用工具,它负责临时文件和目录的创建和清理。它通常在启动时运行一次,然后在特定的间隔后再次运行。

  • timedated

systemd-timedated是一个守护进程(daemon),它可以被用于控制“时间相关”(time-related)的设置,例如,系统时间,系统时区,在UTC和本地时区系统时钟之间选择。

可以通过D-Bus来访问它。它在systemd第30版中被集成进来。

  • udevd

udev是用于Linux内核的一个设备管理器。它负责处理/dev目录,以及当添加或删除设备——包括固件载入——时,管理所有的用户空间动作(user space actions)。2012年04月,udev的一个源代码树被合入到systemd的源代码树。

2014年05年29日,对于通过udev来进行固件载入的支持,被systemd放弃,相关人员决定,内核应当负责载入固件。

  • libudev

libudev是使用udev时所需的一个标准库,它允许第三方应用程序查询udev资源。

  • systemd-boot

systemd-boot是一个引导管理器,曾经名为gummiboot。凯·西沃尔斯(Kay Sievers)在第220版中将其合入到systemd中。

 

systemd的配置

systemd完全通过普通文本文件来进行配置。

systemd在一个配置文件(被称为“unit file”,即“单元文件”)中为每个守护进程记录初始化指令。该文件使用声明式语言(declarative language),替代了传统上使用的、每守护进程一个的shell脚本。“单元文件”的类型包括:

  • .service
  • .socket
  • .device
  • .mount
  • .automount
  • .swap
  • .target
  • .path
  • .timer(可以被用于类cron的任务调度器)
  • .snapshot
  • .slice(用于对进程和资源进行分组和管理)
  • .scope

 

配置文件的层级结构

可以使用“man systemd.unit”命令来查看配置文件的层级结构的解释说明。它们的路径是在编译时就确定的,默认是:

UNIT LOAD PATH
          单元文件(unit files)是从一系列在编译时就确定下来的路径中被载
          入的,这些路径在如下的两张表中列出。如果在多个目录中发现了相同
          文件名的单元文件,则下表中前面目录发现的文件中的配置,会覆盖后
          面目录中的同名文件中的配置。

           表 1.  当以系统模式运行时(--system)的载入路径
           ┌────────────────────────┬─────────────────────────────┐
           │路径                     │ 描述                        │
           ├────────────────────────┼─────────────────────────────┤
           │/etc/systemd/system     │ 本地配置                     │
           ├────────────────────────┼─────────────────────────────┤
           │/run/systemd/system     │ 运行时单元                   │
           ├────────────────────────┼─────────────────────────────┤
           │/usr/lib/systemd/system │ 已安装的软件包的单元          │
           └────────────────────────┴─────────────────────────────┘

采纳情况

(Adoption)

 

Linux发行版

 

加入软件仓库的日期

是否默认启用

作为默认软件包的发布日期

是否可以脱离它运行

Alpine Linux

N/A(不在软件仓库中)

N/A

安卓

N/A(不在软件仓库中)

N/A

Arch Linux

2012年01月

2012年10月

AntiX Linux

N/A(不在软件仓库中)

N/A

Artix Linux

N/A(不在软件仓库中)

N/A

CentOS

2014年04月

2014年04月(7.14.04)

CoreOS

2013年07月

2013年10月(v94.0.0)

Debian

2012年04月

2015年04月(v8)

Devuan

N/A(不在软件仓库中)

N/A

Fedora

2010年11月(v14)

2011年05月(v15)

Gentoo Linux

2011年07月

N/A

Knoppix

N/A

N/A

Linux Mint

2016年06月(v18.0)

N/A

Mageia

2011年01月(v1.0)

2012年05月(v2.0)

Manjaro Linux

2013年11月

2013年11月

openSUSE

2011年03月(v11.4)

2012年09月(v12.2)

Parabola GNU/Linux-libre

2012年01月

可选

N/A

红帽企业级Linux

2014年06月(v7.0)

2014年06月(v7.0)

Slackware

N/A(不在软件仓库中)

N/A

Solus

N/A

N/A

Source Mage GNU/Linux

2011年06月

N/A

SUSE Linux企业级服务器

2014年10月(v12)

2014年10月(v12)

乌班图

2013年04月(v13.04)

2015年04月(v15.04)

在Yaketty(v16.04)中去掉了启动(upstart)选项。缺乏使用除systemd之外的初始化系统的功能。

Void Linux

2011年06月,2015年06月移除

N/A

 

尽管很多发行版默认会引导systemd,但也有一些允许使用其他的初始化(init)系统。在这种情况下,可以通过安装相应的软件包,就能切换到其他的初始化(init)系统。德卞(Debian)的一个分支版名为Devuan被开发出来,其目的就是避免使用systemd,并且其稳定版已经推出了第2.0版。2019年12月,德卞项目投票表决,支持保留systemd作为该发行版的默认初始化(init)系统,但是支持“探索替代品”。

 

与其他软件的集成

为了帮助提升systemd和GNOME桌面环境的互操作性,systemd的作者之一,莱恩纳特·波特林(Lennart Poettering),请求GNOME项目考虑将systemd作为GNOME 3.2的一个外部依赖。

 

2012年11月,GNOME项目得出结论:基础的GNOME功能不应当依赖systemd。然而,GNOME 3.8引入了一个“编译时选项”(compile-time choice),可以选择logind或是ConsoleKit API,而前者当时只由systemd提供。乌班图提供了一个独立的logind的二进制文件,但是systemd仍然称为了用于大多数Linux发行版的GNOME的事实依赖,尤其是在ConsoleKit不再有人活跃维护,以及上游系统建议使用systemd-logind作为替代之后。Gentoo Linux的开发者也曾尝试在OpenRC中适配这些更改,但是这个实现包含了太多的bug,导致该发行版将systemd标记为GNOME的一个依赖。

 

GNOME现在已经进一步与logind集成。截至第3.13.2版“低语”(Mutter),logind已经称为Wayland会话的一个依赖。

 

接受情况

(Reception)

 

systemd的设计在免费软件社区中点燃了争议。有关systemd的批评指出,它过于复杂,以及遭受持续的功能蠕涨(feature creep),并争论说,它的架构违背了Unix的哲学。并且有人担心,它形成了一个具有互锁的依赖关系的系统(a system of interlocked dependencies),而随着更多的用户空间软件开始依赖它的组件,使得发行版的维护者除了采纳systemd之外,再没有多少选择余地。

在一次2012年的访谈中,Slackware的领导者帕特里克·沃克尔丁(Patrick Volkerding)表达了对systemd架构的保留意见,声明,他自己认为,它的设计违背了Unix的哲学——包含少量细分功能的工具软件相互连通(从而构成整个系统)(interconnected utilities with narrowly defined functionalities)。截至2018年08月,Slackware表示它不支持或使用systemd,但是沃克尔丁并未排除切换到它的可能性。

2013年01月,莱恩纳特·波特林(Lennart Poettering)在一篇名为“最大的神话”(The Biggest Myths)的博客文章中,试图应对关于systemd的担心。

2014年02月,musl库的作者里奇·菲尔克(Rich Felker)认为,PID 1太过特殊,应当不超过10行代码,并且在升级时,不应当要求重启。PID 1应当仅用于启动实际的初始化(init)脚本,并回收僵尸进程(reap zombie processes)。然后,可以由从它开始运行的初始化(init)脚本和程序来提供所有的systemd功能。因此,PID 1应当只有一个很小的受攻击面(attack surface),这样用户级程序就可以各自进行不同的演化。

2014年03月,埃里克·S·雷蒙德(Eric S. Raymond)认为,systemd的设计目标就是倾向于任务蠕涨(mission creep)和软件膨胀(software bloat)的。2014年04月,林纳斯·托瓦兹(Linus Torvalds)表达了对凯·西沃尔斯(Kay Sievers)——systemd的一位关键开发者——的态度的保留意见,当时,西沃尔斯提交了一份对Linux内核的改动,导致了很多的用户和漏洞报告。2014年04月晚些时候,有人发起了一项针对systemd的抵制运动,在一个网站上列出了反对采用它的一系列理由。

在一篇2014年08月发表在InfoWorld的文章中,保罗·威尼斯(Paul Venezia)写下了关于systemd的争议,并将其归咎于对Unix哲学的违背,以及“大量自我的人,鉴定地相信他们自己能够做到不出错”。该文章同时还将systemd的架构描述为与svchost.exe类似,后者是微软视窗中的一个关键系统组件,包含广泛的功能范围。

在2014年09月的一次ZDNet的采访中,著名的Linux内核开发者曹子德(Theodore Ts'o,直译为“西奥多·曹”)表达了他的观点,就是,关于systemd的中心化的设计哲学的争论,超过了技术担忧,显示了一个危险的、朝向统一化Linux生态系统的整体潮流,疏远和边缘化一部分开源社区,只为替代性的项目留出了很少的空间。他引用了他在GNOME项目中找到的针对非标准配置的类似态度。在社交媒体上,曹子德随后还将西沃尔斯(Sievers)和他的合作开发者莱恩纳特·波特林(Lennart Poettering)的态度,与那些GNOME的开发者的态度进行了比较。

2015年06月06日,有人在systemd的GitHub页面上提交了一个问题,表达了对在systemd代码中对DNS服务器的硬编码的担忧。波特林(Poettering)回应说,硬编码的并非实际(actual)DNS,而是应急(fallback)DNS。他进一步说,应急DNS仅在“没有人配置了任何东西”的时候才会被使用,其目的是为了防止由于配置文件的灾难性的失效(catastrophic failure)或网络上没有DHCP而导致的连接性问题。如波特林所说,如果,例如,/etc目录丢失了或被清空了,那么系统“应该做正确的事”。波特林同时说明,与systemd一同安装的/etc/systemd/resolved.conf文件,包含了与应急DNS完全相同的DNS服务器配置,因此无论/etc目录是被清空了还是存在,结果都会出现相同的操作。

 

分支版本和替代实现

eudev

2012年,Gentoo Linux项目创建了一个udev分支版本,以避免对systemd架构的依赖。这个分支版本被称为eudev,它让udev的功能可以在没有systemd的情况下,仍能够照常使用。该项目所声明的一个目的就是,保持eudev独立于任何特定的Linux发行版或初始化(init)系统。

 

elogind

Elogind是systemd项目的“logind”,它被单独抽取出来,称为一个独立的守护进程。它与PAM集成,从而能够知道登录到系统的用户集,以及他们是以图形化方式登录,还是通过控制台,或是远程的方式登录。Elogind通过一个标准的org.freedesktop.login1 D-Bus接口来暴露该信息,也可以通过使用systemd的标准的/run/systemd样式的文件系统来暴露。Elogind还提供了“libelogind”,它是由“libsystemd”所提供的工具的一个子集。另外,还有一个名为“libelogind.pc”的pkg-config文件。

 

uselessd

2014年,uselessd作为systemd的一个轻量级分支版被创建。该项目寻求移除被认为对于一个初始化系统来说并无必要的那些功能和程序,同时还设法解决那些已经知晓的错误。不过该项目于2015年01月停止了。

uselessd支持musl库和µClibc库,因此它可能被用在嵌入式系统中,而systemd仅支持glibc。uselessd项目曾经计划了更多的关于跨平台兼容性的改进,以及为未来的Linux构建版本而做的架构上的全面革新(overhaul)和重构(refactor)。

 

systembsd

2014年,一个名为“systembsd”的谷歌编程之夏(Google Summer of Code)项目被启动,目的是为了向OpenBSD提供这些API的替代实现。原始的项目开发者启动该项目的目的,是为了降低他从Linux转为OpenBSD的难度。该项目的开发于2016年07月停止了。

systembsd并不提供一个init的替代品,而是旨在向OpenBSD提供用于hostnamed、timedated、localed和logind的兼容性守护进程。该项目并未创建一个类systemd的功能,只是为了扮演一个在原生OpenBSD系统之上的封装器的角色。该开发者的目的是,让systembsd能够作为移植集合(ports collection)——而不是基础系统的一部分——被安装,并表示“systemd和*BSD在哲学和开发实践上存在根本性的差异”。

 

consolekit2

ConsoleKit是在2014年由Xfce的开发者拉出的一个分支版本,他们希望它的功能能够在Linux之外的操作系统上仍然能够维持和使用。尽管并未排除在未来长期将原始仓库复苏的可能性,但其主要的开发者将ConsoleKit2视为在systembsd成熟之前的一个临时的必需品。

开发工作于2017年12月中止,而该项目可能已经僵死了

 

loginkit

LoginKit是实现一个logind(systemd-logind)衬片(shim)的一个尝试,它允许那些依赖于systemd-logind的软件包能够在不依赖任何特定初始化系统的情况下,仍能正常工作。

该项目从2015年02月开始就僵死了。

 

notsystemd

Notsystemd倾向于实现所有的systemd的功能,让它运行在任何初始化系统上。它是由Parabola GNU/Linux-libre的开发者们拉出的分支版本,是为了使用他们的开发工具来构建软件包,而不需要安装systemd来运行systemd-nspawn。

 

s6

s6是用于UNIX的一个小的程序套件,被设计为允许在daemontools和runit中,以及在进程和守护进程上电各种操作中,实现进程监督(process supervision,也称“service supervision”,即“服务监督”)。它的目的是要成为一个用于底层进程和服务管理的工具箱,提供各种不同集合的独立工具,这些工具可以与框架一起使用,也可以不与框架一起使用。它们可以被一起组装起来,从而实现强大的功能,而只需要很少量的代码。

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值