• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

systemd

武飞扬头像
瞻邈
帮助1

systemd是一个 Linux 系统基础组件的集合,提供了一个系统和服务管理器,运行为 PID 1 并负责启动其它程序。功能包括:支持并行化任务;同时采用 socket 式与 D-Bus 总线式激活服务;按需启动守护进程(daemon);利用 Linux 的 cgroups 监视进程;支持快照和系统恢复;维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。systemd 支持 SysV 和 LSB 初始脚本,可以替代 sysvinit。除此之外,功能还包括日志进程、控制基础系统配置,维护登陆用户列表以及系统账户、运行时目录和设置,可以运行容器和虚拟机,可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。

1. 介绍

systemd 是 linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit 固有的缺点,提高系统的启动速度。systemd 和 ubuntu 的 upstart 是竞争对手,但是时至今日 ubuntu 也采用了 systemd,所以 systemd 在竞争中胜出,大有一统天下的趋势。其实,systemd 的很多概念都来源于苹果 Mac OS 操作系统上的 launchd。
systemd 的优点是功能强大,使用方便,缺点是体系庞大,非常复杂,下图展示了 systemd 的架构(此图来自互联网):

学新通

systemd 能够在与 upstart 的竞争中胜出自然有很多过人之处,接下来让我们介绍一些 systemd 的主要优点。

1.1. 兼容性

systemd 提供了和 sysvinit 兼容的特性。系统中已经存在的服务和进程无需修改。这降低了系统向 systemd 迁移的成本,使得 systemd 替换现有初始化系统成为可能。

1.2. 启动速度

systemd 提供了比 upstart 更激进的并行启动能力,采用了 socket / D-Bus activation 等技术启动服务。一个显而易见的结果就是:更快的启动速度。为了减少系统启动时间,systemd 的目标是:

  • 尽可能启动更少的进程
  • 尽可能将更多进程并行启动

同样地,upstart 也试图实现这两个目标。下图展示了 upstart 相对于 sysvinit 在并发启动这个方面的改进(此图来自互联网):

学新通

upstart 增加了系统启动的并行性,从而提高了系统启动速度。但是在 upstart 中,有依赖关系的服务还是必须先后启动。比如任务 A,B,(C,D)因为存在依赖关系,所以在这个局部,还是串行执行。

systemd 能够更进一步提高并发性,即便对于那些 upstart 认为存在相互依赖而必须串行的服务,比如 Avahi 和 D-Bus 也可以并发启动。从而实现如下图所示的并发启动过程(此图来自互联网):

学新通

在 systemd 中,所有的任务都同时并发执行,总的启动时间被进一步降低为 T1。可见 systemd 比 upstart 更进一步提高了并行启动能力,极大地加速了系统启动时间。

1.3. systemd 提供按需启动能力

当 sysvinit 系统初始化的时候,它会将所有可能用到的后台服务进程全部启动运行。并且系统必须等待所有的服务都启动就绪之后,才允许用户登录。这种做法有两个缺点:首先是启动时间过长,其次是系统资源浪费。

某些服务很可能在很长一段时间内,甚至整个服务器运行期间都没有被使用过。比如 CUPS,打印服务在多数服务器上很少被真正使用到。您可能没有想到,在很多服务器上 SSHD 也是很少被真正访问到的。花费在启动这些服务上的时间是不必要的;同样,花费在这些服务上的系统资源也是一种浪费。

systemd 可以提供按需启动的能力,只有在某个服务被真正请求的时候才启动它。当该服务结束,systemd 可以关闭它,等待下次需要时再次启动它。
这有点类似于以前系统中的 inetd,并且有很多文章介绍如何把过去 inetd 管理的服务迁移到 systemd。

1.4. 采用 linux 的 cgroups 跟踪和管理进程的生命周期

systemd 利用了 Linux 内核的特性即 cgroups 来完成跟踪的任务。当停止服务时,通过查询 cgroups ,systemd 可以确保找到所有的相关进程,从而干净地停止服务。
cgroups 已经出现了很久,它主要用来实现系统资源配额管理。cgroups 提供了类似文件系统的接口,使用方便。当进程创建子进程时,子进程会继承父进程的 cgroups 。因此无论服务如何启动新的子进程,所有的这些相关进程都会属于同一个 cgroups ,systemd 只需要简单地遍历指定的 cgroups 即可正确地找到所有的相关进程,将它们一个一个地停止即可。

