systemd是RHEL7的新特性,用於改變以往SysvInit的啟動方式,提高系統服務的運行效率,為系統的啟動和管理提供一套完整的解決方案。
不同系統的init版本
centos5: Sysv Init centos6: Upstart centos7: systemd
以往通過如下命令來啟動服務:
/etc/init.d/nginx start
或者
service nginx start
一、Unit的含義
systemd可以管理所有系統資源,不同資源統稱為 Unit,一共分為12種:
Service unit: 系統服務 Target unit: 多個unit構成一個組 Device unit: 硬件設備 Mount unit: 文件系統的掛載點 Automount unit: 自動掛載點 Path unit: 文件或路徑 Scope unit: 不是由Systemd啟動的外部進程 Slice unit: 進程組 Snapshot unit: Systemd快照,可以切回某個快照 Socket unit: 進程間通信的socket Swap unit: swap文件 Timer unit: 定時器
二、Unit管理常用命令(主要針對service)
開機自啟動
systemctl enable nginx
關閉自啟動
systemctl disable nginx
服務狀態
systemctl status nginx
服務重啟
systemctl restart nginx
殺死一個服務
systemctl kill nginx
服務是否激活
systemctl is-active nginx
顯示已啟動的服務
systemctl list-units --type=service
顯示服務的配置文件
systemctl list-unit-files --type=service
鎖定服務
systemctl mask nginx
解鎖服務
systemctl unmask nginx
重載服務配置
systemctl daemon-reload
查看服務的依賴關系
systemctl list-dependencies nginx
三、Unit配置文件
每一個Unit都有一個配置文件,用於告訴系統如何啟動Unit,systemd默認從 /etc/systemd/system/ 目錄讀取配置文件,
但該目錄下存放的大部分是鏈接,指向目錄 /usr/lib/systemd/system/ 目錄下的文件。
centos7的服務腳本一般存放在 /usr/lib/systemd 下,有系統 system 和 user 區分。
即 /usr/lib/systemd/system 和 /usr/lib/systemd/user。
Unit配置文件目錄主要有三個:
/lib/systemd/system /run/systemd/system /etc/systemd/system
三個目錄的文件優先級依次從低到高,同一服務三個地方都配置了,優先級高的會覆蓋優先級低的。
/run/systemd/system 是進程在運行時動態創建unit文件的目錄,一般很少修改,除非是修改程序運行時的一些參數時,即Session級別的,才在這里做修改。
四、Unit服務配置
每個服務以.service后綴,一般會分為3部分:[Unit],[Service],[Install],具體以nginx服務為例:
[Unit] Description=nginx - high performance web server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s stop #Restart配置可以在進程被kill掉之后,讓systemctl產生新的進程,避免服務掛掉 Restart=on-failure RestartSec=30 [Install] WantedBy=multi-user.target
1、[Unit]區塊
[Unit]區塊通常是配置文件的第一個區塊,用來定義Unit的元數據,以及配置與其他Unit的關系。
Description: 簡短描述 Documentation: 文檔地址 After:依賴,僅當依賴的服務啟動之后再啟動自定義的服務單元
2、[Service]區塊
[Service]區塊用來Service的配置,只有service類型的unit才有本區塊。
Type: 定義啟動時的進程行為。它有以下幾種值:
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 認為服務就緒。 Type=idle :systemd 會等待所有任務處理完成后,才開始執行 idle 類型的單元。其他行為與 Type=simple 類似。
其他選項:
ExecStart: 啟動服務的命令 ExecStartPre: 啟動服務之前執行的命令 ExecStartPost: 啟動服務之后執行的命令 ExecReload: 重啟服務執行時的命令 ExecStop: 停止服務時執行的命令 ExecStopPost: 停止服務之后執行的命令 RestartSec: 自動重啟服務間隔的秒數 Restart: 定義何種情況下會自動重啟服務,可能的值包括always(總是重啟)、on-success、on-failure、on-abnormal、on-abort、on-watchdog TimeoutSec: 定義Systemd停止服務之前等待的秒數 Environment: 指定環境變量 PIDFile: pid文件路徑 PrivateTmp: true表示給服務分配獨立的臨時空間 User: 執行命令的用戶 Group: 執行命令的組
3、[Install]區塊
[Install]區塊用來定義如何啟動,以及是否開機啟動。
WantedBy: 它的值是一個或多個Target,當前Unit激活時(enable)符號鏈接會放入/etc/systemd/system目錄下面以Target名 + .wants后綴構成的子目錄中 RequiredBy: 它的值是一個或多個Target,當前Unit激活時(enable)符號鏈接會放入/etc/systemd/system目錄下面以Target名 + .required后綴構成的子目錄中 Alias: 當前Unit可用於啟動的別名 Also: 當前Unit激活時(enable),會被同時激活的其他Unit
五、Target的概念
Target就是一個Unit組,包含許多相關Unit。啟動某個Target的時候,Systemd就會啟動里面所有的Unit。
傳統init啟動模式里面,有RunLevel的概念,跟Target的作用很類似。不同的是,RunLevel是互斥的,不可能多個RunLevel同時啟動,但是多個Target可以同時啟動。
Target的常用命令:
查看所有target下的unit systemctl list-unit-files --type=target 查看默認target,即默認的運行級別。對應於舊的`runlevel`命令 systemctl get-default 設置默認的target systemctl set-default multi-user.target 查看target下的unit systemctl list-dependencies multi-user.target 切換target,不屬於新target的unit都會被停止 systemctl isolate multi-user.target
Target與Runlevels的對應關系:
SysV 運行級別 | Systemd 目標 | 注釋 |
0 | runlevel0.target, poweroff.target | 中斷系統(halt) |
1, s, single | runlevel1.target, rescue.target | 單用戶模式 |
2, 4 | runlevel4.target, multi-user.target | 用戶自定義運行級別,通常識別為級別3。 |
3 | multi-user.target | 多用戶,無圖形界面。用戶可以通過終端或網絡登錄。 |
5 | graphical.target | 多用戶,圖形界面。繼承級別3的服務,並啟動圖形界面服務。 |
6 | reboot.target | 重啟 |
emergency | emergency.target | 急救模式(Emergency shell) |
Target與init進程的主要差別如下:
默認的RunLevel(在/etc/inittab文件設置)現在被默認的Target取代,位置是/etc/systemd/system/default.target,通常符號鏈接到graphical.target(圖形界面)或者multi-user.target(多用戶命令行)
啟動腳本的位置: 以前是/etc/init.d目錄,符號鏈接到不同的RunLevel目錄(比如/etc/rc3.d、/etc/rc5.d等),現在則存放在/lib/systemd/system和/etc/systemd/system目錄。
配置文件的位置: 以前init進程的配置文件是/etc/inittab,各種服務的配置文件存放在/etc/sysconfig目錄。現在的配置文件主要存放在/lib/systemd目錄,在/etc/systemd目錄里面的修改可以覆蓋原始設置。
六、日志管理
Systemd統一管理所有Unit的啟動日志。只用journalctl一個命令,查看所有日志(內核日志和應用日志)。日志的配置文件在 /etc/systemd/journald.conf。
查看所有日志(默認顯示本次啟動的所有日志)
journalctl
或者
journalctl -b
查看內核日志
journalctl -k
查看指定時間的日志
通過--since和--until選項,可以過濾任意時間限制,顯示指定條件之前、之后或之間的日志。
查看2020年1月9號10點到現在的日志
journalctl --since="2020-01-09 10:00:00"
查詢一個時間段范圍內的日志。
journalctl --since="2020-01-09 10:00:00" --until="2020-01-09 12:00:00"
journal還能夠理解部分相對值及命名簡寫。例:"yesterday"、"today"、"tomorrow"、"now"等,也可以使用"-"或者"+"設定相對值,或者使用"ago"之前的表達。
查看昨天的日志
journalctl –since yesterday
查看10點到一小時前的日志
journalctl --since 10:00 --until "1 hour ago"
查看指定服務的日志
journalctl -u sshd.service --since today
由於某些服務當中包含多個子進程,因此如果我們可以通過進程ID實現查詢
journalctl _PID=6870 --since today
有時候我們可能希望顯示全部來自特定用戶或者群組的日志條目,這就需要使用_UID或者_GID。
可以通過(id -u 用戶名)來查看用戶的 UID
journalctl _UID=1000 --since today
實時滾動某服務的最新日志
journalctl -u sshd.service -f
顯示指定行數的最新日志
journalctl -u sshd.service -n 20
按日志級別顯示日志
0: emerg
1: alert
2: crit
3: err
4: warning
5: notice
6: info
7: debug
journalctl -p info -u sshd.service
日志默認以分頁輸出,如果不想分頁加上 --no-pager
journalctl -u sshd.service --no-pager
以json格式輸出日志,可讀性更好
journalctl -u sshd.service -o json-pretty
顯示日志占據的硬盤空間
journalctl --disk-usage
設置日志占用的空間
journalctl --vacuum-size=1G
設置日志保存的時間
journalctl --vacuum-time=1month
參考資料:
http://www.jinbuguo.com/systemd/systemd.html https://wiki.archlinux.org/index.php/Systemd https://ivanzz1001.github.io/records/post/linuxops/2018/03/09/linux-systemctl