• Linux’s init system & systemd


    一、init system


    1、计算机是如何启动的

    以早期 Fedora 系统为例。

    1、开机

    2、BIOS 和 GRUB(引导加载程序)

    3、Linux 内核启动后,init 进程 是在 Fedora 上启动的第一个进程。进程 ID (PID) 为 1。它是系统中所有其它进程的母亲,用于启动其他服务和守护程序。

    2、各种 init system

    对于上面介绍的 init 进程,各个不同的发行版采用了不同的 init 实现方式,即 init system(初始化系统)

    (1)System V (Sys V)

    System V 是类 Unix 操作系统传统的也是首款初始化系统。

    (2)Upstart

    Upstart 是由 Ubuntu 的制造商开发的基于事件的初始化系统,用于替代 SysV初始化系统。

    它用于 Ubuntu 9.10 - 14.10 版本和基于 RHEL 6 的系统中,之后的被 systemd 取代了。

    (3)systemd

    systemd 旨在以并行方式启动进程的 init 替换守护程序,以许多标准发行版(Fedora,OpenSuSE,Arch,RHEL,CentOS 等)实现。

    Fedora 15 是第一个采用 systemd 而不是 upstart 的发行版。

    CentOS 7 也跟上,抛弃了 6 的 SysV,改用 systemd。

    (4)其他

    还有一些其他的 init system:

    • Launchd - mac 系统的 init system ,其实 systemd 的很多概念来源于此

    • Epoch - 基于简单性和服务管理的 init 替换守护进程,旨在启动单线程进程。

    • Mudar - 用Python编写的 init 替换守护进程,在Pardus GNU / Linux上实现,旨在异步启动进程。

    (5)总结

    各种 init system 的所在目录:

    • SysV:/etc/init.d
    • UpStart: /usr/share/upstart
    • systemd:/usr/lib/systemd

    二、systemd


    因为鄙人用的最多的 linux 发行版是 CentOS 7 ,所以这里重点介绍 systemd。

    1、介绍

    (1)名字含义

    根据 Linux 惯例,字母 d 是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统

    Linux 的守护进程都习惯加 d ,如 httpd,sshd……

    (2)优点
    • 传统的 SysV ,性能太低,主要原因是 init 是串行启动,前一个服务进程启动完成后下一个服务进程才能启动,这也就导致了 init 进程启动耗时比较长。而 systemd 是并行启动,恰恰解决了这点。

    • 功能强大

    • 使用方便

    (3)缺点
    • 体系庞大,非常复杂

      • 与操作系统的其他部分强耦合,违反"keep simple, keep stupid"的Unix 哲学

    知乎上还有不少人吐槽 systemd,详见:systemd 为什么会有那么大的争议?

    2、管理系统

    前面介绍 systemd 的目标是要守护整个系统,所以他有很多管理系统的命令。

    所以 Systemd 并不是一个命令,而是一组命令

    • systemctl是 Systemd 的主命令,用于管理系统。

      例如:

      • 重启系统 sudo systemctl reboot

      • 查看系统状态 sudo systemctl status

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

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

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

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

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

    3、管理系统资源

    (1)unit —— 配置单元

    systemd 把系统资源划分成12种 Unit

    • 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:定时器

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


    1、查看 unit:

    # 列出正在运行的 Unit
    $ systemctl list-units
    
    # 列出所有Unit,包括没有找到配置文件的或者启动失败的
    $ systemctl list-units --all
    

    2、管理 unit (以管理单个服务为例):

    sudo systemctl start httpd.service 
    sudo systemctl stop httpd.service 
    sudo systemctl kill httpd.service
    
    # 重启 
    sudo systemctl restart httpd.service  # restart = stop + start
    # 重新加载配置文件 
    sudo systemctl reload httpd.service
    
    # 显示某个 Unit 的运行状态
    sudo systemctl status httpd.service 
    
    (2)unit 配置文件

    每一个配置单元都有一个对应的配置文件

    比如一个 MySql 服务对应一个 mysql.service 文件。

    配置文件的后缀名,就是该 Unit 的种类(上面介绍了 Unit 有 12 种分类 ),比如sshd.socket。如果省略,Systemd 默认后缀名.service,所以 sshd 会被理解成sshd.service


    1、(支持 Systemd 的软件会)自动生成配置文件

    下面以 安装 mariadb 并设置开机自启 为例:

    (1)sudo yum install mariadb mariadb-server

    先用 yum 安装 mariadb。对于那些支持 Systemd 的软件,安装完成后,会自动在 /usr/lib/systemd/system 添加一个配置文件,这里叫 mariadb.service

    (2)sudo systemctl start mariadb.service

    通过 systemctl 启动 mariadb.service。

    (3)sudo systemctl enable mariadb.service

    因为每次开机,Systemd 都会默认从 /etc/systemd/system/ 读取配置文件。 所以 systemctl enable 做的就是从 /etc/systemd/system//usr/lib/systemd/system/mariadb.service 的一个软连接

    再加上mariadb.service这个 unit 配置文件里的 [Install] 定义了自启行为,所以 systemctl enable 也做到了开机自启

    (4)sudo systemctl disable mariadb.service

    我们也可以撤销这个软连接,即撤销开机自启。


    2、查看配置文件

    (1)查看单个

    以 sshd.service 为例:

    $ systemctl cat sshd.service
    
    [Unit]
    Description=OpenSSH server daemon
    Documentation=man:sshd(8) man:sshd_config(5)
    After=network.target sshd-keygen.service
    Wants=sshd-keygen.service
    
    [Service]
    EnvironmentFile=/etc/sysconfig/sshd
    ExecStart=/usr/sbin/sshd -D $OPTIONS
    ExecReload=/bin/kill -HUP $MAINPID
    Type=simple
    KillMode=process
    Restart=on-failure
    RestartSec=42s
    
    [Install]
    WantedBy=multi-user.target
    

    关于字段的详细释义,可参考:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html

    # 显示某个 Unit 的所有底层参数
    $ systemctl show httpd.service
    
    # 显示某个 Unit 的依赖关系
    $ systemctl list-dependencies httpd.service
    $ systemctl list-dependencies --all httpd.service
    

    (2)查看多个(列表)

    # 列出所有配置文件
    $ systemctl list-unit-files
    

    在返回的列表里,显示的每个配置文件的状态,一共有 4 种:

    • enabled:已建立启动链接

    • disabled:没建立启动链接

    • static:该配置文件没有 [Install] 部分(无法执行),只能作为其他配置文件的依赖

    • masked:该配置文件被禁止建立启动链接

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


    3、修改(完)配置文件

    修改配置文件需重新启动才能生效。

    # 重载所有修改过的配置文件
    $ sudo systemctl daemon-reload
    $ sudo systemctl restart httpd.service
    
    (3)target —— Unit 组

    上面介绍了 Unit 有 12 种分类,其中一个叫 target ,他其实就是 Unit 组。

    启动某个 Target 的时候,Systemd 就会启动里面所有的 Unit。

    例如上面说到 安装 mariadb 并设置开机自启 时,其实 systemctl enable 做软连接的时候,/usr/lib/systemd/system 下的 mariadb.service 就被加入到 /etc/systemd/system 下 的 targetmulti-user.target.wants 中。即 Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.

    # 查看当前系统的所有 Target
    $ systemctl list-unit-files --type=target
    
    # 查看一个 Target 包含的所有 Unit
    $ systemctl list-dependencies multi-user.target
    

    3、日志管理

    Systemd 除了可以管理系统和系统资源,还统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl 一个命令,查看所有日志(内核日志和应用日志)。

    (1)查看日志
    # 查看所有日志(默认情况下 ,只保存本次启动的日志)
    $ sudo journalctl
    
    # 实时滚动显示最新日志
    $ sudo journalctl -f
    
    # 查看指定进程的日志
    $ sudo journalctl _PID=1
    
    # 查看指定用户的日志
    $ sudo journalctl _UID=33 --since today
    
    # 查看某个 Unit 的日志
    $ sudo journalctl -u nginx.service
    $ sudo journalctl -u nginx.service --since today
    
    (2)编辑日志配置

    日志的配置文件位于/etc/systemd/journald.conf

    # 显示日志占据的硬盘空间
    $ sudo journalctl --disk-usage
    
    # 指定日志文件占据的最大空间
    $ sudo journalctl --vacuum-size=1G
    
    # 指定日志文件保存多久
    $ sudo journalctl --vacuum-time=1years
    

    4、自己从零写一个 unit

    待写


    参考资料

    # Systemd 入门教程:命令篇

    # Systemd 入门教程:实战篇

  • 相关阅读:
    poj 3636
    poj 1065 Wooden Sticks
    2017北京国庆刷题Day6 afternoon
    2017北京国庆刷题Day5 afternoon
    2017北京国庆刷题Day3 afternoon
    2017北京国庆刷题Day3 morning
    2017北京国庆刷题Day2 afternoon
    2017北京国庆刷题Day2 morning
    poj2420 A Star not a Tree?
    NOIP2016 愤怒的小鸟
  • 原文地址:https://www.cnblogs.com/xjnotxj/p/11951957.html
Copyright © 2020-2023  润新知