天天看點

作業系統 - 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

繼續閱讀