歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> CentOS 7 之systemd管理

CentOS 7 之systemd管理

日期:2017/2/28 13:57:57   编辑:Linux教程

CentOS系統啟動流程:

POST --> Boot Sequence --> Bootloader --> kernel + initramfs(initrd) --> rootfs --> /sbin/init

innit程序:

CentOS 5:SysV init

CetnOS 6: Upstart

CentOS 7 : Systemd

Systemd新特性:

系統Sys V init和LSB init scripts兼容

系統引導時實現服務並行啟動;采用socket / D-Bus activation等技術啟動服務;為了減少系統啟動時間,systemd的目標是:盡可能啟動更少的進程;盡可能將更多的進程並行啟動;

按需激活進程;Systemd可以提供按需啟動的能力,只有在某個服務被真正請求的時候才啟動它。當該服務結束,systemd可以關閉它,等待下次需要時再次啟動它。

能夠對系統進行快照和恢復;

啟動掛載點和自動掛載點的管理:

Systemd自助管理系統上的掛載點,以便能夠在系統啟動時自動掛載它們。且兼容/etc/fstab文件;

實現事務依賴關系管理:

systemd 維護一個"事務一致性"的概念,保證所有相關的服務都可以正常啟動而不會出現互相依賴,以至於死鎖的情況。

基於內生依賴關系定義服務控制邏輯;

system利用Linux內核的特性即CGroup來完成進程跟蹤的任務。當停止服務時,通過查詢CGroup,systemd可以確保找到所有的相關進程,從而干淨地停止服務;

日志服務:systemd自帶日志服務journald,該日志服務的設計初衷是克服現有的syslog服務的缺點。

System的基本概念

單元的概念

系統初始化需要做的事情非常多。需要啟動後台服務,比如啟動 SSHD 服務;需要做配置工作,比如掛載文件系統。這個過程中的每一步都被 systemd 抽象為一個配置單元,即 unit。可以認為一個服務是一個配置單元;一個掛載點是一個配置單元;一個交換分區的配置是一個配置單元;等等。systemd 將配置單元歸納為以下一些不同的類型。然而,systemd 正在快速發展,新功能不斷增加。所以配置單元類型可能在不久的將來繼續增加。

•service:代表一個後台服務進程,比如mysqld。這是常用的一類;

•socket:此類配置單元封裝系統和互聯網中的一個套接字。當下,systemd支持流式、數據包和連續包的AF_INET、AF_INET6、AF_UNIX socket。每一個套接字配置單元都有一個相應的服務配置單元 。相應的服務在第一個"連接"進入套接字時就會啟動(例如:nscd.socket 在有新連接後便啟動 nscd.service)。

•device :此類配置單元封裝一個存在於 Linux 設備樹中的設備。每一個使用 udev 規則標記的設備都將會在 systemd 中作為一個設備配置單元出現。

•mount :此類配置單元封裝文件系統結構層次中的一個掛載點。Systemd 將對這個掛載點進行監控和管理。比如可以在啟動時自動將其掛載;可以在某些條件下自動卸載。Systemd 會將/etc/fstab 中的條目都轉換為掛載點,並在開機時處理。

•automount :此類配置單元封裝系統結構層次中的一個自掛載點。每一個自掛載配置單元對應一個掛載配置單元 ,當該自動掛載點被訪問時,systemd 執行掛載點中定義的掛載行為。

•swap: 和掛載配置單元類似,交換配置單元用來管理交換分區。用戶可以用交換配置單元來定義系統中的交換分區,可以讓這些交換分區在啟動時被激活。

•target :此類配置單元為其他配置單元進行邏輯分組。它們本身實際上並不做什麼,只是引用其他配置單元而已。這樣便可以對配置單元做一個統一的控制。這樣就可以實現大家都已經非常熟悉的運行級別概念。比如想讓系統進入圖形化模式,需要運行許多服務和配置命令,這些操作都由一個個的配置單元表示,將所有這些配置單元組合為一個目標(target),就表示需要將這些配置單元全部執行一遍以便進入目標所代表的系統運行狀態。 (例如:multi-user.target 相當於在傳統使用 SysV 的系統中運行級別 3)

•timer:定時器配置單元用來定時觸發用戶定義的操作,這類配置單元取代了 atd、crond 等傳統的定時服務。

