最簡明扼要的 Systemd 教程,只需十分鐘

linux.cn發表於2016-01-14

Linux 101:最有效地使用 Systemd

幹嘛要這麼做?

  • 理解現代 Linux 發行版中的顯著變化;
  • 看看 Systemd 是如何取代 SysVinit 的;
  • 搞定單元(unit)和新的 journal 日誌。

吐槽郵件、人身攻擊、死亡威脅——Lennart Poettering,Systemd 的作者,對收到這些東西早就習以為常了。這位 Red Hat 公司的員工之前在 Google+ 上怒斥 FOSS 社群(http://tinyurl.com/poorlennart)的本質,悲痛且失望地表示:“那真是個令人噁心的地方”。他著重指出 Linus Torvalds 在郵件列表上言辭極其刻薄的帖子,並譴責這位核心的領導者為線上討論定下基調,並使得人身攻擊及貶抑之辭成為常態。

但為何 Poettering 會遭受如此多的憎恨?為何就這麼個搞搞開源軟體的人要忍受這等憤怒?答案就在於他的軟體的重要性。如今大多數發行版中,Systemd 是 Linux 核心發起的第一個程式,並且它還扮演多種角色。它會啟動系統服務、處理使用者登入,每隔特定的時間執行一些任務,還有很多很多。它在不斷地成長,並逐漸成為 Linux 的某種“基礎系統”——提供系統啟動和發行版維護所需的所有工具。

如今,在以下幾點上 Systemd 頗具爭議:它逃避了一些已經確立的 Unix 傳統,例如純文字的日誌檔案;它被看成是個“大一統”的專案,試圖接管一切;它還是我們這個作業系統的支柱的重要革新。然而大多數主流發行版已經接受了(或即將接受)它,因此它就活了下來。而且它確實是有好處的:更快地啟動,更簡單地管理那些有依賴的服務程式,提供強大且安全的日誌系統等。

因此在這篇教程中,我們將探索 Systemd 的特性,並向您展示如何最有效地利用這些特性。即便您此刻並不是這款軟體的粉絲,讀完本文後您至少可以更加了解和適應它。

這部沒正經的動畫片來自http://tinyurl.com/m2e7mv8,它把 Systemd 塑造成一隻狂暴的動物,吞噬它路過的一切。大多數批評者的言辭可不像這隻公仔一樣柔軟。

啟動及服務

大多數主流發行版要麼已經採用 Systemd,要麼即將在下個釋出中採用(如 Debian 和 Ubuntu)。在本教程中,我們使用 Fedora 21(該發行版已經是 Systemd 的優秀實驗場地)的一個預覽版進行演示,但不論您用哪個發行版,要用到的命令和注意事項都應該是一樣的。這是 Systemd 的一個加分點:它消除了不同發行版之間許多細微且瑣碎的區別。

在終端中輸入 ps ax | grep systemd,看到第一行,其中的數字 1 表示它的程式號是1,也就是說它是 Linux 核心發起的第一個程式。因此,核心一旦檢測完硬體並組織好了記憶體,就會執行 /usr/lib/systemd/systemd 可執行程式,這個程式會按順序依次發起其他程式。(在還沒有 Systemd 的日子裡,核心會去執行 /sbin/init,隨後這個程式會在名為 SysVinit 的系統中執行其餘的各種啟動指令碼。)

Systemd 的核心是一個叫單元 (unit)的概念,它是一些存有關於服務(service)(在執行在後臺的程式)、裝置、掛載點、和作業系統其他方面資訊的配置檔案。Systemd 的其中一個目標就是簡化這些事物之間的相互作用,因此如果你有程式需要在某個掛載點被建立或某個裝置被接入後開始執行,Systemd 可以讓這一切正常運作起來變得相當容易。(在沒有 Systemd 的日子裡,要使用指令碼來把這些事情調配好,那可是相當醜陋的。)要列出您 Linux 系統上的所有單元,輸入以下命令:

現在,systemctl 是與 Systemd 互動的主要工具,它有不少選項。在單元列表中,您會注意到這兒有一些格式化:被使能(enabled)的單元顯示為綠色,被禁用(disabled)的顯示為紅色。標記為“static”的單元不能直接啟用,它們是其他單元所依賴的物件。若要限制輸出列表只包含服務,使用以下命令:

注意,一個單元顯示為“enabled”,並不等於對應的服務正在執行,而只能說明它可以被開啟。要獲得某個特定服務的資訊,以 GDM (Gnome Display Manager) 為例,輸入以下命令:

這條命令提供了許多有用的資訊:一段給人看的服務描述、單元配置檔案的位置、啟動的時間、程式號,以及它所從屬的 CGroups(用以限制各組程式的資源開銷)。

如果您去檢視位於 /usr/lib/systemd/system/gdm.service 的單元配置檔案,您可以看到各種選項,包括要被執行的二進位制檔案(“ExecStart”那一行),相沖突的其他單元(即不能同時進入執行的單元),以及需要在本單元執行前進入執行的單元(“After”那一行)。一些單元有附加的依賴選項,例如“Requires”(必要的依賴)和“Wants”(可選的依賴)。

此處另一個有趣的選項是:

當您啟動 gdm.service 後,您將可以通過 systemctl status display-manager.service 來檢視它的狀態。當您知道有顯示管理程式 (display manager)在執行並想對它做點什麼,但您不關心那究竟是 GDM,KDM,XDM 還是什麼別的顯示管理程式時,這個選項會非常有用。

Image

使用 systemctl status 命令後面跟一個單元名,來檢視對應的服務有什麼情況。

“目標(target)”鎖定

如果您在 /usr/lib/systemd/system 目錄中輸入 ls 命令,您將看到各種以 .target 結尾的檔案。啟動目標 (target)是一種將多個單元聚合在一起以致於將它們同時啟動的方式。例如,對大多數類 Unix 作業系統而言有一種“多使用者(multi-user)”狀態,意思是系統已被成功啟動,後臺服務正在執行,並且已準備好讓一個或多個使用者登入並工作——至少在文字模式下。(其他狀態包括用於進行管理工作的單使用者(single-user)狀態,以及用於機器關機的重啟(reboot)狀態。)

如果您開啟 multi-user.target 檔案一探究竟,您可能期待看到的是一個要被啟動的單元列表。但您會發現這個檔案內部幾乎空空如也——其實,一個服務會通過 WantedBy 選項讓自己成為啟動目標的依賴。因此如果您去開啟 avahi-daemon.service, NetworkManager.service 及其他 .service 檔案看看,您將在 Install 段看到這一行:

因此,切換到多使用者啟動目標會使能(enable)那些包含上述語句的單元。還有其他一些啟動目標可用(例如 emergency.target 提供一個緊急情況使用的 shell,以及 halt.target 用於機器關機),您可以用以下方式輕鬆地在它們之間切換:

在許多方面,這些都很像 SysVinit 中的執行級 (runlevel),如文字模式的 multi-user.target 類似於第3執行級,graphical.target 類似於第5執行級,reboot.target 類似於第6執行級,諸如此類。

Image

與傳統的指令碼相比,單元配置檔案也許看起來很陌生,但並不難以理解。

開啟與停止

現在您也許陷入了沉思:我們已經看了這麼多,但仍沒看到如何停止和開啟服務!這其實是有原因的。從外部看,Systemd 也許很複雜,像野獸一般難以駕馭。因此在您開始擺弄它之前,有必要從巨集觀的角度看看它是如何工作的。實際用來管理服務的命令非常簡單:

(若某個單元被禁用了,您可以先通過 systemctl enable 加上該單元名的方式將其使能。這種做法會為該單元建立一個符號連結,並將其放置在當前啟動目標的 .wants 目錄下,這些 .wants 目錄在/etc/systemd/system 資料夾中。)

還有兩個有用的命令是 systemctl restartsystemctl reload,後面接單元名。後者用於讓單元重新載入它的配置檔案。Systemd 的絕大部分都有良好的文件,因此您可以檢視手冊 (man systemctl) 瞭解每條命令的細節。

定時器單元:取代 Cron

除了系統初始化和服務管理,Systemd 還染指了其他方面。在很大程度上,它能夠完成 cron 的工作,而且可以說是以更靈活的方式(並帶有更易讀的語法)。cron 是一個以規定時間間隔執行任務的程式——例如清除臨時檔案,重新整理快取等。

如果您再次進入 /usr/lib/systemd/system 目錄,您會看到那兒有多個 .timer 檔案。用 less 來檢視這些檔案,您會發現它們與 .service.target 檔案有著相似的結構,而區別在於 [Timer] 段。舉個例子:

OnBootSec 選項告訴 Systemd 在系統啟動一小時後啟動這個單元。第二個選項的意思是:自那以後每週啟動這個單元一次。關於定時器有大量選項您可以設定,輸入 man systemd.time 檢視完整列表。

Systemd 的時間精度預設為一分鐘。也就是說,它會在設定時刻的一分鐘內執行單元,但不一定精確到那一秒。這麼做是基於電源管理方面的原因,但如果您需要一個沒有任何延時且精確到毫秒的定時器,您可以新增以下一行:

另外, WakeSystem 選項(可以被設定為 true 或 false)決定了定時器是否可以喚醒處於休眠狀態的機器。

Image

有一個 Systemd 的圖形介面程式,即便它已有多年未被積極維護。

日誌檔案:向 journald 問聲好

Systemd 的第二個主要部分是 journal 。這是個日誌系統,類似於 syslog 但也有些顯著區別。如果您是個 Unix 日誌管理模式的粉絲,準備好出離憤怒吧:這是個二進位制日誌,因此您不能使用常規的命令列文字處理工具來解析它。這個設計決定不出意料地在網上引起了激烈的爭論,但它的確有些優點。例如,日誌可以被更系統地組織,帶有更多的後設資料,因此可以更容易地根據可執行檔名和程式號等過濾出資訊。

要檢視整個 journal,輸入以下命令:

像許多其他的 Systemd 命令一樣,該命令將輸出通過管道的方式引向 less 程式,因此您可以使用空格鍵向下滾動,鍵入/(斜槓)查詢,以及其他熟悉的快捷鍵。您也能在此看到少許顏色,像紅色的警告及錯誤資訊。

以上命令會輸出很多資訊。為了限制其只輸出本次啟動的訊息,使用如下命令:

這就是 Systemd 大放異彩的地方!您想檢視自上次啟動以來的全部訊息嗎?試試 journalctl -b -1 吧。再上一次的?用 -2 替換 -1 吧。那自某個具體時間,例如2014年10月24日16:38以來的呢?

即便您對二進位制日誌感到遺憾,那依然是個有用的特性,並且對許多系統管理員來說,構建類似的過濾器比起寫正規表示式而言容易多了。

我們已經可以根據特定的時間來準確查詢日誌了,那可以根據特定程式嗎?對單元而言,試試這個:

(注意:這是個檢視 X server 產生的日誌的好辦法。)那根據特定的程式號?

您甚至可以請求只看某個可執行檔案產生的訊息:

若您想將輸出的訊息限制在某個優先順序,可以使用 -p 選項。該選項引數為 0 的話只會顯示緊急訊息(也就是說,是時候向 $DEITY 祈求保佑了)(LCTT 譯註: $DEITY 是一個計算機方面的幽默,DEITY 是指廣義上的“神”,$字首表示這是一個變數),為 7 的話會顯示所有訊息,包括除錯訊息。請檢視手冊 (man journalctl) 獲取更多關於優先順序的資訊。

值得指出的是,您也可以將多個選項結合在一起,若想檢視在當前啟動中由 GDM 服務輸出的優先順序數小於等於 3 的訊息,請使用下述命令:

最後,如果您僅僅想開啟一個隨 journal 持續更新的終端視窗,就像在沒有 Systemd 時使用 tail 命令實現的那樣,輸入 journalctl -f 就好了。

二進位制日誌並不流行,但 journal 的確有它的優點,如非常方便的資訊查詢及過濾。

沒有 Systemd 的生活?

如果您就是完全不能接受 Systemd,您仍然有一些主流發行版中的選擇。尤其是 Slackware,作為歷史最為悠久的發行版,目前還沒有做出改變,但它的主要開發者並沒有將其從未來規劃中移除。一些不出名的發行版也在堅持使用 SysVinit 。

但這又將持續多久呢?Gnome 正越來越依賴於 Systemd,其他的主流桌面環境也會步其後塵。這也是引起 BSD 社群一陣恐慌的原因:Systemd 與 Linux 核心緊密相連,導致在某種程度上,桌面環境正變得越來越不可移植。一種折衷的解決方案也許會以 Uselessd (http://uselessd.darknedgy.net) 的形式到來:一種裁剪版的 Systemd,純粹專注於啟動和監控程式,而不消耗整個基礎系統。

Image

若您不喜歡 Systemd,可以嘗試一下 Gentoo 發行版,它將 Systemd 作為初始化工具的一種選擇,但並不強制使用者使用 Systemd。

相關文章