Sysvinit, Systemd & Systemctl

Created: 21 Feb 2017

Author:  Chen Xie

起因

    此次研究的起因是,希望能够配置一个程序开机启动,但网上的教程十分杂乱,脚本和代码都没有写明原理。虽然最后通过service命令成功配置,但是在centos7中,shell打印 (via systemctl),说明systemctl实际替代了service嘛。

    于是层层深挖,挖出了linux整个系统的初始化流程,以及机制的历史发展进程。一下大多数为摘抄,最后Reference中列举所有阅读资料。

阅读要求

摘要

    在各种Linux版本的系统中,init是不可或缺的进程之一。所谓init进程,是一个由内核启动的用户级进程,其ID进程编号始终是1。这一进程负责激活系统中的其他服务,较为常用的守护进程在系统启动时通过shell脚本启动,而不常用的守护进程由其他服务根据需要来启动。因此,许多年来init始终是Linux和UNIX系统的第一个进程。

    大多数 Linux 发行版的 init 系统是和 System V 相兼容的,被称为 sysvinit。这是人们最熟悉的 init 系统。Ubuntu 16.04 和 RHEL 7 之前采用 upstart 替代了传统的 sysvinit。而 Fedora 从版本 15 开始使用了一个被称为 systemd 的新 init 系统。另外,一些发行版如 Slackware 采用的是 BSD 风格 Init 系统,这种风格使用较少。其他的发行版如 Gentoo 是自己定制的。

    近年来,Linux 系统的 init 进程 经历了两次重大的演进,传统的 sysvinit 已经淡出历史舞台,新的 init 系统 UpStartsystemd 各有特点,而越来越多的 Linux 发行版采纳了 systemd。而 servicechkconfig 是sysvinit的管理工具,systemctl 是监视控制systemd的主要工具。upstart 因为使用中未接触过,本文未涉及。

    RHEL 7和CentOS 7中最重要的一个变化就来自systemd,它用于取代红帽企业版Linux 7版本以前的init系统。在RHEL 7中,进程ID=1属于systemd这一新的初始化进程。下面我们一起来学习和掌握systemd进程及systemctl工具。

1 sysvinit

详解见 鸟哥的Linux 私房菜– 第十七章、认识系统服务(daemons), 浅析 Linux 初始化 init 系统,第 1 部分: sysvinit

1.1 sysvinit简介

sysvinit 就是 system V 风格的 init 系统,顾名思义,它源于 System V 系列 UNIX。它提供了比 BSD 风格 init 系统更高的灵活性。是已经风行了几十年的 UNIX init 系统,一直被各类 Linux 发行版所采用。

系统启动时,sysvinit 需要读取/etc/inittab 文件,来确定运行等级X。sysvinit 串行顺序地执行以下这些步骤,从而将系统初始化为预订的 runlevel X

  1. /etc/rc.d/rc.sysinit
  2. /etc/rc.d/rc
  3. /etc/rc.d/rcX.d/ (X 代表运行级别 0-6)
  4. /etc/rc.d/rc.local
  5. X Display Manager(如果需要的话)

而/etc/rc.d/rcX.d/下都是linux软链接文件,真实的脚本文件存放在/etc/init.d 目录下。文件名以 S 开头的脚本就是启动时应该运行的脚本,S 后面跟的数字定义了这些脚本的执行顺序。

Sysvinit 不仅需要负责初始化系统,还需要负责关闭系统。这种顺序的控制这也是依靠/etc/rc.d/rcX.d/目录下所有脚本的命名规则来控制的,在该目录下所有以 K 开头的脚本都将在关闭系统时调用,字母 K 之后的数字定义了它们的执行顺序。这些脚本负责安全地停止服务或者其他的关闭工作。

基于sysvinit提供的常见的shell命令有:

1.2 service & chkconfig

不同的 Linux 发行版在这些 sysvinit 的基本工具基础上又开发了一些辅助工具用来简化 init 系统的管理工作。servicechkconfig 就是最流行常见的两个。

1.3 Sysvinit 的小结

    Sysvinit 的优点是概念简单。Service 开发人员只需要编写启动和停止脚本,概念非常清楚;将 service 添加/删除到某个 runlevel 时,只需要执行一些创建/删除软连接文件的基本操作;这些都不需要学习额外的知识或特殊的定义语法(UpStart 和 Systemd 都需要用户学习新的定义系统初始化行为的语言)。     其次,sysvinit 的另一个重要优点是确定的执行顺序:脚本严格按照启动数字的大小顺序执行,一个执行完毕再执行下一个,这非常有益于错误排查。UpStart 和 systemd 支持并发启动,导致没有人可以确定地了解具体的启动顺序,排错不易。     但是串行地执行脚本导致 sysvinit 运行效率较慢,在新的 IT 环境下,启动快慢成为一个重要问题。此外动态设备加载等 Linux 新特性也暴露出 sysvinit 设计的一些问题。针对这些问题,人们开始想办法改进 sysvinit,以便加快启动时间,并解决 sysvinit 自身的设计问题。

2 Systemd

