走進Linux之systemd啟動過程

linux.cn發表於2016-09-08

Linux系統的啟動方式有點複雜,而且總是有需要優化的地方。傳統的Linux系統啟動過程主要由著名的init程式(也被稱為SysV init啟動系統)處理,而基於init的啟動系統被認為有效率不足的問題,systemd是Linux系統機器的另一種啟動方式,宣稱彌補了以傳統Linux SysV init為基礎的系統的缺點。在這裡我們將著重討論systemd的特性和爭議,但是為了更好地理解它,也會看一下通過傳統的以SysV init為基礎的系統的Linux啟動過程是什麼樣的。友情提醒一下,systemd仍然處在測試階段,而未來發布的Linux作業系統也正準備用systemd啟動管理程式替代當前的啟動過程(LCTT 譯註:截止到本文發表,主流的Linux發行版已經有很多采用了 systemd)。

理解Linux啟動過程

在我們開啟Linux電腦的電源後第一個啟動的程式就是init。分配給init程式的PID是1。它是系統其他所有程式的父程式。當一臺Linux電腦啟動後,處理器會先在系統儲存中查詢BIOS,之後BIOS會檢測系統資源然後找到第一個引導裝置,通常為硬碟,然後會查詢硬碟的主開機記錄(MBR),然後載入到記憶體中並把控制權交給它,以後的啟動過程就由MBR控制。

主開機記錄會初始化載入程式(Linux上有兩個著名的載入程式,GRUB和LILO,80%的Linux系統在用GRUB載入程式),這個時候GRUB或LILO會載入核心模組。核心會馬上查詢/sbin下的“init”程式並執行它。從這裡開始init成為了Linux系統的父程式。init讀取的第一個檔案是/etc/inittab,通過它init會確定我們Linux作業系統的執行級別。它會從檔案/etc/fstab裡查詢分割槽表資訊然後做相應的掛載。然後init會啟動/etc/init.d裡指定的預設啟動級別的所有服務/指令碼。所有服務在這裡通過init一個一個被初始化。在這個過程裡,init每次只啟動一個服務,所有服務/守護程式都在後臺執行並由init來管理。

關機過程差不多是相反的過程,首先init停止所有服務,最後階段會解除安裝檔案系統。

以上提到的啟動過程有一些不足的地方。而用一種更好的方式來替代傳統init的需求已經存在很長時間了。也產生了許多替代方案。其中比較著名的有Upstart,Epoch,Muda和Systemd。而Systemd獲得最多關注並被認為是目前最佳的方案。

理解Systemd

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

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

  • 和init比起來引導過程簡化了很多
  • Systemd支援併發引導過程從而可以更快啟動
  • 通過控制組來追蹤程式,而不是PID
  • 優化了處理引導過程和服務之間依賴的方式
  • 支援系統快照和恢復
  • 監控已啟動的服務;也支援重啟已崩潰服務
  • 包含了systemd-login模組用於控制使用者登入
  • 支援載入和解除安裝元件
  • 低記憶體使用痕跡以及任務排程能力
  • 記錄事件的Journald模組和記錄系統日誌的syslogd模組

Systemd同時也清晰地處理了系統關機過程。它在/usr/lib/systemd/目錄下有三個指令碼,分別叫systemd-halt.service,systemd-poweroff.service,systemd-reboot.service。這幾個指令碼會在使用者選擇關機,重啟或待機時執行。在接收到關機事件時,systemd首先解除安裝所有檔案系統並停止所有記憶體交換裝置,斷開儲存裝置,之後停止所有剩下的程式。

走進Linux之systemd啟動過程

Systemd結構概覽

讓我們看一下Linux系統在使用systemd作為載入程式時的開機啟動過程的結構性細節。為了簡單,我們將在下面按步驟列出來這個過程:

1. 當你開啟電源後電腦所做的第一件事情就是BIOS初始化。BIOS會讀取引導裝置設定,定位並傳遞系統控制權給MBR(假設硬碟是第一引導裝置)。

2. MBR從Grub或LILO載入程式讀取相關資訊並初始化核心。接下來將由Grub或LILO繼續引導系統。如果你在grub配置檔案裡指定了systemd作為引導管理程式,之後的引導過程將由systemd完成。Systemd使用“target”來處理引導和服務管理過程。這些systemd裡的“target”檔案被用於分組不同的引導單元以及啟動同步程式。

3. systemd執行的第一個目標是default.target。但實際上default.target是指向graphical.target的軟連結。Linux裡的軟連結用起來和Windows下的快捷方式一樣。檔案Graphical.target的實際位置是/usr/lib/systemd/system/graphical.target。在下面的截圖裡顯示了graphical.target檔案的內容。

走進Linux之systemd啟動過程

4. 在這個階段,會啟動multi-user.target而這個target將自己的子單元放在目錄“/etc/systemd/system/multi-user.target.wants”裡。這個target為多使用者支援設定系統環境。非root使用者會在這個階段的引導過程中啟用。防火牆相關的服務也會在這個階段啟動。

