1. 程式人生 > >systemd---Linux的初始化系統

systemd---Linux的初始化系統

控制 -abort ola ted 主機 end strong timeout idl

一、概述

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的初始化系統