CentOS7/RHEL7 systemd詳解

目錄
1. 爲什麼是systemd
(1) 關於Linux服務管理
(2) SysV init的優缺點
(3) UpStart的改進
(4) systemd的誕生
(5)爲什麼systemd能做到啓動很快
2. SysV init介紹
(1) 什麼是SystemV
(2)SysV init的運行級別
(3)SysV init運行順序
(4)SysV init和系統關閉
(5)SysV init的管理和控制功能
3. systemd的特性
(1)systemd解決了那些問題?
(2)systemd的爭議在哪裏?
(3)systemd能更徹底的結束服務進程
4. CentOS 7的systemd特性
(1)套接字服務保持激活功能
(2)進程間通訊保持激活功能
(3)設備保持激活功能
(4)文件路徑保持激活功能
(5)系統狀態快照
(6)掛載和自動掛載點管理
(7)閃電並行啓動
(8)單元邏輯模擬檢查
(9)和SysV init向後兼容
5. 如何分析衡量systemd啓動速度
(1)查看詳細的每個服務消耗的啓動時間
(2)查看嚴重消耗時間的服務樹狀表
(3)打印分析圖及其他命令
6. CentOS 7的systemd向後兼容
(1)systemd對運行級別支持有限。
(2)systemd不支持像init腳本那樣的個性化命令。
(3)systemd不支持和沒有從systemd啓動的服務通訊。
(4)systemd可以只停止運行的服務
(5)不能從標準輸出設備讀到系統服務信息。
(6)systemd不繼承任何上下文環境。
(7)SysV init腳本依賴性
(8)超時機制
7. systemd服務管理
(1) 什麼是單元
(2)systemd的服務管理
(3)服務詳細信息查看
8. 使用systemd target
(1)怎樣知道一個目標需要哪些進程服務?
(2)target與運行級別
(3)target管理
9. 關閉、暫停、休眠系統
10. 通過systemd管理遠程系統
11. 創建和修改systemd單元文件
(1)單元文件概述
(2)理解單元文件結構
(3)創建自定義的單元文件
(4)創建emacs.service例子:
(5)創建第二個sshd服務的例子
(6)修改已經存在的單元文件
(7)擴展默認單元配置文件配置
12. 單元實例化
13. VNC SERVER配置


1.爲什麼是systemd

(1) 關於Linux服務管理

Linux系統從啓動到提供服務的過程是這樣,先是機器加電,然後通過MBR或者UEFI加載GRUB,再啓動內核,內核啓動服務,然後開始對外服務。
SysV init UpStart systemd主要是解決服務引導管理的問題。
提示:關於systemd的拼寫,官方的說法就是systemd,既不是Syetemd,也是不systemD。

(2) SysV init的優缺點

SysV init是最早的解決方案,依靠劃分不同的運行級別,啓動不同的服務集,服務依靠腳本控制,並且是順序執行的。
SysV init方案的優點是:
原理簡單,易於理解;
依靠shell腳本控制,編寫服務腳本門檻比較低。
缺點是:
服務順序啓動,啓動過程比較慢;
不能做到根據需要來啓動服務,比如通常希望插入U盤的時候,再啓動USB控制的服務,這樣可以更好的節省系統資源。

(3) UpStart的改進

爲了解決系統服務的即插即用,UpStart應運而生,在CentOS6系統中,SysV init和UpStart是並存的,UpStart主要解決了服務的即插即用。服務順序啓動慢的問題,UpStart的解決辦法是把相關的服務分組,組內的服務是順序啓動,組之間是並行啓動。

(4) systemd的誕生

SysV init服務啓動慢,在以前並不是一個問題,尤其是Linux系統以前主要是在服務器系統上,常年也難得重啓一次。有的服務器光硬件檢測都需要5分鐘以上,相對來說系統啓動已經很快了。
但是隨着移動互聯網的到來,SysV init服務啓動慢的問題顯得越來越突出,許多移動設備都是基於Linux內核,比如安卓。移動設備啓動比較頻繁,每次啓動都要等待服務順序啓動,顯然難以接受,systemd就是爲了解決這個問題誕生的。
systemd的設計思路是:
儘可能的快速啓動服務;
儘可能的減少系統資源佔用。

(5)爲什麼systemd能做到啓動很快

systemd使用並行的方法啓動服務,不像SysV init是順序執行的,所以大大節省了系統啓動時間。
使用並行啓動,最大的難點是要解決服務之間的依賴性,systemd的解決辦法是使用類似緩衝池的辦法。比如對TCP有依賴的服務,在啓動的時候會檢查依賴服務的TCP端口,systemd會把對TCP端口的請求先緩存起來,當依賴的服務器啓動之後,在將請求傳遞給服務,使兩個服務通訊。同樣的進程間通訊的D-BUS也是這樣的原理,目錄掛載則是先讓服務以爲目錄被掛載了,到真正訪問目錄的時候,纔去真正操作。


2.SysV init介紹

SysV init是systemV風格的init系統,顧名思義,它源於SystemV系列UNIX。它提供了比BSD風格init系統更高的靈活性。是已經風行了幾十年的UNIX init系統,一直被各類Linux發行版所採用。
(1) 什麼是SystemV

