一、Systemd 簡介
首先 systmed 是一個用戶空間的程序,屬於應用程序,不屬於 Linux 內核范疇。Systemd 是 Linux 系統中最新的初始化系統(init),它主要的設計目標是克服 sysvinit 固有的缺點,提高系統的啟動速度。
Linux內核加載啟動后,用戶空間的第一個進程就是初始化進程,這個程序的物理文件約定位於/sbin/init,當然也可以通過傳遞內核參數來讓內核啟動指定的程序。這個進程的特點是進程號為1,代表第一個運行的用戶空間進程。不同發行版采用了不同的啟動程序,主要有以下幾種主流選擇:
- 以 Ubuntu 為代表的 Linux 發行版采用 upstart
- CentOS7.0 版本之前的 System V init
- CentOS7.0 版本的 systemd
下面是 CentOS6.5 和 CentOS7 兩個版本初始化進程的信息截圖:
二、Systemd unit
對於開發者來說,工作量最大的部分應該是編寫配置單元文件,定義所需要的單元。
舉例來說,開發人員開發了一個新的服務程序,比如 httpd,就需要為其編寫一個配置單元文件以便該服務可以被 systemd 管理,類似 UpStart 的工作配置文件。在該文件中定義服務啟動的命令行語法,以及和其他服務的依賴關系等。
此外我們之前已經了解到,systemd 的功能繁多,不僅用來管理服務,還可以管理掛載點,定義定時任務等。這些工作都是由編輯相應的配置單元文件完成的。
2.1 systemd unit 類型
Unit Type | File Extension | Description |
---|---|---|
Service unit |
.service |
服務類 |
Target unit |
.target |
一個 unit 服務組,用於模擬實現運行級別 |
Automount unit |
.automount |
文件系統自動掛載點 |
Device unit |
.device |
內核識別的設備文件 |
Mount unit |
.mount |
文件系統掛載點 |
Path unit |
.path |
文件或目錄 |
Scope unit |
.scope |
外部創建的進程 |
Slice unit |
.slice |
A group of hierarchically organized units that manage system processes. |
Snapshot unit |
.snapshot |
系統快照 |
Socket unit |
.socket |
套接字 |
Swap unit |
.swap |
標識 swap 設備 |
Timer unit |
.timer |
systemd 的計時器 |
2.2 unit 文件保存位置
Directory | Description |
---|---|
/usr/lib/systemd/system/ |
RPM 包安裝時分發的 unit 文件 |
/run/systemd/system/ |
systemd 運行時創建的文件 |
/etc/systemd/system/ |
systemctl enable 創建的 unit 文件 |
2.3 幾個配置單元文件示例
下面是 iptables 服務的配置單元文件,服務配置單元文件以 .service 為文件名后綴:
文件分為三個小節。第一部分是 [Unit] ,這里僅僅有一個描述信息。第二部分是 [Service] ,ExecStart 定義啟動服務的具體命令行語法。第三部分是 [Install] ,WangtedBy 表明這個服務是在多用戶模式下所需要的。
接下來我們就來看下 multi-user.target 吧:
在 [Unit] 小節中的 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 文件,這個文件定義了一個文件掛載點:
掛載配置單元文件有一個 [Mount] 配置小節,里面配置了 What,Where 和 Type 三個數據項,這都是掛載命令所必須的。配置單元文件的編寫需要很多的學習,必須參考 systemd 附帶的 man 等文檔進行深入學習。
三、管理系統服務
systemd 的主要命令行工具是 systemctl 。
多數管理員應該都已經非常熟悉系統服務和 init 系統的管理,比如 service、chkconfig 以及 telinit 命令的使用。systemd 也完成同樣的管理任務,只是命令工具 systemctl 的語法有所不同而已。
3.1 Systemd 命令和 sysvinit 命令對比
service 和 systemctl:
service | systemctl | Description |
---|---|---|
service name start |
systemctl start name.service | 啟動服務 |
service name stop |
systemctl stop name.service
|
停止服務 |
service name restart |
systemctl restart name.service
|
重啟服務(沒啟動的服務會啟動) |
service namecondrestart |
systemctl try-restart name.service | 只重啟正在運行的服務 |
service name reload |
systemctl reload name.service | 重載配置文件 |
service name status |
systemctl status name.service systemctl is-active name.service |
檢查服務狀態 檢查服務是否啟動 |
service --status-all |
systemctl list-units --type service --all |
顯示所有的服務狀態 |
chkconfig 和 systemctl:
chkconfig | systemctl | Description |
---|---|---|
chkconfig name on |
systemctl enable name.service |
啟用開機自啟服務 |
chkconfig name off |
systemctl disable name.service |
停用自啟服務 |
chkconfig --list name |
systemctl status name.service systemctl is-enabled name.service |
檢查服務狀態 查看服務是否自啟 |
chkconfig --list |
systemctl list-unit-files --type service |
查看所有服務 |
chkconfig --list |
systemctl list-dependencies --after |
列出在指定服務之前啟動的服務(依賴) |
chkconfig --list |
systemctl list-dependencies --before |
列出在指定服務之后啟動的服務(被依賴) |
一個服務設置為開機啟動使用會將 /usr/lib/systemd/system/name.service 軟鏈接到 /etc/systemd/system/ ,但是 enable 命令不會重寫已經存在的鏈接,所以當我們修改了服務文件就需要重新加載:
systemctl reenable name.service
3.2 服務狀態信息
Field | Description |
---|---|
Loaded |
關於服務是否已經加載的信息,文件的絕對路徑以及是否被啟用的注釋 |
Active |
服務是否正在運行,然后是啟動時間信息 |
Main PID |
服務主進程 PID |
Status |
系統服務的額外信息 |
Process |
進程額外信息 |
CGroup |
Control Groups(cgroups)額外信息 |
3.3 電源管理命令
命令 | 操作 |
---|---|
systemctl reboot |
重啟機器 |
systemctl poweroff |
關機 |
systemctl suspend |
待機 |
systemctl hibernate |
休眠 |
systemctl hybrid-sleep |
混合休眠模式(同時休眠到硬盤並待機) |
關機不是每個登錄用戶在任何情況下都可以執行的,一般只有管理員才可以關機。正常情況下系統不應該允許 SSH 遠程登錄的用戶執行關機命令。否則其他用戶正在工作,一個用戶把系統關了就不好了。為了解決這個問題,傳統的 Linux 系統使用 ConsoleKit 跟蹤用戶登錄情況,並決定是否賦予其關機的權限。現在 ConsoleKit 已經被 systemd 的 logind 所替代。
參考
《淺析 Linux 初始化 init 系統,第 3 部分: Systemd》:https://www.ibm.com/developerworks/cn/linux/1407_liuming_init3
《Managing Services with systemd》:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd