天天看点

操作系统 - systemd

  • 了解systemd.

1.由来

   历史上,Linux 的启动一直采用init进程。下面的命令用来启动服务。

$ sudo /etc/init.d/apache2 start
# 或者
$ service apache2 start
           

   这种方法有两个缺点。

  • 一是启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
  • 二是启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

2.Systemd 概述

   使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

$ systemctl --version //查看 Systemd 的版本。

   Systemd中的d是daemon(守护进程)的缩写,使用ps即可看到这个进程systemd的存在。

root@:# ps -ef |grep systemd |grep -v grep
root      1339     1  0 11月06 ?      00:01:48 /lib/systemd/systemd-journald
root      1357     1  0 11月06 ?      00:00:01 /lib/systemd/systemd-udevd
systemd+  1581     1  0 11月06 ?      00:00:00 /lib/systemd/systemd-timesyncd
message+  1601     1  0 11月06 ?      00:01:42 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root      1714     1  0 11月06 ?      00:00:18 /lib/systemd/systemd-logind
lightdm   2477     1  0 11月06 ?      00:00:01 /lib/systemd/systemd --user
lightdm   2530  2477  0 11月06 ?      00:00:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
uos       3120     1  0 11月06 ?      00:00:01 /lib/systemd/systemd --user
           

   systemd is a software suite that provides an array of system components for Linux operating systems.

   Its main aim is to unify service configuration and behavior across Linux distributions; systemd’s primary component is a “system and service manager”—an init system used to bootstrap user space and manage user processes. It also provides replacements for various daemons and utilities, including device management, login management, network connection management, and event logging. The name systemd adheres to the Unix convention of naming daemons by appending the letter d. It also plays on the term “System D”, which refers to a person’s ability to adapt quickly and improvise to solve problems.

   Since 2015, the majority of Linux distributions have adopted systemd, having replaced other systems such as the UNIX System V and BSD init systems. systemd has faced mixed reception from Linux users, with arguments that systemd suffers from mission creep and bloat, as well as criticism over software (such as the GNOME desktop) adding dependencies on systemd—frustrating compatibility with other Unix-like operating systems.

2.1.Design

  • A system and service manager (manages both the system, by applying various configurations, and its services)
  • A software platform (serves as a basis for developing other software)
  • The glue between applications and the kernel (provides various interfaces that expose functionalities provided by the kernel)

   Systemd includes features like on-demand starting of daemons, snapshot support, process tracking and Inhibitor Locks. It is not just the name of the init daemon but also refers to the entire software bundle around it, which, in addition to the systemd init daemon, includes the daemons journald, logind and networkd, and many other low-level components. In January 2013, Poettering described systemd not as one program, but rather a large software suite that includes 69 individual binaries.

  As an integrated software suite, systemd replaces the startup sequences and runlevels controlled by the traditional init daemon, along with the shell scripts executed under its control. systemd also integrates many other services that are common on Linux systems by handling user logins, the system console, device hotplugging (see udev), scheduled execution (replacing cron), logging, hostnames and locales.

   Like the init daemon, systemd is a daemon that manages other daemons, which, including systemd itself, are background processes. systemd is the first daemon to start during booting and the last daemon to terminate during shutdown. The systemd daemon serves as the root of the user space’s process tree; the first process (PID 1) has a special role on Unix systems, as it replaces the parent of a process when the original parent terminates. Therefore, the first process is particularly well suited for the purpose of monitoring daemons.

   systemd executes elements of its startup sequence in parallel, which is theoretically faster than the traditional startup sequence approach. For inter-process communication (IPC), systemd makes Unix domain sockets and D-Bus available to the running daemons. The state of systemd itself can also be preserved in a snapshot for future recall.