SystemV,曾經也被稱爲AT&T SystemV,是Unix操作系統衆多版本中的一支。它最初由AT&T開發,在1983年第一次發佈。一共發行了4個SystemV的主要版本:版本1、2、3和4。SystemV Release4,或者稱爲SVR4,是最成功的版本,成爲一些UNIX共同特性的源頭,例如”SysV初始化腳本“(/etc/init.d),用來控制系統啓動和關閉,SystemV Interface Definition(SVID)是一個SystemV如何工作的標準定義。

(2)SysV init的運行級別

SysV init用術語runlevel來定義"預訂的運行模式"。SysV init檢查'/etc/inittab'文件中是否含有'initdefault'項。來告訴init系統是否有一個默認運行模式。如果沒有默認的運行模式,那麼用戶將進入系統控制檯,手動決定進入何種運行模式。
SysV init中運行模式描述了系統各種預訂的運行模式。通常會有8種運行模式,即運行模式0到6和S或者s。
每種Linux發行版對運行模式的定義都不太一樣。但0,1,6卻得到了大家的一致贊同:
0關機
1單用戶模式
6重啓
通常在/etc/inittab文件中定義了各種運行模式的工作範圍。比如RedHat定義了runlevel3和5。運行模式3將系統初始化爲字符界面的shell模式;運行模式5將系統初始化爲GUI模式。無論是命令行界面還是GUI,運行模式3和5相對於其他運行模式而言都是完整的正式的運行狀態,計算機可以完成用戶需要的任務。而模式1,S等往往用於系統故障之後的排錯和恢復。
很顯然,這些不同的運行模式下系統需要初始化運行的進程,需要進行的初始化準備都是不同的。比如運行模式3不需要啓動X系統。用戶只需要指定需要進入哪種模式,SysV init負責執行所有該模式所必須的初始化工作。

(3)SysV init運行順序

SysV init巧妙地用腳本,文件命名規則和軟鏈接來實現不同的runlevel。首先,SysV init需要讀取/etc/inittab文件。分析這個文件的內容,它獲得以下一些配置信息:
系統需要進入的runlevel;
捕獲組合鍵的定義;
定義電源fail/restore腳本;
啓動getty和虛擬控制檯;
得到配置信息後,SysV init順序地執行以下這些步驟,從而將系統初始化爲預訂的runlevelX:
/etc/rc.d/rc.sysinit
/etc/rc.d/rc和/etc/rc.d/rcX.d/(X代表運行級別0-6)
/etc/rc.d/rc.local
XDisplayManager(如果需要的話)

1)rc.sysinit腳本功能

首先,運行rc.sysinit以便執行一些重要的系統初始化任務。在RedHat公司的RHEL5中(RHEL6已經使用UpStart了),rc.sysinit主要完成以下這些工作:
激活udev和selinux;
設置定義在/etc/sysctl.conf中的內核參數;
設置系統時鐘;
加載keymaps;
激活交換分區;
設置主機名(hostname);
根分區檢查和remount;
激活RAID和LVM設備;
開啓磁盤配額;
檢查並掛載所有文件系統;
清除過期的locks和PID文件;

2)rc.d腳本

完成了以上這些工作之後,SysV init開始運行/etc/rc.d/rc腳本。根據不同的runlevel,rc腳本將打開對應runlevel的rcX.d目錄(X就是runlevel),找到並運行存放在該目錄下的所有啓動腳本。每個runlevelX都有一個這樣的目錄,目錄名爲/etc/rc.d/rcX.d。
在這些目錄下存放着很多不同的腳本。文件名以S開頭的腳本就是啓動時應該運行的腳本,S後面跟的數字定義了這些腳本的執行順序。在/etc/rc.d/rcX.d目錄下的腳本其實都是一些軟鏈接文件,真實的腳本文件存放在/etc/init.d目錄下。如下所示:
rc5.d目錄下的腳本

[root@www~]#ll/etc/rc5.d/
lrwxrwxrwx1rootroot16Sep42008K02dhcdbd->../init.d/dhcdbd
....(中間省略)....
lrwxrwxrwx1rootroot14Sep42008K91capi->../init.d/capi
lrwxrwxrwx1rootroot23Sep42008S00microcode_ctl->../init.d/microcode_ctl
lrwxrwxrwx1rootroot22Sep42008S02lvm2-monitor->../init.d/lvm2-monitor
....(中間省略)....
lrwxrwxrwx1rootroot17Sep42008S10network->../init.d/network
....(中間省略)....
lrwxrwxrwx1rootroot11Sep42008S99local->../rc.local
lrwxrwxrwx1rootroot16Sep42008S99smartd->../init.d/smartd
....(底下省略)....

當所有的初始化腳本執行完畢。SysV init運行/etc/rc.d/rc.local腳本。
rc.local是Linux留給用戶進行個性化設置的地方。可以把自己私人想設置和啓動的東西放到這裏,一臺LinuxServer的用戶一般不止一個,所以纔有這樣的考慮。

(4)SysV init和系統關閉

SysV init不僅需要負責初始化系統,還需要負責關閉系統。在系統關閉時,爲了保證數據的一致性,需要小心地按順序進行結束和清理工作。
比如應該先停止對文件系統有讀寫操作的服務,然後再umount文件系統。否則數據就會丟失。
這種順序的控制這也是依靠/etc/rc.d/rcX.d/目錄下所有腳本的命名規則來控制的,在該目錄下所有以K開頭的腳本都將在關閉系統時調用,字母K之後的數字定義了它們的執行順序。
這些腳本負責安全地停止服務或者其他的關閉工作。