•snapshot :與 target 配置單元相似,快照是一組配置單元。它保存了系統當前的運行狀態。

依賴關系:

雖然 systemd 將大量的啟動工作解除了依賴,使得它們可以並發啟動。但還是存在有些任務,它們之間存在天生的依賴,不能用"套接字激活"(socket activation)、D-Bus activation 和 autofs 三大方法來解除依賴(三大方法詳情見後續描述)。比如:掛載必須等待掛載點在文件系統中被創建;掛載也必須等待相應的物理設備就緒。為了解決這類依賴問題,systemd 的配置單元之間可以彼此定義依賴關系。

Systemd 用配置單元定義文件中的關鍵字來描述配置單元之間的依賴關系。比如:unit A 依賴 unit B,可以在 unit B 的定義中用"require A"來表示。這樣 systemd 就會保證先啟動 A 再啟動 B。

Systemd事務:

Systemd 能保證事務完整性。Systemd 的事務概念和數據庫中的有所不同,主要是為了保證多個依賴的配置單元之間沒有環形引用。 存在循環依賴,那麼 systemd 將無法啟動任意一個服務。此時systemd 將會嘗試解決這個問題,因為配置單元之間的依賴關系有兩種:required是強依賴;want 則是弱依賴,systemd 將去掉 wants 關鍵字指定的依賴看看是否能打破循環。如果無法修復,systemd會報錯。

Systemd 能夠自動檢測和修復這類配置錯誤,極大地減輕了管理員的排錯負擔。

Target和運行級別:

systemd 用目標(target)替代了運行級別的概念,提供了更大的靈活性,如您可以繼承一個已有的目標,並添加其它服務,來創建自己的目標。下表列舉了 systemd 下的目標和常見 runlevel 的對應關系:

CentOS7/RHEL7 systemd詳解 http://www.linuxidc.com/Linux/2015-04/115937.htm

為什麼systemd會被如此迅速的采用? http://www.linuxidc.com/Linux/2014-08/105789.htm

systemd 與 sysVinit 彩版對照表 http://www.linuxidc.com/Linux/2014-09/106455.htm

太有用了!用systemd命令來管理Linux系統! http://www.linuxidc.com/Linux/2014-09/106490.htm

淺析 Linux 初始化 init 系統,第 3 部分: Systemd http://www.linuxidc.com/Linux/2014-12/110383.htm

Systemd 的並發啟動原理

如前所述,在 Systemd 中,所有的服務都並發啟動,比如Avahi、D-Bus、livirtd、X11、HAL 可以同時啟動。乍一看,這似乎有點兒問題,比如 Avahi 需要syslog 的服務,Avahi 和syslog 同時啟動,假設 Avahi 的啟動比較快,所以syslog 還沒有准備好,可是 Avahi 又需要記錄日志,這豈不是會出現問題?

Systemd 的開發人員仔細研究了服務之間相互依賴的本質問題,發現所謂依賴可以分為三個具體的類型,而每一個類型實際上都可以通過相應的技術解除依賴關系。

•並發啟動原理之一:解決 socket 依賴

絕大多數的服務依賴是套接字依賴。比如服務A 通過一個套接字端口S1 提供自己的服務,其他的服務如果需要服務A,則需要連接S1。因此如果服務A 尚未啟動,S1就不存在,其他的服務就會得到啟動錯誤。所以傳統地,人們需要先啟動服務A,等待它進入就緒狀態,再啟動其他需要它的服務。Systemd認為,只要我們預先把S1 建立好,那麼其他所有的服務就可以同時啟動而無需等待服務A 來創建S1 了。如果服務A 尚未啟動,那麼其他進程向S1 發送的服務請求實際上會被Linux 操作系統緩存,其他進程會在這個請求的地方等待。一旦服務A 啟動就緒,就可以立即處理緩存的請求,一切都開始正常運行。

那麼服務如何使用由 init 進程創建的套接字呢?

Linux 操作系統有一個特性,當進程調用fork 或者exec 創建子進程之後,所有在父進程中被打開的文件句柄(file descriptor) 都被子進程所繼承。套接字也是一種文件句柄,進程A 可以創建一個套接字,此後當進程A 調用 exec 啟動一個新的子進程時,只要確保該套接字的close_on_exec 標志位被清空,那麼新的子進程就可以繼承這個套接字。子進程看到的套接字和父進程創建的套接字是同一個系統套接字,就仿佛這個套接字是子進程自己創建的一樣,沒有任何區別。

