早上群上討論了一下systemd的作用,還導致了一個人的直接退群,出於求知心理,搜索了一些systemd,對此也作出了一些相應的整理; 一、systemd的誕生: 學習嵌入式bootloader與kernel銜接的時候,就入門了init進程;init進程也就是系統的第一個進程,PID號為1; ini ...
早上群上討論了一下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 可以讓這一切正常運作起來變得相當容易。
各種不同的單元類型如下:
-
service 單元。用於封裝一個後臺服務進程。
-
socket 單元。 用於封裝一個系統套接字(UNIX)或互聯網套接字(INET/INET6)或FIFO管道。 相應的服務在第一個"連接"進入套接字時才會被啟動。
-
target 單元。 用於將多個單元在邏輯上組合在一起。
-
device 單元。用於封裝一個設備文件,可用於基於設備的啟動。 並非每一個設備文件都需要一個 device 單元, 但是每一個被 udev 規則標記的設備都必須作為一個 device 單元出現。
-
mount 單元。 用於封裝一個文件系統掛載點(也向後相容傳統的 /etc/fstab 文件)。
-
automount 單元。 用於封裝一個文件系統自動掛載點,也就是僅在掛載點確實被訪問的情況下才進行掛載。 它取代了傳統的 autofs 服務。
-
timer 單元。 用於封裝一個基於時間觸發的動作。它取代了傳統的 atd, crond 等任務計劃服務。
-
swap 單元。 用於封裝一個交換分區或者交換文件。 它與 mount 單元非常類似。
-
path 單元。 用於根據文件系統上特定對象的變化來啟動其他服務。
-
slice 單元。 用於控制特定 CGroup 內(例如一組 service 與 scope 單元)所有進程的總體資源占用。
-
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;