1.5. 启动挂载点和自动挂载的管理

传统的 linux 系统中,用户可以用 /etc/fstab 文件来维护固定的文件系统挂载点。这些挂载点在系统启动过程中被自动挂载,一旦启动过程结束,这些挂载点就会确保存在。这些挂载点都是对系统运行至关重要的文件系统,比如 HOME 目录。和 sysvinit 一样,Systemd 管理这些挂载点,以便能够在系统启动时自动挂载它们。systemd 还兼容 /etc/fstab 文件,您可以继续使用该文件管理挂载点。

有时候用户还需要动态挂载点,比如打算访问 DVD 或者 NFS 共享的内容时,才临时执行挂载以便访问其中的内容,而不访问光盘时该挂载点被取消(umount),以便节约资源。传统地,人们依赖 autofs 服务来实现这种功能。
systemd 内建了自动挂载服务,无需另外安装 autofs 服务,可以直接使用 systemd 提供的自动挂载管理能力来实现 autofs 的功能。

1.6. 实现事务性依赖关系管理

系统启动过程是由很多的独立工作共同组成的,这些工作之间可能存在依赖关系,比如挂载一个 NFS 文件系统必须依赖网络能够正常工作。systemd 虽然能够最大限度地并发执行很多有依赖关系的工作,但是类似"挂载 NFS"和"启动网络"这样的工作还是存在天生的先后依赖关系,无法并发执行。对于这些任务,systemd 维护一个"事务一致性"的概念,保证所有相关的服务都可以正常启动而不会出现互相依赖,以至于死锁的情况。

1.7. 日志服务

systemd 自带日志服务 journald,该日志服务的设计初衷是克服现有的 syslog 服务的缺点。比如:

  • syslog 不安全,消息的内容无法验证。每一个本地进程都可以声称自己是 Apache PID 4711,而 syslog 也就相信并保存到磁盘上。
  • 数据没有严格的格式,非常随意。自动化的日志分析器需要分析人类语言字符串来识别消息。一方面此类分析困难低效;此外日志格式的变化会导致分析代码需要更新甚至重写。

systemd journal 用二进制格式保存所有日志信息,用户使用 journalctl 命令来查看日志信息。无需自己编写复杂脆弱的字符串分析处理程序。

1.8. systemd journal 的优点如下

简单性:代码少,依赖少,抽象开销最小。
零维护:日志是除错和监控系统的核心功能,因此它自己不能再产生问题。举例说,自动管理磁盘空间,避免由于日志的不断产生而将磁盘空间耗尽。
移植性:日志文件应该在所有类型的 Linux 系统上可用,无论它使用的何种 CPU 或者字节序。
性能:添加和浏览日志非常快。
最小资源占用:日志数据文件需要较小。
统一化:各种不同的日志存储技术应该统一起来,将所有的可记录事件保存在同一个数据存储中。所以日志内容的全局上下文都会被保存并且可供日后查询。例如一条固件记录后通常会跟随一条内核记录,最终还会有一条用户态记录。重要的是当保存到硬盘上时这三者之间的关系不会丢失。syslog 将不同的信息保存到不同的文件中,分析的时候很难确定哪些条目是相关的。
扩展性:日志的适用范围很广,从嵌入式设备到超级计算机集群都可以满足需求。
安全性:日志文件是可以验证的,让无法检测的修改不再可能。

2. 命令

systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面,但最常用的命令是systemctl。

2.1. systemctl

systemctl是 Systemd 的主命令,用于管理系统。systemctl命令主要有两大功能:控制systemd系统和管理系统上运行的服务

  1.  
    # 重启系统
  2.  
    $ sudo systemctl reboot
  3.  
     
  4.  
    # 关闭系统,切断电源
  5.  
    $ sudo systemctl poweroff
  6.  
     
  7.  
    # CPU停止工作
  8.  
    $ sudo systemctl halt
  9.  
     
  10.  
    # 暂停系统
  11.  
    $ sudo systemctl suspend
  12.  
     
  13.  
    # 让系统进入冬眠状态
  14.  
    $ sudo systemctl hibernate
  15.  
     
  16.  
    # 让系统进入交互式休眠状态
  17.  
    $ sudo systemctl hybrid-sleep
  18.  
     
  19.  
    # 启动进入救援状态(单用户状态)
  20.  
    $ sudo systemctl rescue
