Linux Systemd 詳細介紹: Unit、Unit File、Systemctl、Target
- 2020 年 6 月 23 日
- 筆記
Systemd
簡介
CentOS 7 使用 Systemd 替換了SysV
Ubuntu 從 15.04 開始使用 Systemd
Systemd 是 Linux 系統工具,用來啟動守護進程,已成為大多數發行版的標準配置
特點
優點:
-
按需啟動進程,減少系統資源消耗
-
並行啟動進程,提高系統啟動速度
在 SysV-init 時代,將每個服務項目編號,依次執行啟動腳本。Ubuntu 的 Upstart 解決了沒有直接依賴的啟動之間的並行啟動。而 Systemd 通過 Socket 快取、DBus 快取和建立臨時掛載點等方法進一步解決了啟動進程之間的依賴,做到了所有系統服務並發啟動。對於用戶自定義的服務,Systemd 允許配置其啟動依賴項目,從而確保服務按必要的順序運行。
SystemV Upstart 參考上一篇博文:Linux 初始化系統 SystemV Upstart
-
使用 CGroup 監視和管理進程的生命周期
CGroup 提供了類似文件系統的介面,當進程創建子進程時,子進程會繼承父進程的 CGroup。因此無論服務如何啟動新的子進程,所有的這些相關進程都會屬於同一個 CGroup
在 Systemd 之前的主流應用管理服務都是使用 進程樹 來跟蹤應用的繼承關係的,而進程的父子關係很容易通過 兩次 fork 的方法脫離。
而 Systemd 則提供通過 CGroup 跟蹤進程關係,引補了這個缺漏。通過 CGroup 不僅能夠實現服務之間訪問隔離,限制特定應用程式對系統資源的訪問配額,還能更精確地管理服務的生命周期
-
統一管理服務日誌
-
支援快照和系統恢復
缺點:
- 過於複雜,與作業系統的其他部分強耦合,違反”keep simple, keep stupid”的Unix 哲學
架構圖
Unit(單元|服務)
Systemd 可以管理所有系統資源:
- 將系統資源劃分為12類
- 將每個系統資源稱為一個 Unit。Unit 是 Systemd 管理系統資源的基本單位
- 使用一個 Unit File 作為 Unit 的單元文件,Systemd 通過單元文件控制 Unit 的啟動
例如,MySQL服務被 Systemd 視為一個 Unit,使用一個 mysql.service 作為啟動配置文件
Unit File(單元文件|配置文件)
單元文件中包含該單元的描述、屬性、啟動命令等
類型
Systemd 將系統資源劃分為12類,對應12種類型的單元文件
系統資源類型 | 單元文件擴展名 | 單元文件描述 |
---|---|---|
Service | .service | 封裝守護進程的啟動、停止、重啟和重載操作,是最常見的一種 Unit 文件 |
Target | .target | 定義 target 資訊及依賴關係,一般僅包含 Unit 段 |
Device | .device | 對於 /dev 目錄下的硬體設備,主要用於定義設備之間的依賴關係 |
Mount | .mount | 定義文件系統的掛載點,可以替代過去的 /etc/fstab 配置文件 |
Automount | .automount | 用於控制自動掛載文件系統,相當於 SysV-init 的 autofs 服務 |
Path | .path | 用於監控指定目錄或文件的變化,並觸發其它 Unit 運行 |
Scope | .scope | 這種 Unit 文件不是用戶創建的,而是 Systemd 運行時產生的,描述一些系統服務的分組資訊 |
Slice | .slice | 用於表示一個 CGroup 的樹 |
Snapshot | .snapshot | 用於表示一個由 systemctl snapshot 命令創建的 Systemd Units 運行狀態快照,可以切回某個快照 |
Socket | .socket | 監控來自於系統或網路的數據消息 |
Swap | .swap | 定義一個用戶做虛擬記憶體的交換分區 |
Timer | .timer | 用於配置在特定時間觸發的任務,替代了 Crontab 的功能 |
對於操作單元文件的命令,如果預設擴展名,則默認
.service
擴展名而操作 target 的命令,例如 isolate,則默認
.target
擴展名
語法
單元文件的語法來源於 XDG桌面入口配置文件.desktop
文件
Unit 文件可以分為三個配置區段:
- Unit 段:所有 Unit 文件通用,用來定義 Unit 的元數據,以及配置與其他 Unit 的關係
- Install 段:所有 Unit 文件通用,用來定義如何啟動,以及是否開機啟動
- Service 段:服務(Service)類型的 Unit 文件(後綴為 .service)特有的,用於定義服務的具體管理和執行動作
單元文件中的區段名和欄位名大小寫敏感
每個區段內都是一些等號連接的鍵值對(鍵值對的等號兩側不能有空格)
Unit 段
主要欄位如下:
-
Description
:當前服務的簡單描述 -
Documentation
:文檔地址,可以是一個或多個文檔的 URL 路徑【依賴關係】
-
Requires
:與其它 Unit 的強依賴關係,如果其中任意一個 Unit 啟動失敗或異常退出,當前 Unit 也會被退出 -
Wants
:與其它 Unit 的弱依賴關係,如果其中任意一個 Unit 啟動失敗或異常退出,不影響當前 Unit 繼續執行只涉及依賴關係,默認情況下 兩個 Unit 同時啟動
【啟動順序】
-
After
:該欄位指定的 Unit 全部啟動完成以後,才會啟動當前 Unit -
Before
:該欄位指定的 Unit 必須在當前 Unit 啟動完成之後再啟動只涉及啟動順序,不影響啟動結果和運行情況
-
Binds To
:與 Requires 相似,該欄位指定的 Unit 如果退出,會導致當前 Unit 停止運行 -
Part Of
:一個 Bind To 作用的子集,僅在列出的 Unit 失敗或重啟時,終止或重啟當前 Unit,而不會隨列出Unit 的啟動而啟動
//manpages.ubuntu.com/manpages/bionic/en/man5/systemd.unit.5.html
Install 段
主要欄位如下:
WantedBy
:它的值是一個或多個 target,執行enable命令時,符號鏈接會放入/etc/systemd/system
目錄下以 target 名 +.wants
後綴構成的子目錄中RequiredBy
:它的值是一個或多個 target,執行enable命令時,符號鏈接會放入/etc/systemd/system
目錄下以 target 名 +.required
後綴構成的子目錄中Alias
:當前 Unit 可用於啟動的別名Also
:當前 Unit 被 enable/disable 時,會被同時操作的其他 Unit
//manpages.ubuntu.com/manpages/bionic/en/man5/systemd.unit.5.html
Service 段
主要欄位如下:
【啟動類型】
Type
:定義啟動時的進程行為。它有以下幾種值。Type=simple
:默認值,ExecStart
欄位啟動的進程為主進程- 服務進程不會 fork,如果該服務要啟動其他服務,不要使用此類型啟動,除非該服務是 socket 激活型
Type=forking
:ExecStart
欄位將以fork()
方式從父進程創建子進程啟動,創建後父進程會立即退出,子進程成為主進程。- 通常需要指定
PIDFile
欄位,以便 Systemd 能夠跟蹤服務的主進程 - 對於常規的守護進程(daemon),除非你確定此啟動方式無法滿足需求,使用此類型啟動即可
- 通常需要指定
Type=oneshot
:只執行一次,Systemd 會等當前服務退出,再繼續往下執行- 適用於只執行一項任務、隨後立即退出的服務
- 通常需要指定
RemainAfterExit=yes
欄位,使得 Systemd 在服務進程退出之後仍然認為服務處於激活狀態
Type=dbus
:當前服務通過 D-Bus 訊號啟動。當指定的 BusName 出現在 DBus 系統匯流排上時,Systemd認為服務就緒Type=notify
:當前服務啟動完畢會發出通知訊號,通知 Systemd,然後 Systemd 再啟動其他服務Type=idle
:Systemd 會等到其他任務都執行完,才會啟動該服務。- 一種使用場合是:讓該服務的輸出,不與其他服務的輸出相混合
【啟動行為】
-
ExecStart
:啟動當前服務的命令ExecStart=/bin/echo execstart1 ExecStart= ExecStart=/bin/echo execstart2
順序執行設定的命令,把欄位置空,表示清除之前的值
-
ExecStartPre
:啟動當前服務之前執行的命令 -
ExecStartPost
:啟動當前服務之後執行的命令 -
ExecReload
:重啟當前服務時執行的命令 -
ExecStop
:停止當前服務時執行的命令 -
ExecStopPost
:停止當前服務之後執行的命令 -
RemainAfterExit
:當前服務的所有進程都退出的時候,Systemd 仍認為該服務是激活狀態- 這個配置主要是提供給一些並非常駐記憶體,而是啟動註冊後立即退出,然後等待消息按需啟動的特殊類型服務使用的
-
TimeoutSec
:定義 Systemd 停止當前服務之前等待的秒數註:所有的啟動設置之前,都可以加上一個連詞號(
-
),表示”抑制錯誤”,即發生錯誤的時候,不影響其他命令的執行。比如,EnvironmentFile=-/etc/sysconfig/sshd
(注意等號後面的那個連詞號),就表示即使/etc/sysconfig/sshd
文件不存在,也不會拋出錯誤。
【重啟行為】
RestartSec
:Systemd 重啟當前服務間隔的秒數KillMode
:定義 Systemd 如何停止服務,可能的值包括:- control-group(默認值):當前控制組裡面的所有子進程,都會被殺掉
- process:只殺主進程(sshd 服務,推薦值)
- mixed:主進程將收到 SIGTERM 訊號,子進程收到 SIGKILL 訊號
- none:沒有進程會被殺掉,只是執行服務的 stop 命令。
Restart
:定義何種情況 Systemd 會自動重啟當前服務,可能的值包括:- no(默認值):退出後不會重啟
- on-success:只有正常退出時(退出狀態碼為0),才會重啟
- on-failure:非正常退出時(退出狀態碼非0),包括被訊號終止和超時,才會重啟(守護進程,推薦值)
- on-abnormal:只有被訊號終止和超時,才會重啟(對於允許發生錯誤退出的服務,推薦值)
- on-abort:只有在收到沒有捕捉到的訊號終止時,才會重啟
- on-watchdog:超時退出,才會重啟
- always:不管是什麼退出原因,總是重啟
【上下文】
-
PIDFile
:指向當前服務 PID file 的絕對路徑。 -
User
:指定運行服務的用戶 -
Group
:指定運行服務的用戶組 -
EnvironmentFile
:指定當前服務的環境參數文件。該文件內部的key=value
鍵值對,可以用$key
的形式,在當前配置文件中獲取啟動
sshd
,執行的命令是/usr/sbin/sshd -D $OPTIONS
,其中的變數$OPTIONS
就來自EnvironmentFile
欄位指定的環境參數文件。
//manpages.ubuntu.com/manpages/bionic/en/man5/systemd.service.5.html
佔位符
在 Unit 文件中,有時會需要使用到一些與運行環境有關的資訊,例如節點 ID、運行服務的用戶等。這些資訊可以使用佔位符來表示,然後在實際運行中動態地替換為實際的值。
模板
在現實中,往往有一些應用需要被複制多份運行,就會用到模板文件
模板文件的寫法與普通單元文件基本相同,只是模板文件名是以 @ 符號結尾。例如:[email protected]
通過模板文件啟動服務實例時,需要在其文件名的 @ 字元後面附加一個用於區分服務實例的參數字元串,通常這個參數是用於監控的埠號或控制台 TTY 編譯號
systemctl start [email protected]
Systemd 在運行服務時,首先尋找跟單元名完全匹配的單元文件,如果沒有找到,才會嘗試選擇匹配模板
例如上面的命令,System 首先會在約定的目錄下尋找名為 [email protected] 的單元文件,如果沒有找到,而文件名中包含 @ 字元,它就會嘗試去掉後綴參數匹配模板文件。對於 [email protected],Systemd 會找到 [email protected] 模板文件,並通過這個模板文件將服務實例化。
狀態
systemctl list-unit-files
將會列出文件的 state,包括 static, enabled, disabled, masked, indirect
-
masked
service軟鏈接到
/dev/null
該單元文件被禁止建立啟動鏈接
-
static
該單元文件沒有
[Install]
部分(無法執行),只能作為其他配置文件的依賴 -
enabled
已建立啟動鏈接
-
disabled
沒建立啟動鏈接
示例
-
關掉觸摸板配置文件
Unit] Description=Switch-off Touchpad [Service] Type=oneshot ExecStart=/usr/bin/touchpad-off start ExecStop=/usr/bin/touchpad-off stop RemainAfterExit=yes [Install] WantedBy=multi-user.target
- oneshot 表明這個服務只要運行一次就夠了,不需要長期運行
RemainAfterExit
欄位設為yes
,表示進程退出以後,服務仍然保持執行。這樣的話,一旦使用systemctl stop
命令停止服務,ExecStop
指定的命令就會執行,從而重新開啟觸摸板
Systemd 內建命令
systemd-analyze
Analyze and debug system manager, If no command is passed, Systemd-analyze time is implied
//www.freedesktop.org/software/systemd/man/systemd-analyze.html
systemd-analyze time
查看初始化耗時
systemd-analyze blame
列印所有運行單元,按它們初始化的時間排序。此資訊可用於優化啟動時間。注意,輸出可能具有誤導性,因為一個服務的初始化可能非常緩慢,因為它等待另一個服務的初始化完成
systemd-run
將一個指定的服務變成後台服務
未測試
參考 //www.freedesktop.org/software/systemd/man/systemd-run.html
systemctl 系統服務管理命令
systemctl
是 Systemd 的主命令,用於管理系統
與 service 命令的區別
- systemctl 融合了 service 和 chkconfig 的功能
- 在 Ubuntu18.04 中沒有自帶 chkconfig 命令;service 命令實際上重定向到 systemctl 命令
動作 | SysV Init 指令 | Systemd 指令 |
---|---|---|
啟動某服務 | service httpd start | systemctl start httpd |
停止某服務 | service httpd stop | systemctl stop httpd |
重啟某服務 | service httpd restart | systemctl restart httpd |
檢查服務狀態 | service httpd status | systemctl status httpd |
刪除某服務 | chkconfig –del httpd | 停掉應用,刪除其配置文件 |
使服務開機自啟動 | chkconfig –level 5 httpd on | systemctl enable httpd |
使服務開機不自啟動 | chkconfig –level 5 httpd off | systemctl disable httpd |
查詢服務是否開機自啟 | chkconfig –list | grep httpd | systemctl is-enabled httpd |
加入自定義服務 | chkconfig –add test | systemctl load test |
顯示所有已啟動的服務 | chkconfig –list | systemctl list-unit-files | grep enabled |
參數
--all
顯示載入到記憶體的所有單元
--type
-t
--type=
顯示指定類型(12種類型)的單元
--state
--state=
顯示指定狀態的單元或單元文件
單元狀態
輸入
systemctl list-units --state
按Tab
鍵,顯示所有可用的值單元文件狀態
另外還可以用 enabled static disabled 等
systemctl list-unit-files
顯示的狀態
--failed
--state=failed
顯示載入失敗的單元
systemctl --failed
--version
列印 Systemd 版本
lfp@legion:/lib/systemd/system$ systemctl --version
Systemd 237
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
單元命令
我的理解
- systemd 對單元的管理,不涉及單元文件自身屬性和內容
list-units
相當於systemctl
列出當前已載入的單元(記憶體)
默認情況下僅顯示處於激活狀態(正在運行)的單元
UNIT 單元名
LOAD 載入狀態
ACTIVE SUB 執行狀態(大狀態 子狀態)
DESCRIPTION 描述
start
啟動單元
systemctl start mysql.service
stop
停止單元
systemctl stop mysql.service
kill
殺掉單元進程
systemctl kill mysql.service
reload
不終止單元,重新載入 針對該單元的 運行配置文件,而不是 針對 systemd的 該單元的啟動配置文件
例如啟動 MySQL 服務,reload 可以在不停止服務的情況下重載 MySQL 的配置文件
my.cnf
restart
重啟單元
該單元在重啟之前擁有的資源不會被完全清空,比如文件描述符存儲設施
systemctl reload mysql.service
status
status [unit | PID]
顯示單元或進程所屬單元的運行資訊
systemctl status mysql.service
Loaded
行:配置文件的位置,是否設為開機啟動
Active
行:表示正在運行
Main PID
行:主進程ID
CGroup
塊:應用的所有子進程日誌塊:應用的日誌
is-active
判斷指定的單元是否處於激活狀態
# 默認會列印當前單元的狀態,可以通過 --quiet 參數取消列印
lfp@legion:~$ systemctl is-active mysql
active
is-failed
判斷指定的單元是否處於啟動失敗狀態
lfp@legion:~$ systemctl is-failed mysql
active
list-dependencies
查看單元之間的依賴關係
systemctl list-dependencies graphical.target
systemctl list-dependencies mysql.service
show
show --property= Unit
<==> show -p Unit
顯示單元所有底層參數
lfp@legion:~$ systemctl show -p MainPID mysql
MainPID=1061
set-property
在單元啟動的時候設置運行時的某個屬性,立即生效,並保存在磁碟中作為啟動配置
如果添加了--runtime
則重啟後失效
並非所有的屬性都可以設置,只是 systemd.resource-control 包含的屬性
isolate
切換到某個 target(系統狀態),立即停止該 target 未包含的單元進程。也可以理解為切換 runlevel
如果沒有指定擴展名,則默認.target
只有當.target單元文件中的AllowIsolate=yes
時,才能使用 isolate 切換;也可以用IgnoreOnIsolate=yes
欄位來拒絕使用 isolate 切換
systemctl isolate multi-user.target
cat
顯示單元配置文件的備份文件,包括插入式配置drop-ins
,可以完整的看到單元服務的配置。注意這裡列印的依據是磁碟的上內容,如果用戶修改了配置文件(磁碟已修改)但是未執行daemon-reload
命令(記憶體中未更新),那麼該命令顯示的配置和實際執行情況有出入
lfp@legion:~$ systemctl cat mysql.service
# /lib/systemd/system/mysql.service
# MySQL Systemd service file
[Unit]
Description=MySQL Community Server
...
[Install]
WantedBy=multi-user.target
[Service]
Type=forking
...
# 這段就顯示的是 插入式配置 drop-in 的內容
# /etc/systemd/system/mysql.service.d/mysql.conf
# MySQL Systemd service file
[Unit]
# Description=MySQL Community Server conf
[Service]
# ExecStartPost=/home/lfp/bin/espeak.sh
單元文件命令
我的理解
- systemd 對單元文件自身屬性和內容的管理
list-unit-files
列出所有已安裝的單元文件和它們的啟用狀態
和
list-units
的區別是
- list-units 僅顯示當前已載入到記憶體中的單元
- list-unit-files 會讀取單元文件內容,列出所有單元,包括存在於硬碟未載入進記憶體的單元
實際測試結果:
systemctl list-unit-files 顯示「348 Unit files listed」
systemctl list-units –all 顯示「405 loaded units listed」
systemctl list-units 顯示 「232 loaded units listed」
enable
使某個單元開機自啟動
這會根據單元文件內容中的[Install]
指定的 target 組,創建一個軟鏈接
lfp@legion:/etc/systemd/system$ vim v2rayL.service # 文件內容 [Install] 段 ...... [Install] WantedBy=multi-user.target ...... lfp@legion:/etc/systemd/system$ systemctl is-enabled v2rayL.service disabled lfp@legion:/etc/systemd/system$ systemctl enable v2rayL.service # 根據 [Install] 段指定的組,添加軟鏈接 Created symlink /etc/systemd/system/multi-user.target.wants/v2rayL.service → /etc/systemd/system/v2rayL.service. lfp@legion:/etc/systemd/system$ systemctl is-enabled v2rayL.service enabled
disable
取消某個單元開機自啟動設置,刪除軟鏈接
這會刪除所有指向該單元文件的軟鏈接,不僅僅是 enable 操作創建的
reenable
disable 和 enable 的結合,根據單元文件內容中的 [Install] 段,重置軟鏈接
is-enabled
檢查某個單元是否是開機自啟動的(建立的啟動鏈接)
lfp@legion:~$ systemctl is-enabled mysql
enabled
get-default
獲取默認啟動 target,default-target 是指向該 target 的軟鏈接
set-default
設置默認啟動 target,同時修改 default-target 指向設定的 target
systemctl set-default multi-user.target
生命周期管理命令
daemon-reload
重新載入所有的單元文件和依賴關係
對單元文件有修改的時候,需要執行該命令重新載入文件內容
系統管理命令
reboot
systemctl reboot
重啟系統(非同步操作)
it will return after the reboot operation is enqueued, without waiting for it to complete
poweroff
關閉系統,切斷電源(非同步操作)
halt
僅CPU停止工作,其他硬體仍處於開機狀態(非同步操作)
suspend
暫停系統(非同步操作)
將觸發執行suspend.target
hibernate
讓系統進入冬眠狀態(非同步操作)
將觸發執行hibernate.target
目錄、文件
/run/systemd/system/
單元(服務)運行時生成的配置文件所在目錄
/etc/systemd/system/
系統或用戶自定義的配置文件,初始化過程中Systemd
只執行/etc/systemd/system
目錄裡面的配置文件
/lib/systemd/system/
軟體安裝時添加的配置文件,類似於 /etc/init.d/
對於支援 Systemd 的程式,安裝的時候,會自動的在 /lib/systemd/system
目錄添加一個配置文件
其他目錄都是軟鏈接
/etc/systemd/system/default.target
Systemd 執行的第一個單元文件,符號鏈接到默認啟動 target 對應的 .target
單元文件
優先順序
SysV 的啟動腳本放在/etc/init.d
目錄下
Systemd 的單元文件放在/etc/systemd/system
和 /lib/systemd/system
目錄下
當一個程式在3個目錄下都存在啟動方式時,優先順序是/etc/systemd/system --> /lib/systemd/system --> /etc/init.d
lfp@legion:/etc/init.d$ ll
-rwxr-xr-x 1 root root 5650 5月 19 22:09 mysql*
lfp@legion:/etc/systemd/system$ ll
-rw-r--r-- 1 root root 511 5月 20 01:42 mysql.service
lfp@legion:/lib/systemd/system$ ll
-rw-r--r-- 1 root root 499 5月 20 01:20 mysql.service
-
/etc/systemd/system
裡面的同名service會覆蓋/lib/systemd/system
裡面的注意查看文件資訊,該同名文件不能是指向 /lib/systemd/system 的軟鏈接
軟鏈接不會覆蓋而會同步
-
如果某個程式不存在Systemd 單元文件,那麼會執行
/etc/init.d
裡面的啟動腳本
根據啟動過程,
/etc/systemd/system/multi-user.target.wants/
目錄下是很多指向/lib/systemd/system/
目錄的軟鏈接,所以兩個目錄下的單元文件會互相同步。如果
/etc/systemd/system/
和/etc/systemd/system/multi-user.target.wants/
同時存在單元文件,測試發現,不管是手動啟動還是開機自啟動,使用的都是/etc/systemd/system/
目錄下的service單元文件
測試
執行/etc/init.d
目錄下的腳本
mysql 修改 mysql.service
為mysql.service.bak
然後通過service mysql restart
啟動/etc/init.d/mysql
腳本
下面是啟動後的一些資訊
註:在恢復
mysql.service
之前,需要先通過service mysql stop
利用/etc/init.d/mysql
腳本中的stop
結束上面的進程,否則一旦恢復,service mysql stop
執行的操作就不是/etc/init.d/mysql
腳本中的stop
,無法結束上面的進程,出現命令無法正常執行的情況
結束上面的進程,恢復mysql.service
,重新啟動
/etc/systemd/system
覆蓋測試
未修改前,查看MySQL的狀態
lfp@legion:~$ service mysql status
● mysql.service - MySQL Community Server
# 可以發現這裡的 mysql.service 是在 /lib/systemd/system 下面
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: en
Active: active (running) since Sat 2020-04-25 18:34:30 CST; 5h 33min ago
Main PID: 988 (mysqld)
Tasks: 28 (limit: 4915)
CGroup: /system.slice/mysql.service
└─988 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
4月 25 18:34:30 legion Systemd[1]: Starting MySQL Community Server...
4月 25 18:34:30 legion Systemd[1]: Started MySQL Community Server.
將 /lib/systemd/system 下面的文件複製到 /etc/systemd/system/
下面
sudo cp /lib/systemd/system/mysql.service /etc/systemd/system/
修改 mysql.service
sudo vim /etc/systemd/system/mysql.service
重啟 mysql.service ,系統提示需要重新載入
lfp@legion:~$ systemctl restart mysql.service
Warning: The Unit file, source configuration file or drop-ins of mysql.service changed on disk.
Run 'systemctl daemon-reload' to reload units.
lfp@legion:~$ systemctl daemon-reload # 重新載入
lfp@legion:~$ systemctl restart mysql.service # 重啟
lfp@legion:~$ systemctl status mysql.service
● mysql.service - MySQL Community Server hahahaha # 發現這裡是修改之後的,覆蓋了 /lib/systemd/lib 中的
# 這裡也可以看到載入路徑
Loaded: loaded (/etc/systemd/system/mysql.service; enabled; vendor preset: en
Active: active (running) since Sun 【2020-04-26】 00:47:02 CST; 5s ago
Process: 21590 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/m
Process: 21581 ExecStartPre=/usr/share/mysql/mysql-Systemd-start pre (code=exi
Main PID: 21592 (mysqld)
Tasks: 27 (limit: 4915)
CGroup: /system.slice/mysql.service
└─21592 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pi
4月 26 00:47:02 legion Systemd[1]: Starting MySQL Community Server hahahaha...
4月 26 00:47:02 legion Systemd[1
Target
兩個含義
-
系統的某個狀態稱為一個 target(類似於”狀態點”)
-
達到某個系統狀態,所需的一個或多個資源(Unit)稱為一個 target(一個 Unit 組)
-
target是一個抽象的系統資源,不像MySQL有實體
-
如果一個target只包含一個Unit,那麼該 target,沒有對應的目錄,指的就是這個 Unit
例如
hibernate.target
只包含systemd-hibernate.service
一個Unit如果一個target包含多個Unit,那麼該target,有對應的 xxx.target.wants 目錄,指的是目錄裡面所有的Unit
例如
multi-user.target
包含位於/etc/systemd/system/multi-user.target.wants
目錄下的多個 Unit
-
target也是一個 Target 類型的系統資源,有對應的單元文件 xxx.target
Systemd 使用 target 來劃分和管理資源(Unit),啟動(激活)某個 xxx.target 單元文件,通過執行該 target 包含的 Unit,使系統達到某種狀態
對於狀態點的理解:
例如,執行
systemd suspend
命令讓系統暫停,會觸發啟動suspend.target
,然後執行裡面的systemd-suspend.service
Unit,使系統達到一個暫停的狀態
傳統的init
啟動模式裡面,有 RunLevel 的概念,跟 Target 的作用很類似。不同的是,RunLevel 是互斥的,不可能多個 RunLevel 同時啟動,但是多個 Target 可以同時啟動
啟動 target
runlevel是 SysV init 初始化系統中的概念,在Systemd初始化系統中使用的是 Target,他們之間的映射關係是
Runlevel | Target | 說明 |
---|---|---|
0 | poweroff.target | 關閉系統 |
1 | rescue.target | 維護模式 |
2,3,4 | multi-user.target | 多用戶,無圖形系統(命令行介面) |
5 | graphical.target | 多用戶,圖形化系統(圖形用戶介面) |
6 | reboot.target | 重啟系統 |
啟動過程
-
讀入
/boot
目錄下的內核文件 -
內核文件載入完之後,開始執行第一個程式
/sbin/init
初始化進程,由 Systemd 初始化系統引導,完成相關的初始化工作 -
Systemd 執行
default.target
,獲知設定的啟動 target實際上
default.target
是指向設定的啟動 target 的軟鏈接
-
Systemd 執行啟動 target 對應的單元文件。根據單元文件中定義的依賴關係,傳遞控制權,依次執行其他 target 單元文件,同時啟動每個 target 包含的單元
對於圖形化介面,默認 target 是 graphical,Systemd 執行位於
/lib/systemd/system/
目錄下的 graphical.target 單元文件,根據 target 單元文件中定義的依賴關係,依次啟動其他 target 單元文件以及各個 target 包含的位於/etc/systemd/system/
目錄下的單元例如: graphical.target 的依賴關係是
[Unit] Description=Graphical Interface Documentation=man:systemd.special(7) Requires=multi-user.target # Wants=display-manager.service # Conflicts=rescue.service rescue.target After=multi-user.target rescue.service rescue.target display-manager.service # AllowIsolate=yes
因此,依次啟動 multi-user.target –> basic.target –> sysinit.target –> local-fs.target –>local-fs-pre.target –> …
同時啟動每個 target 包含的位於
/etc/systemd/system/
目錄下的UnitSysV對應的 rc5.d –> /etc/init.d 目錄下的指定的腳本就不會在開機的時候執行了
查看默認 target
systemctl get-default
lfp@legion:~$ runlevel
N 5
lfp@legion:~$ systemctl get-default
graphical.target
修改默認 target
systemctl set-default [xxx.target]
# Ubuntu18.04
# 圖形用戶介面 切換 命令行介面
sudo systemctl set-default multi-user.target
# 命令行介面 切換 圖形用戶介面
systemctl set-default graphical.target
reboot
# 命令行介面 想進入 圖形用戶介面(僅進入一次,重啟系統後仍然會進入命令行模式)
sudo systemctl start lightdm
其他操作
修改配置文件
-
直接修改
/lib/systemd/system
目錄下的單元文件如果軟體包更新,修改會被丟棄
-
將
/lib/systemd/system
中的單元文件複製到/etc/systemd/system/
如果軟體包更新,不會同步更新
-
在
/etc/systemd/system/
中添加配置(推薦)
添加配置
步驟:
- 在
/etc/systemd/system/
目錄下新建<單元名>.d
目錄 - 在
<單元名>.d
目錄下,新建<單元名>.conf
文件 - 在
<單元名>.conf
文件中修改配置
測試:
-
創建目錄及文件
# /mysql.service.d lfp@legion:/etc/systemd/system/mysql.service.d$ ls mysql.conf
-
修改配置
# MySQL Systemd service config file # 不需要所有的組,僅添加需要修改的組及選項 [Unit] Description=MySQL Community Server config test [Service] ExecStartPost=/home/lfp/bin/espeak.sh
-
重啟測試
lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl daemon-reload lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl restart mysql.service lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl status mysql.service lfp@legion:/etc/systemd/system/mysql.service.d$ systemctl status mysql.service # 描述已經被修改 ● mysql.service - MySQL Community Server config test Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) # 加入了配置文件 Drop-In: /etc/systemd/system/mysql.service.d └─mysql.conf Active: active (running) since Thu 2020-05-21 20:18:02 CST; 12min ago # 新增的動作執行成功 Process: 4703 ExecStartPost=/home/lfp/bin/espeak.sh (code=exited, status=0/SUCCESS) Process: 4672 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS) Process: 4663 ExecStartPre=/usr/share/mysql/mysql-Systemd-start pre (code=exited, status=0/SUCCESS) Main PID: 4674 (mysqld) Tasks: 27 (limit: 4915) CGroup: /system.slice/mysql.service └─4674 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid 5月 21 20:18:02 legion espeak.sh[4703]: ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
添加開機啟動服務
- 添加啟動配置文件
- 通過
rc.local
文件
/lib/systemd/rc.local.service
# 如果存在,就自動添加到 multi-user.target
# This Unit gets pulled automatically into multi-user.target by
# Systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
創建 rc.local 文件,賦予可執行許可權,即可添加啟動命令
sudo touch /etc/rc.local
chmod 755 /etc/rc.local
lfp@legion:/etc$ vim rc.local
#!/bin/sh -e
echo "test rc.local" > /usr/local/rclocal.log
echo "rc.local `date +%Y-%m-%d-%H:%M:%S`" >/home/lfp/log/rclocal.log
exit 0
system 工具集
hostnamectl 主機名管理命令
hostnamectl
hostnamectl status
Show current system hostname and related information
lfp@legion:/lib/systemd/system$ hostnamectl status
Static hostname: legion
Icon name: computer-laptop
Chassis: laptop
Machine ID: b28xxxxxxxx2ecafa29e
Boot ID: 21xxxxxxxxxxxx1d3a47504d
Operating System: Ubuntu 18.04.4 LTS
Kernel: Linux 5.3.0-51-generic
Architecture: x86-64
journalctl 日誌管理命令
Systemd 統一管理所有 Unit 的啟動日誌。帶來的好處就是,可以只用journalctl
一個命令,查看所有日誌(內核日誌和應用日誌)。
配置文件
/etc/systemd/journald.conf
日誌保存目錄
/var/log/journal/
默認日誌最大限制為所在文件系統容量的 10%,可通過 /etc/systemd/journald.conf
中的 SystemMaxUse 欄位來指定
該目錄是 systemd 軟體包的一部分。若被刪除,systemd 不會自動創建它,直到下次升級軟體包時重建該目錄。如果該目錄缺失,systemd 會將日誌記錄寫入 /run/systemd/journal。這意味著,系統重啟後日誌將丟失。
journalctl -u [服務名]
查看指定單元的日誌
journalctl -b
- journalctl -b -0 顯示本次啟動的資訊
- journalctl -b -1 顯示上次啟動的資訊
- journalctl -b -2 顯示上上次啟動的資訊
參考
//manpages.ubuntu.com/manpages/bionic/en/man1/systemctl.1.html
//manpages.ubuntu.com/manpages/bionic/en/man5/systemd.unit.5.html
//www.cnblogs.com/yingsong/p/6012180.html
//www.cnblogs.com/sparkdev/p/8472711.html
//www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
//www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
//linoxide.com/linux-how-to/systemd-boot-process/
//cloud.tencent.com/developer/article/1516125
//www.cnblogs.com/sparkdev/p/8472711.html
//www.ibm.com/developerworks/cn/linux/1407_liuming_init3/index.html?ca=drs-