首頁 > 軟體

systemd 和 systemctl 使用深入理解

2020-06-16 16:48:58

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都不一樣。CentOS 7系列就是仿照了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

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

本文永久更新連結地址https://www.linuxidc.com/Linux/2018-08/153545.htm


IT145.com E-mail:sddin#qq.com