学新通

2.2. systemd-analyze

systemd-analyze命令用于查看启动耗时。

  1.  
    # 查看启动耗时
  2.  
    $ systemd-analyze
  3.  
     
  4.  
    # 查看每个服务的启动耗时
  5.  
    $ systemd-analyze blame
  6.  
     
  7.  
    # 显示瀑布状的启动过程流
  8.  
    $ systemd-analyze critical-chain
  9.  
     
  10.  
    # 显示指定服务的启动流
  11.  
    $ systemd-analyze critical-chain atd.service

2.3. hostnamectl

hostnamectl命令用于查看当前主机的信息。

  1.  
    # 显示当前主机的信息
  2.  
    $ hostnamectl
  3.  
     
  4.  
    # 设置主机名。
  5.  
    $ sudo hostnamectl set-hostname rhel7

2.4. localectl

localectl命令用于查看本地化设置。

  1.  
    # 查看本地化设置
  2.  
    $ localectl
  3.  
     
  4.  
    # 设置本地化参数。
  5.  
    $ sudo localectl set-locale LANG=en_GB.utf8
  6.  
    $ sudo localectl set-keymap en_GB

2.5. timedatectl

timedatectl命令用于查看当前时区设置。

  1.  
    # 查看当前时区设置
  2.  
    $ timedatectl
  3.  
     
  4.  
    # 显示所有可用的时区
  5.  
    $ timedatectl list-timezones
  6.  
     
  7.  
    # 设置当前时区
  8.  
    $ sudo timedatectl set-timezone America/New_York
  9.  
    $ sudo timedatectl set-time YYYY-MM-DD
  10.  
    $ sudo timedatectl set-time HH:MM:SS

2.6. loginctl

loginctl命令用于查看当前登录的用户。

  1.  
    # 列出当前session
  2.  
    $ loginctl list-sessions
  3.  
     
  4.  
    # 列出当前登录用户
  5.  
    $ loginctl list-users
  6.  
     
  7.  
    # 列出显示指定用户的信息
  8.  
    $ loginctl show-user ruanyf

3. Unit

3.1. 含义

Systemd 可以管理所有系统资源。不同的资源统称为 Unit(单位)。

Unit 一共分成12种。

Service unit:系统服务
Target unit:多个 Unit 构成的一个组
Device Unit:硬件设备
Mount Unit:文件系统的挂载点
Automount Unit:自动挂载点
Path Unit:文件或路径
Scope Unit:不是由 Systemd 启动的外部进程
Slice Unit:进程组
Snapshot Unit:Systemd 快照,可以切回某个快照
Socket Unit:进程间通信的 socket
Swap Unit:swap 文件
Timer Unit:定时器

systemctl list-units命令可以查看当前系统的所有 Unit 。 

  1.  
    # 列出正在运行的 Unit
  2.  
    $ systemctl list-units
  3.  
     
  4.  
    # 列出所有Unit,包括没有找到配置文件的或者启动失败的
  5.  
    $ systemctl list-units --all
  6.  
     
  7.  
    # 列出所有没有运行的 Unit
  8.  
    $ systemctl list-units --all --state=inactive
  9.  
     
  10.  
    # 列出所有加载失败的 Unit
  11.  
    $ systemctl list-units --failed
  12.  
     
  13.  
    # 列出所有正在运行的、类型为 service 的 Unit
  14.  
    $ systemctl list-units --type=service

3.2. Unit 的状态

systemctl status命令用于查看系统状态和单个 Unit 的状态。

  1.  
    # 显示系统状态
  2.  
    $ systemctl status
  3.  
     
  4.  
    # 显示单个 Unit 的状态
  5.  
    $ sysystemctl status bluetooth.service
  6.  
     
  7.  
    # 显示远程主机的某个 Unit 的状态
  8.  
    $ systemctl -H root@rhel7.example.com status httpd.service