(5)SysV init的管理和控制功能

此外,在系統啓動之後,管理員還需要對已經啓動的進程進行管理和控制。SysV init軟件包包含了一系列的控制啓動,運行和關閉所有其他程序的工具。
halt停止系統。
init就是SysV init本身的init進程實體,以pid1身份運行,是所有用戶進程的父進程。最主要的作用是在啓動過程中使用/etc/inittab文件創建進程。
killall5就是System V的killall命令。向除自己的會話(session)進程之外的其它進程發出信號,所以不能殺死當前使用的shell。
last回溯/var/log/wtmp文件(或者-f選項指定的文件),顯示自從這個文件建立以來,所有用戶的登錄情況。
lastb作用和last差不多,默認情況下使用/var/log/btmp文件,顯示所有失敗登錄企圖。
mesg控制其它用戶對用戶終端的訪問。
pidof找出程序的進程識別號(pid),輸出到標準輸出設備。
poweroff等於shutdown-h–p,或者telinit0。關閉系統並切斷電源。
reboot等於shutdown–r或者telinit6。重啓系統。
runlevel讀取系統的登錄記錄文件(一般是/var/run/utmp)把以前和當前的系統運行級輸出到標準輸出設備。
shutdown以一種安全的方式終止系統,所有正在登錄的用戶都會收到系統將要終止通知,並且不準新的登錄。
sulogin當系統進入單用戶模式時,被init調用。當接收到啓動加載程序傳遞的-b選項時,init也會調用sulogin。
telinit實際是init的一個連接,用來向init傳送單字符參數和信號。
utmpdump以一種用戶友好的格式向標準輸出設備顯示/var/run/utmp文件的內容。
wall向所有有信息權限的登錄用戶發送消息。
不同的Linux發行版在這些SysV init的基本工具基礎上又開發了一些輔助工具用來簡化init系統的管理工作。比如RedHat的RHEL在SysV init的基礎上開發了initscripts軟件包,包含了大量的啓動腳本(如rc.sysinit),還提供了service,chkconfig等命令行工具,甚至一套圖形化界面來管理init系統。其他的Linux發行版也有各自的initscript或其他名字的init軟件包來簡化SysV init的管理。
只要理解了SysV init的機制,在一個最簡的僅有SysV init的系統下,可以直接調用腳本啓動和停止服務,手動創建inittab和創建軟連接來完成這些任務。因此理解SysV init的基本原理和命令是最重要的。甚至也可以開發自己的一套管理工具。


3.systemd的特性

(1)systemd解決了那些問題?

按需啓動服務,減少系統資源消耗;
儘可能並行啓動進程,減少系統啓動等待時間;
提供一個一致的配置環境,不光是服務配置;
提供服務狀態快照,可以恢復特定點的服務狀態。

(2)systemd的爭議在哪裏?

systemd試圖提供一個一致的配置環境,請注意不光是服務配置,還包括其他方面的系統配置,這個也是systemd的野心,希望能把Linux系統上的配置統一起來,爲了達到這個目標,systemd犧牲掉了SysV init和BSD系統的兼容性。systemd充分利用了Linux內核API,不在支持BSD系統,這個是systemd目前在開源社區最大的爭論。
個人人爲這個是個好事情,對管理員來講,再也不用學習不同發行版上不同的配置,也不用爲了寫一個腳本,先去寫一堆判斷,判斷不同的髮型版。運維自動化的前提是標準化,只有標準化了,才能自動化,systemd朝這個方向走了一大步。即使systemd的學習成本比較高。

(3)systemd能更徹底的結束服務進程

服務(daemon)進程,爲了成爲服務,會fork兩次,所以進程編號會發生變化,UpStart在結束進程的時候,有可能會找錯進程編號,造成服務永遠不被停止。
還有更特殊的情況,如果進程產生了子進程,子進程又自己fork了兩次,脫離了主進程,要結束這樣的子進程,UpStart的辦法是通過strace追蹤fork,exit調用,這種方法非常複雜。
systemd利用了內核最新的特性,使用CGroup解決這個問題,CGroup的進程是樹狀的,因此無論服務如何啓動新的子進程,所有的這些相關進程都會屬於同一個CGroup,systemd只需要簡單地遍歷指定的CGroup即可正確地找到所有的相關進程,將它們一一停止即可。


4.CentOS 7的systemd特性

(1)套接字服務保持激活功能

在系統啓動的時候,systemd爲所有支持套接字激活功能的服務創建監聽端口,當服務啓動後,就將套接字傳給這些服務。這種方式不僅可以允許服務在啓動的時候平行啓動,也可以保證在服務重啓期間,試圖連接服務的請求,不會丟失。對服務端口的請求被保留,並且存放到隊列中。

(2)進程間通訊保持激活功能

當有客戶端應用第一次通過D-Bus方式請求進程間通訊時,systemd會立即啓動對應的服務。systemd依據D-Bus的配置文件使用進程間通訊保持激活功能。

(3)設備保持激活功能

當特定的硬件插入時,systemd啓動對應的硬件服務支持。systemd依據硬件服務單元配置文件保持硬件隨時被激活。

(4)文件路徑保持激活功能

當特定的文件或者路徑狀態發生改變的時候,systemd會激活對應的服務。systemd依據路徑服務單元配置文件保證服務被激活。

(5)系統狀態快照