走進Linux之systemd啟動過程

“multi-user.target”會將控制權交給另一層“basic.target”。

走進Linux之systemd啟動過程

5. “basic.target”單元用於啟動普通服務特別是圖形管理服務。它通過/etc/systemd/system/basic.target.wants目錄來決定哪些服務會被啟動,basic.target之後將控制權交給sysinit.target.

走進Linux之systemd啟動過程

6. “sysinit.target”會啟動重要的系統服務例如系統掛載,記憶體交換空間和裝置,核心補充選項等等。sysinit.target在啟動過程中會傳遞給local-fs.target。這個target單元的內容如下面截圖裡所展示。

走進Linux之systemd啟動過程

7. local-fs.target,這個target單元不會啟動使用者相關的服務,它只處理底層核心服務。這個target會根據/etc/fstab和/etc/inittab來執行相關操作。

系統引導效能分析

Systemd提供了工具用於識別和定位引導相關的問題或效能影響。Systemd-analyze是一個內建的命令,可以用來檢測引導過程。你可以找出在啟動過程中出錯的單元,然後跟蹤並改正引導元件的問題。在下面列出一些常用的systemd-analyze命令。

systemd-analyze time 用於顯示核心和普通使用者空間啟動時所花的時間。

$ systemd-analyze time

Startup finished in 1440ms (kernel) + 3444ms (userspace)

systemd-analyze blame 會列出所有正在執行的單元,按從初始化開始到當前所花的時間排序,通過這種方式你就知道哪些服務在引導過程中要花較長時間來啟動。

$ systemd-analyze blame

2001ms mysqld.service
234ms httpd.service
191ms vmms.service

systemd-analyze verify 顯示在所有系統單元中是否有語法錯誤。

systemd-analyze plot 可以用來把整個引導過程寫入一個SVG格式檔案裡。整個引導過程非常長不方便閱讀,所以通過這個命令我們可以把輸出寫入一個檔案,之後再檢視和分析。下面這個命令就是做這個。

systemd-analyze plot > boot.svg

Systemd的爭議

Systemd並沒有幸運地獲得所有人的青睞,一些專家和管理員對於它的工作方式和開發有不同意見。根據對於Systemd的批評,它不是“類Unix”方式因為它試著替換一些系統服務。一些專家也不喜歡使用二進位制配置檔案的想法。據說編輯systemd配置非常困難而且沒有一個可用的圖形工具。

如何在Ubuntu 14.04和12.04上測試Systemd

本來,Ubuntu決定從Ubuntu 16.04 LTS開始使用Systemd來替換當前的引導過程。Ubuntu 16.04預計在2016年4月釋出,但是考慮到Systemd的流行和需求,剛剛釋出的Ubuntu 15.04採用它作為預設載入程式。另外,Ubuntu 14.04 Trusty Tahr和Ubuntu 12.04 Precise Pangolin的使用者可以在他們的機器上測試Systemd。測試過程並不複雜,你所要做的只是把相關的PPA包含到系統中,更新倉庫並升級系統。

宣告:請注意它仍然處於Ubuntu的測試和開發階段。升級測試包可能會帶來一些未知錯誤,最壞的情況下有可能損壞你的系統配置。請確保在嘗試升級前已經備份好重要資料。

在終端裡執行下面的命令來新增PPA到你的Ubuntu系統裡:

sudo add-apt-repository ppa:pitti/systemd

你將會看到警告資訊因為我們嘗試使用臨時/測試PPA,而它們是不建議用於實際工作機器上的。

走進Linux之systemd啟動過程

然後執行下面的命令更新APT包管理倉庫。

sudo apt-get update

走進Linux之systemd啟動過程

執行下面的命令升級系統。

sudo apt-get dist-upgrade

走進Linux之systemd啟動過程

就這些,你應該已經可以在你的Ubuntu系統裡看到Systemd配置檔案了,開啟/lib/systemd/目錄可以看到這些檔案。

好吧,現在讓我們編輯一下grub配置檔案指定systemd作為預設載入程式。可以使用Gedit文字編輯器編輯grub配置檔案。

sudo gedit /etc/default/grub

走進Linux之systemd啟動過程

在檔案裡修改GRUBCMDLINELINUX_DEFAULT項,設定它的引數為:“init=/lib/systemd/systemd

走進Linux之systemd啟動過程

就這樣,你的Ubuntu系統已經不再使用傳統的載入程式了,改為使用Systemd管理器。重啟你的機器然後檢視systemd引導過程吧。

走進Linux之systemd啟動過程

結論

Systemd毫無疑問為改進Linux引導過程前進了一大步;它包含了一套漂亮的庫和守護程式配合工作來優化系統引導和關閉過程。許多Linux發行版正準備將它作為自己的正式載入程式。在以後的Linux發行版中,我們將有望看到systemd開機。但是另一方面,為了獲得成功並廣泛應用,systemd仍需要認真處理批評意見。

相關文章