這個特性以前被一個叫做 inetd 的系統服務所利用。Inetd 進程會負責監控一些常用套接字端口,比如Telnet,當該端口有連接請求時,inetd才啟動 telnetd 進程,並把有連接的套接字傳遞給新的telnetd 進程進行處理。這樣,當系統沒有telnet 客戶端連接時,就不需要啟動telnetd 進程。Inetd可以代理很多的網絡服務,這樣就可以節約很多的系統負載和內存資源,只有當有真正的連接請求時才啟動相應服務,並把套接字傳遞給相應的服務進程。

和 inetd 類似,systemd 是所有其他進程的父進程,它可以先建立所有需要的套接字,然後在調用exec 的時候將該套接字傳遞給新的服務進程,而新進程直接使用該套接字進行服務即可。

•並發啟動原理之二:解決 D-Bus 依賴

D-Bus 是 desktop-bus 的簡稱,是一個低延遲、低開銷、高可用性的進程間通信機制。它越來越多地用於應用程序之間通信,也用於應用程序和操作系統內核之間的通信。很多現代的服務進程都使用D-Bus取代套接字作為進程間通信機制,對外提供服務。比如簡化Linux 網絡配置的NetworkManager 服務就使用D-Bus 和其他的應用程序或者服務進行交互:郵件客戶端軟件evolution 可以通過D-Bus 從NetworkManager 服務獲取網絡狀態的改變,以便做出相應的處理。

D-Bus 支持所謂"busactivation"功能。如果服務A 需要使用服務 B 的 D-Bus 服務,而服務 B 並沒有運行,則 D-Bus 可以在服務 A 請求服務 B 的 D-Bus 時自動啟動服務 B。而服務 A 發出的請求會被 D-Bus 緩存,服務 A 會等待服務 B 啟動就緒。利用這個特性,依賴D-Bus 的服務就可以實現並行啟動。

•並發啟動原理之三:解決文件系統依賴

系統啟動過程中,文件系統相關的活動是最耗時的,比如掛載文件系統,對文件系統進行磁盤檢查(fsck),磁盤配額檢查等都是非常耗時的操作。在等待這些工作完成的同時,系統處於空閒狀態。那些想使用文件系統的服務似乎必須等待文件系統初始化完成才可以啟動。但是systemd 發現這種依賴也是可以避免的。

Systemd 參考了 autofs 的設計思路,使得依賴文件系統的服務和文件系統本身初始化兩者可以並發工作。autofs可以監測到某個文件系統掛載點真正被訪問到的時候才觸發掛載操作,這是通過內核automounter 模塊的支持而實現的。比如一個open()系統調用作用在"/misc/cd/file1"的時候,/misc/cd 尚未執行掛載操作,此時 open()調用被掛起等待,Linux 內核通知 autofs,autofs 執行掛載。這時候,控制權返回給open()系統調用,並正常打開文件。

Systemd 集成了 autofs 的實現,對於系統中的掛載點,比如/home,當系統啟動的時候,systemd 為其創建一個臨時的自動掛載點。在這個時刻/home真正的掛載設備尚未啟動好,真正的掛載操作還沒有執行,文件系統檢測也還沒有完成。可是那些依賴該目錄的進程已經可以並發啟動,他們的open()操作被內建在systemd 中的autofs 捕獲,將該open()調用掛起(可中斷睡眠狀態)。然後等待真正的掛載操作完成,文件系統檢測也完成後,systemd將該自動掛載點替換為真正的掛載點,並讓open()調用返回。由此,實現了那些依賴於文件系統的服務和文件系統本身同時並發啟動。

當然對於"/"根目錄的依賴實際上一定還是要串行執行,因為systemd 自己也存放在/之下,必須等待系統根目錄掛載檢查好。

不過對於類似/home 等掛載點,這種並發可以提高系統的啟動速度,尤其是當/home是遠程的 NFS 節點,或者是加密盤等,需要耗費較長的時間才可以准備就緒的情況下,因為並發啟動,這段時間內,系統並不是完全無事可做,而是可以利用這段空余時間做更多的啟動進程的事情,總的來說就縮短了系統啟動時間。

Copyright © Linux教程網 All Rights Reserved