Upstart 和 systemd 的优缺点是什么?

tsh*_*ang 190 systemd init upstart

看起来systemd是该块上最热门的新init系统,就像几年前的Upstart一样。每个的优点/缺点是什么?另外,每个与其他初始化系统相比如何?

rsp*_*rsp 98

2016年更新

这里的大多数答案已有五年历史,因此是时候进行一些更新了。

Ubuntu 曾经默认使用 upstart,但去年他们放弃了它,转而使用 systemd - 请参阅:

因此,Ubuntu wiki 上有一篇很好的文章Systemd for Upstart Users - upstart 和 systemd 之间的非常详细的比较以及从 upstart 到 systemd 的过渡指南。

(请注意,根据 Ubuntu wiki,默认情况下您仍然可以通过安装upstart-sysv和运行在当前版本的 Ubuntu 上运行 upstartsudo update-initramfs -u但考虑到 systemd 项目的范围,我不知道它在实践中是如何工作的,或者 systemd 是否是可以卸载。)

下面的命令和脚本部分中的大部分信息都改编自该文章中使用的一些示例(就像 Stack Exchange 用户在Creative Commons Attribution-ShareAlike 3.0 License下的贡献一样方便地获得许可)。

这里是常用命令和简单脚本的快速比较,详细说明请参见下面的部分。这个答案是将基于 Upstart 的系统的旧行为与基于 systemd 的系统的新行为进行比较,如问题中所问,但请注意,标记为“Upstart”的命令不一定特定于 Upstart - 它们通常是命令对于每个非系统化的 Linux 和 Unix 系统都是通用的。

命令

运行苏:

  • 暴发户: su
  • 系统: machinectl shell

(请参阅下面的“su 命令替换”部分)

运行画面:

  • 暴发户: screen
  • 系统: systemd-run --user --scope screen

(请参阅下面的“意外杀死后台进程”部分)

运行 tmux:

  • 暴发户: tmux
  • 系统: systemd-run --user --scope tmux

(请参阅下面的“意外杀死后台进程”部分)

开始工作 foo:

  • 暴发户: start foo
  • 系统: systemctl start foo

停止工作 foo:

  • 暴发户: stop foo
  • 系统: systemctl stop foo

重新启动作业 foo:

  • 暴发户: restart foo
  • 系统: systemctl restart foo

列出工作:

  • 暴发户: initctl list
  • 系统: systemctl status

检查作业 foo 的配置:

  • 暴发户: init-checkconf /etc/init/foo.conf
  • 系统: systemd-analyze verify /lib/systemd/system/foo.service

列出作业的环境变量:

  • 暴发户: initctl list-env
  • 系统: systemctl show-environment

设置作业的环境变量:

  • 暴发户: initctl set-env foo=bar
  • 系统: systemctl set-environment foo=bar

删除作业的环境变量:

  • 暴发户: initctl unset-env foo
  • 系统: systemctl unset-environment foo

日志

在 upstart 中,日志是 /var/log/upstart 目录中的普通文本文件,因此您可以照常处理它们:

cat /var/log/upstart/foo.log
tail -f /var/log/upstart/foo.log
Run Code Online (Sandbox Code Playgroud)

在 systemd 中,日志以内部二进制格式(而不是文本文件)存储,因此您需要使用journalctl命令来访问它们:

sudo journalctl -u foo
sudo journalctl -u foo -f
Run Code Online (Sandbox Code Playgroud)

脚本

用以下语言编写的示例新贵脚本/etc/init/foo.conf

description "Job that runs the foo daemon"
start on runlevel [2345]
stop on runlevel [016]
env statedir=/var/cache/foo
pre-start exec mkdir -p $statedir
exec /usr/bin/foo-daemon --arg1 "hello world" --statedir $statedir
Run Code Online (Sandbox Code Playgroud)

用以下代码编写的示例systemd 脚本/lib/systemd/system/foo.service

[Unit]
Description=Job that runs the foo daemon
Documentation=man:foo(1)
[Service]
Type=forking
Environment=statedir=/var/cache/foo
ExecStartPre=/usr/bin/mkdir -p ${statedir}
ExecStart=/usr/bin/foo-daemon --arg1 "hello world" --statedir ${statedir}
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