除了status命令,systemctl还提供了三个查询状态的简单方法,主要供脚本内部的判断语句使用。

  1.  
    # 显示某个 Unit 是否正在运行
  2.  
    $ systemctl is-active application.service
  3.  
     
  4.  
    # 显示某个 Unit 是否处于启动失败状态
  5.  
    $ systemctl is-failed application.service
  6.  
     
  7.  
    # 显示某个 Unit 服务是否建立了启动链接
  8.  
    $ systemctl is-enabled application.service

3.3 Unit 管理

对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。

  1.  
    # 立即启动一个服务
  2.  
    $ sudo systemctl start apache.service
  3.  
     
  4.  
    # 立即停止一个服务
  5.  
    $ sudo systemctl stop apache.service
  6.  
     
  7.  
    # 重启一个服务
  8.  
    $ sudo systemctl restart apache.service
  9.  
     
  10.  
    # 杀死一个服务的所有子进程
  11.  
    $ sudo systemctl kill apache.service
  12.  
     
  13.  
    # 重新加载一个服务的配置文件
  14.  
    $ sudo systemctl reload apache.service
  15.  
     
  16.  
    # 重载所有修改过的配置文件
  17.  
    $ sudo systemctl daemon-reload
  18.  
     
  19.  
    # 显示某个 Unit 的所有底层参数
  20.  
    $ systemctl show httpd.service
  21.  
     
  22.  
    # 显示某个 Unit 的指定属性的值
  23.  
    $ systemctl show -p CPUShares httpd.service
  24.  
     
  25.  
    # 设置某个 Unit 的指定属性
  26.  
    $ sudo systemctl set-property httpd.service CPUShares=500
学新通

3.4 依赖关系

Unit 之间存在依赖关系:A 依赖于 B,就意味着 Systemd 在启动 A 的时候,同时会去启动 B。

systemctl list-dependencies命令列出一个 Unit 的所有依赖。

$ systemctl list-dependencies nginx.service

上面命令的输出结果之中,有些依赖是 Target 类型(详见下文),默认不会展开显示。如果要展开 Target,就需要使用--all参数。

$ systemctl list-dependencies --all nginx.service

4. Unit 的配置文件

4.1. 概述

每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit 。

Systemd 默认从目录/etc/systemd/system/读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在那个目录。

systemctl enable命令用于在上面两个目录之间,建立符号链接关系。

  1.  
    $ sudo systemctl enable clamd@scan.service
  2.  
    # 等同于
  3.  
    $ sudo ln -s '/usr/lib/systemd/system/clamd@scan.service' '/etc/systemd/system/multi-user.target.wants/clamd@scan.service'

如果配置文件里面设置了开机启动,systemctl enable命令相当于激活开机启动。

与之对应的,systemctl disable命令用于在两个目录之间,撤销符号链接关系,相当于撤销开机启动。

$ sudo systemctl disable clamd@scan.service

配置文件的后缀名,就是该 Unit 的种类,比如sshd.socket。如果省略,Systemd 默认后缀名为.service,所以sshd会被理解成sshd.service。

4.2 配置文件的状态

systemctl list-unit-files命令用于列出所有配置文件。

  1.  
    # 列出所有配置文件
  2.  
    $ systemctl list-unit-files
  3.  
     
  4.  
    # 列出指定类型的配置文件
  5.  
    $ systemctl list-unit-files --type=service

这个命令会输出一个列表。

  1.  
    $ systemctl list-unit-files
  2.  
     
  3.  
    UNIT FILE STATE
  4.  
    chronyd.service enabled
  5.  
    clamd@.service static
  6.  
    clamd@scan.service disabled

这个列表显示每个配置文件的状态,一共有四种。

  • enabled:已建立启动链接
  • disabled:没建立启动链接
  • static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖
  • masked:该配置文件被禁止建立启动链接

注意,从配置文件的状态无法看出,该 Unit 是否正在运行。这必须执行前面提到的systemctl status命令。

 $ systemctl status bluetooth.service

一旦修改配置文件,就要让 SystemD 重新加载配置文件,然后重新启动,否则修改不会生效。 

  1.  
    $ sudo systemctl daemon-reload
  2.  
    $ sudo systemctl restart httpd.service

参考文献

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiabhkh
系列文章
更多 icon
同类精品
更多 icon
继续加载