systemd可以臨時保存當前所有的單元配置文件,或者從前一個快照中恢復單元配置文件。爲了保存當前系統服務狀態,systemd可以動態的生成單元文件快照。

(6)掛載和自動掛載點管理

systemd監控和管理掛載和自動掛載點,並根據掛載點的單元配置文件進行掛載。

(7)閃電並行啓動

因爲使用套接字保持激活功能,systemd可以並行的啓動所以套接字監聽服務,大大減少系統啓動時間。

(8)單元邏輯模擬檢查

當激活或者關閉一個單元,systemd會計算依賴行,產生一個臨時的模擬檢查,並且校驗一直性。如果不一致,systemd會嘗試自動修正,並且移除報錯的不重要的任務。

(9)和SysV init向後兼容

systemd完全支持SysV initLinux標準的基礎核心規範腳本,這樣的腳本易於升級到systemd服務單元。


5.如何分析衡量systemd啓動速度

systemd-analyze是一個分析啓動性能的工具,用於分析啓動時服務時間消耗。默認顯示啓動是內核和用戶空間的消耗時間:

[root@localhost~]#systemd-analyze
Startupfinishedin818ms(kernel)+6.240s(initrd)+32.979s(userspace)=40.038s

和使用systemd-analyzetime命令的效果一樣。

(1)查看詳細的每個服務消耗的啓動時間

通過systemd-analyzeblame命令查看詳細的每個服務消耗的啓動時間:

[root@localhost~]#systemd-analyzeblame
30.852siscsi.service
16.994skdump.service
10.871sboot.mount
...
103mssystemd-sysctl.service
101msdatapool.mount

(2)查看嚴重消耗時間的服務樹狀表

systemd-analyzecritical-chain命令打印嚴重消耗時間的服務樹狀表,按照啓動消耗的時間進行排序,時間消耗越多,越排到前面。@之後是服務激活或者啓動的時間,+號之後是服務啓動消耗的時間。個人理解@是從系統引導到服務啓動起來的時間,是一個相對時間消耗,+是服務啓動消耗的時間,是一個絕對時間消耗。

[root@localhost~]#systemd-analyzecritical-chain
Thetimeaftertheunitisactiveorstartedisprintedafterthe"@"character.
Thetimetheunittakestostartisprintedafterthe"+"character.
[email protected]
└─[email protected]+16.994s
└─[email protected]
└─[email protected]+54ms
└─[email protected]+535ms
└─[email protected]
└─[email protected]
└─[email protected]
└─[email protected]
└─[email protected]+2ms
└─[email protected]+67ms
└─[email protected]
└─[email protected]+10.871s
└─systemd-fsck@dev-disk-by\x2duuid-8c77568b\x2d7e51\x2d4e32\x2dbbdf\[email protected]+226ms
└─[email protected]+152ms
└─[email protected]+25ms

(3)打印分析圖及其他命令

systemd-analyzeplot打印一個svg格式的服務消耗時間表,通過瀏覽器可以以圖形的方式展示,非常直觀:

[root@localhost~]#systemd-analyzeplot>plot.svg

注:以上圖片上傳到紅聯Linux系統教程頻道中。

其他參數:
systemd-analyzedot用分隔符產生當前服務
systemd-analyzedump以友好方式顯示當前服務狀態
6systemd文件類型及存放位置
systemd配置文件被稱爲unit單元,根據類型不同,以不同的擴展名結尾。
.service系統服務;
.target一組系統服務;
.automount自動掛載點;
.device能被內核識別的設備;
.mount掛載點;
.path文件系統的文件或者目錄;
.scope外部創建的進程;
.slice一組分層次管理的系統進程;
.snapshot系統服務狀態管理;
.socket進程間通訊套接字;
.swap定義swap文件或者設備;
.timer定義定時器。


6.CentOS 7的systemd向後兼容

systemd被設計成儘可能向後兼容SysV init和Upstart,下面是一些特別要注意的和之前主要版本的RHEL不再兼容的部分。

(1)systemd對運行級別支持有限。

爲了保存兼容,systemd提供一定數量的target單元,可以直接和運行級別對應,也可以被早期的分佈式的運行級別命令支持。不是所有的target都可以被映射到運行級別,在這種情況下,使用runlevel命令有可能會返回一個爲N的不知道的運行級別,所以推薦儘量避免在RHEL7中使用runlevel命令。

(2)systemd不支持像init腳本那樣的個性化命令。

除了一些標準命令參數例如:start、stop、status,SysV init腳本可以根據需要支持想要的任何參數,通過參數提供附加的功能,因爲SysV init的服務器腳本實際上就是shell腳本,命令參數實際上就是shell子函數。舉個例子,RHEL6的iptables服務腳本可以執行panic命令行參數,這個參數可以讓系統立即進入緊急模式,丟棄所有的進入和發出的數據包。但是類似這樣的命令行參數在systemd中是不支持的,systemd只支持在配置文件中指定命令行參數。

(3)systemd不支持和沒有從systemd啓動的服務通訊。

當systemd啓動服務的時候,他保存進程的主ID以便於追蹤,systemctl工具使用進程PID查詢和管理服務。相反的,如果用戶從命令行啓動特定的服務,systemctl命令是沒有辦法判斷這個服務的狀態是啓動還是運行的。

(4)systemd可以只停止運行的服務

