Linux init系统:dinit, openrc, runit, s6的区别

Artix Linux 是基于 Arch Linux 但不使用 systemd 的发行版。它提供了几种不同的初始化系统(init systems)供用户选择。这四种系统的核心区别在于设计哲学、启动速度、配置难度以及对依赖项的处理。

以下是它们的详细对比:

1. Dinit

特点: 现代、快速、类 systemd 语法。

  • 是什么: Dinit 是用 C++ 编写的现代初始化系统。它采用并行启动服务,支持服务间的依赖管理。

  • 优势: 启动和关机速度极快;命令(dinitctl)与 systemctl 比较接近,容易上手;原生支持用户服务。

  • 缺点: 相对较新,社区积累的脚本和文档不如 OpenRC 丰富。

2. OpenRC

特点: 成熟、稳定、基于脚本。

  • 是什么: 源自 Gentoo,是一个非常成熟的初始化系统。它基于 Shell 脚本工作,虽然也支持并行启动,但由于脚本解析的原因,速度通常略慢于 Dinit 或 Runit。

  • 优势: 文档极其丰富(可以参考 Gentoo 和 Alpine 的资料);兼容性极佳;非常稳定。

  • 缺点: 不具备原生的进程监控(Service Supervision,即程序崩溃后自动重启),需要额外配置。

3. Runit

特点: 极简、极致稳定、目录结构式。

  • 是什么: runit 是由三阶段组成的极简 init,最早在 Void Linux 中出名。它通过文件系统的符号链接(link farm)来管理服务。

  • 优势: 极致精简且非常稳定;进程监控非常强悍(秒级重启崩溃进程);结构透明。

  • 缺点: 不支持自动依赖管理(你需要确保网络服务在依赖网络的服务之前启动);功能最少。

4. S6 (s6-rc)

特点: 模块化、极致灵活、面向高级用户。

  • 是什么: 一个非常底层的、高度模块化的工具集。它将“启动、监控、依赖管理”拆分成不同的组件。

  • 优势: 理论上最为完美和严谨的设计;对服务的控制粒度最细;性能极高。

  • 缺点: 学习曲线最陡峭;修改服务配置后通常需要通过 s6-rc-compile 编译数据库,对新手不友好。


哪个“最好用”?

“最好用”取决于你的需求和技术背景:

用户群体 推荐系统 理由
刚从 Systemd 转移过来 Dinit 语法熟悉,功能全面(带依赖管理),启动最快。
追求稳定与丰富文档 OpenRC 出错率低,遇到问题几乎都能在网上找到现成的脚本或教程。
追求极致简约/老手 Runit “它就是能动”,没有任何多余逻辑。
折腾控/追求极致控制 S6 享受极致的模块化设计和进程管理艺术。

总结建议: 如果你是第一次尝试 Artix,建议选择 DinitOpenRC。Dinit 能给你带来类似 systemd 的现代化体验,而 OpenRC 则是最稳妥的选择。


 

初始化系统(Init System)是操作系统的基石。关于你提到的这几种系统,它们代表了两种截然不同的设计哲学:一种是**“全能集成式”(以 systemd 为代表),另一种是“极简模块化”**(Unix 哲学的践行者)。


一、 主流初始化系统优缺点对比

系统 核心定位 优点 缺点
systemd 现代 Linux 事实标准 强大的依赖管理、并行启动极快、统一管理日志/网络/硬件、生态极广。 极其臃肿(单体化)、二进制日志格式、违反 Unix 哲学、不可移植(仅限 Linux)。
launchd macOS 专用 统一管理所有后台任务、按需启动服务、设计超前。 仅限苹果生态、使用繁琐的 XML 配置、对自由软件社区不透明。
OpenRC 传统增强型 极其稳定、基于 Shell 脚本(易读)、兼容传统 SysVinit 脚本。 启动速度略慢(脚本解析)、原生进程监控能力弱、无内建并行机制。
runit 极致简约型 速度极快、代码量极小、进程监控非常强悍(崩溃自启)。 不支持复杂的自动依赖管理(需要手动控制启动顺序)。
dinit 现代简约型 C++ 编写、支持服务依赖、并行启动、语法比 systemd 简洁。 社区规模较小,服务脚本积累不如 OpenRC 丰富。
s6 技术派专家型 极致的模块化、设计极其严密且安全、支持复杂的进程树控制。 学习曲线最陡峭,配置极其繁琐(需要编译服务库)。

二、 为什么 Linux 社区中有人强烈排斥 systemd?

systemd 的争议不是性能问题,而是权力斗争工程哲学的冲突。

1. 违反 Unix 哲学(Do one thing and do it well)

Unix 的核心原则是“只做一件事,并把它做好”。

  • systemd 的做法: 它不仅是 PID 1(初始化进程),它还接管了日志(journald)、网络(networkd)、登录管理(logind)、时间同步(timesyncd)、甚至挂载管理。

  • 反对者的声音: 这让系统变得不可分割。如果你只想用 systemd 的服务管理,却不想用它的日志系统,你会发现它们深度耦合,极难拆分。

2. “臃肿”带来的安全隐患

  • 攻击面增大: 作为 PID 1(系统权限最高的进程),systemd 包含了数百万行代码。在安全领域,代码越多,漏洞越多。一旦 systemd 崩溃,整个系统会立即陷入内核恐慌(Kernel Panic)。

  • 复杂性灾难: 当系统出问题时,传统的 OpenRC 你可以通过阅读简单的 Shell 脚本定位故障;而 systemd 复杂的 C 源码和二进制组件让普通管理员难以进行底层排障。

