Skip to contentsystemd Basics
- 程序 ID 始終為 1
- 所有其他程序不是由 systemd 直接啟動,就是由其子程序啟動
- 由 Linux Kernal 直接啟動
- 抗拒信號 9
- 替代 System V 的 init 背景程序
為了向後兼容,systemd 仍然支持 runlevels,但它使用了一個不同的概念,稱為 target units 來定義系統的具體狀態。
管理 service and target units 是 Linux 系統管理的一個重要部分。
Unit File (單元文件 | 配置文件)
單元文件中包含該單元的描述、屬性、啟動命令等
- 每種類型都有一個手冊頁,比如說
- man systemd.service,解釋各自類型的具體內容。
- Service unit file 可以取代
/etc/init.d/ 腳本
- 文件名擴展名定義了 Unit type
- 所在目錄
/usr/lib/systemd/system/ 和/etc/systemd/system/
/etc/systemd/system/目錄下的文件優先於/usr/lib/systemd/system/目錄下的文件。如果你想改變某個服務的配置,請將相應的服務單元文件從/usr/lib/systemd/system/複製到/etc/systemd/system/,並根據需要在那裡編輯。
由於軟件套件只會將其服務文件放在/usr/lib/systemd/system/中,因此你的改動不會被軟件更新所覆蓋。如果你想恢復軟件包附帶的配置,只需刪除你在/etc/systemd/system/中編輯的文件。
“Unit file “是 systemd 的一個通用術語,用於表示以下內容。
- Service
- 定義背景程序的啟動、停止、重啟和重載操作;文件以
.service 結尾
- Target
- 定義 target 信息及依賴關係,一般僅包含 Unit 段,用於分組 unit 和啟動時的同步點;文件以
.target結尾。
- socket
- 有關 IPC 或 network socket 或 檔案系統 FIFO 的信息,用於 socket-based 的激活(如
inetd);文件以.socket結尾。 - 白話來說就是,監控來自於系統或網絡的數據消息
- Path
- 用於監控指定目錄或文件的變化,並觸發其它 Unit 運行 (例如,當檔案改變時,運行一個服務);文件以
.path結尾。
- Timer
- 關於定時器控制的信息,用於 timer-based 的激活;文件以
.timer結尾。 - 用於配置在特定時間觸發的任務
- Mount point
- 通常由 fstab generator 自動生成;文件以
.mount結尾。 - 定義檔案系統的掛載點,可以替代過去的
/etc/fstab 配置文件
- Automount point
- 用於控制自動掛載檔案系統,相當於 SysV-init 的 autofs 服務;文件以
.automount結尾。
- Swap
- 有關用於 memory paging 的交換設備或檔案的信息;文件以
.swap結尾。 - 定義一個使用者做虛擬記憶體的交換分區
- Device
- 關於在 sysfs/udev(7) device tree 中顯示的設備 unit 的信息; 文件以
.device 結尾。 - 對於 /dev 目錄下的硬件設備,主要用於定義設備之間的依賴關
- Scope / Slice
- 一個分級管理一組程序用的資源的概念;文件以
.scope/.slice結尾。 - Slice : 用於表示一個 CGroup 的樹
- Scope : 這種 Unit 文件不是用戶創建的,而是 Systemd 運行時產生的,描述一些系統服務的分組信息
:::spoiler 快速記憶 Unit 對應的 Filename 表格

