Systemd
1 简介
systemd 是 Linux 系统的一组基本构建块。它提供了一个以 PID 1 运行的系统和服务管理器,并启动了系统的其余部分。systemd 提供积极的并行化功能,使用套接字和 D-Bus 激活来启动服务,按需启动守护程序,使用 Linux 控制组跟踪进程,维护安装和自动挂载点以及实现精心设计的基于事务依赖关系的服务控制逻辑。systemd 支持 SysV 和 LSB 初始化脚本,并替代 sysvinit。其他部分包括日志记录守护程序,用于控制基本系统配置的实用程序,例如主机名,日期,区域设置,维护已登录用户和正在运行的容器和虚拟机的列表,系统帐户,运行时目录和设置,以及用于管理简单网络的守护程序配置,网络时间同步,日志转发和名称解析。
Systemd 是 Linux 系统工具,用来启动守护进程,目前已成为大多数发行版的标准配置。但在历史上,Linux 的启动一直采用 init 进程,用下面的命令启动服务:
1 |
|
这种方法有两个缺点:
- 一是启动时间长。init 进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
- 二是启动脚本复杂。init 进程只是执行启动脚本,不管其他事情,脚本需要自己处理各种情况,这往往使得脚本变得很长。
2 争议
优势
- 手册文档详细。
- 统一用
/etc/os-release
文件区分各个 Linux 发行版。 - systemd 本来是一个先进的 init 程序,除了管理 daemon 之外,还实现了 socket-activation 来支持按需加载服务。就架构上来说完胜现有的任何系统上的任何服务管理体系。
- 启动速度相比与其他 init 程序,会稍快一些。
- 迭代迅速,新功能增加很快。
争议点
- 不遵循 UNIX 原则。UNIX 的哲学是做一件事,并且把它做好,而 systemd 则是把 pid 1 扩张到最大化。
- systemd 在设计之初就不考虑 Linux 以外的平台,不遵循 POSIX 标准,而且很多功能根本就是 Linux 特有的,无法移植到 Linux 之外的平台,这尤其让 BSD 爱好者们很受伤,在 Debian 7 以前,一直维护着 Linux 和 FreeBSD 两个内核,只不过后者没什么人用,Debian 8 为了支持 systemd 不得不放弃支持 Debian kFreeBSD。
- 接管了太多设施,如 syslog 被 systemd-journal 取代,crond 也被 systemd 的 timer 单元取代,udev 也准备集成到 systemd 中来,未来甚至还可能取代 /etc/fstab。尽管这些新的服务大部分都是独立于主进程的,但是还是有整个系统被红帽控制住的感觉(systemd 的作者 Lennart Poettering 就职于红帽,systemd 也主要是红帽的 Fedora 首先在推,OpenSUSE 后面跟随)。这在开源社区看来是件政治不正确的事情。
- 有人怀疑 systemd 的可靠程度,然后就是很多管理员以前积攒的脚本全报废了(这也是管理员反对的主因吧)。
- systemd 的作者是 Lennart Poettering,其主要的三个项目是 avahi, PulseAudio, systemd。他和他的小伙伴有这样的特点
- 生产力极高。systemd 以不可思议的速度刷版本号,而且每次更新都有新功能。Linux 的核心服务大部分都很有年头了,systemd 的开发节奏和它们反差甚大。
- 代码质量不高。PulseAudio 和 systemd 初期都有巨量的 bug,经过很长时间才达到稳定。对于 systemd 这显然不符合人们的期望。Init 应该由 Linus 这样的靠谱程序员而不是 Poettering 这种傻逼程序员负责。
- 频繁变更设计和接口。systemd 的新功能,最好都等几个版本再用。因为 Poettering 似乎是喜欢让用户的实践去打磨他的设计的。
- 不考虑向后兼容。Poettering 和小伙伴们有着极端的“只用正确的方法做事”的态度。如果某个用法过去可以工作,但不符合他们心目中“正确的方式”,他们会在新版本中毫不犹豫地将你 break 掉。这种态度屡次遭到 Linus 痛骂(由于 udev 和内核紧密集成)。很多人不喜欢这种以飞速不断生产 bug 和不成熟设计的风格。实际上这更接近商业软件公司(比如微软)的开发风格,而这显然也会招黑。
- systemd 极端地奉行“只考虑 Linux”,不接受任何改进非 Linux 系统兼容性的 patch。由于 systemd 项目合并了 udev, logind 等基础设施,以及 Gnome/KDE 积极与 systemd 集成,这给其它开源内核的桌面用户(以及 Debian 这样的多内核发行版)造成了困扰。
- 对比 sysvinit,系统管理员不喜欢 systemd:
- systemd 是用 C 而不是系统管理员熟悉的 shell 写成。
- systemd 的核心是单个 binary,而不是一堆脚本和小程序拼凑而成,不符合所谓 The Unix Way。
- 喜欢重新发明轮子。systemd 重新发明了一堆历史悠久的核心服务(通常是简化功能和配置):syslog, ntp, cron, fstab, dhcpcd, vt… 系统管理员更信赖他们熟悉的服务(尽管配置较为复杂)。而重新发明轮子总体上在开源社区是不被赞许的。
3 概述
Systemd 就是的设计目标是,为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例,字母 d 是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。使用了 Systemd,就不需要再用 init 了。Systemd 取代了 initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。
1 |
|
Systemd 的优点是功能强大,使用方便,缺点是体系庞大,非常复杂。事实上,现在还有很多人反对使用 Systemd,理由就是它过于复杂,与操作系统的其他部分强耦合,违反 “keep simple, keep stupid” 的 Unix 哲学。
4 系统管理
Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面。
4.1 systemctl
systemctl
是 Systemd 的主要命令,用于管理系统。
1 |
|
4.2 systemd-analyze
systemd-analyze
命令用于查看启动耗时。
1 |
|
4.3 hostnamectl
hostnamectl
命令用于查看当前主机的信息。
1 |
|
4.4 localectl
localectl
命令用于查看本地化设置。
1 |
|
4.5 timedatectl
timedatectl
命令用于查看当前时区设置。
1 |
|
4.6 loginctl
loginctl
命令用于查看当前登录的用户。
1 |
|
5 Unit
Systemd 可以管理所有系统资源,不同的资源统称为 Unit(单位)。
5.1 Unit 种类
Unit 一共分成 12 种。
1 |
|
systemctl list-units
命令可以查看当前系统的所有 Unit 。
1 |
|
5.2 Unit 状态
systemctl status
命令用于查看系统状态和单个 Unit 的状态。
1 |
|
除了 systemctl
命令,status 还提供了三个查询状态的简单方法,主要供脚本内部的判断语句使用。
1 |
|
5.3 Unit 管理
对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。
1 |
|
5.4 依赖关系
Unit 之间存在依赖关系:A 依赖于 B,就意味着 Systemd 在启动 A 的时候,同时会去启动 B。有些依赖是 Target 类型(详见下文),默认不会展开显示。如果要展开 Target,就需要使用 –all 参数。
1 |
|
6 Target
启动计算机的时候,需要启动大量的 Unit。如果每一次启动,都要一一写明本次启动需要哪些 Unit,显然非常不方便。Systemd 的解决方案就是 Target。
简单说,Target 就是一个 Unit 组,包含许多相关的 Unit 。启动某个 Target 的时候,Systemd 就会启动里面所有的 Unit。从这个意义上说,Target 这个概念类似于”状态点”,启动某个 Target 就好比启动到某种状态。
传统的 init 启动模式里面,有 RunLevel 的概念,跟 Target 的作用很类似。不同的是,RunLevel 是互斥的,不可能多个 RunLevel 同时启动,但是多个 Target 可以同时启动。
1 |
|
7 日志管理
Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用 journalctl 一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是 /etc/systemd/journald.conf。journalctl 功能强大,用法非常多。
1 |
|