3. 二进制日志(journald)

  • 传统系统将日志存为纯文本,你可以用 grepawk 等任何工具处理,哪怕系统崩溃,挂载硬盘也能读日志。

  • systemd 使用二进制日志,必须使用专用工具 journalctl 才能读取。如果日志文件损坏,可能整个日志库都无法打开。

4. 强行绑架开发者(Vendor Lock-in)

由于 systemd 提供了大量的底层 API(如 D-Bus 接口),很多桌面环境(如 GNOME)开始深度依赖 systemd。这意味着如果你想用 GNOME,你就被迫必须使用 systemd。这种“捆绑销售”引起了开发者对自由选择权的担忧。


三、 设计实现上的缺陷

  1. 非 POSIX 标准: systemd 大量使用了 Linux 内核特有的功能(如 cgroups, epoll),导致它完全无法移植到 BSD 或其他系统。这破坏了类 Unix 世界的跨平台共性。

  2. 大一统架构: 它试图在用户态构建一个类似于“宏内核”的结构,任何一个小模块的崩溃都可能波及 PID 1。

  3. 关机逻辑混乱: systemd 在处理某些僵死服务或挂载点时,经常会出现“等待 90 秒”无法关机的情况,且用户很难干预其超时逻辑。


总结建议

  • 如果你是普通用户/开发者: systemd 是最好的选择,因为它省心,几乎所有软件都有现成的配置。

  • 如果你是系统管理员/极致追求者:

    • 追求稳定与传统OpenRC(Artix 或 Gentoo)。

    • 追求启动速度与极简runit(Void Linux)。

    • 想要平衡现代感与简洁dinit


 

补充说明:

OpenRC

OpenRC 是一个基于依赖关系的初始化系统,最初与 sysvinit 保持兼容,但从 OpenRC 0.25 版本开始,它用自己的程序取代了 /sbin/init 由 Gentoo 开发人员编写,旨在供其他发行版和 BSD 系统使用。

 

Runit

runit 是一套工具,它提供了一个 init(PID 1)以及与 daemontools 兼容的进程监控框架,以及一些可以简化服务创建和维护的实用程序。

 

dinit

dinit 是一个具有依赖项支持的服务管理器,它也可以充当系统“init”程序。它的创建目的是提供一个可移植的、具有依赖项管理功能的 init 系统,其功能优于许多现有的 init 程序。

Dinit 可以并行启动多个服务,并进行依赖管理(例如,如果一个服务的运行依赖于另一个服务,则后者会先启动)。它可以监控服务对应的进程,并在进程崩溃时重新启动它,而且它能够以智能的方式执行此操作——首先“回滚”所有依赖服务,然后在依赖关系得到满足后重新启动它们。可以使用 dinitctl 工具来启动或停止服务并检查其状态。

Dinit 可以作为系统服务管理器运行(以 root 用户身份运行,使用系统路径进行配置),也可以作为用户进程运行(以用户身份运行,使用用户主目录中的路径进行配置)。

 

s6

s6 是一个进程监控套件,它还提供服务管理 ( s6-rc ) 和系统初始化/关闭 ( s6-linux-init ) 的工具。

s6 软件的设计理念是高度模块化,可以与其他组件灵活组合使用。同时,s6 软件之间也具备良好的协同工作能力。在 Artix,我们充分利用 s6 的各项功能,并使用所有可用工具为用户提供 /sbin/init、PID1、进程监控套件和服务管理器。

s6-linux-init 负责实际启动系统。它会将 tmpfs 挂载到 /run 目录,并将 /etc/s6/current/run-image 目录复制到 /run 。/sbin/init 随后会执行 s6-svscan 程序(由 s6 提供),该程序在机器的整个生命周期内 /sbin/init 作为 PID1 运行。完成此步骤后,初始化的第一阶段就完成了。除了作为 PID1 之外, s6-svscan 还是进程监控树的根进程。它会监控发现的每个服务,并为每个服务生成相应的 s6-supervise 进程。

此外,启动过程中会执行位于 /etc/ s6 /etc/s6/current/scripts 目录下的 rc.init 脚本。s6 本身并不进行服务管理,只负责进程监控。rc.init rc.init 会启动实际的服务管理器 s6-rc 。之后,我们会启动由 s6-rc 定义的默认运行级别,并启动所需的服务。 

关闭时,s6-rc 中的所有服务都会停止运行,然后终止所有 s6-supervise 进程和其他进程,然后卸载所有内容,最后终止 s6-svscan 进程。

注意 :artix 上的 s6-linux-init 编译时启用了将消息打印到 /dev/console 指向 tty1。如果需要,您可以使用内核参数将 /dev/console 更改为其他位置(请参阅引导加载程序的配置)。

恢复 :s6-linux-init 始终在 tty12 上提供 getty 服务,可用于系统恢复(例如,在 s6-rc 崩溃的情况下)。只要系统能够正常启动,该服务就会一直存在。

 

 systemd

  • systemd — Linux 系统中现代的 SysV 风格的 init 和 rc 替代方案。

 

 refs:

https://wiki.artixlinux.org/Main/OpenRC
https://wiki.artixlinux.org/Main/Runit
https://wiki.artixlinux.org/Main/dinit
https://wiki.artixlinux.org/Main/S6

posted @ 2026-01-12 18:31  petercao  阅读(39)  评论(0)    收藏  举报