systemd---Linux的初始化系統
一、概述
systemd是一套Linux系統的基本構建塊。它提供了一個系統和服務管理器,它作為PID 1運行,並啟動系統的其余部分。systemd提供了積極的並行化能力,使用Socket和D-bus激活來啟動服務,提供守護進程的按需啟動,使用Linux控制組跟蹤進程,維護mount 和automount點(autofs)。systemd支持Sys v和LSB init腳本,並作為Sys V init的替代。其他部分包括日誌守護程序、用於控制基本系統配置的實用工具,如主機名、日期、區域設置、維護登錄用戶列表和運行容器和虛擬機、系統帳戶、運行時目錄和設置,以及管理簡單網絡配置的守護進程。總之systemd誕生的目的是為了能夠並發啟動服務,加快系統啟動速度,並可以通過linux cgroup來監控追蹤進程。
(systemd的架構圖,從圖上可以看出,systemd利用了Linux的三個模塊cgroups, autofs, kdbus。分別對進程控制,文件自動掛載,進程的通訊服務來優化啟動服務)
二、systemd常用的命令
1. systemctl
用於操作控制系統的命令:
$ systemctl poweroff # 關機
$ systemctl reboot # 重新開機
$ systemctl suspend # 進入暫停模式
$ systemctl hibernate # 進入休眠模式
$ systemctl rescue # 強制進入救援模式
$ systemctl emergency # 強制進入緊急救援模式
管理單個 unit systemctl 提供了一組子命令來管理單個的 unit,其命令格式為: systemctl [command] [unit] command 主要有: start:立刻啟動後面接的 unit。 stop:立刻關閉後面接的 unit。 restart:立刻關閉後啟動後面接的 unit,亦即執行 stop 再 start 的意思。 reload:不關閉 unit 的情況下,重新載入配置文件,讓設置生效。 enable:設置下次開機時,後面接的 unit 會被啟動。 disable:設置下次開機時,後面接的 unit 不會被啟動。 status:目前後面接的這個 unit 的狀態,會列出有沒有正在執行、開機時是否啟動等信息。 is-active:目前有沒有正在運行中。 is-enable:開機時有沒有默認要啟用這個 unit。 kill :向運行 unit 的進程發送信號。 show:列出 unit 的配置。 mask:註銷 unit,註銷後你就無法啟動這個 unit 了。 unmask:取消對 unit 的註銷。
查看系統上的 unit systemctl 提供了子命令可以查看系統上的 unit,命令格式為: systemctl [command] [--type=TYPE] [--all] command 有: list-units:列出當前已經啟動的 unit,如果添加 -all 選項會同時列出沒有啟動的 unit。 list-unit-files:根據 /lib/systemd/system/ 目錄內的文件列出所有的 unit。 --type=TYPE:可以過濾某個類型的 unit。
操作 target unit 命令的格式: systemctl [command] [unit.target] command 有: get-default:取得目前的 target。 set-default:設置後面接的 target 成為默認的操作模式。 isolate:切換到後面接的模式。
查看 unit 間的依賴關系: systemctl list-dependencies [unit] [--reverse] 選項 --reverse 會反向追蹤是誰在使用這個 unit。 查看系統打開的socket文件命令: $systemctl list-sockets
2.systemd-analyze
$ systemd-analyze #查看系統啟動耗時 $ systemd-analyze blame # 查看每個服務的啟動耗時 $ systemd-analyze critical-chain [service] #查看系統啟動流或者指定服務的啟動流
3.hostnamectl
查看當前主機信息,或者設置本機或部署環境的名稱
4. timedatectl 查看或者設置當前時區
5.loginctl 查看當前登錄用戶信息
三、systemd配置服務的規則 (抄自:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html,官方文檔:https://www.freedesktop.org/software/systemd/man/systemd.unit.html)
[Unit]區塊通常是配置文件的第一個區塊,用來定義 Unit 的元數據,以及配置與其他 Unit 的關系。它的主要字段如下。
Description:簡短描述
Documentation:文檔地址
Requires:當前 Unit 依賴的其他 Unit,如果它們沒有運行,當前 Unit 會啟動失敗
Wants:與當前 Unit 配合的其他 Unit,如果它們沒有運行,當前 Unit 不會啟動失敗
BindsTo:與Requires類似,它指定的 Unit 如果退出,會導致當前 Unit 停止運行
Before:如果該字段指定的 Unit 也要啟動,那麽必須在當前 Unit 之後啟動
After:如果該字段指定的 Unit 也要啟動,那麽必須在當前 Unit 之前啟動
Conflicts:這裏指定的 Unit 不能與當前 Unit 同時運行
Condition...:當前 Unit 運行必須滿足的條件,否則不會運行
Assert...:當前 Unit 運行必須滿足的條件,否則會報啟動失敗
[Install]通常是配置文件的最後一個區塊,用來定義如何啟動,以及是否開機啟動。它的主要字段如下。
WantedBy:它的值是一個或多個 Target,當前 Unit 激活時(enable)符號鏈接會放入/etc/systemd/system目錄下面以 Target 名 + .wants後綴構成的子目錄中
RequiredBy:它的值是一個或多個 Target,當前 Unit 激活時,符號鏈接會放入/etc/systemd/system目錄下面以 Target 名 + .required後綴構成的子目錄中
Alias:當前 Unit 可用於啟動的別名
Also:當前 Unit 激活(enable)時,會被同時激活的其他 Unit
[Service]區塊用來 Service 的配置,只有 Service 類型的 Unit 才有這個區塊。它的主要字段如下。
Type:定義啟動時的進程行為。它有以下幾種值。
Type=simple:默認值,執行ExecStart指定的命令,啟動主進程
Type=forking:以 fork 方式從父進程創建子進程,創建後父進程會立即退出
Type=oneshot:一次性進程,Systemd 會等當前服務退出,再繼續往下執行
Type=dbus:當前服務通過D-Bus啟動
Type=notify:當前服務啟動完畢,會通知Systemd,再繼續往下執行
Type=idle:若有其他任務執行完畢,當前服務才會運行
ExecStart:啟動當前服務的命令
ExecStartPre:啟動當前服務之前執行的命令
ExecStartPost:啟動當前服務之後執行的命令
ExecReload:重啟當前服務時執行的命令
ExecStop:停止當前服務時執行的命令
ExecStopPost:停止當其服務之後執行的命令
RestartSec:自動重啟當前服務間隔的秒數
Restart:定義何種情況 Systemd 會自動重啟當前服務,可能的值包括always(總是重啟)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
TimeoutSec:定義 Systemd 停止當前服務之前等待的秒數
Environment:指定環境變量
有時我們需要將多個unit組裝在一起弄成一個target service。啟動某個target時,會同時啟動這個target下的所有unit。多個target服務也可以同時啟動。
四、日誌管理命令
# 查看所有日誌(默認情況下 ,只保存本次啟動的日誌) $ sudo journalctl # 查看內核日誌(不顯示應用日誌) $ sudo journalctl -k # 查看系統本次啟動的日誌 $ sudo journalctl -b $ sudo journalctl -b -0 # 查看上一次啟動的日誌(需更改設置) $ sudo journalctl -b -1 # 查看指定時間的日誌 $ sudo journalctl --since="2012-10-30 18:17:16" $ sudo journalctl --since "20 min ago" $ sudo journalctl --since yesterday $ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00" $ sudo journalctl --since 09:00 --until "1 hour ago" # 顯示尾部的最新10行日誌 $ sudo journalctl -n # 顯示尾部指定行數的日誌 $ sudo journalctl -n 20 # 實時滾動顯示最新日誌 $ sudo journalctl -f # 查看指定服務的日誌 $ sudo journalctl /usr/lib/systemd/systemd # 查看指定進程的日誌 $ sudo journalctl _PID=1 # 查看某個路徑的腳本的日誌 $ sudo journalctl /usr/bin/bash # 查看指定用戶的日誌 $ sudo journalctl _UID=33 --since today # 查看某個 Unit 的日誌 $ sudo journalctl -u nginx.service $ sudo journalctl -u nginx.service --since today # 實時滾動顯示某個 Unit 的最新日誌 $ sudo journalctl -u nginx.service -f # 合並顯示多個 Unit 的日誌 $ journalctl -u nginx.service -u php-fpm.service --since today # 查看指定優先級(及其以上級別)的日誌,共有8級 # 0: emerg # 1: alert # 2: crit # 3: err # 4: warning # 5: notice # 6: info # 7: debug $ sudo journalctl -p err -b # 日誌默認分頁輸出,--no-pager 改為正常的標準輸出 $ sudo journalctl --no-pager # 以 JSON 格式(單行)輸出 $ sudo journalctl -b -u nginx.service -o json # 以 JSON 格式(多行)輸出,可讀性更好 $ sudo journalctl -b -u nginx.serviceqq -o json-pretty # 顯示日誌占據的硬盤空間 $ sudo journalctl --disk-usage # 指定日誌文件占據的最大空間 $ sudo journalctl --vacuum-size=1G # 指定日誌文件保存多久 $ sudo journalctl --vacuum-time=1years
systemd---Linux的初始化系統