2.2…Core components and libraries

   Following its integrated approach, systemd also provides replacements for various daemons and utilities, including the startup shell scripts, pm-utils, inetd, acpid, syslog, watchdog, cron and atd. systemd’s core components include the following:

  • systemd is a system and service manager for Linux operating systems.
  • systemctl is a command to introspect and control the state of the systemd system and service manager. Not to be confused with sysctl.
  • systemd-analyze may be used to determine system boot-up performance statistics and retrieve other state and tracing information from the system and service manager.

   systemd tracks processes using the Linux kernel’s cgroups subsystem instead of using process identifiers (PIDs); thus, daemons cannot “escape” systemd, not even by double-forking. systemd not only uses cgroups, but also augments them with systemd-nspawn and machinectl, two utility programs that facilitate the creation and management of Linux containers.Since version 205, systemd also offers ControlGroupInterface, which is an API to the Linux kernel cgroups.The Linux kernel cgroups are adapted to support kernfs, and are being modified to support a unified hierarchy.

2.3.Ancillary components

  Beside its primary purpose of providing a Linux init system, the systemd suite can provide additional functionality, including the following components:

操作系统 - systemd
Systemd 的优点是功能强大,使用方便,缺点是体系庞大,非常复杂。事实上,现在还有很多人反对使用 Systemd,理由就是它过于复杂,与操作系统的其他部分强耦合,违反"keep simple, keep stupid"的Unix 哲学。
  • journald

    systemd-journald is a daemon responsible for event logging, with append-only binary files serving as its logfiles. The system administrator may choose whether to log system events with systemd-journald, syslog-ng or rsyslog. The potential for corruption of the binary format has led to much heated debate.

  • logind

    systemd-logind is a daemon that manages user logins and seats in various ways. It is an integrated login manager that offers multiseat improvements and replaces ConsoleKit, which is no longer maintained. For X11 display managers the switch to logind requires a minimal amount of porting. It was integrated in systemd version 30.

  • resolved
  • timesyncd
  • networkd

    networkd is a daemon to handle the configuration of the network interfaces; in version 209, when it was first integrated, support was limited to statically assigned addresses and basic support for bridging configuration. In July 2014, systemd version 215 was released, adding new features such as a DHCP server for IPv4 hosts, and VXLAN support.networkctl may be used to review the state of the network links as seen by systemd-networkd.[48] Configuration of new interfaces has to be added under the /lib/systemd/network/ as a new file ending with .network extension.

  • tmpfiles

    systemd-tmpfiles is a utility that takes care of creation and clean-up of temporary files and directories. It is normally run once at startup and then in specified intervals.

  • timedated

    systemd-timedated is a daemon that can be used to control time-related settings, such as the system time, system time zone, or selection between UTC and local time-zone system clock. It is accessible through D-Bus. It was integrated in systemd version 30.

  • udevd

    udev is a device manager for the Linux kernel, which handles the /dev directory and all user space actions when adding/removing devices, including firmware loading. In April 2012, the source tree for udev was merged into the systemd source tree.

    On 29 May 2014, support for firmware loading through udev was dropped from systemd, as it was decided that the kernel should be responsible for loading firmware.

  • libudev

    libudev is the standard library for utilizing udev, which allows third-party applications to query udev resources.

  • systemd-boot

    systemd-boot is a boot manager, formerly known as gummiboot. Kay Sievers merged it into systemd with rev 220.

2.系统管理

  Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面。

3.1 systemctl

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

# 重启系统
$ sudo systemctl reboot

# 关闭系统,切断电源
$ sudo systemctl poweroff

# CPU停止工作
$ sudo systemctl halt

# 暂停系统
$ sudo systemctl suspend

# 让系统进入冬眠状态
$ sudo systemctl hibernate

# 让系统进入交互式休眠状态
$ sudo systemctl hybrid-sleep

# 启动进入救援状态(单用户状态)
$ sudo systemctl rescue
           

3.2 systemd-analyze

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

# 查看启动耗时
$ systemd-analyze                                                                                       

# 查看每个服务的启动耗时
$ systemd-analyze blame

# 显示瀑布状的启动过程流
$ systemd-analyze critical-chain

# 显示指定服务的启动流
$ systemd-analyze critical-chain atd.service
           

4.Unit

4.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 。