在RHEL6及之前的版本,當關閉系統的程序啓動之後,RHEL6的系統會執行/etc/rc0.d/下所有服務腳本的關閉操作,不管服務是處於運行或者根本沒有運行的狀態。而systemd可以做到只關閉在運行的服務,這樣可以大大節省關機的時間。

(5)不能從標準輸出設備讀到系統服務信息。

systemd啓動服務的時候,將標準輸出信息定向到/dev/null,以免打擾用戶。

(6)systemd不繼承任何上下文環境。

systemd不繼承任何上下文環境,如用戶或者會話的HOME或者PATH的環境變量。每個服務得到的是乾淨的上下文環境。

(7)SysV init腳本依賴性

當systemd啓動SysV init腳本,systemd在運行的時候,從LinuxStandardBase(LSB)Linux標準庫頭文件讀取服務的依賴信息並繼承。

(8)超時機制

爲了防止系統被卡住,所有的服務有5分鐘的超時機制。


7.systemd服務管理

(1) 什麼是單元

在RHEL7之前,服務管理是分佈式的被SysV init或UpStart通過/etc/rc.d/init.d下的腳本管理。這些腳本是經典的Bash腳本,允許管理員控制服務的狀態。在RHEL7中,這些腳本被服務單元文件替換。
在systemd中,服務、掛載等資源統一被稱爲單元,所以systemd中有許多單元類型,服務單元文件的擴展名是.service,同腳本的功能相似。例如有查看、啓動、停止、重啓、啓用或者禁止服務的參數。
systemd單元文件放置位置:
/usr/lib/systemd/system/systemd默認單元文件安裝目錄
/run/systemd/systemsystemdsystemd單元運行時創建,這個目錄優先於按照目錄
/etc/systemd/system系統管理員創建和管理的單元目錄,優先級最高。

(2)systemd的服務管理

使用systemcl命令可以控制服務,service命令和chkconfig命令依然可以使用,但是主要是出於兼容的原因,應該儘量避免使用。
使用systemctl命令的時候,服務名字的擴展名可以寫全,例如:
systemctl stop bluuetooth.service
也可以忽略,例如:
systemctl stop bluetooth
systemctl常用命令:
啓動服務 systemctl start name.service
關閉服務 systemctl stop name.service
重啓服務 systemctl restar tname.service
僅當服務運行的時候,重啓服務 systemctl try-restart name.service
重新加載服務配置文件 systemctl relaod name.service
檢查服務運作狀態 systemctl status name.service 或者 systemctl is-active\ name.service
展示所有服務狀態詳細信息 systemctl list-units--type service --all
允許服務開機啓動 systemctl enable name.service
禁止服務開機啓動 systemclt disable name.service
檢查服務開機啓動狀態 systemctl status name.service 或者systemctl\
is-enabled name.service
列出所有服務並且檢查是否開機啓動 systemctl list-unit-files --type service

(3)服務詳細信息查看

使用如下命令列出服務:
systemctl list-units --type service
默認只列出處於激活狀態的服務,如果希望看到所有的服務,使用--all或-a參數:
systemctl list-units--type service --all
有時候希望看到所以可以設置開機啓動的服務,使用如下命令:
systemctl list-unit-files --type service
查看服務詳細信息,使用如下命令:
systemctl status name.service
服務信息關鍵詞解釋
Loaded服務已經被加載,顯示單元文件絕對路徑,標誌單元文件可用。
Active服務已經被運行,並且有啓動時間信息。
Main PID與進程名字一致的PID,主進程PID。
Status服務的附件信息。
Process相關進程的附件信息。
CGroup進程的CGroup信息。


8.使用systemd target

(1)怎樣知道一個目標需要哪些進程服務?

例如,可能想搞明白目標單元multi-user.target究竟啓用了哪些服務,使用以下命令:

$systemctlshow-p"Wants"multi-user.target
Wants=rc-local.serviceavahi-daemon.servicerpcbind.serviceNetworkManager.serviceacpid.servicedbus.serviceatd.servicecrond.serviceauditd.

servicentpd.serviceudisks.servicebluetooth.serviceorg.cups.cupsd.servicewpa_supplicant.servicegetty.targetmodem-manager.serviceportreserve.serviceabrtd.serviceyum-updatesd.serviceupowerd.servicetest-first.servicepcscd.servicersyslog.

servicehaldaemon.serviceremote-fs.targetplymouth-quit.servicesystemd-update-utmp-runlevel.servicesendmail.servicelvm2-monitor.

servicecpuspeed.serviceudev-post.servicemdmonitor.serviceiscsid.servicelivesys.servicelivesys-late.serviceirqbalance.serviceiscsi.service

除了Wants,還可以查看各種形式的依賴和被依賴信息:WantedBy、Requires、RequiredBy、Conflicts、ConflictedBy、Before、After。

(2)target與運行級別

