systemd的作用

yooooooo發表於2018-03-17

早上群上討論了一下systemd的作用,還導致了一個人的直接退群,出於求知心理,搜尋了一些systemd,對此也作出了一些相應的整理;

一、systemd的誕生:

學習嵌入式bootloader與kernel銜接的時候,就入門了init程式;init程式也就是系統的第一個程式,PID號為1;

 

init程式總所周知的問題是從它開始啟動,並從下一個程式開始,都是以一個程式啟動另一個程式的方式來進行;這樣做的顯而易見的缺點就是執行速度慢,沒有一整套的系統來管理,並且/ect/目錄下的隨便一個指令碼簡直長的髮指;關機過程差不多是相反的過程,首先init停止所有服務,最後階段會解除安裝檔案系統。

 

所以偉大的程式設計師開始了自己的創作,systemd也就誕生啦。systemd 幾乎完全相容傳統的 SysV init 系統: SysV init 指令碼可以作為另一種配置檔案格式被識別; 提供與 SysV 相容的 /dev/initctl 介面; 提供各種 SysV 工具的相容實現; 依然相容例如 /etc/fstab 或者 utmp之類傳統的 Unix 特性。

 

systemd現在廣泛用於Fedora 21、Ubuntu(Ubuntu 15.04以上)、Centos等linux作業系統上;

 

二、systemd是什麼?

開發Systemd的主要目的就是減少系統引導時間和計算開銷。

Systemd(系統管理守護程式),最開始以GNU GPL協議授權開發,現在已轉為使用GNU LGPL協議,它是如今討論最熱烈的引導和服務管理程式。如果你的Linux系統配置為使用Systemd載入程式,它取替傳統的init程式,啟動過程將交給systemd處理。Systemd的一個核心功能是它同時支援init程式的後開機啟動指令碼。

 

 Systemd引入了並行啟動的概念,它會為每個需要啟動的守護程式建立一個套接字,這些套接字對於使用它們的程式來說是抽象的,這樣它們可以允許不同守護程式之間進行互動。Systemd會建立新程式併為每個程式分配一個控制組(cgroup)。處於不同控制組的程式之間可以通過核心來互相通訊。 cgroups 資訊由核心負責維護, 並且可以通過 /sys/fs/cgroup/systemd/ 介面進行訪問。

 

當作為系統例項執行時, systemd 將會按照 system.conf 配置檔案 以及 system.conf.d 配置目錄中的指令工作; 當作為使用者例項執行時,systemd 將會按照 user.conf 配置檔案 以及 user.conf.d 配置目錄中的指令工作。

2.1 單位:

systemd 將各種系統啟動和執行相關的物件, 表示為各種不同型別的單元(unit), 並提供了處理不同單元之間依賴關係的能力。 

Systemd 的其中一個目標就是簡化這些事物之間的相互作用,因此如果你有程式需要在某個掛載點被建立或某個裝置被接入後開始執行,Systemd 可以讓這一切正常運作起來變得相當容易。

各種不同的單元型別如下:

  1. service 單元。用於封裝一個後臺服務程式。 

  2. socket 單元。 用於封裝一個系統套接字(UNIX)或網際網路套接字(INET/INET6)或FIFO管道。 相應的服務在第一個”連線”進入套接字時才會被啟動。

  3. target 單元。 用於將多個單元在邏輯上組合在一起。

  4. device 單元。用於封裝一個裝置檔案,可用於基於裝置的啟動。 並非每一個裝置檔案都需要一個 device 單元, 但是每一個被 udev 規則標記的裝置都必須作為一個 device 單元出現。

  5. mount 單元。 用於封裝一個檔案系統掛載點(也向後相容傳統的 /etc/fstab 檔案)。

  6. automount 單元。 用於封裝一個檔案系統自動掛載點,也就是僅在掛載點確實被訪問的情況下才進行掛載。 它取代了傳統的 autofs 服務。

  7. timer 單元。 用於封裝一個基於時間觸發的動作。它取代了傳統的 atd, crond 等任務計劃服務。

  8. swap 單元。 用於封裝一個交換分割槽或者交換檔案。 它與 mount 單元非常類似。

  9. path 單元。 用於根據檔案系統上特定物件的變化來啟動其他服務。

  10. slice 單元。 用於控制特定 CGroup 內(例如一組 service 與 scope 單元)所有程式的總體資源佔用。

  11. scope 單元。它與 service 單元類似,但是由 systemd 根據 D-bus 介面接收到的資訊自動建立, 可用於管理外部建立的程式。

systemd 能夠處理各種型別的依賴關係, 包括依賴與衝突(也就是 Requires= 與 Conflicts= 指令), 以及先後順序(也就是 After= 與 Before= 指令)。 注意, 上述兩種型別的依賴關係(依賴與衝突、先後順序)之間是相互獨立的(無關的)。 舉例來說,假定 foo.service 依賴於(Requires) bar.service 但並未指定先後順序, 那麼這兩個服務將被同時並行啟動。 不過在兩個單元之間既存在依賴關係也存在先後順序的情形也很常見。 另外需要注意的是, 大多數依賴關係都是由 systemd 隱式建立和維護的, 因此沒有必要額外手動建立它們。

 

 

2.2 systemctl:

systemctrl是systemd的系統管理的指令,相應指令如下:http://man.linuxde.net/systemctl

 1 # 重啟系統
 2 $ sudo systemctl reboot
 3 
 4 # 關閉系統,切斷電源
 5 $ sudo systemctl poweroff
 6 
 7 # CPU停止工作
 8 $ sudo systemctl halt
 9 
10 # 暫停系統
11 $ sudo systemctl suspend
12 
13 # 讓系統進入冬眠狀態
14 $ sudo systemctl hibernate
15 
16 # 讓系統進入互動式休眠狀態
17 $ sudo systemctl hybrid-sleep
18 
19 # 啟動進入救援狀態(單使用者狀態)
20 $ sudo systemctl rescue

 

 

2.3 target檔案:

Systemd使用“target”來處理引導和服務管理過程。這些systemd裡的“target”檔案被用於分組不同的引導單元以及啟動同步程式。

簡單說,Target 就是一個 Unit 組,包含許多相關的 Unit 。啟動某個 Target 的時候,Systemd 就會啟動裡面所有的 Unit。從這個意義上說,Target 這個概念類似於”狀態點”,啟動某個 Target 就好比啟動到某種狀態。

 

傳統的init啟動模式裡面,有執行級別的概念,跟 Target 的作用很類似。不同的是,執行級別是互斥的,不可能多個執行級別同時啟動,但是多個 Target 可以同時啟動。

 

它與init程式的主要差別如下。

(1)預設的 RunLevel(在/etc/inittab檔案設定)現在被預設的 Target 取代,位置是/etc/systemd/system/default.target,通常符號連結到graphical.target(圖形介面)或者multi-user.target(多使用者命令列)。

 

(2)啟動指令碼的位置,以前是/etc/init.d目錄,符號連結到不同的 RunLevel 目錄 (比如/etc/rc3.d/etc/rc5.d等),現在則存放在/lib/systemd/system/etc/systemd/system目錄。

 

(3)配置檔案的位置,以前init程式的配置檔案是/etc/inittab,各種服務的配置檔案存放在/etc/sysconfig目錄。現在的配置檔案主要存放在/lib/systemd目錄,在/etc/systemd目錄裡面的修改可以覆蓋原始設定;

 

2.4 日誌檔案:

systemd使用journalctl來管理相應的日誌檔案;

 1 # 檢視所有日誌(預設情況下 ,只儲存本次啟動的日誌)
 2 $ sudo journalctl
 3 
 4 # 檢視核心日誌(不顯示應用日誌)
 5 $ sudo journalctl -k
 6 
 7 # 檢視系統本次啟動的日誌
 8 $ sudo journalctl -b
 9 $ sudo journalctl -b -0
10 
11 # 檢視上一次啟動的日誌(需更改設定)
12 $ sudo journalctl -b -1
13 
14 # 檢視指定時間的日誌
15 $ sudo journalctl --since="2012-10-30 18:17:16"
16 $ sudo journalctl --since "20 min ago"
17 $ sudo journalctl --since yesterday
18 $ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
19 $ sudo journalctl --since 09:00 --until "1 hour ago"
20 
21 # 顯示尾部的最新10行日誌
22 $ sudo journalctl -n
23 
24 # 顯示尾部指定行數的日誌
25 $ sudo journalctl -n 20
26 
27 # 實時滾動顯示最新日誌
28 $ sudo journalctl -f
29 
30 # 檢視指定服務的日誌
31 $ sudo journalctl /usr/lib/systemd/systemd
32 
33 # 檢視指定程式的日誌
34 $ sudo journalctl _PID=1
35 
36 # 檢視某個路徑的指令碼的日誌
37 $ sudo journalctl /usr/bin/bash
38 
39 # 檢視指定使用者的日誌
40 $ sudo journalctl _UID=33 --since today
41 
42 # 檢視某個 Unit 的日誌
43 $ sudo journalctl -u nginx.service
44 $ sudo journalctl -u nginx.service --since today
45 
46 # 實時滾動顯示某個 Unit 的最新日誌
47 $ sudo journalctl -u nginx.service -f
48 
49 # 合併顯示多個 Unit 的日誌
50 $ journalctl -u nginx.service -u php-fpm.service --since today
51 
52 # 檢視指定優先順序(及其以上級別)的日誌,共有8級
53 # 0: emerg
54 # 1: alert
55 # 2: crit
56 # 3: err
57 # 4: warning
58 # 5: notice
59 # 6: info
60 # 7: debug
61 $ sudo journalctl -p err -b
62 
63 # 日誌預設分頁輸出,--no-pager 改為正常的標準輸出
64 $ sudo journalctl --no-pager
65 
66 # 以 JSON 格式(單行)輸出
67 $ sudo journalctl -b -u nginx.service -o json
68 
69 # 以 JSON 格式(多行)輸出,可讀性更好
70 $ sudo journalctl -b -u nginx.serviceqq
71  -o json-pretty
72 
73 # 顯示日誌佔據的硬碟空間
74 $ sudo journalctl --disk-usage
75 
76 # 指定日誌檔案佔據的最大空間
77 $ sudo journalctl --vacuum-size=1G
78 
79 # 指定日誌檔案儲存多久
80 $ sudo journalctl --vacuum-time=1years

 

 

三、systemd的爭議:

直接看知乎問題吧:https://www.zhihu.com/question/25873473

 

 

相關文章