# 列出正在运行的 Unit
$ systemctl list-units

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

# 列出所有没有运行的 Unit
$ systemctl list-units --all --state=inactive

# 列出所有加载失败的 Unit
$ systemctl list-units --failed

# 列出所有正在运行的、类型为 service 的 Unit
$ systemctl list-units --type=service
           

4.2 Unit 的状态

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

# 显示系统状态
$ systemctl status

# 显示单个 Unit 的状态
$ sysystemctl status bluetooth.service

# 显示远程主机的某个 Unit 的状态
$ systemctl -H [email protected].example.com status httpd.service
           

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

# 显示某个 Unit 是否正在运行
$ systemctl is-active application.service

# 显示某个 Unit 是否处于启动失败状态
$ systemctl is-failed application.service

# 显示某个 Unit 服务是否建立了启动链接
$ systemctl is-enabled application.service
           

4.3 Unit 管理

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

# 立即启动一个服务
$ sudo systemctl start apache.service

# 立即停止一个服务
$ sudo systemctl stop apache.service

# 重启一个服务
$ sudo systemctl restart apache.service

# 杀死一个服务的所有子进程
$ sudo systemctl kill apache.service

# 重新加载一个服务的配置文件
$ sudo systemctl reload apache.service

# 重载所有修改过的配置文件
$ sudo systemctl daemon-reload

# 显示某个 Unit 的所有底层参数
$ systemctl show httpd.service

# 显示某个 Unit 的指定属性的值
$ systemctl show -p CPUShares httpd.service

# 设置某个 Unit 的指定属性
$ sudo systemctl set-property httpd.service CPUShares=500
           

4.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
           

5.日志管理

  Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf。journalctl功能强大,用法非常多。

# 查看所有日志(默认情况下 ,只保存本次启动的日志)
$ sudo journalctl

# 查看内核日志(不显示应用日志)
$ sudo journalctl -k

# 查看系统本次启动的日志
$ sudo journalctl -b
$ sudo journalctl -b -0

# 查看上一次启动的日志(需更改设置)
$ sudo journalctl -b -1

# 查看指定时间的日志
$ sudo journalctl --since="2012-10-30 18:17:16"
$ sudo journalctl --since "20 min ago"
$ sudo journalctl --since yesterday
$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$ sudo journalctl --since 09:00 --until "1 hour ago"

# 显示尾部的最新10行日志
$ sudo journalctl -n

# 显示尾部指定行数的日志
$ sudo journalctl -n 20

# 实时滚动显示最新日志
$ sudo journalctl -f

# 查看指定服务的日志
$ sudo journalctl /usr/lib/systemd/systemd

# 查看指定进程的日志
$ sudo journalctl _PID=1

# 查看某个路径的脚本的日志
$ sudo journalctl /usr/bin/bash

# 查看指定用户的日志
$ sudo journalctl _UID=33 --since today

# 查看某个 Unit 的日志
$ sudo journalctl -u nginx.service
$ sudo journalctl -u nginx.service --since today

# 实时滚动显示某个 Unit 的最新日志
$ sudo journalctl -u nginx.service -f

# 合并显示多个 Unit 的日志
$ journalctl -u nginx.service -u php-fpm.service --since today

# 查看指定优先级(及其以上级别)的日志,共有8级
# 0: emerg
# 1: alert
# 2: crit
# 3: err
# 4: warning
# 5: notice
# 6: info
# 7: debug
$ sudo journalctl -p err -b

# 日志默认分页输出,--no-pager 改为正常的标准输出
$ sudo journalctl --no-pager

# 以 JSON 格式(单行)输出
$ sudo journalctl -b -u nginx.service -o json

# 以 JSON 格式(多行)输出,可读性更好
$ sudo journalctl -b -u nginx.serviceqq
 -o json-pretty

# 显示日志占据的硬盘空间
$ sudo journalctl --disk-usage

# 指定日志文件占据的最大空间
$ sudo journalctl --vacuum-size=1G