在RHEL7之前的版本,使用運行級別代表特定的操作模式。運行級別被定義爲七個級別,用數字0到6表示,每個級別可以啓動特定的一些服務。RHEL7使用target替換運行基本。
systemd target使用target單元文件描述,target單位文件擴展名是.target,target單元文件的唯一目標是將其他systemd單元文件通過一連串的依賴關係組織在一起。舉個例子,graphical.target單元,用於啓動一個圖形會話,systemd會啓動像GNOME顯示管理(gdm.service)、帳號服務(axxounts-daemon)這樣的服務,並且會激活multi-user.target單元。相似的multi-user.target單元,會啓動必不可少的NetworkManager.service、dbus.service服務,並激活basic.target單元。
RHEL7預定義了一些target和之前的運行級別或多或少有些不同。爲了兼容,systemd也提供一些target映射爲SysV init的運行級別,具體的對應信息如下:
0runlevel0.target,poweroff.target關閉系統。
1runlevel1.target,rescue.target進入救援模式。
2runlevel2.target,multi-user.target進入非圖形界面的多用戶方式。
3runlevel3.target,multi-user.target進入非圖形界面的多用戶方式。
4runlevel4.target,multi-user.target進入非圖形界面的多用戶方式。
5runlevel5.target,graphical.target進入圖形界面的多用戶方式。
6runlevel6.target,reboot.target重啓系統。

(3)target管理

1)使用如下命令查看目前可用的target:

systemctl list-units --type target

改變當前的運行基本使用如下命令:

1 systemctl isolate name.target

2)修改默認的運行級別
使用systemctl get-default命令得到默認的運行級別:

[root@localhost~]#systemctlget-default
multi-user.target

使用systemctl set-default name.target修改默認的運行基本

[root@localhost~]#systemctlset-defaultgraphical.target
rm'/etc/systemd/system/default.target'
ln-s'/usr/lib/systemd/system/graphical.target''/etc/systemd/system/default.target'

3)救援模式和緊急模式
使用systemctl rescue進入救援模式,如果連救援模式都進入不了,可以進入緊急模式:

systtmctl emergency

緊急模式進入做小的系統環境,以便於修復系統。緊急模式根目錄以只讀方式掛載,不激活網絡,只啓動很少的服務,進入緊急模式需要root密碼。


9.關閉、暫停、休眠系統

RHEL7中,使用systemctl替換一些列的電源管理命令,原有的命令依舊可以使用,但是建議儘量不用使用。systemctl和這些命令的對應關係爲:
hatl,systemctl halt停止系統
poweroff,systemctl poweroff關閉系統,關閉系統電源。
reboot,systemctl reboot重啓系統
pm-suspend,systemctl suspend暫停系統
pm-hibernate,systemct lhibernate休眠系統
pm-suspend-hybrid,systemctl hybrid-sleep暫停並休眠系統


10.通過systemd管理遠程系統

不光是可以管理本地系統,systemd還可以控制遠程系統,管理遠程系統主要是通過SSH協議,只有確認可以連接遠程系統的SSH,在systemctl命令後面添加-H或者--host參數,加上遠程系統的ip或者主機名就可以。


11.創建和修改systemd單元文件

(1)單元文件概述

單元文件包含單元的指令和行爲信息。在後臺systemctl命令和單元文件一起工作。爲了出色而正確的完成工作,系統管理員必須能夠手工編輯單元文件。一般系統管理員手工創建的單元文件建議存放在/etc/systemd/system/目錄下面。
單元配置文件的格式是:

unit_name.type_extension

這裏的unit_name代表單元名稱,type_extension代表單元類型。
單元文件可以作爲附加的文件放置到一個目錄下面,比如爲了定製sshd.service服務,可以創建sshd.service.d/custom.conf文件,在文件中做一些自定義的配置。
同樣的,可以創建sshd.service.wants/和sshd.service.requires/目錄。這些目錄包含sshd服務關聯服務的軟連接,在系統安裝的時候,這些軟連接或自動創建,也可以手工創建軟連接。
許多單元配置文件可以使用單元說明符--通配的字符串,可以在單元文件被引導的時候動態的被變量替換。這使創建一些通用的單元配置模版成爲可能。

(2)理解單元文件結構

典型的單元文件包含三節:
[Unit]節,包含不依賴單元類型的一般選項,這些選型提供單元描述,知道單元行爲,配置單元和其他單元的依賴性。
[unittype]節,如果單元有特定的類型指令,在unittype節這些指令被組織在一起。舉個例子,服務單元文件包含[Service]節,裏面有經常使用的服務配置。
[Install]節,包含systemctlenable或者disable的命令安裝信息。
1)[Unit]節選項
Description單元描述信息,這些文字信息在systemclstatus命令是會輸出。
Documentation單元文檔信息的URLs。
After定義在那些單元之後啓動,本單元只在制定的單元啓動之後啓動,不像Requires選項,After選項不明確激活特定的單元,Before選項則是有相反的功能。
Requires配置單元的依賴性,在Requires選項中的單元需要一起被激活,如果有一個單元啓動失敗,其他單元都不會被啓動。
Wants比Requires選項依賴性要弱很多,如果列表之中的的單元啓動失敗,不會對其他單元造成影響,這是推薦的建立自定義單元依賴性的方式。
Conflicts定義單元衝突關係,和Requires相反。
2)[unittype]類型是[Service]時的選項
Type配置單元進程在啓動時候的類型,影響執行和關聯選項的功能,可選的關鍵字是:
simple默認值,進程和服務的主進程一起啓動;
forking進程作爲服務主進程的一個子進程啓動,父進程在完全啓動之後退出。
oneshot同simple相似,但是進程在啓動單元之後隨之退出。
dbus同simple相似,但是隨着單元啓動後只有主進程得到D-BUS名字。
notify同simple相似,但是隨着單元啓動之後,一個主要信息被sd_notify()函數送出。
idle同simple相似,實際執行進程的二進制程序會被延緩直到所有的單元的任務完成,主要是避免服務狀態和shell混合輸出。
ExecStart指定啓動單元的命令或者腳本,ExecStartPre和ExecStartPost節指定在ExecStart之前或者之後用戶自定義執行的腳本。Type=oneshot允許指定多個希望順序執行的用戶自定義命令。
ExecStop指定單元停止時執行的命令或者腳本。
ExecReload指定單元重新加載是執行的命令或者腳本。
Restart這個選項如果被允許,服務重啓的時候進程會退出,會通過systemctl命令執行清除並重啓的操作。
RemainAfterExit如果設置這個選擇爲真,服務會被認爲是在激活狀態,即使所以的進程已經退出,默認的值爲假,這個選項只有在Type=oneshot時需要被配置。
3)[Install]節選項
Alias爲單元提供一個空間分離的附加名字。
RequiredBy單元被允許運行需要的一系列依賴單元,RequiredBy列表從Require獲得依賴信息。
WantBy單元被允許運行需要的弱依賴性單元,Wantby從Want列表獲得依賴信息。
Also指出和單元一起安裝或者被協助的單元。
DefaultInstance實例單元的限制,這個選項指定如果單元被允許運行默認的實例。
4)一個postfix服務的例子:
單元文件位於/usr/lib/systemd/system/postifix.service,內容如下:

[Unit]
Description=PostfixMailTransportAgent
After=syslog.targetnetwork.target
Conflicts=sendmail.serviceexim.service
[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfixstart
ExecReload=/usr/sbin/postfixreload
ExecStop=/usr/sbin/postfixstop
[Install]
WantedBy=multi-user.target

(3)創建自定義的單元文件

以下幾種場景需要自定義單元文件:
希望自己創建守護進程;
爲現有的服務創建第二個實例;
引入SysV init腳本。
另外一方面,有時候需要修改已有的單元文件。
下面介紹創建單元文件的步驟:
1)準備自定義服務的執行文件。
可執行文件可以是腳本,也可以是軟件提供者的的程序,如果需要,爲自定義服務的主進程準備一個PID文件,一保證PID保持不變。另外還可能需要的配置環境變量的腳本,確保所以腳本都有可執行屬性並且不需要交互。
2)在/etc/systemd/system/目錄創建單元文件,並且保證只能被root用戶編輯:

touch/etc/systemd/system/name.servicechmod664/etc/systemd/system/name.service

文件不需要執行權限。
3)打開name.service文件,添加服務配置,各種變量如何配置視所添加的服務類型而定,下面是一個依賴網絡服務的配置例子:

[Unit]
Description=service_description
After=network.target
[Service]
ExecStart=path_to_executable
Type=forking
PIDFile=path_to_pidfile
[Install]
WantedBy=default.target

4)通知systemd有個新服務添加:

systemctldaemon-reload
systemctlstartname.service

(4)創建emacs.service例子:

1)創建文件,並確保正確權限:

~]#touch/etc/systemd/system/emacs.service
~]#chmod664/etc/systemd/system/emacs.service

2)添加配置信息:

[Unit]
Description=Emacs:theextensible,self-documentingtexteditor
[Service]
Type=forking
ExecStart=/usr/bin/emacs--daemon
ExecStop=/usr/bin/emacsclient--eval"(kill-emacs)"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=always
[Install]
WantedBy=default.target

3)通知systemd並開啓服務:

~]#systemctldaemon-reload
~]#systemctlstartemacs.service

(5)創建第二個sshd服務的例子

1)拷貝sshd_config文件

]#cp/etc/ssh/sshd{,-second}_config

2)編輯sshd-second_config文件,添加22220的端口,和PID文件:

Port22220
PidFile/var/run/sshd-second.pid

如果還需要修改其他參數,請閱讀幫助。
3)拷貝單元文件:

~]#cp/usr/lib/systemd/system/sshd{,-second}.service

4)編輯單元文件sshd-second.service
修改描述字段
Description=OpenSSHserversecondinstancedaemon
添加sshd.service服務在After關鍵字之後:
After=syslog.targetnetwork.targetauditd.servicesshd.service
移除sshdkey創建:
ExecStartPre=/usr/sbin/sshd-keygen移除這一行
在執行腳本里,添加第二sshd服務的配置文件:
ExecStart=/usr/sbin/sshd-D-f/etc/ssh/sshd-second_config$OPTIONS
修改後的sshd-second.service文件內容如下:

[Unit]
Description=OpenSSHserversecondinstancedaemon
After=syslog.target network.targe tauditd.service sshd.service
[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sshd-second_config$OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target

5)如果使用SELinux,添加tcp端口,負責第二sshd服務的端口就會被拒絕綁定:

~]#semanage port -a -tssh_port_t -p tcp22220

6)設置開機啓動並測試:

12 ~]#systemctl enable sshd-second.service
~]$ssh -p 22220 user@server

確保防火牆端口也開放。

(6)修改已經存在的單元文件

systemd單元配置文件默認保存在/usr/lib/systemd/system/目錄,系統管理員不建議直接修改這個目錄下的文件,自定義的文件在/etc/systemd/system/目錄下,如果有擴展的需求,可以使用以下方案:
創建一個目錄/etc/systemd/system/unit.d/,這個是最推薦的一種方式,可以參考初始的單元文件,通過附件配置文件來擴展默認的配置,對默認單元文件的升級會被自動升級和應用。
從/usr/lib/systemd/system/拷貝一份原始配置文件到/etc/systemd/system/,然後修改。複製的版本會覆蓋原始配置,這種方式不能增加附件的配置包,用於不需要附加功能的場景。
如果需要恢復到默認的配置文件,只需要刪除/etc/systemd/system/下的配置文件就可以了,不需要重啓機器,使用如下命令應用改變就可以:

systemctl daemon-reload

daemon-reload選項重新加載所以單元文件並重新創建依賴書,在需要立即應用單元文件改變的時候使用。另外,也可以使用下面的命令達到同樣的目的:

init q

還有,如果修改的是一個正在運行服務的單元文件,服務需要被重啓下:

systemct lrestart name.service

(7)擴展默認單元配置文件配置

爲了擴展默認的單元文件配置,需要先在/etc/systemd/system/下創建一個目錄,用root執行類似下面的命令:

mkdir/etc/systemd/system/name.service.d

在剛纔創建的目錄之下創建配置文件,必須以.conf文件結尾。
例如創建一個自定義的依賴文件,內容如下:

[Unit]
Requires=new_dependency
After=new_dependency

另外一個例子,可以配置重啓的時候,在主進程退出後30秒在重啓,配置例子如下:

[Service]
Restart=always
RestartSec=30

推薦每次只產生一個小文件,每個文件只聚焦完善一個功能,這樣配置文件很容易被移除或者鏈接到其他服務對的配置目錄中。
爲了應用剛纔的修改,使用root執行以下操作:

systemctldaemon-reload
systemctlrestartname.service

例子:擴展httpd.service服務配置
爲了是httpd服務啓動的時候用戶自定義的腳本,需要修改httpd的單元配置文件,執行以下幾步操作,首先創建一個自定義文件的目錄及自定義文件:

~]#mkdir/etc/systemd/system/httpd.service.d
~]#touch/etc/systemd/system/httpd.service.d/custom_script.conf

假設自定義文件位置在/usr/local/bin/custom.sh,將這個信息添加到custom_script.conf自定義腳本中:

[Service]
ExecStartPost=/usr/local/bin/custom.sh

應用更改:

~]#systemctldaemon-reload
~]#systemctlrestarthttpd.service


12.單元實例化

在運行的時候有可能需要將一個模版實例化好幾個單元,@字符用於標識模版和單元文件的關係,實例化單元可以從另外一個單元文件(使用Requires或者Wants選項),或者使用systemctlstart命令。實例化服務單元可以按照下面的方式命名:

template_name@instance_name.service

幾個實例可以指向同一個模板文件配置選項常見的所有實例,舉個例子,一個單元配置文件的Wants選項可以是:

[email protected],[email protected]

首先讓systemd搜索給定服務單位,如果沒有發現,systemd忽略@和點號之間的部分,直接搜索[email protected]服務文件,讀取配置,並啓動服務。
通配符字段,稱爲單元說明符,可以在任何單元配置文件使用。單位說明符替代某些單位在運行時參數和解釋。常用的單元說明符說明如下:
%n整個單元名字,包括類型的後綴,%N是相同的意義,但是ASCII取代爲禁止字符。
%p前綴名字,在實例化的時候,%p代表@字符前面的部分。
%i實例名字,@字符和單元類型直接的部分。%I是相同的意義,但是ASCII取代爲禁止字符。
%H主機名字,當配置文件被加載的時候的主機名。
%t運行時目錄,當前的運行目錄,對root用戶就是/run目錄,對於無特權用戶就是XDG_RUNTIME_DIR變量指定的目錄。
舉個例子,[email protected]包含下面的結構:

[Unit]
Description=Gettyon%I
...
[Service]
ExecStart=-/sbin/agetty--noclear%I$TERM
...

[email protected][email protected]實例化的時候,Description=被解釋爲“GettyonttyA”和"GettyonttyB"。


13.VNC SERVER配置

安裝:

yum install tigervnc-server

配置:

(1) 複製配置文件:

~]# cp /lib/systemd/system/[email protected] \
/etc/systemd/system/[email protected]

(2) 編輯配置文件:

ExecStart=/sbin/runuser -l USER -c "/usr/bin/vncserver %i -geometry 1280x1024"
PIDFile=/home/USER/.vnc/%H%i.pid

將USER換成要使用的VNC服務的用戶,比如root:

ExecStart=/sbin/runuser -l root -c "/usr/bin/vncserver %i"

如果要修改分辨率可以修改geometry內容,其他不需要做修改。
然後保持配置。

(3)使用systemctl命令,強制重新讀取配置文件:

 ~]# systemctl daemon-reload

(4)配置vncserver密碼

vncpasswd

(5)如果有兩個用戶希望同時使用vnc,需要配置兩份配置文件:
 [email protected][email protected],文件內容同root用戶的配置方法
然後爲兩個用戶創建vnc密碼:

$ su - USER_1
~]$ vncpasswd
Password:
Verify:
~]$ su - USER_2
~]$ vncpasswd
Password:
Verify:

(6)啓動vnc服務

systemctl start vncserver@:10

爲了開機啓動,使用如下命令:

systemctl enable vncserver@:10
ln -s '/etc/systemd/system/[email protected]' \
'/etc/systemd/system/multi-user.target.wants/vncserver@:10.service'

(7) 關閉進程

systemctl disable vncserver@:display_number.service
systemctl stop vncserver@:display_number.service


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章