su 命令替换

一个su命令替换并入systemd上拉请求#1022:

因为,根据Lennart Poettering 的说法,“su 真的是一个破碎的概念”

他解释说“您可以像以前一样使用 su 和 sudo,但不要指望它会完全起作用

实现类似su行为的官方方法现在是:

machinectl shell
Run Code Online (Sandbox Code Playgroud)

Lennart Poettering 在讨论 issue #825 中进一步解释了这一点 :

“嗯,关于这个问题已经讨论了很长时间,但问题是 su 应该做什么并不清楚。[...] 长话短说:su 真的是一个破碎的概念。它会给你一种壳,并且可以为此使用它,但它不是完整登录,不应被误认为是登录。” - 伦纳特·波特林

也可以看看:

意外杀死后台进程

命令如:

不再按预期工作。例如,nohup是一个 POSIX 命令,用于确保在您从会话注销后该进程继续运行。它不再适用于 systemd。像这样的程序screentmux需要以特殊方式调用,否则与它们一起运行的进程将被杀死(而没有杀死这些进程通常是首先运行 screen 或 tmux 的主要原因)。

这不是错误,而是经过深思熟虑的决定,因此将来不太可能修复。这就是 Lennart Poettering对这个问题所说的

在我看来,UNIX 在默认情况下让任意用户代码在注销后不受限制地保留实际上很奇怪。许多 OS 人员已经讨论了很长时间,这应该是可能的,但肯定不是默认设置,但到目前为止没有人敢打开开关将其从默认设置变为选项。注销后不清理用户会话不仅丑陋且有些骇人听闻,而且还是一个安全问题。 systemd 230 现在终于打开了开关,默认情况下,当用户注销时,最后会正确清理所有内容。

有关更多信息,请参阅:

高水平的创业理念

在某种程度上,systemd 是逆向工作的——在新贵的工作中,他们会尽快开始,而在 systemd 中,工作则是在必须的时候开始。在一天结束时,两个系统都可以以几乎相同的顺序启动相同的作业,但是您可以从相反的方向考虑它。

以下是Systemd for Upstart Users 的解释:

Upstart用于启动进程(作业)的模型是“基于贪婪事件的”,即所有启动事件发生的可用作业都尽可能早地启动。在启动过程中,upstart 将一些初始事件(如启动或 rcS)合成为“树根”,早期的服务在这些事件上启动,之后的服务在前者运行时启动。新作业只需要将其配置文件安装到 /etc/init/ 中即可激活。

systemd用于启动进程(单元)的模型是“基于惰性的依赖”,即一个单元只有在其他启动单元依赖它时才会启动。在启动过程中,systemd 启动一个“根单元”(default.target,可以在 grub 中覆盖),然后它会传递性地扩展并启动它的依赖项。新单元需要将自身添加为引导序列单元(通常为 multi-user.target)的依赖项,才能变为活动状态。

在发行版中的使用

现在根据维基百科的一些最新数据:

默认情况下使用 upstart 的发行版:

默认使用 systemd 的发行版:

(有关最新信息,请参阅维基百科

既不使用 Upstart 也不使用 systemd 的发行版:

争议

过去曾有人提议 Debian 的一个分支来避免 systemd。该Devuan GNU + Linux的创建-的Debian的一个分支,而不systemd(感谢fpmurphy1指点出来的评论)。

有关此争议的更多信息,请参阅:

你们中的许多人可能已经知道,由 Ian Jackson 推动的 Init GR Debian 投票对于保护 Debian 的遗产及其用户免受 systemd 雪崩的影响并没有用。

这种情况可能会锁定 systemd 依赖项,这实际上威胁着开发自由,并对 Debian 及其上游和下游产生严重后果。

CTTE 设法交换了依赖关系,并通过 sysvinit 微妙安装 systemd 为我们赢得了时间,但即使是这个过程也令人筋疲力尽且充满戏剧性。最终,一周前,伊恩·杰克逊辞职了。[...]

我将立即辞去技术委员会的职务。

虽然同意我的项目的 30-40% 的观点应该继续在 TC 中得到代表很重要,但我本人显然在这一点上太有争议了,无法这样做。我应该靠边站,尽量减少有关项目治理的对话的个性化程度。[...]

Devuan 诞生于关于将其用作 Debian 的默认初始化系统的决定的争议。Debian 在 systemd 上官方立场充满了其他人已经揭穿的说法。感兴趣的读者可以在Systemd 争议中继续讨论这个热门话题。但是,我们鼓励您保持头脑冷静,声音文明。在 Devuan,我们更感兴趣的是对它们进行错误编程而不是回顾过去。[...]

已经创建了一些专门讨论 systemd 争议的网站和文章:

很多Hacker News上有趣的讨论的:

在其他发行版中也可以观察到类似的趋势:

哲学

upstart遵循 DOTADIW 的 Unix 哲学——“做一件事并做好”。它是传统 init 守护进程的替代品。除了启动和停止服务之外,它不会做任何事情。其他任务委托给其他专门的子系统。

systemd做的远不止这些。除了启动和停止服务之外,它还管理密码、登录、终端、电源管理、出厂重置、日志处理、文件系统挂载点、网络等等 - 请参阅新闻文件了解一些功能。

扩张计划

根据A Perspective for systemd What Has Being Achieved, and What Lies Ahead by Lennart Poettering 于 2014 年在 GNOME.asia 上的演讲,以下是 systemd 的主要目标、已经涵盖的领域和仍在进行中的领域:

系统目标:

我们的目标

  • 将 Linux 从一堆比特变成具有竞争力的通用操作系统。

  • 构建互联网的下一代操作系统 统一发行版之间的无意义差异

  • 将创新带回核心操作系统

  • 桌面、服务器、容器、嵌入式、移动、云、集群、. . . 这些区域比您想象的更紧密

  • 降低管理员的复杂性,无需监督的可靠性

  • 一切自省

  • 自动发现,即插即用是关键

  • 我们修理坏了的东西,从不粘在上面

已经覆盖的领域:

我们已经涵盖的内容:

初始化系统、日志记录、登录管理、设备管理、临时和易失性文件管理、二进制格式注册、背光保存/恢复、rfkill 保存/恢复、引导图、预读、加密存储设置、EFI/GPT 分区发现、虚拟机/容器注册、最小容器管理、主机名管理、区域设置管理、时间管理、随机种子管理、sysctl 变量管理、控制台管理、. . .

工作正在进行中:

我们正在做的事情:

  • 网络管理
  • 系统网络
  • 本地 DNS 缓存、mDNS 响应器、LLMNR 响应器、DNSSEC 验证
  • 内核中的IPC
  • kdbus, sd 总线
  • 与NTP时间同步
  • systemd-timesyncd
  • 与容器的更多集成
  • 服务沙盒
  • 应用程序沙盒
  • 操作系统映像格式
  • 容器镜像格式
  • 应用图片格式
  • 具有自动发现功能的 GPT
  • 无状态系统、可实例化系统、恢复出厂设置
  • /usr 是操作系统
  • /etc 是(可选)配置
  • /var 是(可选)状态
  • 原子节点初始化和更新
  • 与云集成
  • 跨节点服务管理
  • 可验证的操作系统映像
  • 一直到固件
  • 引导加载

本回答的范围

正如fpmurphy1在评论中指出的那样,“应该指出的是,多年来 systemd 的工作范围已远远超出系统启动的范围。”

我试图在此处包含大部分相关信息。在这里,我比较了 Upstart 和 systemd 在用作 init 系统时的共同特性,我只提到了 systemd 超出 init 系统范围的特性,因为这些特性无法与 Startup 进行比较,但它们的存在很重要了解这两个项目之间的区别。应检查相关文档以获取更多信息。

更多信息

可以在以下位置找到更多信息:

  • ... Debian 出现了这样的分支。Devuan GNU+Linux 是 Debian 的一个分支,没有 systemd。 (5认同)
  • @ronsmith `service <foo> start/stop/restart/status` 仍然可以正常工作。像大多数 unix 软件一样,systemd 提供对众所周知的默认值的命令兼容性。 (4认同)
  • 需要指出的是,systemd 多年来的工作范围已经远远超出了简单的系统启动。 (3认同)
  • 出色的帖子,对 Cent 的人非常有帮助。感谢您抽出宝贵时间先生!!! (2认同)
  • 我绝对不喜欢不那么直观和更冗长的 systemctl 命令。服务 myservice stop/start/restart/status 很优雅。 (2认同)
  • 很好的答案。不过有一点:BSD 操作系统不是 Linux 发行版:它们是具有自己内核的不同 Unix 操作系统。 (2认同)

jsb*_*ngs 69

upstart 和 systemd 都在尝试解决传统 SysV init 系统存在的一些问题。例如,某些服务需要在其他服务之后启动(例如,您不能在网络运行之前挂载 NFS 文件系统),但在 SysV 中唯一处理的方法是在 rc#.d 目录中设置链接这样一个在另一个之前。除此之外,您可能需要稍后在添加或更改依赖项时重新编号所有内容。Upstart 和 Systemd 有更智能的设置来定义需求。此外,还有一个问题是,一切都是某种形式的 shell 脚本,并不是每个人都编写了最好的 init 脚本。这也会影响启动速度。

我可以看到 systemd 的一些优点:

  • 每个启动的进程都有自己的 cgroup 或特定的 cgroup。
  • 为服务预先创建套接字和文件句柄,类似于 xinetd 为它的服务所做的,允许依赖服务更快地启动。例如,systemd 将为 syslog 保持打开 /dev/log 的文件句柄,随后发送到 /dev/log 的服务将缓冲其消息,直到 syslogd 准备好接管。
  • 运行以实际启动服务的进程较少。这意味着您不是在编写 shell 脚本来启动您的服务。这可以提高速度,并且(IMO)一开始就更容易设置。

我知道的一个缺点是,为了利用 systemd 的套接字/FH 预分配,必须修补许多守护进程才能让 systemd 将 FH 传递给它们。

  • PulseAudio 是一个备受诟病的声音系统 (http://www.pulseaudio.org/),最初由 systemd 的作者 Lennart Poettering 编写。我在这里主要是在开玩笑,因为我知道有几个人喜欢抱怨pulseaudio,我相信他们也会抱怨systemd。老实说,我对 systemd 或 pulseaudio 都没有问题。 (13认同)
  • 太棒了。请查看 http://0pointer.de/blog/projects/the-biggest-myths。我目睹了 systemd 的成长,可以证明这里给出的许多批评都是毫无根据的。在链接中,您会发现一连串的,_reasoned_ 反驳。 (8认同)
  • 对Plan9 丰富的峡湾来说几乎是松树......一切都是一个文件。 (4认同)
  • 老实说,pulseaudio 是一个不存在的问题的解决方案。PA 没有什么是 ALSA 做不到的,而且我听说很多人一遍又一遍地遇到 PA 问题。 (4认同)
  • 您错过的两个 systemd 缺点:(1)所有启动脚本都需要重写。(2) 与非 linux 操作系统(例如 BSD)的兼容性较差。 (3认同)
  • ... 由 Lennart Poettering 撰写。这就像问鲁珀特默多克福克斯新闻有什么问题一样。 (3认同)

xen*_*ide 29

看到今天systemdArch General ML上提到的。所以仔细阅读它。H Online一如既往是 Linux 技术的重要来源,也是我开始研究Systemd 作为 SysV Init 和 Upstart 替代方案的地方。然而,H Online 文章(在这种情况下)并不是一个非常有用的阅读,它背后的真正用途是它提供了有用阅读的链接。

真正的答案在systemd公告中。这给出了 SysV initd 有什么问题的一些关键点,以及新系统需要做什么

  • 开始少。
  • 并开始更多的并行。

它执行此操作的主要计划似乎是仅在需要时启动服务,并为该服务启动一个套接字,以便需要它的服务可以在守护程序完全在线之前很久就连接到创建的套接字。显然,套接字会保留少量缓冲数据,这意味着在延迟期间不会丢失任何数据,只要守护进程在线,就会处理这些数据。

该计划的另一部分似乎是不序列化文件系统,而是按需挂载那些文件系统,这样您就不会等待您的/home/等(不要与 混淆/etc)挂载,和/或fsck何时可以挂载启动守护进程作为//var/等,都已经安装。它表示将为此使用 autofs。

它还具有创建.desktop样式初始化描述符作为脚本替代品的目标。这将防止万吨缓慢的sh过程,并从之类的东西的过程更加叉sedgrep那些经常在shell脚本中使用。

他们还计划在被要求之前不启动某些服务,甚至可能在不再需要它们时将它们关闭,例如,仅当您使用蓝牙设备时才需要蓝牙模块和守护程序。给出的另一个示例是 ssh 守护进程。这是 inetd 能够做的事情。就我个人而言,我不确定我是否喜欢这个,因为这可能意味着我确实需要它们时的延迟,而在 ssh 的情况下,我认为这意味着可能存在安全漏洞,如果我的 inetd 受到损害,整个系统都会受到影响。但是,我被告知使用它来破坏这个系统是不可行的,如果我愿意,我可以禁用每个服务和其他方式的这个功能。

另一个功能显然是能够根据时间事件启动,无论是在定期安排的时间间隔还是在特定时间。这类似于现在做什么crondatd做什么。虽然有人告诉我它不支持用户“cron”。就个人而言,这听起来是最没有意义的事情。我认为这是由不在多用户环境中工作的人编写/想到的,如果您是系统上唯一的用户,则用户 cron 没有太大意义,除了不以 root 身份运行。我每天都在多用户系统上工作,规则总是以用户身份运行用户脚本。但也许我没有他们那样的远见,它决不会让我无法运行crondatd,所以它不会伤害任何人,但我想除了开发人员。

systemd 的一大缺点是必须修改一些守护进程才能充分利用它。它们现在可以工作,但如果它们是专门为其套接字模型编写的,它们会工作得更好。

在大多数情况下,systemd 对新贵的人的问题似乎是事件系统,他们认为它没有意义或没有必要。也许他们的话最能说明问题。

或者更简单地说:用户刚刚启动 D-Bus 的事实绝不表明 NetworkManager 也应该启动(但这正是 Upstart 会做的)。反过来也是对的:当用户要求使用 NetworkManager 时,这绝对表明 D-Bus 也应该启动(这肯定是大多数用户所期望的,对吧?)。
一个好的 init 系统应该只启动需要的东西,并且按需启动。延迟或并行化并提前。但是,它不应在不必要的情况下启动,尤其是安装的所有可以使用该服务的东西。

正如我已经说过的,在systemd公告中对此进行了更全面的讨论。

  • 这比@John 的答案好在哪里?它是占位符吗?*H Online* 的促销活动? (2认同)

小智 11

你们大多数人忘记的一件事是cgroups 中的流程组织。

因此,如果 systemd 启动了一个东西,它会将这个东西放在它自己的 cgroup 中,并且进程没有(非特权的)方法可以逃脱该 cgroup。这是这样做的后果:

  • 拥有众多用户的大型系统的管理员拥有识别恶意用户/进程的有效新方法。
  • CPU 调度的优先级可以通过“Wonder autocgroup patch”更好地确定。


von*_*and 8

要非常详细地了解 systemd,从第一个设计草案开始(以及对现有 init 系统的详细评论,包括 upstart,以及 systemd 建议如何修复它们),请转到其主页。随着时间的推移,LWN上发表了几篇关于启动的文章。请注意,任何提到 systemd(或pulseaudio)的地方都会触发无休止的火焰战争。

IMVHO(以及作为 Fedora 用户)我对它非常满意。这方面的东西早就应该处理当前 Linux 系统的复杂性了。Fedora 使用 upstart 有一段时间了,但它从未摆脱过作为 sysvinit 的奇特替代品的阶段,运行大部分未更改的 init 脚本。它承诺简化启动配置的代价是再次手动设置相互依赖关系,但那是行不通的。systemd 自己计算依赖关系(或者只允许启动而不考虑依赖关系,他们自己解决)。另一个很大的优点(有人说这是一个严重的缺点)是它充分利用了 Linux 特定的功能(特别是 cgroups 允许隔离守护进程及其所有后代,因此很容易监视、限制资源或杀死它们)一组;还有许多其他人)。