详解见 浅析 Linux 初始化 init 系统,第 3 部分: Systemd, 《RHEL7专题系列》之systemctl控制系统服务, CoreOS实践指南(三):系统服务管家Systemd

    Systemd 的很多概念来源于苹果 Mac OS 操作系统上的 launchd,不过 launchd 专用于苹果系统,因此长期未能获得应有的广泛关注。

    systemd 引入了新的配置方式,对应用程序的开发也有一些新的要求。如果 systemd 想替代目前正在运行的初始化系统,就必须和现有程序兼容。任何一个 Linux 发行版都很难为了采用 systemd 而在短时间内将所有的服务代码都修改一遍。Systemd 提供了和 Sysvinit 以及 LSB initscripts 兼容的特性。系统中已经存在的服务和进程无需修改。这降低了系统向 systemd 迁移的成本,使得 systemd 替换现有初始化系统成为可能。

    systemd是一种新的Linux管理系统和服务的进程,它可以在系统启动时和运行时激活系统资源、服务器守护进程和其他进程。 在RHEL 7中systemd取代了init系统,成为新的默认初始化系统,用systemd初始化工具来启动系统,优势在于并发读取、管理服务。

    它主要的设计目标是克服传统Linux主流启动程序SysVinit 固有的缺点,提高系统的启动速度。

systemd能够管理系统的启动进程和一些系统服务,一旦系统启动,就将监管整个系统。systemd这一名字源于UNIX中的一个惯例:在UNIX中常以’d’作为系统守护进程(daemon,亦称后台进程)的后缀标识,守护进程是在执行各种任务的后台等待或运行的进程,一般情况下,守护进程在系统启动时自动启动并持续运行至关机或被手动停止。

    注意:为了软件的向下兼容,旧有的service命令在CentOS 7中仍然可用,会重定向所有service命令到新的systemctl工具。

2.1 Systemd使用及基础概念-Unit

Systemd 日常使用介绍。下一章有 Unit文件详解章节

    系统初始化需要做的事情非常多。需要启动后台服务,比如启动 SSHD 服务;需要做配置工作,比如挂载文件系统。这个过程中的每一步都被 systemd 抽象为一个配置单元,即 unit,对应于之前SysVinit时代的Daemon(守护进程)的超集。可以认为一个服务是一个配置单元;一个挂载点是一个配置单元;一个交换分区的配置是一个配置单元等等。

    systemd 将配置单元归纳为以下一些不同的类型:

常见Unit

其他Unit

    然而,systemd 正在快速发展,新功能不断增加。所以配置单元类型可能在不久的将来继续增加。

2.2 Systemd优点

使用详见:Systemd 日常使用介绍

1 提高并发启动能力,加快了系统启动时间

2 按需启动服务

Systemd 可以提供按需启动的能力,只有在某个服务被真正请求的时候才启动它。当该服务结束,systemd 可以关闭它,等待下次需要时再次启动它。

3 System解决Unit依赖和事物处理

每个Unit的配置文件都会指定其运行所需的依赖关系(Unit配置文件中[Unit]字段描述),依赖关系有两种:

3 Systemctl

    监视控制systemd的主要工具是systemctl 。systemctl向systemd发送命令,可用于查看系统状态和管理系统、服务。systemctl用于管理各种类型的systemd对象,称为单元。

    具体 使用详解 可阅读 《RHEL7专题系列》之systemctl控制系统服务

3.1 systemctl 与 sysvinit对应操作

Sysvinit 命令 Systemd 命令 备注
service foo start systemctl start foo.service 用来启动一个服务 (并不会重启现有的)
service foo stop systemctl stop foo.service 用来停止一个服务 (并不会重启现有的)。
service foo restart systemctl restart foo.service 用来停止并启动一个服务。
service foo reload systemctl reload foo.service 当支持时,重新装载配置文件而不中断等待操作。
service foo condrestart systemctl condrestart foo.service 如果服务正在运行那么重启它。
service foo status systemctl status foo.service 汇报服务是否正在运行。
ls /etc/rc.d/init.d/ systemctl list-unit-files –type=service 用来列出可以启动或停止的服务列表。
chkconfig foo on systemctl enable foo.service 在下次启动时或满足其他触发条件时设置服务为启用
chkconfig foo off systemctl disable foo.service 在下次启动时或满足其他触发条件时设置服务为禁用
chkconfig foo systemctl is-enabled foo.service 用来检查一个服务在当前环境下被配置为启用还是禁用。
chkconfig –list systemctl list-unit-files –type=service 输出在各个运行级别下服务的启用和禁用情况
chkconfig foo –list ls /etc/systemd/system/*.wants/foo.service 用来列出该服务在哪些运行级别下启用和禁用。
chkconfig foo –add systemctl daemon-reload 当您创建新服务文件或者变更设置时使用。
telinit 3 systemctl isolate multi-user.target (OR systemctl isolate runlevel3.target OR telinit 3) 改变至多用户运行级别。

3.2 Unit文件详解

具体介绍: Understanding Systemd Units and Unit Files, CoreOS实践指南(八):Unit文件详解

Unit文件位置

编写经验后续补全

4 实际使用场景

4.1 sytemctl使用init.d文件

以Jenkins为例,yum安装的Jenkins只会生成/etc/init.d/jenkins文件,适用于sysvinit。但是CentOS7 采用的是systemd系统,及systemctl工具来管理。

启动

service jenkins start

jenkins service result

由此上图可知,系统通过systemctl启动服务。因为安装后没有jenkins.service文件,所以,只能service命令启动,但系统内部通过systemctl工作。

查看

systemctl status jenkins.service

jenkins service

由上图可见,systemctl将init.d文件 自动转化 为临时的jenkins.service文件进行运行管理

5 Reference

# linux