# 指定日志文件保存多久
$ sudo journalctl --vacuum-time=1years
           

6.Debug

6.1.Debug Logging to a Serial Console

  If you have a hardware serial console available or if you are debugging in a virtual machine (e.g. using virt-manager you can switch your view to a serial console in the menu View -> Text Consoles or connect from the terminal using virsh console MACHINE), you can ask systemd to log lots of useful debugging information to it by booting with:

systemd.log_level=debug systemd.log_target=console console=ttyS0,38400 console=tty1

  The above is useful if pid 1 is failing, but if a later but critical boot service is broken (such as networking), you can configure journald to forward to the console by using:

systemd.journald.forward_to_console=1 console=ttyS0,38400 console=tty1

console= can be specified multiple times, systemd will output to all of them.

6.2.Booting into Rescue or Emergency Targets

  To boot directly into rescue target add systemd.unit=rescue.target or just 1 to the kernel command line. This target is useful if the problem occurs somewhere after the basic system is brought up, during the starting of “normal” services. If this is the case, you should be able to disable the bad service from here. If the rescue target will not boot either, the more minimal emergency target might.

  To boot directly into emergency shell add systemd.unit=emergency.target or emergency to the kernel command line. Note that in the emergency shell you will have to remount the root filesystem read-write by yourself before editing any files:

mount -o remount,rw /

  Common issues that can be resolved in the emergency shell are bad lines in /etc/fstab. After fixing /etc/fstab, run systemctl daemon-reload to let systemd refresh its view of it.

  If not even the emergency target works, you can boot directly into a shell with init=/bin/sh. This may be necessary in case systemd itself or some libraries it depends on are damaged by filesystem corruption. You may need to reinstall working versions of the affected packages.

If init=/bin/sh does not work, you must boot from another medium.

6.3.Early Debug Shell

  You can enable shell access to be available very early in the startup process to fall back on and diagnose systemd related boot up issues with various systemctl commands. Enable it using:

systemctl enable debug-shell.service

or by specifying systemd.debug-shell=1 on the kernel command line.

  Tip: If you find yourself in a situation where you cannot use systemctl to communicate with a running systemd (e.g. when setting this up from a different booted system), you can avoid communication with the manager by specifying --root=:

systemctl --root=/ enable debug-shell.service

  Once enabled, the next time you boot you will be able to switch to tty9 using CTRL+ALT+F9 and have a root shell there available from an early point in the booting process. You can use the shell for checking the status of services, reading logs, looking for stuck jobs with systemctl list-jobs, etc.

Warning: Use this shell only for debugging! Do not forget to disable systemd-debug-shell.service after you’ve finished debugging your boot problems. Leaving the root shell always available would be a security risk.

It is also possible to alias kbrequest.target to debug-shell.service to start the debug shell on demand. This has the same security implications, but avoids running the shell always.

6.3.Reporting systemd Bugs

  Be prepared to include some information (logs) about your system as well. These should be complete (no snippets please), not in an archive, uncompressed.

6.3.1.Information to Attach to a Bug Report

  Whenever possible, the following should be mentioned and attached to your bug report:

  • The exact kernel command-line used. Typically from the bootloader configuration file (e.g. /boot/grub2/grub.cfg) or from /proc/cmdline
  • The journal (the output of journalctl -b > journal.txt)
    • ideally after booting with systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M printk.devkmsg=on
  • The output of a systemd dump: systemd-analyze dump > systemd-dump.txt
  • The output of /usr/lib/systemd/systemd --test --system --log-level=debug > systemd-test.txt 2>&1

refer to

  • https://en.wikipedia.org/wiki/Systemd
  • https://blog.csdn.net/liumiaocn/article/details/89082738
  • https://liumiaocn.blog.csdn.net/article/details/89079485
  • https://www.freedesktop.org/wiki/Software/systemd/
  • https://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
  • http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
  • https://freedesktop.org/wiki/Software/systemd/Debugging/
  • https://fedoraproject.org/wiki/How_to_debug_Systemd_problems

继续阅读