systemd詳解

CentOS 7 使用systemd替換了SysV。Systemd目的是要取代Unix時代以來一直在使用的init系統,兼容SysV和LSB的啓動腳本,並且夠在進程啓動過程當中更有效地引導加載服務。php

systemd的特性有:html

  • 支持並行化任務
  • 同時採用socket式與D-Bus總線式激活服務;
  • 按需啓動守護進程(daemon);
  • 利用 Linux 的 cgroups 監視進程;
  • 支持快照和系統恢復;
  • 維護掛載點和自動掛載點;
  • 各服務間基於依賴關係進行精密控制。

systemd基本工具
檢視和控制systemd的主要命令是systemctl。該命令可用於查看系統狀態和管理系統及服務。詳見man 1 systemctl。
前端

小貼士: 在 systemctl 參數中添加 -H <用戶名>@<主機名> 能夠實現對其餘機器的遠程控制。該過程使用ssh連接。 linux

注意: systemadm 是 systemd 的官方圖形前端。shell

分析系統狀態
輸出激活的單元:vim

$ systemctl

如下命令等效:網絡

$ systemctl list-units

輸出運行失敗的單元:ssh

$ systemctl --failed

全部可用的單元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目錄(後者優先級更高)。查看全部已安裝服務:socket

$ systemctl list-unit-files

使用單元
一個單元配置文件能夠描述以下內容之一:系統服務(.service)、掛載點(.mount)、sockets(.sockets 、系統設備、交換分區/文件、啓動目標(target)、文件系統路徑、由 systemd 管理的計時器。詳情參閱 man 5 systemd.unit.工具

使用 systemctl 控制單元時,一般須要使用單元文件的全名,包括擴展名(例如 sshd.service)。可是有些單元能夠在systemctl中使用簡寫方式。

  • 若是無擴展名,systemctl 默認把擴展名看成 .service。例如 netcfg 和 netcfg.service 是等價的。
  • 掛載點會自動轉化爲相應的 .mount 單元。例如 /home 等價於 home.mount。
  • 設備會自動轉化爲相應的 .device 單元,因此 /dev/sda2 等價於 dev-sda2.device。

當即激活單元:

# systemctl start <單元>

當即中止單元:

# systemctl stop <單元>

重啓單元:

# systemctl restart <單元>

命令單元從新讀取配置:

# systemctl reload <單元>

輸出單元運行狀態:

$ systemctl status <單元>

檢查單元是否配置爲自動啓動:

$ systemctl is-enabled <單元>

開機自動激活單元:

# systemctl enable <單元>

注意: 若是服務沒有Install段落,通常意味着應該經過其它服務自動調用它們。若是真的須要手動安裝,能夠直接鏈接服務,以下(將foo替換爲真實的服務名):

# ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/

取消開機自動激活單元:

# systemctl disable <單元>

顯示單元的手冊頁(必須由單元文件提供):

# systemctl help <單元>

從新載入 systemd,掃描新的或有變更的單元:

# systemctl daemon-reload

電源管理
安裝 polkit 後纔可以使用電源管理。

若是你正登陸在一個本地的systemd-logind用戶會話,且當前沒有其它活動的會話,那麼如下命令無需root權限便可執行。不然(例如,當前有另外一個用戶登陸在某個tty),systemd 將會自動請求輸入root密碼。

重啓:

$ systemctl reboot

退出系統並中止電源:

$ systemctl poweroff

待機:

$ systemctl suspend

休眠:

$ systemctl hibernate

混合休眠模式(同時休眠到硬盤並待機):

$ systemctl hybrid-sleep

原生 systemd 配置文件

注意: 可能須要手動建立某些文件。全部文件的權限都是644,屬主 root,屬組 root。

虛擬控制檯
能夠用/etc/vconsole.conf 文件或者localectl 配置虛擬控制檯,包括鍵盤佈局和控制檯字體。詳情請訪問 控制檯字體 和 鍵盤佈局。

硬件時鐘
systemd 默認硬件時鐘爲協調世界時(UTC)。

小貼士: 推薦使用NTP服務來在線同步硬件時鐘。

硬件時鐘設定爲地方時
將硬件時鐘配置爲地方時(不建議):

# timedatectl set-local-rtc true

從新調整爲 UTC:

# timedatectl set-local-rtc false

若是設置成本地時間,處理夏令時有些麻煩。若是夏令時調整發生在關機時,下次啓動時時間會出現問題。最新的內核直接從實時時鐘芯片(RTC)讀取時間,不 使用 hwclock,內核把從 RTC 讀取的時間看成 UTC 處理。因此若是硬件時間是地方時,系統啓動一開始識別的時間是錯誤的,以後很快會進行矯正。這可能致使一些問題(尤爲是時間倒退時)。

若是同時安裝了 Windows 操做系統(默認使用地方時),那麼通常 RTC 會被設置爲地方時。Windows 其實也能處理 UTC,須要修改註冊表。建議讓 Windows 使用 UTC,而非讓 Linux 使用地方時。Windows 使用 UTC 後,請記得禁用 Windows 的時間同步功能,以防 Windows 錯誤設置硬件時間。如上文所說,Linux 可使用NTP服務來在線同步硬件時鐘。

內核模塊
請訪問Kernel modules

文件系統掛載
默認行爲是:在啓動一個須要掛載特定分區的服務以前,系統自動檢查並掛載分區。/etc/fstab 中設定的網絡文件系統(如 NFS、Samba)無需配置便可正常工做,systemd 將確保網絡文件系統在網絡連接就緒後掛載。

詳情參閱:man 5 systemd.mount。

LVM
若是裝有不經過 initramfs 激活的LVM卷,則需啓動 lvm-monitoring 服務(由 lvm2 軟件包提供):

# systemctl enable lvm-monitoring

ACPI 電源管理
參閱 Power Management

臨時文件
/usr/lib/tmpfiles.d/ 和 /etc/tmpfiles.d/ 中的文件描述了 systemd-tmpfiles 如何建立、清理、刪除臨時文件和目錄,這些文件和目錄一般存放在 /run 和 /tmp 中。配置文件名稱爲 /etc/tmpfiles.d/<program>.conf。此處的配置能覆蓋 /usr/lib/tmpfiles.d/ 目錄中的同名配置。

臨時文件一般和服務文件同時提供,以生成守護進程須要的文件和目錄。例如 Samba 服務須要目錄 /run/samba 存在並設置正確的權限位,就象這樣:

/usr/lib/tmpfiles.d/samba.conf D /run/samba 0755 root root

此外,臨時文件還能夠用來在開機時向特定文件寫入某些內容。好比,要禁止系統從USB設備喚醒,利用舊的 /etc/rc.local 能夠用 echo USBE > /proc/acpi/wakeup,而如今能夠這麼作:

/etc/tmpfiles.d/disable-usb-wake.conf w /proc/acpi/wakeup - - - - USBE

詳情參見 man 5 tmpfiles.d。

注意: 該方法不能向 /sys 中的配置文件添加參數,由於 systemd-tmpfiles-setup 有可能在相關模塊加載前運行。這種狀況下,須要首先經過 modinfo <模塊名> 確認須要的參數,並在 /etc/modprobe.d 下的一個文件中設置改參數。另外,還可使用 udev 規則,在設備就緒時設置相應屬性。

本身編寫 .service 文件
systemd 的單元文件是受 XDG Desktop Entry .desktop 文件啓發而產生,而最初起源是 Windows 下的 .ini 文件。

處理依賴關係
使用systemd時,可經過正確編寫單元配置文件來解決其依賴關係。典型的狀況是,單元A要求單元B在A啓動以前運行。在此狀況下,向單元A配置文件中 的 [Unit] 段添加 Requires=B 和 After=B 便可。若此依賴關係是可選的,可添加 Wants=B 和 After=B。請注意 Wants= 和 Requires= 並不意味着 After=,即若是 After= 選項沒有制定,這兩個單元將被並行啓動。

依賴關係一般被用在服務(service)而不是目標(target)上。例如, network.target 通常會被某個配置網絡接口的服務引入,因此,將自定義的單元排在該服務以後便可,由於 network.target 已經啓動。

啓動方式
編寫自定義的service文件時,能夠選擇幾種不一樣的服務啓動方式。啓動方式可經過配置文件 [Service] 段中的 Type= 參數進行設置。具體的參數說明請參閱 man systemd.service 。

  • Type=simple(默認值):systemd認爲該服務將當即啓動。服務進程不會fork。若是該服務要啓動其餘服務,不要使用此類型啓動,除非該服務是socket激活型。
  • Type=forking:systemd認爲當該服務進程fork,且父進程退出後服務啓動成功。對於常規的守護進程(daemon),除非你肯定此啓 動方式沒法知足需求,使用此類型啓動便可。使用此啓動類型應同時指定 PIDFile=,以便systemd可以跟蹤服務的主進程。
  • Type=oneshot:這一選項適用於只執行一項任務、隨後當即退出的服務。可能須要同時設置 RemainAfterExit=yes 使得 systemd 在服務進程退出以後仍然認爲服務處於激活狀態。
  • Type=notify:與 Type=simple 相同,但約定服務會在就緒後向 systemd 發送一個信號。這一通知的實現由 libsystemd-daemon.so 提供。
  • Type=dbus:若以此方式啓動,當指定的 BusName 出如今DBus系統總線上時,systemd認爲服務就緒。

修改現存單元文件
要更改由軟件包提供的單元文件,先建立名爲 /etc/systemd/system/<單元名>.d/ 的目錄(如 /etc/systemd/system/httpd.service.d/),而後放入 *.conf 文件,其中能夠添加或重置參數。這裏設置的參數優先級高於原來的單元文件。例如,若是想添加一個額外的依賴,建立這麼一個文件便可:

/etc/systemd/system/<unit>.d/customdependency.conf [Unit] Requires=<新依賴> After=<新依賴>

而後運行如下命令使更改生效:

# systemctl daemon-reload # systemctl restart <單元>

此外,把舊的單元文件從 /usr/lib/systemd/system/ 複製到 /etc/systemd/system/,而後進行修改,也能夠達到一樣效果。在 /etc/systemd/system/ 目錄中的單元文件的優先級老是高於 /usr/lib/systemd/system/ 目錄中的同名單元文件。注意,當 /usr/lib/ 中的單元文件因軟件包升級變動時,/etc/ 中自定義的單元文件不會同步更新。此外,你還得執行 systemctl reenable <unit>,手動從新啓用該單元。所以,建議使用前面一種利用 *.conf 的方法。

小貼士: 能夠用 systemd-delta 命令來查看哪些單元文件被覆蓋、哪些被修改。

單元配置文件的 vim 語法高亮支持
可從官方倉庫安裝 vim-systemd 軟件包,使 unit 配置文件在 Vim 下支持語法高亮。

目標(target)
啓動級別(runlevel)是一箇舊的概念。如今,systemd 引入了一個和啓動級別功能類似又不一樣的概念——目標(target)。不像數字表示的啓動級別,每一個目標都有名字和獨特的功能,而且能同時啓用多個。一些 目標繼承其餘目標的服務,並啓動新服務。systemd 提供了一些模仿 sysvinit 啓動級別的目標,仍可使用舊的 telinit 啓動級別 命令切換。
獲取當前目標

不要使用 runlevel 命令了:

$ systemctl list-units --type=target

建立新目標
在 Fedora 中,啓動級別 0、一、三、五、6 都被賦予特定用途,而且都對應一個 systemd 的目標。然而,沒有什麼很好的移植用戶定義的啓動級別(二、4)的方法。要實現相似功能,能夠以原有的啓動級別爲基礎,建立一個新的目標 /etc/systemd/system/<新目標>(能夠參考 /usr/lib/systemd/system/graphical.target),建立 /etc/systemd/system/<新目標>.wants 目錄,向其中加入額外服務的連接(指向 /usr/lib/systemd/system/ 中的單元文件)。

目標表

SysV 啓動級別 Systemd 目標 註釋
0 runlevel0.target, poweroff.target 中斷系統(halt)
1, s, single runlevel1.target, rescue.target 單用戶模式
2, 4 runlevel2.target, runlevel4.target, multi-user.target 用戶自定義啓動級別,一般識別爲級別3。
3 runlevel3.target, multi-user.target 多用戶,無圖形界面。用戶能夠經過終端或網絡登陸。
5 runlevel5.target, graphical.target 多用戶,圖形界面。繼承級別3的服務,並啓動圖形界面服務。
6 runlevel6.target, reboot.target 重啓
emergency emergency.target 急救模式(Emergency shell)

切換啓動級別/目標
systemd 中,啓動級別經過「目標單元」訪問。經過以下命令切換:

# systemctl isolate graphical.target

該命令對下次啓動無影響。等價於telinit 3 或 telinit 5。

修改默認啓動級別/目標
開機啓動進的目標是 default.target,默認連接到 graphical.target (大體至關於原來的啓動級別5)。能夠經過內核參數更改默認啓動級別:

小貼士: 能夠省略擴展名 .target。

  •  systemd.unit=multi-user.target (大體至關於級別3)
  •  systemd.unit=rescue.target (大體至關於級別1)

另外一個方法是修改 default.target。能夠經過 systemctl 修改它:

# systemctl enable multi-user.target

命令執行狀況由 systemctl 顯示:連接 /etc/systemd/system/default.target 被建立,指向新的默認啓動級別。該方法當且僅當目標配置文件中有如下內容時有效:

[Install] Alias=default.target

目前,multi-user.target、graphical.target 都包含這段內容。

日誌
systemd提供了本身日誌系統(logging system),稱爲 journal. 使用 systemd 日誌,無需額外安裝日誌服務(syslog)。讀取日誌的命令:

# journalctl

默認狀況下(當 Storage= 在文件 /etc/systemd/journald.conf 中被設置爲 auto),日誌記錄將被寫入 /var/log/journal/。該目錄是 systemd 軟件包的一部分。若被刪除,systemd 不會自動建立它,直到下次升級軟件包時重建該目錄。若是該目錄缺失,systemd 會將日誌記錄寫入 /run/systemd/journal。這意味着,系統重啓後日志將丟失。

過濾輸出
journalctl能夠根據特定字段過濾輸出,例如:

顯示本次啓動後的全部日誌:

# journalctl -b

不過,通常你們更關心的不是本次啓動後的日誌,而是上次啓動時的(例如,剛剛系統崩潰了)。目前尚未這項功能,正在 systemd-devel@lists.freedesktop.org 討論中。

目前的折中方案是:

# journalctl --since=today | tac | sed -n '/-- Reboot --/{n;:r;/-- Reboot --/q;p;n;b r}' | tac

以上命令輸出本日內的全部啓動信息。但要注意,若是日誌不少,該命令執行時間會比較漫長。

動態跟蹤最新信息:

# journalctl -f

顯示特定程序的全部消息:

 # journalctl /usr/lib/systemd/systemd

顯示特定進程的全部消息:

# journalctl _PID=1

顯示指定單元的全部消息:

# journalctl -u netcfg

詳情參閱man journalctl、man systemd.journal-fields

日誌大小限制
若是按上面的操做保留日誌的話,默認日誌最大限制爲所在文件系統容量的 10%,即:若是 /var/log/journal 儲存在 50GiB 的根分區中,那麼日誌最多存儲 5GiB 數據。能夠修改 /etc/systemd/journald.conf 中的 SystemMaxUse 來指定該最大限制。如限制日誌最大 50MiB:

SystemMaxUse=50M

詳情參見 man journald.conf.

配合syslog使用
systemd提供了 socket /run/systemd/journal/syslog,以兼容傳統日誌服務。全部系統信息都會被傳入。要使傳統日誌服務工做,須要讓服務連接該 socket,而非 /dev/log(官方說明)。Arch 軟件倉庫中的 syslog-ng 已經包含了須要的配置。

設置開機啓動 syslog-ng:

 # systemctl enable syslog-ng

疑難解答
關機/重啓十分緩慢
若是關機特別慢(甚至跟死機了同樣),極可能是某個拒不退出的服務在做怪。systemd 會等待一段時間,而後再嘗試殺死它。請閱讀這篇文章,確認你是不是該問題受害者。

短時進程無日誌記錄
若 journalctl -u foounit.service 沒有顯示某個短時進程的任何輸出,那麼改用 PID 試試。例如,若 systemd-modules-load.service 執行失敗,那麼先用 systemctl status systemd-modules-load 查詢其 PID(好比是123),而後檢索該 PID 相關的日誌 journalctl -b _PID=123。運行時進程的日誌元數據(諸如 _SYSTEMD_UNIT 和 _COMM)被亂序收集在 /proc 目錄。要修復該問題,必須修改內核,使其經過套接字鏈接來提供上述數據,該過程相似於 SCM_CREDENTIALS。

診斷啓動問題
使用以下內核參數引導: systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M

禁止在程序崩潰時轉儲內存
要使用老的內核轉儲,建立下面文件:

/etc/sysctl.d/49-coredump.conf kernel.core_pattern = core kernel.core_uses_pid = 0

而後運行:

# /usr/lib/systemd/systemd-sysctl

一樣可能須要執行「unlimit」設置文件大小:

$ ulimit -c unlimited

原文:https://blog.linuxeye.com/400.html

相關文章
相關標籤/搜索