Linux 系统服务管理器(初始化系统/init system) -- systemd 及命令 systemctl 的详细介绍
文章目錄
- 一、系統服務管理器 systemd
- (一)systemd 的特性
- (二)systemd 與 傳統 init 系統的區別
- (三)systemd 的目錄和文件
- (四)systemd 的 Unit 介紹
- 1.Unit 類型
- 2.Unit 的配置文件
- (1)配置文件的狀態
- (2)配置文件的格式
- (4)配置文件的區塊
- 1)[Unit]區塊
- 2)[Service]區塊
- 3)[Install]區塊
- A.替換符
- 3.Unit 的依賴管理
- (五)systemd 的 Target 介紹
- 1.查看當前系統的所有 Target
- 2.查看一個 Target 包含的所有 Unit
- 3.查看啟動時的默認 Target
- 4.設置啟動時的默認 Target
- 5.切換 Target
- 6.Target 與 傳統 Run Level 的對應關系
- (六)systemd 并行啟動原理
- 并發啟動原理之一:解決 socket 依賴
- 并發啟動原理之二:解決 D-Bus 依賴
- 并發啟動原理之三:解決文件系統依賴
- (七)systemd 配置使用
- 1.對于系統開發人員
- 2.對于系統管理員
- (八)日志管理
- 二、使用命令 systemctl 管理系統服務
- (一)命令介紹
- (二)命令選項
- (三)systemd 命令和 SysV init 命令的對比
- (四)命令示例
- 1.重啟服務
- 2.純重啟 try-restart
- 3.重新加載某個服務的配置文件
- 4.啟動服務
- 5.停止服務
- 6.查看服務狀態
- (1)解讀服務狀態信息
- (2)關于服務的啟動狀態
- (3)關于服務的運行狀態
- 7.設置開機啟動某個服務
- 8.取消某個服務的開機啟動
- 9.查看某個服務是否開機啟動
- 10.查看啟動失敗的服務
- 11.查看進程是不是在運行中
- 12.查看系統中所有已經啟動的服務
- 13.列出目錄 /lib/systemd/system/ 下的所有 unit
- 14.只看服務類型的 unit
- 15.查看加載失敗的 unit
- 16.管理系統的操作環境(target unit)
- (1)查看系統目前的操作模式(target)
- (2)設置系統默認的操作模式
- (3)切換操作模式
- 17.讓系統進入暫停模式
- 18.讓系統進入休眠模式
- 19.強制系統進入救援模式
- 20.強制系統進入緊急救援模式
- 22.重新加載 systemd 程序的配置文件
- 23.殺死服務
- 24.管理系統掛載點的命令
- 25.查看 systemd 的版本
- 26.查看系統啟動耗時
- 27.查看每個進程在引導時花費的時間
- 28.查看指定服務的關鍵鏈
- 29.獲取服務的依賴項列表
- 30.按層次列出控制組
- 31.根據CPU,內存,輸入和輸出列出控制組
- 32.查看指定類型的 unit
- 33.列出所有沒有運行的 Unit
- 34.查看系統狀態
- 35.顯示遠程主機的某個 Unit 的狀態
- 36.顯示某個 Unit 是否處于啟動失敗狀態
- 37.重載所有修改過的配置文件
- 38.顯示某個 Unit 的指定屬性的值
- 39.設置某個 Unit 的指定屬性
- 40.電源管理命令
systemd GitHub 主頁:https://github.com/systemd/systemd
systemd 官方網站:https://www.freedesktop.org/wiki/Software/systemd/
arch 的 systemd 的 wiki 主頁:https://wiki.archlinux.org/title/systemd_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
fedora 的 systemd 說明頁面:http://fedoraproject.org/wiki/Packaging:Systemd,中文:https://fedoraproject.org/wiki/Systemd/zh-cn
unbuntu 的 systemd 說明頁面:https://wiki.edubuntu.org/systemd
一、系統服務管理器 systemd
init(initialization 的簡寫)是 Unix 和 類 Unix 系統中用來產生其它所有進程的程序。Linux 內核加載啟動后,用戶空間的第一個進程就是 init 進程,這個進程的進程號為1,代表第一個運行的用戶空間進程,它作為父守護進程在運行,用戶空間中的其它進程都是它的子進程。
Linux 系統在引導時加載 Linux 內核后,便由 Linux 內核加載 init 程序,由 init 程序完成余下的引導過程,比如加載運行級別,加載服務,引導 Shell/圖形化界面等。
Systmed 是 Linux 下的一種系統初始化程序,負責控制和管理系統服務,由 Lennart Poettering 帶頭開發,并在 LGPL 2.1 及其后續版本許可證下開源發布。其開發目標是提供更優秀的框架以表示系統服務間的依賴關系,并依此實現系統初始化時服務的并行啟動,同時達到降低系統開銷的效果,最終代替現在常用的 System V 與 BSD 風格 init 程序。
傳統的 System V 是串行啟動,即在啟動下一個腳本前,上一個腳本必須執行完,這樣在啟動時間上會有很大的浪費。在這個時間就是金錢的年代,這種啟動方式必將被淘汰。首先是 Ubuntu 最先造反,啟用了自己的 upstart 啟動方式,upstart 基于事件觸發,但還是串行啟動,但是對于沒有必要的服務就不會啟動。
systemd 盡可能減少對 Shell 腳本的依賴。傳統 SysVinit使用inittab來決定運行哪些Shell腳本,大量使用Shell腳本被認為是效率低下無法并行的原因。systemd 使用了Linux專屬技術,不再顧及POSIX兼容,只要能滿足社會變革的需要,突破一些可能過時的技術約束,這也是當今創新理念的需要,相信市場會給出評判。
這時 systemd出現了,主要優點就是并行啟動,節約啟動時間,systemd作者曾口出狂言,最快2秒啟動。
systemd 其實是一個用戶空間的程序,屬于應用程序,不屬于 Linux 內核范疇,Linux 內核的主要特征在所有發行版中是統一的,廠商可以自由改變的是用戶空間的應用程序。以 systemd 作為系統服務管理器(啟動程序)的 Linux 系統開啟后,systemd 就是 init 進程。
傳統的啟動是內核啟動完后,首先執行的第一個進程是 /sbin/init。如果要以 systemd 方式啟動,則首先讓內核執行的第一個進程是 /lib/systemd/systemd 或者 /usr/lib/systemd/systemd。
systemd 啟動后,首先會去三個目錄下找相應的配置文件,按優先級從高到底為 /etc/systemd/,/usr/lib/systemd/ 和/ lib/systemd/,優先級高的配置文件會覆蓋優先級低的配置文件。
systemd 這一名字源于 Unix 中的一個慣例:在 Unix 中常以 d 作為系統守護進程的后綴標識。d 是英文單詞 daemon(意指后臺進程) 的首字母。
不同發行版采用了不同的啟動程序:
Fedora 15 是第一個采用 systemd 作為系統服務管理器的 Linux 發行版,后來 Red Hat 旗下 CentOS 7.0 也拋棄之前的 SysV,改用 systemd,逐漸地其它派系也開始使用 systemd 作為最新發行版的初始化系統。
從設計構思上說,由于systemd使用了cgroup與fanotify 等組件以實現其特性,所以只適用于Linux。有鑒于此,基于 kFreeBSD 分支的軟件源無法納入 systemd。
備注:Lennart Poettering 就職于紅帽,systemd 是紅帽的 Fedora 首先在推,OpenSUSE 后面跟隨
(一)systemd 的特性
開機時并行啟動系統服務,極大地提高了系統啟動速度
按需啟動守護進程
支持系統狀態快照
基于依賴的服務控制邏輯,自動化的服務依賴關系管理
用 CGroup 代替 PID 統計跟蹤子進程,即使是兩次 fork 之后生成的守護進程也不會脫離systemd的控制
同時采用socket式與D-Bus總線式激活服務,以提高相互依賴的各服務的并行運行性能
(二)systemd 與 傳統 init 系統的區別
systemd用目標(target)代替了System V init 中運行級別的概念
默認的 Run Level(在/etc/inittab文件設置)現在被默認的 Target 取代,由文件 /etc/systemd/system/default.target 定義,通常符號鏈接到 graphical.target(圖形界面)或者 multi-user.target(多用戶命令行)
啟動腳本的位置,以前是 /etc/init.d 目錄,符號鏈接到不同的 Run Level 目錄 (比如 /etc/rc3.d、/etc/rc5.d 等),現在則存放在 /lib/systemd/system 和 /etc/systemd/system 目錄下
配置文件的位置,以前 init 進程的配置文件是 /etc/inittab,各種服務的配置文件存放在 /etc/sysconfig 目錄。現在的配置文件主要存放在/lib/systemd目錄,在 /etc/systemd 目錄里面的修改可以覆蓋原始設置
(三)systemd 的目錄和文件
在不同的發行版中與 systemd 相關的文件路徑可能會不太一樣,在此以 ubuntu 16.04 舉例簡單介紹如下:
/lib/systemd/system/:大多數 unit 的配置文件都放在這個目錄下,CentOS 則放在 /usr/lib/systemd/system/ 目錄中,使用命令:systemctl list-unit-files 可以列出該目錄下的所有配置文件。
/etc/systemd/system/:這個目錄中主要的文件都是指向 /lib/systemd/system/ 目錄中的鏈接文件。注意,在我們自己創建 unit 配置文件時,既可以把配置文件放在 /lib/systemd/system/ 目錄下,也可以放在 /etc/systemd/system/ 目錄下。
/run/systemd/system/:系統運行過程中產生的腳本,比如用戶相關的腳本和會話相關的腳本。
/etc/default/ 這個目錄中放置很多服務默認的配置文件。
/var/lib/ 一些會產生數據的服務都會將他的數據寫入到 /var/lib/ 目錄中,比如 docker 相關的數據文件就放在這個目錄下。
/bin 和 /sbin 工具命令位于這兩個目錄下。
/run/ 這個目錄放置了好多服務運行時的臨時數據,比如 lock file,PID file,socket file 等。
我們使用命令:systemctl list-sockets 查看下 socket 文件所存放的位置:
[root@htlwk0001host ~]# systemctl list-sockets LISTEN UNIT ACTIVATES /run/dbus/system_bus_socket dbus.socket dbus.service /run/dmeventd-client dm-event.socket dm-event.service /run/dmeventd-server dm-event.socket dm-event.service /run/initctl systemd-initctl.socket systemd-initctl.service /run/lvm/lvmpolld.socket lvm2-lvmpolld.socket lvm2-lvmpolld.service /run/systemd/coredump systemd-coredump.socket /run/systemd/journal/dev-log systemd-journald-dev-log.socket systemd-journald.service /run/systemd/journal/socket systemd-journald.socket systemd-journald.service /run/systemd/journal/stdout systemd-journald.socket systemd-journald.service /run/udev/control systemd-udevd-control.socket systemd-udevd.service /var/run/.heim_org.h5l.kcm-socket sssd-kcm.socket sssd-kcm.service kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service12 sockets listed. Pass --all to see loaded but inactive sockets, too.在 CentOS 系統下我們可以使用命令:rpm -ql systemd 查看 systemd 的相關目錄和文件:
[root@htlwk0001host ~]# rpm -ql systemd /etc/X11/xinit/xinitrc.d/50-systemd-user.sh /etc/X11/xorg.conf.d/00-keyboard.conf /etc/binfmt.d /etc/crypttab /etc/dnf/protected.d/systemd.conf /etc/hostname /etc/inittab文件 /etc/inittab 是 System V init 的標準配置文件,而使用 systemd 作為 init 系統后,我們再看看這個文件的內容:
[root@htlwk0001host ~]# cat /etc/inittab # inittab is no longer used. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. # # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target # # systemd uses 'targets' instead of runlevels. By default, there are two main targets: # # multi-user.target: analogous to runlevel 3 # graphical.target: analogous to runlevel 5 # # To view current default target, run: # systemctl get-default # # To set a default target, run: # systemctl set-default TARGET.target如上的內容可以看到在 systemd 掌權后,/etc/inittab 這個文件不再使用了,也沒有了“運行級”的概念。現在起作用的配置文件是 /etc/systemd/system/default.target 這個文件了。此文件的內容如下:
[root@htlwk0001host ~]# cat /etc/systemd/system/default.target # SPDX-License-Identifier: LGPL-2.1+ # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version.[Unit] Description=Multi-User System Documentation=man:systemd.special(7) Requires=basic.target Conflicts=rescue.service rescue.target After=basic.target rescue.service rescue.target AllowIsolate=yes(四)systemd 的 Unit 介紹
systemd 的核心概念是 Unit(單元),Unit 表示不同類型的 systemd 對象,通過配置文件進行標識和配置。使用 SysV 或者 UpStart 初始化的 Linux 發行版,都是使用位于目錄 /etc/rc.d/init.d/ 下的 bash 初始化腳本來對系統服務進行管理的,而使用 systemd 作為初始化系統的 Linux 發行版(例如:RHEL 7.x、CentOS 7.x)則用服務單元(Service Unit)取代了這些啟動腳本,服務單元是一種以 .service 作為擴展名的服務文件,提供了與初始化腳本同樣的用途。
systemd 啟動的第一個 unit 文件為 /lib/systemd/system/ 下的 default.target 文件(這里的 default.target 一般為鏈接文件,這樣default.target 指向不同的文件,可達到不同的啟動等級)
1.Unit 類型
Service:文件擴展名為.service, 用于定義系統服務
Target:Unit 的邏輯分組,包含多個相關的 Unit,用于模擬實現 System V 的運行級別。此類 unit 為其他 unit 進行邏輯分組。它們本身實際上并不做什么,只是引用其他 unit 而已。這樣便可以對 unit 做一個統一的控制。(例如:multi-user.target 相當于在傳統使用 SysV 的系統中運行級別5);bluetooth.target 只有在藍牙適配器可用的情況下才調用與藍牙相關的服務,如:bluetooth 守護進程、obex 守護進程等)
Device:用于定義內核識別的設備,對應 udev 規則標記的一個設備。此類 unit 封裝一個存在于 Linux 設備樹中的設備。每一個使用 udev 規則標記的設備都將會在 systemd 中作為一個設備 unit 出現。udev 的屬性設置可以作為配置設備 unit 依賴關系的配置源。
Mount:定義文件系統掛載點,systemd 據此進行自動掛載。為了與 System V init 兼容,目前 systemd 自動處理 /etc/fstab 并轉化為Mount
Socket:用于標識進程間通信用的 socket 文件,也可在系統啟動時,延遲啟動服務,實現按需啟動。此類 unit 封裝系統和互聯網中的一個 socket 。當下,systemd 支持流式、數據報和連續包的 AF_INET、AF_INET6、AF_UNIX socket 。也支持傳統的 FIFOs 傳輸模式。每一個 socket unit 都有一個相應的服務 unit 。相應的服務在第一個“連接”進入 socket 或 FIFO 時就會啟動(例如:nscd.socket 在有新連接后便啟動 nscd.service)。
Snapshot:管理系統快照,與 Target 類似,表示當前的運行狀態。快照本身不做什么,唯一的目的就是引用其他 unit 。
Swap:用于標識 swap 設備
Automount:文件系統的自動掛載點。此類 unit 封裝系統結構層次中的一個自掛載點。每一個自掛載 unit 對應一個已掛載的掛載 unit (需要在自掛載目錄可以存取的情況下盡早掛載)。
Path:用于定義文件系統中的一個文件或目錄使用,常用于當文件系統變化時,延遲激活服務
Timer:定時器,用來定時觸發用戶定義的操作,它可以用來取代傳統的 atd,crond 等
Scope:不是由 systemd 啟動的外部進程
Slice:進程組
2.Unit 的配置文件
每一個 Unit 都有一個配置文件,告訴 systemd 怎么啟動這個 Unit 。系統管理員的任務就是編寫和維護這寫不同的配置文件。
systemd 默認從目錄 /etc/systemd/system/ 讀取配置文件。但是里面存放的大部分文件都是符號鏈接,指向目錄 /usr/lib/systemd/system/ 內的配置文件,該目錄是配置文件存放的真正目錄。
配置文件的后綴名,就是該 Unit 的種類,比如 sshd.socket。
- 如果省略,systemd 默認后綴名為.service,所以 sshd 會被理解成sshd.service。
- 掛載點會自動轉化為相應的 .mount 單元。例如 /home 等價于 home.mount。
- 設備會自動轉化為相應的 .device 單元,所以 /dev/sda2 等價于 dev-sda2.device。
一旦修改配置文件,就要讓 systemd 重新加載配置文件,然后重新啟動,否則修改不會生效,例如:
$ sudo systemctl daemon-reload $ sudo systemctl restart httpd.service注: 有一些單元的名稱包含一個 @ 標記, (e.g. name@string.service): 這意味著它是模板單元 name@.service 的一個 實例。 string 被稱作實例標識符, 在 systemctl 調用模板單元時,會將其當作一個參數傳給模板單元,模板單元會使用這個傳入的參數代替模板中的 %I 指示符。 在實例化之前,systemd 會先檢查 name@string.suffix 文件是否存在(如果存在,應該就是直接使用這個文件,而不是模板實例化了)。大多數情況下,包含 @ 標記都意味著這個文件是模板。如果一個模板單元沒有實例化就調用,該調用會返回失敗,因為模板單元中的 %I 指示符沒有被替換。
systemd 單元文件的語法來源于 XDG 桌面入口配置文件.desktop文件,最初的源頭則是Microsoft Windows的.ini文件。單元文件可以從兩個地方加載,優先級從高到低分別是:
- /etc/systemd/system/: 系統管理員安裝的單元
- /usr/lib/systemd/system/: 軟件包安裝的單元
注意: 當systemd運行在用戶模式下時,使用的加載路徑是完全不同的。
單元文件的語法,可以參考系統已經安裝的單元,也可以參考man systemd.service中的Examples章節。
小貼士: 以 # 開頭的注釋可能也能用在 unit-files 中, 但是只能在新行中使用。 不要在 systemd 的參數后面使用行末注釋, 否則 unit 將會啟動失敗。
(1)配置文件的狀態
一共有四種:
enabled:已建立啟動鏈接
disabled:沒建立啟動鏈接
static:該配置文件沒有 [Install] 部分(無法執行),只能作為其他配置文件的依賴
masked:該配置文件被禁止建立啟動鏈接
(2)配置文件的格式
配置文件就是普通的文本文件,可以用文本編輯器打開。systemctl cat 命令可以查看配置文件的內容。
$ systemctl cat atd.service[Unit] Description=ATD daemon[Service] Type=forking ExecStart=/usr/bin/atd[Install] WantedBy=multi-user.target從上面的輸出可以看到,配置文件分成幾個區塊。每個區塊的第一行,是用方括號表示的區別名,比如 [Unit]。注意,配置文件的區塊名和字段名,都是大小寫敏感的。
每個區塊內部是一些等號連接的鍵值對。
[Section] Directive1=value Directive2=value . . .注意,鍵值對的等號兩側不能有空格。
(4)配置文件的區塊
1)[Unit]區塊
[Unit]區塊通常是配置文件的第一個區塊,用來定義 Unit 的元數據,以及配置與其他 Unit 的關系。它的主要字段如下。
Description:一些簡短描述,顯示給用戶界面看的,可以是任何字符串,一般是關于服務的說明。
Documentation:指定參考文檔的地址列表,以空格分開的 URI 形式,如http://, https://, file:, info:, man:,這是有順序的,最好是先解釋這個服務的目的是什么,然后是它是如何配置的,再然后是其它文件,這個選項可以多次指定,會將多行的合并,如果指定了一個空的,那么會重置此項,前的配置不在起作用。
Requires:當前 Unit 依賴的其他 Unit,如果它們沒有運行,當前 Unit 會啟動失敗。指定此服務依賴的其它服務,如果本服務被激活,那么 Requires 后面的服務也會被激活,反之,如果 Requires 后面的服務被停止或無法啟動,則本服務也會停止。這個選項可以指定多次,那么就要求所有指定的服務都被激活。需要注意的是這個選項不影響啟動或停止的順序,啟動順序使用單句的 After= 和 Before= 來配置。例如,如果 foo.service 依賴 bar.serivce,但是只配置了 Requires= 而沒有 After= 或 Before=,那么 foo.service 啟動時會同時激活 foo.service 和 bar.service。通常使用 Wants= 代替 Requires= 是更好的選擇,因為系統會更好的處理服務失敗的情況。注意,這種依賴關系,也可以在文件之外來處理,即使用 .requires/ 目錄,可以參看上面的說明。
RequiresOverridable:類似上面的 Requires,不過這種情況下,只要用戶明確要求它啟動,才會影響到被依賴的服務,不然服務出錯什么的,不會影響被依賴服務的啟動。
Requisite 和 RequisiteOverridable:分別類似上面的兩個,不過如果是這個指定服務沒有啟動,被依賴的服務會不啟動,立即失敗。
Wants:與當前 Unit 配合的其他 Unit,如果它們沒有運行,當前 Unit 不會啟動失敗。相對弱化的依賴,這里列出的服務會被啟動,但如果無法啟動或無法添加到事務處理,并不影響本服務做為一個整體的啟動。這是推薦的兩個服務關聯的方式。這種依賴也可以配置文件外,通過 .wants/ 目錄添加,具體可以看上面的說明。
BindsTo:與Requires類似,它指定的 Unit 如果退出,會導致當前 Unit 停止運行,即如果它后面列出的服務停止運行或崩潰之類的,本服務也會同時停止。
PartOf:又一個類似 Requires 的選項,但是限制在停止或重啟動服務,如果這里列出的服務被停止或重啟動,那么本服務也會停止或重啟動,注意這個依賴是意向,即本服務停止或重啟動,不會影響到這里列出服務的運行狀態。
Before:如果該字段指定的 Unit 也要啟動,那么必須在當前 Unit 之后啟動。比如一個 foo.service 包含了一行 Before=bar.service,那么當他們同時啟動時,bar.service 會等待 foo.service 啟動完成后才啟動。注意這個設置和 Requires= 的相互獨立的,同時包含 After= 和 Requires= 也是常見的。此選項可以指定一次以上,這時是按順序全部啟動。
After:如果該字段指定的 Unit 也要啟動,那么必須在當前 Unit 之前啟動
Conflicts:這里指定的 Unit 不能與當前 Unit 同時運行,配置一個依賴沖突,當 A 服務啟動時,B 服務停止,反過來,B 服務啟動,那么 A 就會停止。注意,此設置和 After= 和 Before= 是互相獨立的。如果服務 A 和 B 沖突,且在 B 啟動的時候同時啟動,那么有可能會啟動失敗。
Condition:當前 Unit 運行必須滿足的條件,否則不會運行
Assert:當前 Unit 運行必須滿足的條件,否則會報啟動失敗
AllowIsolate:布爾值。如果是真值,則此服務可以使用 systemctl isolate 命令進行操作。否則會拒絕此操作。默認值是假。最好的辦法是不要動這處選項,除非目標服務的行為類似于 SysV 啟動系統中的 runlevels。只是一種預防措施,避免系統無法使用的狀態。默認值是假。
OnFailure:列出一個或更多的服務,當本服務啟動狀態是 failed 的時候,激活這些服務。
PropagatesReloadTo 和 ReloadPropagatedFrom:這兩個是列出一些服務,當其它服務 reload 時同時 reload 這個服務,或者反之。
RequiresMountsFor:用空格分開的絕對路徑列表,是 Requires 和 After 添加的依賴中的 mount 文件需要訪問的指定的路徑。
OnFailureIsolate:是一個布爾值,如果是真,那么 OnFailure 后面的服務會進入隔離模式,即所有不是它依賴的服務都會停止。如果只設置一個服務,可以放在 OnFailure 后,默認值是假。
IgnoreOnIsolate:一個布爾值.如果是真則當隔離其它服務時本服務不會停止,默認是假。
IgnoreOnSnapshot:一個布爾值.如果是真則本服務不包含快照(snapshots)。對 device 和 snapshot 服務默認為真,其它服務默認為假。
StopWhenUnneeded:一個布爾值。如果是真則當本服務不使用時會停止。 注意,為了盡量減少 systemd 的工作,默認情況下是不會停止不使用的服務的,除非和其它服務沖突,或用戶明確要求停止。如果設置了這個選項,那么如果沒有其它活動的服務需要此服務,它會自動停止。默認值是假。
RefuseManualStart 和 RefuseManualStop:布爾值。如果設為真值,則此服務只能間接的激活或停止。這種情況下,用戶直接啟動或停止此服務會被拒絕,只有做為其它的服務依賴關系,由其它服務進行啟動或停止才可以。這主要是為了停止用戶誤操作。默認值是假。
DefaultDependencies:布爾值。如果是真(默認值),一些本服務默認的依賴會隱式的建立,具體是哪些依賴,則于服務的類型決定。比如,對于普通的服務(.service類型),它會確保在系統基本服務啟動后才啟動本服務,會在系統關機前確保本服務已關閉。一般來說,只有早期開機服務和后期的關機服務,才需要把這個設成假。強烈對大多數普通服務,讓這個選項啟用即可。如果設成假,也不會禁用所有的隱式依賴,只是禁用那些非必要的。
JobTimeoutSec:當一個客戶端等待本服務的某個 Job 完成時,所指定的超時時間。如果達到了限制的時間,此 Job 會取消運行,但服務不會更改狀態,包括進入“failed”狀態。除了設備服務(即.device類型),其它的默認值是0(即沒有超時設置)。注意,這個是獨立于特定服務所設置的超時設置的(比如對 .service 類型所設置的 Timeout=),它對服務本身沒有影響,但特定服務的設置是有影響的(能用來更改服務狀態)。
SourcePath:這個服務生成的配置文件所在的路徑,這主要是用在生成工具從外部配置文件的格式轉換到本地服務的配置格式中。因此,對一般的服務不要使用此選項。
接下來幾個以 Condition 開頭的字段一組類似的東西。檢測特定的條件是不是真值,如果不是真值,服務會略過啟動,但是它依賴的服務還是會正常運行的。這個條件測試失敗不會讓服務進入失敗狀態。條件是在服務開始運行時檢查的。
ConditionPathExists= 是指定在服務啟動時檢查指定文件的存在狀態。如果指定的絕對路徑名不存在,這個條件的結果就是失敗。如果絕對路徑帶有 ! 前綴,則條件反轉,即只有路徑不存在時服務才啟動。
ConditionPathExistsGlob:類似上面的選項,但支持通配符。
ConditionPathIsDirectory:判斷指定路徑是不是目錄。
ConditionPathIsSymbolicLink:判斷指定路徑是不是鏈接。
ConditionPathIsMountPoint:判斷指定路徑是不是一個掛載點。
ConditionPathIsReadWrite:年指定路徑是否可讀寫(即不是做為只讀系統掛載的)
ConditionDirectoryNotEmpty:判斷指定目錄是否存在且不為空。
ConditionFileNotEmpty:判斷指定文件是否是常規文件且不為空(即大小不是0)。
ConditionFileIsExecutable:判斷指定文件是否是常規文件且可執行。
ConditionKernelCommandLine:是判斷有沒有指定的內核命令行啟動參數(或帶有 ! 取反),這個參數必須是一個單詞或用=分開的兩個單詞,前一種情況下,會尋找內核參數是否有此單詞或是賦值的左邊。后一種情況則必須是賦值的左右同時符合。
ConditionVirtualization:是判斷是不是在虛擬化環境下執行的服務。這可以是個布爾值以判斷是不是任意的虛擬化環境,或者下列的字符串之一: qemu, kvm, vmware, microsoft, oracle, xen, bochs, chroot, openvz, lxc, lxc-libvirt, systemd-nspawn,以判斷是不是特定的虛擬化環境,多重嵌套的虛擬化環境,只判斷最后一層。可以使用!進行反轉判斷。
ConditionSecurity:是判斷系統是否啟用了安全環境,當前僅能識別selinux, apparmor, 和 smack。可以使用!進行反轉判斷。
ConditionCapability:是判斷服務管理器綁定的 capability 是否存在。(可以查看其它部分的詳細信息。)設置為 capability 的名字,比如 CAP_MKNOD。可以通過在前面加!反轉判斷。
ConditionHost:是判斷主機名 (hostname)或機器ID(machine ID)是否匹配。可以加!反轉。
ConditionACPower:是判斷機器是否在使用交流電源。如果設成 true,而只有至少連接一個交流電源時結果才為真,反過來,設成 false,則不連接所有交流電源時才為真。
ConditionNull:是一個常量性質的判斷條件,它應該是布爾值,如果設成 false ,則條件永遠失敗,反過來則永遠成立。
如果指定多個條件,則所有條件都需要成立(即條件之間是 AND 的關系)。條件前面可以加上 | 符號,這時條件變成一個觸發條件,服務定義了觸發條件,那么在滿足其它非觸發條件和這個觸發條件的情況下,服務會至少執行一次。同時指定|和!前綴時,先處理|,后處理!。除了ConditionPathIsSymbolicLink=,其它條件均跟隨鏈接。如果這些條件指定為空,則相當于重置,前面的任何設置都不再起作用。
2)[Service]區塊
[Service]區塊用來 Service 的配置,只有 Service 類型的 Unit 才有這個區塊。它的主要字段如下:
Type:定義啟動時的進程行為。它有以下幾種值。
Type=simple:默認值,執行ExecStart指定的命令,啟動主進程。systemd 認為該服務將立即啟動。服務進程不會fork。如果該服務要啟動其他服務,不要使用此類型啟動,除非該服務是socket激活型。
Type=forking:以 fork 方式從父進程創建子進程,創建后父進程會立即退出。systemd認為當該服務進程fork,且父進程退出后服務啟動成功。對于常規的守護進程(daemon),除非你確定此啟動方式無法滿足需求,使用此類型啟動即可。使用此啟動類型應同時指定 PIDFile=,以便systemd能夠跟蹤服務的主進程。
Type=oneshot:一次性進程,systemd 會等當前服務退出,再繼續往下執行。這一選項適用于只執行一項任務、隨后立即退出的服務。可能需要同時設置 RemainAfterExit=yes 使得 systemd 在服務進程退出之后仍然認為服務處于激活狀態。
Type=dbus:當前服務通過D-Bus啟動。若以此方式啟動,當指定的 BusName 出現在DBus系統總線上時,systemd認為服務就緒。
Type=notify:當前服務啟動完畢,會通知systemd,再繼續往下執行。與 Type=simple 相同,但約定服務會在就緒后向 systemd 發送一個信號。這一通知的實現由 libsystemd-daemon.so 提供。
Type=idle:若有其他任務執行完畢,當前服務才會運行。systemd會等待所有任務(Jobs)處理完成后,才開始執行idle類型的單元。除此之外,其他行為和Type=simple 類似。
小貼士:type的更多解釋可以參考 systemd.service(5)。
ExecStart:啟動當前服務的命令
ExecStartPre:啟動當前服務之前執行的命令
ExecStartPost:啟動當前服務之后執行的命令
ExecReload:重啟當前服務時執行的命令
ExecStop:停止當前服務時執行的命令
ExecStopPost:停止當其服務之后執行的命令
RestartSec:自動重啟當前服務間隔的秒數
Restart:定義何種情況 systemd 會自動重啟當前服務,可能的值包括always(總是重啟)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
TimeoutSec:定義 systemd 停止當前服務之前等待的秒數
Environment:指定環境變量
3)[Install]區塊
[Install]通常是配置文件的最后一個區塊,用來定義如何啟動,以及是否開機啟動。這個段的內容服務的安裝信息。它不在 systemd 的運行期間使用。只在使用 systemctl enable 和 systemctl disable 命令啟用/禁用服務時有用。
它的主要字段如下:
WantedBy 和 RequiredBy:在 .wants/ 或 .requires/ 子目錄中為服務建立相應的鏈接。這樣做的效果是當列表中的服務啟動,本服務也會啟動。 在 bar.service 中的 WantedBy=foo.service 和 Alias=foo.service.wants/bar.service 基本是一個意思。
WantedBy:它的值是一個或多個 Target,當前 Unit 激活時(enable)符號鏈接會放入/etc/systemd/system目錄下面以 Target 名 + .wants后綴構成的子目錄中
RequiredBy:它的值是一個或多個 Target,當前 Unit 激活時,符號鏈接會放入/etc/systemd/system目錄下面以 Target 名 + .required后綴構成的子目錄中
Alias:當前 Unit 可用于啟動的別名。在安裝使用應該使用的別名。名字必須和服務本身有同樣的后綴(即同樣的類型)。這個選項可以指定多次,所有的名字都起作用,當執行 systemctl enable 命令時,會建立相當的鏈接。
Also:當前 Unit 激活(enable)時,會被同時激活的其他 Unit。當此服務安裝時同時需要安裝的附加服務。 如果用戶請求安裝的服務中配置了此項,則 systemctl enable 命令執行時會自動安裝本項所指定的服務。
Unit 配置文件的完整字段清單,請參考官方文檔。
A.替換符
在 [Install] 小節的選項中,可以使用如下替換符: %n, %N, %p, %i, %j, %g, %G, %U, %u, %m, %H, %b, %v 。 在許多選項中都可以使用一些替換符(不只是 [Install] 小節中的選項), 以引用一些運行時才能確定的值, 從而可以寫出更通用的單元文件。 替換符必須是已知的、并且是可以解析的,這樣設置才能生效。 當前可識別的所有替換符及其解釋如下:
| “%b” | 系統的"Boot ID"字符串。參見 random(4) 手冊 |
| “%C” | 緩存根目錄。對于系統實例來說是 /var/cache ;對于用戶實例來說是 “$XDG_CACHE_HOME” |
| “%E” | 配置根目錄。對于系統實例來說是 /etc ;對于用戶實例來說是 “$XDG_CONFIG_HOME” |
| “%f” | 原始單元文件名稱(不含路徑,且遵守前文描述的已轉義絕對文件系統路徑的還原規則)。對于實例化的單元,就是帶有 / 前綴的原始實例名;對于其他單元,就是帶有 / 前綴的原始前綴名。 |
| “%h” | 用戶的家目錄。運行 systemd 實例的用戶的家目錄,對于系統實例則是 “/root” |
| “%H” | 系統的主機名(hostname) |
| “%i” | 已轉義的實例名稱。對于實例化單元,就是 “@” 和后綴之間的部分。對于非實例化單元則為空。 |
| “%I” | 原始實例名稱。對于實例化單元,就是 “@” 和后綴之間的部分(已還原的)。對于非實例化單元則為空。 |
| “%j” | 已轉義的前綴名最后一部分。也就是前綴名中最后一個 “-” 之后的部分。如果沒有 “-” 那么與 “%p” 相同。 |
| “%J” | 原始前綴名最后一部分。也就是前綴名中最后一個 “-” 之后的部分(已還原的)。如果沒有 “-” 那么與 “%p” 相同。 |
| “%L” | 日志根目錄。對于系統實例來說是 /var/log ;對于用戶實例來說是 “$XDG_CONFIG_HOME”/log |
| “%m” | 系統的"Machine ID"字符串。參見 machine-id(5) 手冊 |
| “%n” | 帶類型后綴的完整單元名稱 |
| “%N” | 無類型后綴的完整單元名稱 |
| “%p” | 已轉義的前綴名稱。對于實例化單元來說,就是單元名稱里第一個 “@” 之前的字符串。對于非實例化單元來說,等價于 “%N” |
| “%P” | 原始前綴名稱。對于實例化單元來說,就是單元名稱里第一個 “@” 之前的字符串(已還原的)。對于非實例化單元來說,等價于 “%N” |
| “%s” | 用戶的shell。運行 systemd 實例的用戶的shell,對于系統實例則是 “/bin/sh” |
| “%S” | 狀態根目錄。對于系統實例來說是 /var/lib ;對于用戶實例來說是 “$XDG_CONFIG_HOME” |
| “%t” | 運行時根目錄。對于系統實例來說是 /run ;對于用戶實例來說是 “$XDG_RUNTIME_DIR” |
| “%T” | 臨時文件目錄。也就是 /tmp 或 “$TMPDIR”, “$TEMP”, “$TMP” 之一(若已設置) |
| “%g” | 運行 systemd 用戶實例的組名稱。對于 systemd 系統實例來說,則是 “root” |
| “%G” | 運行 systemd 用戶實例的組GID。對于 systemd 系統實例來說,則是 “0” |
| “%u” | 運行 systemd 用戶實例的用戶名稱。對于 systemd 系統實例來說,則是 “root” |
| “%U” | 運行 systemd 用戶實例的用戶UID。對于 systemd 系統實例來說,則是 “0” |
| “%v” | 內核版本(uname -r 的輸出) |
| “%V” | 存放大體積臨時文件以及持久臨時文件的目錄。也就是 /var/tmp 或 “$TMPDIR”, “$TEMP”, “$TMP” 之一(若已設置) |
| “%%” | 百分號自身(%)。使用 “%%” 表示一個真正的 “%” 字符。 |
3.Unit 的依賴管理
很多服務之間是有依賴關系的,systemd 的一大亮點就是可以管理 unit 之間的依賴關系。我們可以通過下面的命令來查看 unit 間的依賴關系:
systemctl list-dependencies [unit] [–reverse],選項 --reverse 會反向追蹤是誰在使用這個 unit。
下面讓我們看看 graphical.target 的依賴關系:
[root@htlwk0001host ~]# systemctl list-dependencies multi-user.target multi-user.target ● ├─aegis.service ● ├─aliyun.service ● ├─AssistDaemon.service系統當前運行在 multi-user.target 下,它有一個長長的依賴列表(上面僅僅截取了部分項目),其中有一個依賴項目為 aliyun.service。下面我們使用 --reverse 選項查看 aliyun.service unit 被誰使用:
[root@htlwk0001host ~]# systemctl list-dependencies --reverse aliyun.service aliyun.service ● └─multi-user.target ● └─graphical.target上面可以看到,aliyun.service 被 multi-user.target 使用,而 multi-user.target 被 graphical.target 使用,換句話說,multi-user.target 依賴于 aliyun.service,而 graphical.target 又依賴于 multi-user.target。
列出一個 Unit 的所有依賴:
$ systemctl list-dependencies nginx.service有些依賴是 Target 類型,默認不會展開顯示。如果要展開 Target,就需要使用 --all 參數:
$ systemctl list-dependencies --all nginx.service(五)systemd 的 Target 介紹
啟動計算機的時候,需要啟動大量的 Unit。如果每一次啟動,都要一一寫明本次啟動需要哪些 Unit,顯然非常不方便。systemd 的解決方案就是 Target。
簡單說,Target 就是一個 Unit 組,包含許多相關的 Unit 。啟動某個 Target 的時候,systemd 就會啟動里面所有的 Unit。從這個意義上說,Target 這個概念類似于"狀態點",啟動某個 Target 就好比啟動到某種狀態。
使用命令 systemctl enable 設置開機自啟時,/usr/lib/systemd/system 下的 mysqld.service 就被加入到目錄 /etc/systemd/system 下的子目錄 multi-user.target.wants 中。效果如下面的語句:
Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld.service to /usr/lib/systemd/system/mysqld.service.傳統的 init 啟動模式里面,有 Run Level 的概念,跟 Target 的作用很類似。不同的是,Run Level 是互斥的,不可能多個 Run Level 同時啟動,但是多個 Target 可以同時啟動。
systemd 使用 Target 取代了 System V 的運行級的概念。在 systemd 中,默認運行級別由 /etc/systemd/system/default.target 定義,這個文件本身是一個軟連接,如果它指向 graphical.targer 那么默認的運行級別就是圖形界面。
備注:Target 類型的 Unit 也可以理解為系統環境,當運行或切換個環境時往往會伴隨著啟動很多其他的 Unit 用以支持這個環境,最常見的環境就是字符界面(multi-user.target)和圖形界面(graphical.target)
1.查看當前系統的所有 Target
[root@htlwk0001host ~]# systemctl list-unit-files --type=target UNIT FILE STATE basic.target static bluetooth.target static cloud-config.target static cloud-init.target enabled-runtime cryptsetup-pre.target static2.查看一個 Target 包含的所有 Unit
[root@htlwk0001host ~]# systemctl list-dependencies multi-user.target3.查看啟動時的默認 Target
[root@htlwk0001host ~]# systemctl get-default4.設置啟動時的默認 Target
[root@htlwk0001host ~]# sudo systemctl set-default multi-user.target如果需要將系統默認運行的目標修改為“多用戶,無圖形”模式,可以直接用 ln 命令把多用戶模式目標文件連接到 /etc/systemd/system/ 目錄:
[root@htlwk0001host ~]# ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target5.切換 Target
切換 Target 時,默認不關閉前一個 Target 啟動的進程,
[root@htlwk0001host ~]# systemctl isolate multi-user.target6.Target 與 傳統 Run Level 的對應關系
Traditional runlevel New target name Symbolically linked to...Runlevel 0 | runlevel0.target -> poweroff.target 關閉系統 Runlevel 1 | runlevel1.target -> rescue.target 救援模式,單用戶模式 Runlevel 2 | runlevel2.target -> multi-user.target 多用戶,無圖形模式,字符界面,標準模式,即命令行模式 Runlevel 3 | runlevel3.target -> multi-user.target 多用戶,無圖形模式,字符界面,標準模式,即命令行模式 Runlevel 4 | runlevel4.target -> multi-user.target 多用戶,無圖形模式,字符界面,標準模式,即命令行模式 Runlevel 5 | runlevel5.target -> graphical.target 多用戶,圖形化模式 Runlevel 6 | runlevel6.target -> reboot.target 重啟系統(六)systemd 并行啟動原理
在 systemd 中,所有的服務都并發啟動,比如 Avahi、D-Bus、livirtd、X11、HAL 可以同時啟動。乍一看,這似乎有點兒問題,比如 Avahi 需要 syslog 的服務,Avahi 和 syslog 同時啟動,假設 Avahi 的啟動比較快,所以 syslog 還沒有準備好,可是 Avahi 又需要記錄日志,這豈不是會出現問題?
systemd 的開發人員仔細研究了服務之間相互依賴的本質問題,發現所謂依賴可以分為三個具體的類型,而每一個類型實際上都可以通過相應的技術解除依賴關系。
并發啟動原理之一:解決 socket 依賴
絕大多數的服務依賴是套接字依賴。比如服務 A 通過一個套接字端口 S1 提供自己的服務,其他的服務如果需要服務 A,則需要連接 S1。因此如果服務 A 尚未啟動,S1 就不存在,其他的服務就會得到啟動錯誤。所以傳統地,人們需要先啟動服務 A,等待它進入就緒狀態,再啟動其他需要它的服務。systemd 認為,只要我們預先把 S1 建立好,那么其他所有的服務就可以同時啟動而無需等待服務 A 來創建 S1 了。如果服務 A 尚未啟動,那么其他進程向 S1 發送的服務請求實際上會被 Linux 操作系統緩存,其他進程會在這個請求的地方等待。一旦服務 A 啟動就緒,就可以立即處理緩存的請求,一切都開始正常運行。
那么服務如何使用由 init 進程創建的套接字呢?
Linux 操作系統有一個特性,當進程調用 fork 或者 exec 創建子進程之后,所有在父進程中被打開的文件句柄 (file descriptor) 都被子進程所繼承。套接字也是一種文件句柄,進程 A 可以創建一個套接字,此后當進程 A 調用 exec 啟動一個新的子進程時,只要確保該套接字的 close_on_exec 標志位被清空,那么新的子進程就可以繼承這個套接字。子進程看到的套接字和父進程創建的套接字是同一個系統套接字,就仿佛這個套接字是子進程自己創建的一樣,沒有任何區別。
這個特性以前被一個叫做 inetd 的系統服務所利用。Inetd 進程會負責監控一些常用套接字端口,比如 Telnet,當該端口有連接請求時,inetd 才啟動 telnetd 進程,并把有連接的套接字傳遞給新的 telnetd 進程進行處理。這樣,當系統沒有 telnet 客戶端連接時,就不需要啟動 telnetd 進程。Inetd 可以代理很多的網絡服務,這樣就可以節約很多的系統負載和內存資源,只有當有真正的連接請求時才啟動相應服務,并把套接字傳遞給相應的服務進程。
和 inetd 類似,systemd 是所有其他進程的父進程,它可以先建立所有需要的套接字,然后在調用 exec 的時候將該套接字傳遞給新的服務進程,而新進程直接使用該套接字進行服務即可。
并發啟動原理之二:解決 D-Bus 依賴
D-Bus 是 desktop-bus 的簡稱,是一個低延遲、低開銷、高可用性的進程間通信機制。它越來越多地用于應用程序之間通信,也用于應用程序和操作系統內核之間的通信。很多現代的服務進程都使用D-Bus 取代套接字作為進程間通信機制,對外提供服務。比如簡化 Linux 網絡配置的 NetworkManager 服務就使用 D-Bus 和其他的應用程序或者服務進行交互:郵件客戶端軟件 evolution 可以通過 D-Bus 從 NetworkManager 服務獲取網絡狀態的改變,以便做出相應的處理。
D-Bus 支持所謂"bus activation"功能。如果服務 A 需要使用服務 B 的 D-Bus 服務,而服務 B 并沒有運行,則 D-Bus 可以在服務 A 請求服務 B 的 D-Bus 時自動啟動服務 B。而服務 A 發出的請求會被 D-Bus 緩存,服務 A 會等待服務 B 啟動就緒。利用這個特性,依賴 D-Bus 的服務就可以實現并行啟動。
并發啟動原理之三:解決文件系統依賴
系統啟動過程中,文件系統相關的活動是最耗時的,比如掛載文件系統,對文件系統進行磁盤檢查(fsck),磁盤配額檢查等都是非常耗時的操作。在等待這些工作完成的同時,系統處于空閑狀態。那些想使用文件系統的服務似乎必須等待文件系統初始化完成才可以啟動。但是 systemd 發現這種依賴也是可以避免的。
systemd 參考了 autofs 的設計思路,使得依賴文件系統的服務和文件系統本身初始化兩者可以并發工作。autofs 可以監測到某個文件系統掛載點真正被訪問到的時候才觸發掛載操作,這是通過內核 automounter 模塊的支持而實現的。比如一個 open()系統調用作用在"/misc/cd/file1"的時候,/misc/cd 尚未執行掛載操作,此時 open()調用被掛起等待,Linux 內核通知 autofs,autofs 執行掛載。這時候,控制權返回給 open()系統調用,并正常打開文件。
systemd 集成了 autofs 的實現,對于系統中的掛載點,比如/home,當系統啟動的時候,systemd 為其創建一個臨時的自動掛載點。在這個時刻/home 真正的掛載設備尚未啟動好,真正的掛載操作還沒有執行,文件系統檢測也還沒有完成。可是那些依賴該目錄的進程已經可以并發啟動,他們的 open()操作被內建在 systemd 中的 autofs 捕獲,將該 open()調用掛起(可中斷睡眠狀態)。然后等待真正的掛載操作完成,文件系統檢測也完成后,systemd 將該自動掛載點替換為真正的掛載點,并讓 open()調用返回。由此,實現了那些依賴于文件系統的服務和文件系統本身同時并發啟動。
當然對于"/"根目錄的依賴實際上一定還是要串行執行,因為 systemd 自己也存放在/之下,必須等待系統根目錄掛載檢查好。
不過對于類似/home 等掛載點,這種并發可以提高系統的啟動速度,尤其是當/home 是遠程的 NFS 節點,或者是加密盤等,需要耗費較長的時間才可以準備就緒的情況下,因為并發啟動,這段時間內,系統并不是完全無事可做,而是可以利用這段空余時間做更多的啟動進程的事情,總的來說就縮短了系統啟動時間。
(七)systemd 配置使用
1.對于系統開發人員
開發人員需要了解 systemd 的更多細節。比如您打算開發一個新的系統服務,就必須了解如何讓這個服務能夠被 systemd 管理。這需要您注意以下這些要點:
(1)后臺服務進程代碼不需要執行兩次派生來實現后臺精靈進程,只需要實現服務本身的主循環即可。
(2)不要調用 setsid(),交給 systemd 處理。
(3)不再需要維護 pid 文件。
(4)systemd 提供了日志功能,服務進程只需要輸出到 stderr 即可,無需使用 syslog。
(5)處理信號 SIGTERM,這個信號的唯一正確作用就是停止當前服務,不要做其他的事情。
(6)SIGHUP 信號的作用是重啟服務。
(7)需要套接字的服務,不要自己創建套接字,讓 systemd 傳入套接字。
(8)使用 sd_notify()函數通知 systemd 服務自己的狀態改變。一般地,當服務初始化結束,進入服務就緒狀態時,可以調用它。
對于開發者來說,工作量最大的部分應該是編寫配置單元文件,定義所需要的單元。
舉例來說,開發人員開發了一個新的服務程序,比如 httpd,就需要為其編寫一個配置單元文件以便該服務可以被 systemd 管理,類似 UpStart 的工作配置文件。在該文件中定義服務啟動的命令行語法,以及和其他服務的依賴關系等。
此外我們之前已經了解到,systemd 的功能繁多,不僅用來管理服務,還可以管理掛載點,定義定時任務等。這些工作都是由編輯相應的配置單元文件完成的。我在這里給出幾個配置單元文件的例子。
服務配置單元文件以 .service 為文件名后綴,下面是 SSH 服務的配置單元文件:
[root@htlwk0001host ~]# cat /etc/system/system/sshd.service[Unit]Description=OpenSSH server daemon[Service]EnvironmentFile=/etc/sysconfig/sshdExecStartPre=/usr/sbin/sshd-keygenExecStart=/usrsbin/sshd –D $OPTIONSExecReload=/bin/kill –HUP $MAINPIDKillMode=processRestart=on-failureRestartSec=42s[Install]WantedBy=multi-user.target文件分為三個小節:
第一部分是[Unit],這里僅僅有一個描述信息。
第二部分是[Service] ,對服務進行相關的定義。其中,ExecStartPre 定義啟動服務之前應該運行的命令;ExecStart 定義啟動服務的具體命令行語法。
第三部分是[Install],WangtedBy 表明這個服務是在多用戶模式下所需要的。
那我們再就來看下 multi-user.target:
[root@htlwk0001host ~]# cat multi-user.target[Unit]Description=Multi-User SystemDocumentation=man.systemd.special(7)Requires=basic.targetConflicts=rescue.service rescure.targetAfter=basic.target rescue.service rescue.targetAllowIsolate=yes[Install]Alias=default.target第一部分中的 Requires 定義表明 multi-user.target 啟動的時候 basic.target 也必須被啟動;另外 basic.target 停止的時候,multi-user.target 也必須停止。如果您接著查看 basic.target 文件,會發現它又指定了 sysinit.target 等其他的單元必須隨之啟動。同樣 sysinit.target 也會包含其他的單元。采用這樣的層層鏈接的結構,最終所有需要支持多用戶模式的組件服務都會被初始化啟動好。
在[Install]小節中有 Alias 定義,即定義本單元的別名,這樣在運行 systemctl 的時候就可以使用這個別名來引用本單元。這里的別名是 default.target,比 multi-user.target 要簡單一些。
此外在/etc/systemd/system 目錄下還可以看到諸如*.wants 的目錄,放在該目錄下的配置單元文件等同于在[Unit]小節中的 wants 關鍵字,即本單元啟動時,還需要啟動這些單元。比如您可以簡單地把您自己寫的 foo.service 文件放入 multi-user.target.wants 目錄下,這樣每次都會被默認啟動了。
最后,讓我們來看看 sys-kernel-debug.mout 文件,這個文件定義了一個文件掛載點:
[root@htlwk0001host ~]# cat sys-kernel-debug.mount [Unit] Description=Debug File Syste DefaultDependencies=no ConditionPathExists=/sys/kernel/debug Before=sysinit.target [Mount] What=debugfs Where=/sys/kernel/debug Type=debugfs這個配置單元文件定義了一個掛載點。掛載配置單元文件有一個[Mount]配置小節,里面配置了 What,Where 和 Type 三個數據項。這都是掛載命令所必須的,例子中的配置等同于下面這個掛載命令:
[root@htlwk0001host ~]# mount –t debugfs /sys/kernel/debug debugfs配置單元文件的編寫需要很多的學習,必須參考 systemd 附帶的 man 等文檔進行深入學習。希望通過上面幾個小例子,大家已經了解配置單元文件的作用和一般寫法了。
2.對于系統管理員
作為系統管理員必須非常熟悉系統服務和 init 系統的管理,否則請自動辭職。比如 service、chkconfig 以及 telinit 命令的使用。而使用 systemd 作為初始化系統的 Linux 系統則是使用命令 systemctl 來管理和控制系統服務,systemctl 和舊命令存在較大的語法差別,所以作為系統管理員必須牢記其中的差別,能夠做到在新舊系統靈活切換。
其實 systemctl 只是 systemd 的主命令,還有幾個較為常用的命令如下:
(1)hostnamectl:用于查看當前主機的信息。
(2)localectl:用于查看本地化設置。
(3)timedatectl:用于查看當前時區設置。
(4)loginctl:用于查看當前登錄的用戶。
(八)日志管理
systemd 統一管理所有 Unit 的啟動日志。帶來的好處就是,可以只用 journalctl一個命令,查看所有日志(內核日志和應用日志)。日志的配置文件是 /etc/systemd/journald.conf。
# 查看所有日志(默認情況下 ,只保存本次啟動的日志) $ 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 httpd.service -o json-pretty# 顯示日志占據的硬盤空間 $ sudo journalctl --disk-usage# 指定日志文件占據的最大空間 $ sudo journalctl --vacuum-size=1G# 指定日志文件保存多久 $ sudo journalctl --vacuum-time=1years二、使用命令 systemctl 管理系統服務
(一)命令介紹
我們知道使用 SysV 或者 UpStart 初始化的 Linux 發行版(例如:Red Hat 旗下的 7.0 版本之前的CentOS)都是使用命令 service 和 chkconfig 來管理系統服務,而使用 systemd 作為 Init System 的Linux 發行版(例如:7.0 版本之后的CentOS)則是使用新的管理命令 systemctl 來啟動、停止、重啟、禁用、查看系統服務,該命令集成了命令 service、chkconfig、setup、init 的大部分功能于一身。
systemctl 命令有兩大類功能:
備注:為了向前兼容,舊命令 service 在新版本的 Linux 中仍然可以使用,只是會被重定向到新的 systemctl 工具
(二)命令選項
systemctl 提供了一組子命令(命令選項)來管理單個的 unit,其命令格式為: systemctl <command> <unit>。unit 是指服務單元,就是指服務進程。命令選項如下:
| start | 立刻啟動后面接的 unit |
| stop | 立刻關閉后面接的 unit |
| restart | 立刻關閉后啟動后面接的 unit,亦即執行 stop 再 start 的意思 |
| reload | 不關閉 unit 的情況下,重新載入配置文件,讓設置生效 |
| enable | 設置下次開機時,后面接的 unit 會被啟動 |
| disable | 設置下次開機時,后面接的 unit 不會被啟動 |
| status | 目前后面接的這個 unit 的狀態,會列出有沒有正在執行、開機時是否啟動等信息 |
| is-active | 目前有沒有正在運行中 |
| is-enable | 開機時有沒有默認啟動這個 unit |
| kill | 向運行 unit 的進程發送終止信號 |
| show | 列出 unit 的配置 |
| mask | 注銷 unit,注銷后你就無法啟動這個 unit 了 |
| unmask | 取消對 unit 的注銷 |
| list-dependencies | 添加選項 --reverse 會反向追蹤是誰在使用這個 unit |
| list-units | 列出當前所有已啟動的服務,如果添加 -all 選項會同時列出沒有啟動的服務,添加 --type 可以過濾某個類型的 unit |
| list-unit-files | 根據 /lib/systemd/system/ 目錄內的文件列出所有的 uni |
| get-default | 取得目前的操作模式(target) |
| set-default | 設置后面接的 target 成為默認的操作模式 |
| isolate | 切換到后面接的模式 |
| poweroff | 系統關機,systemctl poweroff 關機(相當于 systemctl isolate poweroff.target) |
| reboot | 重啟系統 |
| suspend | 進入暫停模式,即待機模式,將系統數據寫入內存,同時將大部分硬件關閉,等待喚醒(相當于Windows下的睡眠) |
| hibernate | 進入休眠模式,將系統數據寫入硬盤,然后關機 |
| rescue | 強制進入救援模式 |
| hybrid-sleep | 混合休眠模式(同時休眠到硬盤并待機) |
| emergency | 強制進入緊急救援模式,比救援模式更強更徹底 |
(三)systemd 命令和 SysV init 命令的對比
| systemctl start foo.service | service foo start | 啟動一個服務 |
| systemctl stop foo.service | service foo stop | 停止一個服務 |
| systemctl restart foo.service | service foo restart | 重啟一個服務 |
| systemctl reload foo.service | service foo reload | 重新裝載配置文件而不中斷等待操作 |
| systemctl condrestart foo.service | service foo condrestart | 如果服務正在運行那么重啟它 |
| systemctl status foo.service | service foo status | 查看服務的狀態 |
| systemctl list-unit-files --type=service | ls /etc/rc.d/init.d/ | 列出可以啟動或停止的服務列表 |
| systemctl list-units --type=service | chkconfig --list | 顯示所有已啟動的服務 |
| systemctl enable foo.service | chkconfig foo on 或者 chkconfig --level 3 httpd on | 設置開機時啟動某個服務 |
| systemctl disable foo.service | chkconfig foo off 或者 chkconfig --level 3 httpd off | 取消開機時啟動某個服務 |
| systemctl is-enabled foo.service | chkconfig foo | 查看某個服務是否開機啟動 |
| ls /etc/systemd/system/*.wants/foo.service | chkconfig foo –list | 用來列出該服務在哪些運行級別下啟用和禁用 |
| systemctl daemon-reload | chkconfig foo –add | 重載配置文件,當您創建新服務文件或者變更設置時使用 |
| systemctl isolate multi-user.target 或者 systemctl isolate runlevel3.target 或者 telinit 3 | telinit 3 | 切換至多用戶運行級別 |
(四)命令示例
1.重啟服務
restart
使用選項 restart,如果服務在運行中,它將重啟服務;如果服務不在運行中,它將會啟動服務
2.純重啟 try-restart
使用選項 try-restart,服務若處于運行中則重啟服務:
[root@htlwk0001host ~]# systemctl try-restart httpd.service3.重新加載某個服務的配置文件
使用選項 reload,它會重新加載配置文件
[root@htlwk0001host ~]# systemctl reload httpd.service4.啟動服務
啟動服務
[root@htlwk0001host ~]# systemctl start httpd.service5.停止服務
停止服務
[root@htlwk0001host ~]# systemctl stop httpd.service6.查看服務狀態
查看服務的狀態,我們看看服務 mysqld 的基本信息有些什么:
[root@htlwk0001host ~]# systemctl status mysqld.service ● mysqld.service - MySQL ServerLoaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)Active: active (running) since Fri 2021-04-23 16:11:01 CST; 1 weeks 1 days agoDocs: man:mysqld(8)http://dev.mysql.com/doc/refman/en/using-systemd.htmlProcess: 1069004 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)Process: 1068982 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)Main PID: 1069006 (mysqld)Tasks: 55 (limit: 23070)Memory: 344.2MCGroup: /system.slice/mysqld.service└─1069006 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid4月 23 16:10:59 htlwk0001host systemd[1]: Starting MySQL Server... 4月 23 16:11:01 htlwk0001host systemd[1]: Started MySQL Server.(1)解讀服務狀態信息
第一行是對 mysqld 的基本描述。
第二行是描述操作系統啟動時會不會啟動這個服務,enabled 表示開機時啟動,disabled 表示開機時不啟動。而啟動該服務的配置文件路徑為:/usr/lib/systemd/system/mysqld.service。
第三行是描述服務當前的狀態,active (running) 表示服務正在運行中。如果是 inactive (dead) 則表示服務當前沒有運行。后面則是服務的啟動時間。
第四行提供了關于服務的在線文檔地址。
第七行顯示出該服務的主進程的 ID。
第八行顯示了該服務關聯的任務數量。
第九行顯示了該服務占用的內存大小。
第十行顯示的是 mysqld 的所有子進程。
最后兩行是輸出的日志信息。
(2)關于服務的啟動狀態
關于 unit 的啟動狀態,除了 enable 和 disable 之外還有:
- static:這個 unit 不可以自己啟動,不過可能會被其它的 enabled 的服務來喚醒。
- mask:這個 unit 無論如何都無法被啟動!因為已經被強制注銷。可通過 systemctl unmask 改回原來的狀態。
(3)關于服務的運行狀態
關于 unit 的運行狀態 Active,除了 active 和 inactive 之外還有:
- active (exited):僅執行一次就正常結束的服務,舉例來說,開機或者是掛載時才會進行一次的 quotaon 功能,就是這種模式。Quotaon 不需要一直執行,只在執行一次之后,就交給文件系統去自行處理。通常用 bash shell 寫的小型服務,大多是屬于這種類型。
- active (waiting):正在執行當中,不過還再等待其他的事件才能繼續處理。舉例來說,打印的相關服務就是這種狀態。
7.設置開機啟動某個服務
使用選項 enable 設置開機啟動某個服務
[root@htlwk0001host ~]# systemctl enable mysqld.service開機啟動的原理說明:
MySQL 安裝后會自動在 /usr/lib/systemd/system 添加一個配置文件 mysqld.service。每次開機,systemd 都會默認從 /etc/systemd/system/ 讀取配置文件。 而 systemctl enable 其實就是創建一個從 /etc/systemd/system/ 到 /usr/lib/systemd/system/mysqld.service 的軟鏈接(符號鏈接)。而 mysqld.service 這個 unit 配置文件里的 [Install] 定義了自啟行為,所以 systemctl enable 相當于給服務設置開機自啟。
這也意味著,如果把自己修改后的配置文件放在該目錄,就可以達到覆蓋原始配置的效果。
8.取消某個服務的開機啟動
使用選項 disable 設置開機禁用某個服務,就是取消某個服務的開機啟動
[root@htlwk0001host ~]# systemctl disable httpd.service9.查看某個服務是否開機啟動
[root@htlwk0001host ~]# systemctl is-enabled httpd.service10.查看啟動失敗的服務
[root@htlwk0001host ~]# systemctl –failed11.查看進程是不是在運行中
[root@htlwk0001host ~]# systemctl is-active sshd.service12.查看系統中所有已經啟動的服務
輸入命令 systemctl,相當于 輸入 systemctl list-units
[root@htlwk0001host ~]# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automount loaded active running Arbitrary Executable File Formats File System Automount Point sys-devices-pci0000:00-0000:00:03.0-virtio0-virtio\x2dports-vport0p1.device loaded active plugged /sys/devices/pci0000:00/0000:00:03.0/virtio0/virtio-ports/vport0p1 sys-devices-pci0000:00-0000:00:04.0-virtio1-block-vda-vda1.device loaded active plugged /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1 sys-devices-pci0000:00-0000:00:04.0-virtio1-block-vda.device loaded active plugged /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda sys-devices-pci0000:00-0000:00:05.0-virtio2-net-eth0.device loaded active plugged Virtio network device sys-devices-platform-serial8250-tty-ttyS1.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS1 sys-devices-platform-serial8250-tty-ttyS2.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS2UNIT:項目的名稱,包括各個 unit 的類別(看擴展名)。
LOAD:開機時 unit 的配置是否被加載。
ACTIVE:服務的運行主狀態,active 表示“活著”,inactive 表示“死了”
SUB:服務的運行子狀態,例如:running,表示服務不僅“活著”,還正在“忙碌”呢!
DESCRIPTION:描述信息
13.列出目錄 /lib/systemd/system/ 下的所有 unit
[root@htlwk0001host ~]# systemctl list-unit-files; UNIT FILE STATE proc-sys-fs-binfmt_misc.automount static -.mount generated dev-hugepages.mount static dev-mqueue.mount static proc-sys-fs-binfmt_misc.mount static sys-fs-fuse-connections.mount static sys-kernel-config.mount static sys-kernel-debug.mount static tmp.mount disabled在返回的列表里,顯示每個配置文件的狀態,一共有 4 種:
(1)enabled:已建立啟動鏈接
(2)disabled:沒建立啟動鏈接
(3)static:該配置文件沒有 [Install] 部分(無法執行),只能作為其他配置文件的依賴
(4)masked:該配置文件被禁止建立啟動鏈接
從配置文件的狀態無法看出,該 Unit 是否正在運行。這必須執行前面提到的 systemctl status 命令。
14.只看服務類型的 unit
[root@htlwk0001host ~]# systemctl list-units --type=service UNIT LOAD ACTIVE SUB DESCRIPTION aegis.service loaded active running LSB: aegis update. aliyun.service loaded active running 阿里云助手 AssistDaemon.service loaded active running AssistDaemon atd.service loaded active running Job spooling tools auditd.service loaded active running Security Auditing Service15.查看加載失敗的 unit
[root@htlwk0001host ~]# systemctl --failed 0 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.16.管理系統的操作環境(target unit)
通過指定 --type=target 就可以用 systemctl list-units 命令查看系統中默認有多少種 target:
[root@htlwk0001host ~]# systemctl list-units --type=target -allUNIT LOAD ACTIVE SUB DESCRIPTION basic.target loaded active active Basic System cloud-config.target loaded active active Cloud-config availability cloud-init.target loaded active active Cloud-init target cryptsetup.target loaded active active Local Encrypted Volumes emergency.target loaded inactive dead Emergency Mode getty-pre.target loaded inactive dead Login Prompts (Pre) getty.target loaded active active Login Prompts graphical.target loaded inactive dead Graphical Interface initrd-fs.target loaded inactive dead Initrd File Systems initrd-root-device.target loaded inactive dead Initrd Root Device initrd-root-fs.target loaded inactive dead Initrd Root File System initrd-switch-root.target loaded inactive dead Switch Root initrd.target loaded inactive dead Initrd Default Target local-fs-pre.target loaded active active Local File Systems (Pre) local-fs.target loaded active active Local File Systems multi-user.target loaded active active Multi-User System network-online.target loaded active active Network is Online network-pre.target loaded active active Network (Pre) network.target loaded active active Network nss-lookup.target loaded active active Host and Network Name Lookupsnss-user-lookup.target loaded active active User and Group Name Lookups paths.target loaded active active Paths remote-fs-pre.target loaded inactive dead Remote File Systems (Pre) remote-fs.target loaded active active Remote File Systems rescue.target loaded inactive dead Rescue Mode shutdown.target loaded inactive dead Shutdown slices.target loaded active active Slices sockets.target loaded active active Sockets sshd-keygen.target loaded active active sshd-keygen.target swap.target loaded active active Swap sysinit.target loaded active active System Initialization syslog.target not-found inactive dead syslog.target time-sync.target loaded inactive dead System Time Synchronized timers.target loaded active active Timers umount.target loaded inactive dead Unmount All Filesystems LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type.35 loaded units listed. To show all installed unit files use 'systemctl list-unit-files'.我的服務器主機居然有 34 個 target,在此僅介紹幾個常用的 target:
- graphical.target:就是文字界面再加上圖形界面,這個 target 已經包含了下面的 multi-user.target
- multi-user.target:純文本模式
- rescue.target:在無法使用 root 登陸的情況下,systemd 在開機時會多加一個額外的臨時系統,與你原本的系統無關。這時你可以取得 root 的權限來維護你的系統
- emergency.target:緊急處理系統的錯誤,在無法使用 rescue.target 時,可以嘗試使用這種模式
- shutdown.target:就是執行關機
- getty.target:可以設置 tty 的配置
正常的模式是 multi-user.target 和 graphical.target 兩個,救援方面的模式主要是 rescue.target 以及更嚴重的 emergency.target。如果要修改可提供登陸的 tty 數量,則修改 getty.target。
(1)查看系統目前的操作模式(target)
[root@htlwk0001host ~]# systemctl get-default; multi-user.target(2)設置系統默認的操作模式
[root@htlwk0001host ~]# systemctl set-default multi-user.target(3)切換操作模式
可以在不重新啟動的情況下切換不同的 target,比如從圖形界面切換到純文本的模式(即命令行模式):
[root@htlwk0001host ~]# systemctl isolate multi-user.target切換到圖形模式:
[root@htlwk0001host ~]# systemctl isolate runlevel5.target # 運行等級5或者
[root@htlwk0001host ~]# systemctl isolate graphical.target17.讓系統進入暫停模式
[root@htlwk0001host ~]# systemctl suspend暫停模式會將系統的狀態保存到內存中,然后關閉掉大部分的系統硬件,當然,并沒有實際關機。當用戶按下喚醒機器的按鈕,系統數據會從內存中回復,然后重新驅動被大部分關閉的硬件,所以喚醒系統的速度比較快。
18.讓系統進入休眠模式
[root@htlwk0001host ~]# systemctl hibernate休眠模式則是將系統狀態保存到硬盤當中,保存完畢后,將計算機關機。當用戶嘗試喚醒系統時,系統會開始正常運行,然后將保存在硬盤中的系統狀態恢復回來。因為數據需要從硬盤讀取,因此喚醒的速度比較慢(如果你使用的是 SSD 磁盤,喚醒的速度也是非常快的)。
19.強制系統進入救援模式
[root@htlwk0001host ~]# systemctl rescue20.強制系統進入緊急救援模式
[root@htlwk0001host ~]# systemctl emergency22.重新加載 systemd 程序的配置文件
[root@htlwk0001host ~]# systemctl daemon-reload(1)新添加 unit 配置文件時需要執行 systemctl daemon-reload
(2)有 unit 的配置文件發生變化時也需要執行 systemctl daemon-reload
daemon-reload 命令會做很多的事情,其中之一是重新生成依賴樹(也就是 unit 之間的依賴關系),所以當你修改了 unit 配置文件中的依賴關系后如果不執行 daemon-reload 命令是不會生效的。
23.殺死服務
有時候使用子命令 stop 停止服務可能沒有響應,服務停不下來。這時候就不得不"殺進程"了,向正在運行的進程發出kill信號。
[root@htlwk0001host ~]# systemctl kill mysqld.service24.管理系統掛載點的命令
(1)掛載
[root@htlwk0001host ~]# systemctl start tmp.mount(2)卸載
[root@htlwk0001host ~]# systemctl stop tmp.mount(3)重新掛載
[root@htlwk0001host ~]# systemctl restart tmp.mount(4)重新加載掛載點
[root@htlwk0001host ~]# systemctl reload tmp.mount(5)查看掛載點狀態
[root@htlwk0001host ~]# systemctl status tmp.mount25.查看 systemd 的版本
[root@htlwk0001host ~]# systemctl --version systemd 239 +PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy26.查看系統啟動耗時
[root@htlwk0001host ~]# systemd-analyze Startup finished in 659ms (kernel) + 5.114s (initrd) + 10.495s (userspace) = 16.269s multi-user.target reached after 9.540s in userspace27.查看每個進程在引導時花費的時間
查看每個服務的啟動耗時:
[root@htlwk0001host ~]# systemd-analyze blame5.405s cloud-init-local.service2.875s cloud-init.service2.631s sshd-keygen@rsa.service1.707s dracut-pre-pivot.service1.501s mysqld.service1.095s aegis.service954ms systemd-logind.service28.查看指定服務的關鍵鏈
顯示指定服務的瀑布狀的啟動過程流:
[root@htlwk0001host ~]# systemd-analyze critical-chain httpd.service The time after the unit is active or started is printed after the "@" character. The time the unit takes to start is printed after the "+" character. httpd.service +142ms └─network.target @11.168s └─network.service @9.456s +1.712s └─NetworkManager.service @8.858s +596ms └─firewalld.service @4.931s +3.926s └─basic.target @4.916s └─sockets.target @4.916s └─dbus.socket @4.916s └─sysinit.target @4.905s └─systemd-update-utmp.service @4.864s +39ms └─auditd.service @4.563s +301ms └─systemd-tmpfiles-setup.service @4.485s +69ms └─rhel-import-state.service @4.342s +142ms └─local-fs.target @4.324s └─boot.mount @4.286s +31ms └─systemd-fsck@dev-disk-by\x2duuid-79f594ad\x2da332\x2d4730\x2dbb5f\x2d85d196080964.service @4.092s +149ms └─dev-disk-by\x2duuid-79f594ad\x2da332\x2d4730\x2dbb5f\x2d85d196080964.device @4.092s顯示瀑布狀的啟動過程流:
[root@htlwk0001host ~]# systemd-analyze critical-chain29.獲取服務的依賴項列表
[root@htlwk0001host ~]# systemctl list-dependencies httpd.service httpd.service ├─system.slice └─basic.target ├─firewalld.service ├─microcode.service ├─rhel-autorelabel-mark.service ├─rhel-autorelabel.service ├─rhel-configure.service ├─rhel-dmesg.service ├─rhel-loadmodules.service ├─paths.target ├─slices.target │ ├─-.slice │ └─system.slice ├─sockets.target │ ├─dbus.socket ....30.按層次列出控制組
[root@htlwk0001host ~]# systemd-cgls ├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 23 ├─user.slice │ └─user-0.slice │ └─session-1.scope │ ├─2498 sshd: root@pts/0 │ ├─2500 -bash │ ├─4521 systemd-cgls │ └─4522 systemd-cgls └─system.slice ├─httpd.service │ ├─4440 /usr/sbin/httpd -DFOREGROUND │ ├─4442 /usr/sbin/httpd -DFOREGROUND │ ├─4443 /usr/sbin/httpd -DFOREGROUND │ ├─4444 /usr/sbin/httpd -DFOREGROUND │ ├─4445 /usr/sbin/httpd -DFOREGROUND │ └─4446 /usr/sbin/httpd -DFOREGROUND ├─polkit.service │ └─721 /usr/lib/polkit-1/polkitd --no-debug ....31.根據CPU,內存,輸入和輸出列出控制組
[root@htlwk0001host ~]# systemd-cgtop Path Tasks %CPU Memory Input/s Output/s / 83 1.0 437.8M - - /system.slice - 0.1 - - - /system.slice/mariadb.service 2 0.1 - - - /system.slice/tuned.service 1 0.0 - - - /system.slice/httpd.service 6 0.0 - - - /system.slice/NetworkManager.service 1 - - - - /system.slice/atop.service 1 - - - - /system.slice/atopacct.service 1 - - - - /system.slice/auditd.service 1 - - - - /system.slice/crond.service 1 - - - - /system.slice/dbus.service 1 - - - - /system.slice/firewalld.service 1 - - - - /system.slice/lvm2-lvmetad.service 1 - - - - /system.slice/polkit.service 1 - - - - /system.slice/postfix.service 3 - - - - /system.slice/rsyslog.service 1 - - - - /system.slice/system-getty.slice/getty@tty1.service 1 - - - - /system.slice/systemd-journald.service 1 - - - - /system.slice/systemd-logind.service 1 - - - - /system.slice/systemd-udevd.service 1 - - - - /system.slice/webmin.service 1 - - - - /user.slice/user-0.slice/session-1.scope 3 - - - -32.查看指定類型的 unit
[root@htlwk0001host ~]# systemctl -t target UNIT LOAD ACTIVE SUB DESCRIPTION basic.target loaded active active Basic System cloud-config.target loaded active active Cloud-config availability cloud-init.target loaded active active Cloud-init target cryptsetup.target loaded active active Local Encrypted Volumes getty.target loaded active active Login Prompts local-fs-pre.target loaded active active Local File Systems (Pre) local-fs.target loaded active active Local File Systems multi-user.target loaded active active Multi-User System network-online.target loaded active active Network is Online network-pre.target loaded active active Network (Pre) network.target loaded active active Network nss-lookup.target loaded active active Host and Network Name Lookups nss-user-lookup.target loaded active active User and Group Name Lookups paths.target loaded active active Paths remote-fs.target loaded active active Remote File Systems slices.target loaded active active Slices sockets.target loaded active active Sockets sshd-keygen.target loaded active active sshd-keygen.target swap.target loaded active active Swap sysinit.target loaded active active System Initialization timers.target loaded active active Timers LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type.21 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'. [root@htlwk0001host ~]# systemctl --type target UNIT LOAD ACTIVE SUB DESCRIPTION basic.target loaded active active Basic System cloud-config.target loaded active active Cloud-config availability cloud-init.target loaded active active Cloud-init target cryptsetup.target loaded active active Local Encrypted Volumes getty.target loaded active active Login Prompts local-fs-pre.target loaded active active Local File Systems (Pre) local-fs.target loaded active active Local File Systems multi-user.target loaded active active Multi-User System network-online.target loaded active active Network is Online network-pre.target loaded active active Network (Pre) network.target loaded active active Network nss-lookup.target loaded active active Host and Network Name Lookups nss-user-lookup.target loaded active active User and Group Name Lookups paths.target loaded active active Paths remote-fs.target loaded active active Remote File Systems slices.target loaded active active Slices sockets.target loaded active active Sockets sshd-keygen.target loaded active active sshd-keygen.target swap.target loaded active active Swap sysinit.target loaded active active System Initialization timers.target loaded active active Timers LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type.21 loaded units listed. Pass --all to see loaded but inactive units [root@htlwk0001host ~]# systemctl --type=target UNIT LOAD ACTIVE SUB DESCRIPTION basic.target loaded active active Basic System cloud-config.target loaded active active Cloud-config availability cloud-init.target loaded active active Cloud-init target cryptsetup.target loaded active active Local Encrypted Volumes getty.target loaded active active Login Prompts local-fs-pre.target loaded active active Local File Systems (Pre) local-fs.target loaded active active Local File Systems multi-user.target loaded active active Multi-User System network-online.target loaded active active Network is Online network-pre.target loaded active active Network (Pre) network.target loaded active active Network nss-lookup.target loaded active active Host and Network Name Lookups nss-user-lookup.target loaded active active User and Group Name Lookups paths.target loaded active active Paths remote-fs.target loaded active active Remote File Systems slices.target loaded active active Slices sockets.target loaded active active Sockets sshd-keygen.target loaded active active sshd-keygen.target swap.target loaded active active Swap sysinit.target loaded active active System Initialization timers.target loaded active active Timers LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type.21 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.33.列出所有沒有運行的 Unit
$ systemctl list-units --all --state=inactive34.查看系統狀態
[root@htlwk0001host ~]# systemctl status ● htlwk0001hostState: runningJobs: 0 queuedFailed: 0 unitsSince: Sun 2020-08-23 18:02:02 CST; 8 months 10 days agoCGroup: /├─user.slice│ └─user-0.slice│ ├─session-10.scope│ │ ├─ 26556 nginx: master process nginx│ │ ├─414774 nginx: worker process│ │ └─414775 nginx: worker process│ ├─session-575.scope│ │ ├─1111169 sshd: root [priv]│ │ ├─1111171 sshd: root@pts/035.顯示遠程主機的某個 Unit 的狀態
$ systemctl -H root@rhel7.example.com status httpd.service36.顯示某個 Unit 是否處于啟動失敗狀態
$ systemctl is-failed application.service37.重載所有修改過的配置文件
$ sudo systemctl daemon-reload38.顯示某個 Unit 的指定屬性的值
$ systemctl show -p CPUShares httpd.service39.設置某個 Unit 的指定屬性
$ sudo systemctl set-property httpd.service CPUShares=50040.電源管理命令
安裝 polkit 后才可使用電源管理。
| systemctl reboot | 重啟機器 |
| systemctl poweroff | 關機 |
| systemctl suspend | 待機 |
| systemctl hibernate | 休眠 |
| systemctl hybrid-sleep | 混合休眠模式(同時休眠到硬盤并待機) |
關機不是每個登錄用戶在任何情況下都可以執行的,一般只有管理員才可以關機。正常情況下系統不應該允許 SSH 遠程登錄的用戶執行關機命令。否則其他用戶正在工作,一個用戶把系統關了就不好了。為了解決這個問題,傳統的 Linux 系統使用 ConsoleKit 跟蹤用戶登錄情況,并決定是否賦予其關機的權限。現在 ConsoleKit 已經被 systemd 的 logind 所替代。
logind 不是 pid-1 的 init 進程。它的作用和 UpStart 的 session init 類似,但功能要豐富很多,它能夠管理幾乎所有用戶會話(session)相關的事情。logind 不僅是 ConsoleKit 的替代,它可以:
(1)維護,跟蹤會話和用戶登錄情況。如上所述,為了決定關機命令是否可行,系統需要了解當前用戶登錄情況,如果用戶從 SSH 登錄,不允許其執行關機命令;如果普通用戶從本地登錄,且該用戶是系統中的唯一會話,則允許其執行關機命令;這些判斷都需要 logind 維護所有的用戶會話和登錄情況。
(2)Logind 也負責統計用戶會話是否長時間沒有操作,可以執行休眠/關機等相應操作。
(3)為用戶會話的所有進程創建 CGroup。這不僅方便統計所有用戶會話的相關進程,也可以實現會話級別的系統資源控制。
(4)負責電源管理的組合鍵處理,比如用戶按下電源鍵,將系統切換至睡眠狀態。
(5)多席位(multi-seat) 管理。如今的電腦,即便一臺筆記本電腦,也完全可以提供多人同時使用的計算能力。多席位就是一臺電腦主機管理多個外設,比如兩個屏幕和兩個鼠標/鍵盤。席位一使用屏幕 1 和鍵盤 1;席位二使用屏幕 2 和鍵盤 2,但他們都共享一臺主機。用戶會話可以自由在多個席位之間切換。或者當插入新的鍵盤,屏幕等物理外設時,自動啟動 gdm 用戶登錄界面等。所有這些都是多席位管理的內容。ConsoleKit 始終沒有實現這個功能,systemd 的 logind 能夠支持多席位。
小貼士:
總結
以上是生活随笔為你收集整理的Linux 系统服务管理器(初始化系统/init system) -- systemd 及命令 systemctl 的详细介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 真心话大冒险变态版大全经典105个
- 下一篇: 龙且怎么读