1. 程式人生 > 其它 >systemd 和 systemctl 使用深入理解

systemd 和 systemctl 使用深入理解

https://www.linuxidc.com/Linux/2018-08/153545.htm

Linux系統的啟動方式有點複雜,而且總是有需要優化的地方。傳統的Linux系統啟動過程主要由著名的init程序(也被稱為SysV init啟動系統)處理,而基於init的啟動系統被認為有效率不足的問題,systemd是Linux系統機器的另一種啟動方式,宣稱彌補了以傳統Linux SysV init為基礎的系統的缺點。

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

Systemd引入了並行啟動的概念,它會為每個需要啟動的守護程序建立一個套接字,這些套接字對於使用它們的程序來說是抽象的,這樣它們可以允許不同守護程序之間進行互動。Systemd會建立新程序併為每個程序分配一個控制組(cgroup)。處於不同控制組的程序之間可以通過核心來互相通訊。systemd處理開機啟動程序的方式非常漂亮,和傳統基於init的系統比起來優化了太多。讓我們看下Systemd的一些核心功能。

一、systemd

使用者空間中的init程式很是關鍵,各個系統版本採用的init都不一樣。CentOS7系列就是仿照了MAC OS X的啟動方式以及管理使用者程序的程式,寫出了一套系統守護的一個應用程式Systemd。

CentOS 5: SysV init
CentOS 6: Upstart
CentOS 7: Systemd

仿照這蘋果系統寫出的一套應用空間管理或啟動程式,其具有的特性為:

Systend的新特性:
系統引導時實現服務的並行啟動;
按需啟用程序;
系統實現快照;
基於依賴關係定義服務的控制邏輯;

而對於CentOS 7來說,其引入到了一個核心概念,稱之為unit,用配置檔案進行標識和識別,所以說,有沒有unit,就是看其有沒有相關的配置檔案,在檔案當中包含了幾種類別,分別為系統服務、監聽的套接字、儲存的快照以及其它與init相關的資訊。

核心概念:unit
unit涵蓋了相關的配置檔案進行標識、識別和配置;檔案中主要包含了系統服務、監聽的socket、儲存的快照以及其它與init相關的資訊;這些配置檔案主要儲存在:
/usr/lib/systemd/system
/run/systemd/system
/etc/systemd/system

systemd的unit配置檔案包含很多種型別,我們以後綴名來區分出大體的型別。

unit的常見型別:
Service unit: 副檔名.service, 用於定義系統服務;
Target unit: 副檔名.target, 用於模擬實現"執行級別";
Device unit: 副檔名.device, 用於定義核心識別的裝置;
Mount unit: 副檔名.mount, 用於定義檔案系統的掛載點;
Socket unit: 副檔名.socket, 用於標識程序間通訊用到的socket檔案;
Snapshot unit: 副檔名.snapshot, 用於管理系統快照;
Swap unit: 副檔名.swap, 用於標識swap裝置;
Automount unit: 副檔名.automount, 用於定義檔案系統自動點裝置;
Path unit: 副檔名.path, 用於定義檔案系統中的一檔案或目錄;

對於Linux-3.10以後的核心來講,即使使用者沒有掛載任何裝置,也會看到以cgroup的裝置掛載,這個叫做控制組,來實現核心中的資源分配的一種機制,以Docker,主要依賴的就是cgroup機制以及namespace機制用來實現。

那麼以上就是unit特別常見的型別,那麼為了瞭解systemd的工作方式,接下來我們就簡單的描述一下其關鍵特性:

關鍵特性:
基於socket啟用機制: 意味著socket與程式是可以進行分離的;
基於bus的啟用機制;
基於device的啟用機制;
基於path的啟用機制;
系統快照:儲存各unit的當前狀態資訊於持久儲存裝置中;
向後相容SysV init指令碼;
/etc/init.d/

當服務啟動時,可事先將socket分予給該服務程式,但該服務程式可先暫時並未啟動,接下來我們還可以基於匯流排(bus)進行啟用等特性。

不過需要注意的是,systemd也有不相容的此前較老版本的功能特性。

不相容特性:
systemctl的命令是固定不變的;
由非systemd啟動的服務,systemctl無法與之通訊,意味著systemd無法控制此服務;

二、systemctl命令

2.1 管理系統服務

其實我們使用很多次systemctl命令來管理服務,對於RHEL 7以上來說,只要是service以及其它型別的unit的檔案,都是由systemd進行管控的,而且還能相容/etc/init.d/目錄下的各個服務指令碼,而且對於命令的使用也很好掌握。

RHEL 7:service等型別的unit檔案;
systemctl命令:
systemctl - Control the systemd system and service manager

systemctl [OPTIONS...] COMMAND [NAME...]

對於該命令來說,擁有著許多的子命令,我們就瞭解systemctl命令,而後看一下與CentOS 6的對比區別。