:::
Unit File Structure
- All unit files can have
[Unit] and [Install] sections.- Unit 段:定義 Unit 的數據,以及配置與其他 Unit 的關係
- Install 段:定義如何啟動,以及是否開機啟動
- Each type of unit file also has a section that matches its type
- a service unit file has a [Service] section
- a socket unit file has a [Socket] section
- 用於定義服務的具體管理和執行動作
Unit File Sections: [Unit]
- 【啟動順序】: 只涉及啟動順序,不影響啟動結果和運行情況
After=- Start of the unit is delayed until all listed units have started up
- unit 的啟動被推遲,直到 After 中所有列出的 units 都啟動了,才啟動 unit。
Before=- Inverse of After
- 在所有列出的 units 都啟動之前,先啟動 unit。
- 【依賴關係】: 只涉及依賴關係,默認情況下 兩個 Unit 同時啟動
Requires=- The units listed here are activated as well
- Requires 列出的 units 也被激活(平行啟動)
- 如果當前 unit 被激活,Requires 列出的單元也必須成功激活,否則本單元將失敗。
- 與其它 Unit 的強依賴關係,如果其中任意一個 Unit 啟動失敗或異常退出,當前 Unit 也會被退出
Wants=- 與其它 Unit 的弱依賴關係,當本單元被激活時,Systemd 將同時嘗試啟動這裡列出的任何單元。
- 如果沒有找到這些單元或啟動失敗,當前單元將繼續工作。
Conflicts=- Unit is in conflict with the listed units (unit 與所列 units 有衝突)
- 定義了當一個服務和另一個服務發生衝突時應該採取的操作。
- 這可以用來列出不能與當前單元同時運行的單元,啟動有這種關係的單元將導致其他單元被停止。
Description=Documentation=- 文檔地址,可以是一個或多個文檔的 URL 路徑
systemctl status 命令會顯示這些信息,使之易於發現。
如果一個 unit 被啟動,那麼在 Requires 後面列出的 unit 也會被啟動。這個選項對服務啟動順序沒有影響,服務啟動順序需要單獨使用 Before 或 After 設定。如果沒有設定啟動順序,則服務將會平行啟動。
每個 unit 類型都有一個手冊頁面,例如 systemd.service 的手冊頁面就是用來管理服務 unit 的。
Unit File Sections: [Service]
- 【啟動類型】: 定義程序啟動時的行為
Type=simple- 默認值,
ExecStart= 字段啟動的程序為主程序 - 服務程序不會 fork,如果該服務要啟動其他服務,不要使用此類型啟動,除非該服務是 socket 激活型
Type=forkingExecStart=字段將以fork()方式從父程序創建子程序啟動,創建後父程序會立即退出,子程序成為主程序。- 這告訴
systemd 雖然父程序已退出,但程序仍在運行。 - 通常需要指定
PIDFile 字段,以便 Systemd 能夠跟蹤服務的主程序
Type=oneshot- 只執行一次,Systemd 會等當前服務退出,再繼續往下執行
- 適用於只執行一項任務、隨後立即退出的服務
- 通常需要指定
RemainAfterExit=yes字段,使得 Systemd 在服務程序退出之後仍然認為服務處於激活狀態
Type=dbus- 當前服務通過 D-Bus 信號啟動。當指定的 BusName 出現在 DBus 系統總線上時,Systemd 認為服務就緒
BusName =:當使用“dbus”服務類型時,應將此指示設置為服務將嘗試獲取的D-Bus總線名稱。
Type=notify- 當前服務啟動完畢會發出通知信號,通知 Systemd,然後 Systemd 再啟動其他服務
Type=idle- Systemd 會等到其他任務都執行完,才會啟動該服務。
- 一種使用場合是:讓該服務的輸出,不與其他服務的輸出相混合
- 【啟動行為】
- 所有的啟動設置之前,都可以加上一個連詞號
-,表示”抑制錯誤”,即發生錯誤的時候,不影響其他命令的執行。 ExecStartExecStartPre, ExecStartPost- 在 ExecStart 的命令之前或之後執行的命令
ExecReloadExecStopExecStopPostRemainAfterExit- 當前服務的所有程序都退出的時候,Systemd 仍認為該服務是激活狀態
- 這個配置主要是提供給啟動註冊后立即退出,然後等待消息按需啟動的特殊類型服務使用的
TimeoutSec
- 【重啟行為】
Restart- 定義 main service process 退出時是否要重新啟動
- Available options:
no: 退出後不會重啟 (默認值)on-success: 只有正常退出時(退出狀態碼為 0),才會重啟on-failure: 非正常退出時(退出狀態碼非 0),包括被信號終止和超時,才會重啟(適合背景程序)on-abort: 只有在收到沒有捕捉到的信號終止時,才會重啟always: 不管是什麼退出原因,總是重啟
RestartSecKillMode- 定義 Systemd 如何停止服務的程序
- Available modes:
control-group,當前控制組裡面的所有子程序,都會被殺掉process,只殺主程序(適合 sshd 服務)mixed,主程序將收到 SIGTERM 信號,子程序收到 SIGKILL 信號none ,沒有程序會被殺掉,只是執行服務的 stop 命令。
- 【上下文】
PIDFileEnvironmentFile- 指定當前服務的環境參數檔案。
- 該檔案內部的
key=value,可以用 $key 的形式,在當前設定檔中獲取
簡易範例 :
螢幕輸出 :
- 啟動
sshd,執行的命令是/usr/sbin/sshd -D $OPTIONS,其中的變量$OPTIONS就來自EnvironmentFile字段指定的環境參數文件。
Unit File Sections: Secure Services
適用於 [Service], [Socket], [Mount], [Swap] sections / unit types
- 限製網路訪問(namespace)
PrivateNetwork=yes- 讓服務僅能在自己的 Network namespace 中運作
- 私有的
/tmpPrivateTmp=yes- 讓服務的
/tmp 目錄變成私有,只有該服務才能存取該目錄。
- 限制對目錄的訪問
InaccessibleDirectories=/homeReadOnlyDirectories=/var
- 限制 capabilities
CapabilitiesBoundingSet=CAP_CHOWN CAP_KILL- 只允許服務使用 CAP_CHOWN 和 CAP_KILL 權限
CapabilitiesBoundingSet=-CAP_PTRACE
- 設定使用者、群組和根目錄
User=,指定運行服務的用戶Group=,指定運行服務的用戶組RootDirectory=
- 設備訪問限制(白名單)
- 資源限制
services, sockets, mount points, and swap devices 的 unit 設定檔共享一個配置選項子集,這些選項定義了生成的程序的執行環境。
Unit File Sections: [Install]
- Unit 文件可能包含一個
[Install] 部分。 - 它承載了 Unit 的安裝信息。
systemd在執行時不會解釋這部分內容。- 在 Unit 安裝過程中,它只被
systemctl 工具的 enable 啟用和 disable 禁用命令使用。
WantedBy=, RequiredBy=
- 該選項可以多次使用,也可以給出一個用空格分隔的 Unit 名稱列表。
- 通過
systemctl enable 安裝該 Unit 時,會在所列 Unit 的 .wants/ 或 .requirements/ 目錄下創建一個符號鏈接。 - 這樣做的效果是,從列出的 Unit 到當前 Unit 增加了一個 Wants= 或 Requires= 類型的依賴關係。
- 主要結果是,當列出的 Unit 被啟動時,當前 Unit 將被啟動。
Alias=
- 當前 Unit 可用於啟動的別名
- 一個以空格分隔的列表,列出該 Unit 應安裝的其他名稱。
- 這裡列出的名稱必須與 Unit 文件名有相同的後綴(即類型)。
- 該選項可以多次指定,在這種情況下,所有列出的名稱都會被使用。
- 在安裝時,
systemctl enable 將從這些名字創建符號鏈接到 Unit 檔案名。
also=
- 當前 Unit 被 enable/disable 時,會被同時操作的其他 Unit
- 在安裝/卸載本 Unit 時要安裝/卸載的其他 Unit 。
- 如果用戶要求安裝/卸載配置了該選項的 Unit ,
systemctl enable 和 systemctl disable 也會自動安裝/卸載該選項中列出的 Unit 。 - 該選項可以多次使用,也可以給出一個用空格分隔的 Unit 名稱列表
systemctl
systemctl 是用來與 systemd 互動的指令
- 不帶選項時,它會顯示系統上所有已啟動的 Unit
- 加上
-a 則會顯示所有未啟動的 Unit - 預設使用
less 當作分頁器 - 有些 Unit 沒有在
/usr/lib/systemd/system/ 中的檔案定義,而是會自動建立,例如- 依據 /etc/fstab 中的設定,建立各種
.mount Unit - 其他 Unit 是根據
/usr/lib/udev/rules.d/ 中的規則,包含含有 TAG+=systemd 的規則建立的。
Manage Services
- systemd 用的 Command 是 :
systemctl <command> <service>.service
- System V 用的 Command 是 :
- 在 SysV init 中,需要在某個運行級別下啟動的服務是透過
/etc/init.d/rcX.d/ 目錄中的符號連結來配置的,這些符號連結指向 /etc/init.d/ 中的腳本。 - 在 SysV init 中,你可以通過使用
start 參數來調用服務的啟動腳本手動啟動服務,或者通過使用 stop 參數來調用腳本來停止服務。
systemd 允許你一次管理多個服務。不像 SysV init 一樣一個接一個執行初始化腳本,你可以執行以下命令:
如果你想列出系統上可用的所有服務,輸入
systemd 最重要的服務管理命令。
- start - 啟動服務。
- stop - 停止服務。
- restart - 關閉服務並重新啟動,若服務還沒運行,則會啟動服務。
- try-restart - 重啟當前正在運行的服務。對未運行的服務沒有任何作用。
- reload - 告訴服務在不中斷操作的情況下重新加載其配置文件。
- 例如 : 告訴 Apache 重新加載一個修改過的 httpd.conf 配置文件。
- 注意,不是所有的服務都支持重載。
- reload-or-restart - 如果支持重載,就重新加載服務,否則就重新啟動。如果一個服務還沒有運行,它將被啟動。
- reload-or-try-restart - 如果支持重載,則重新加載服務,否則,如果當前正在運行,則重新啟動它們。對未運行的服務沒有任何作用。
- status - 列出服務的狀態信息。
- systemd 命令顯示的細節包括描述、可執行文件、狀態、cgroup 和服務最後發布的信息。
- 不同的服務,System V init 顯示的細節級別也不同。
- is-active - 顯示服務是否處於激活狀態。
在 systemd 中,你可以使用 systemctl start <service> 或 service <service> start 命令(後者在 SLES 11 的 SysV init 中也適用)來啟動一個服務。
Enabling/Disabling Services
systemd 還可以讓你永久性地啟用或禁用服務,使它們在被要求時自動啟動或始終不可用。
可以通過 YaST 或者命令行來實現這一功能。
如果你想知道某個服務是否被啟用,可以使用下面的命令
在 sysv init 中使用的 chkconfig 或 insserv 命令的功能也被包含在 systemctl 命令中,使用 enable 和 disable ,如下所示。
Enable service
螢幕輸出 :
Disable service
螢幕輸出 :
為啟用一個服務而創建的鏈接是基於 service unit file 中[Install]部分的信息 (上例中的 sshd.service,指定 WantedBy=multi-user.target )。
注意
- 當在命令行上 enable 一個服務時,它不會被自動啟動。
- 它被安排在下一次系統啟動或
runlevel/target 改變時啟動。
要在啟用服務後立即啟動它,請明確運行
systemctl start <service>.service 或 rc<service> start。
當禁用一個服務時,你可能仍然需要停止當前正在運行的服務實例。
注意: 可以用 service 命令來啟動和停止服務,但不能用這個命令來 enable 或 disable 服務。
參考文章 : Understanding Systemd Units and Unit Files
參考文章 : Linux Systemd 詳細介紹: Unit、Unit File、Systemctl、Target
What is Target
代表 Linux 系統目前或期望的運行狀態,Target (目標)定義了必須存在的一個或多個資源(Unit),讓系統能夠在該狀態下運行並處於活動狀態。
例如,執行 systemd suspend 命令讓系統暫停,會觸發啟動 suspend.target,然後執行裏面的 systemd-suspend.service Unit,使系統達到一個暫停的狀態
Target Units
「Targets」是類似「runlevels」的同步點,但是更細緻。
- Targets 會將服務和其他 units 分組。
- 一些 Target units 相當於 runlevels(運行等級)
multi-user.target 相當於 runlevel 3graphical.target 相當於 runlevel 5
- 切換 Target:
- 使用
systemctl isolate multi-user.target指令。
以下是一個描述 systemd 的 Target Unit 的文字段落,其中包含不同的 Target Unit 名稱、描述以及它們在 System V 中的等級對應。
- default.target:系統默認啟動的 target,沒有對應的 System V 等級。
- 這個 Target 總是透過符號連結(alias)與
multi-user.target或graphical.target連結
- graphical.target:帶有網絡、多用戶支持和顯示管理器的系統。在 System V 中對應到 Runlevel 5。
Multi-user.target with a GUI
- multi-user.target:帶有網絡的多用戶系統。在 System V 中對應到 Runlevel 3。
- 所有服務都在運行中,但只能使用命令列介面(CLI)。
- n/a:本地的無網絡多用戶系統。在 System V 中沒有對應的等級。
- mail-transfer-agent.target:所有必要的郵件收發服務。沒有對應的 System V 等級。
- rescue.target:單用戶系統,也就是維護模式,沒有網絡。在 System V 中對應到 Runlevel 1 或 Runlevel S。
- 一個基本系統,僅運行最基本的服務,並在主控制台上提供救援殼層(rescue shell)以掛載檔案系統。
- emergency.target:在控制台上使用緊急 shell。
- reboot.target:重新啟動系統。在 System V 中對應到 Runlevel 6。
- halt.target:在不關閉系統電源的情況下停止系統。在 System V 中對應到 Runlevel 0。