啟動:service NAME start ==> systemctl start NAME.service
停止:service NAME stop ==> systemctl stop NAME.service
重啟:service NAME restart ==> systemctl restart NAME.service
狀態:service NAME status ==> systemctl status NAME.service
條件式重啟:service NAME condrestart ==> systemctl try-restart NAME.service
過載或重啟服務:systemctl reload-or-restart NAME.service
過載或條件式重啟服務:systemctl reload-try-restart NAME.service

檢視某服務當前啟用與否的狀態:systemctl is-active NAME.service
檢視所有已啟用的服務:systemctl list-units --type service
檢視所有服務(已啟用及未啟用): chkconfig --list ==> systemctl list-units -t service --all
檢視某服務是否能開機自啟:chkconfig --list NAME ==> systemctl is-enable NAME.service

禁止某服務設定為開機自啟:systemctl mask NAME.service
取消此禁止:systemctl umask NAME.service

檢視服務的依賴關係:systemctl list-dependencies NAME.service

以上就是關於service型別的unit檔案與CentOS 6中的命令對比,那麼我們接下來介紹一下對於target型別的檔案是如何進行管理的,我們在剛才的文章中寫道unit的常見型別,其中target型別就是用於實現其系統啟動的執行級別,一共有七個執行級別,從0開始,到6結束,我們介紹一下這七個執行級別。

0:關機;
1:單使用者模式,無網路連線,不執行守護程序,不允許非超級使用者登入;
2:多使用者模式,無網路連線,不執行守護程序;
3:多使用者模式,正常啟動系統;
4:使用者自定義;
5:多使用者模式,圖形介面;
6:重啟;

而在RHEL 7帶有systemd功能中使用target代替Runlevel,例如:multi-user.target相當於是init 3,但systemd可以向後相容其執行級別,目前的絕大多數發行版採用systemd代替Unix SystemV。

那麼現在說一下在systemd命令中所對應的執行級別以及在CentOS 6上對應的的執行切換等命令:

執行級別:
0 ==> runlevel0.target, poweroff.target
1 ==> runlevel1.target, rescue.target
2 ==> runlevel2.target, multi-user.target
3 ==> runlevel3.target, multi-user.target
4 ==> runlevel4.target, multi-user.target
5 ==> runlevel5.target, graphical.target
6 ==> runlevel6.target, reboot.target

切換切換:init N ==> systemctl isolate NAME.target

檢視級別:runlevel ==> systemctl list-utits --type target
檢視所有級別:systemctl list-units -t target -a

獲取預設執行級別:systemctl get-default
修改預設執行級別:systemctl get-default NAME.target

切換至緊急救援模式:systemctl rescre
切換至emergency模式:systemctl emergency

以上就是管理常見的target型別的命令,我們還有一些其它常用命令來進行總結。

其它常用命令:
關機:systemctl halt, systemctl poweroff
重啟:systemctl reboot
掛起:systemctl suspend
快照:systemctl hibernate
快照並掛起:systemctl hybrid-sleep

三、systemd unit file

在我們介紹完systemd以及講解了systemctl命令之後,我們瞭解unit file架構是什麼樣子的,以及如何寫出unit file。

而unit檔案是由描述各其行為及配置指令組成的,其配置檔案屬於.ini風格,通過各種指令來管理以上的功能。

那麼unit file共有三部分組成.

service unit file
檔案通常由三部分組成:
[Unit]: 定義與Unit型別無關的通用選項;用於提供unit的描述資訊,unit行為及依賴關係等;
[Service]:與特定型別相關的專用選項;此處為Service型別;
[Install]:定義由"systemctl enable"及"systemctl disable"命令在實現服務啟用或禁用時用到的一些選項;

以上就是unit配置檔案的結構,接下來我們說一下這三部分的常用選項。

首先我們來說unit配置段:

Unit段的常用選項:
Description:描述資訊,意義性描述;
After:定義unit的啟動次序;表示當前unit應晚於哪些unit啟動;其功能與Before相反;
Requies:依賴到其它的units;強依賴,被依賴的units無法啟用時,當前的unit即無法啟用;
Wants:依賴到其它的units;弱依賴;
Confilcts:定義units 的衝突關係;

而Service的功能配置段選項示例如下:

Service段的常用選項:
Type:用於定義影響ExecStart及相關引數的功能的unit程序型別;
型別:
simple:
forking:
oneshot:
dbus:
notify:
idle:
EnvironmentFile:環境配置檔案;
ExecStart:指明啟動unit要執行的命令或指令碼;ExecStart, ExecStartPost
ExecStop:指明停止unit要執行的命令或指令碼;
Restart:

最後,我們來說一下Install的配置段。

Install段的常用配置:
Alias:
RequiredBy:被哪些unit所依賴;
WantBy:被哪些unit所依賴;

不過,我們需要注意的是對於新建立的unit檔案以及修改過的unit檔案,我們需要使用systemctl來過載其配置檔案。

注意:對於新建立的unit檔案或者修改過的unit檔案,要通知systemd過載其配置檔案:
# systemctl daemon-reload