幾個月前, Linux 基金會宣布 LFCS (Linux 基金會認證系統管理員) 認證誕生了,這個令人興奮的新計劃定位於讓來自全球各地的初級到中級的 Linux 系統管理員得到認證。這其中包括維護已經在運行的系統和服務的能力、第一手的問題查找和分析能力、以及決定何時向開發團隊提交問題的能力。
第七講: Linux 基金會認證系統管理員
下面的視頻簡要介紹了 Linux 基金會認證計劃。
本講是系列教程中的第七講,在這篇文章中,我們會介紹如何管理 Linux 系統自啟動進程和服務,這是 LFCS 認證考試要求的一部分。
管理 Linux 自啟動進程
Linux 系統的啟動程序包括多個階段,每個階段由一個不同的圖示塊表示。下面的圖示簡要總結了啟動過程以及所有包括的主要組件。
Linux 啟動過程
當你按下你機器上的電源鍵時,存儲在主板 EEPROM 芯片中的固件初始化 POST(通電自檢) 檢查系統硬件資源的狀態。POST 結束後,固件會搜索並加載位於第一塊可用磁盤上的 MBR 或 EFI 分區的第一階段引導程序,並把控制權交給引導程序。
MBR 方式
MBR 是位於 BIOS 設置中標記為可啟動磁盤上的第一個扇區,大小是 512 個字節。
前面 446 個字節:包括可執行代碼和錯誤信息文本的引導程序
接下來的 64 個字節:四個分區(主分區或擴展分區)中每個分區一條記錄的分區表。其中,每條記錄標示了每個一個分區的狀態(是否活躍)、大小以及開始和結束扇區。
最後 2 個字節: MBR 有效性檢查的魔法數。
下面的命令對 MBR 進行備份(在本例中,/dev/sda 是第一塊硬盤)。結果文件 mbr.bkp 在分區表被破壞、例如系統不可引導時能排上用場。
當然,為了後面需要的時候能使用它,我們需要把它保存到別的地方(例如一個 USB 設備)。該文件能幫助我們重新恢復 MBR,這只在我們操作過程中沒有改變硬盤驅動布局時才有效。
備份 MBR# dd if=/dev/sda of=mbr.bkp bs=512 count=1
在 Linux 中備份 MBR
恢復 MBR# dd if=mbr.bkp of=/dev/sda bs=512 count=1
在 Linux 中恢復 MBR
EFI/UEFI 方式
對於使用 EFI/UEFI 方式的系統, UEFI 固件讀取它的設置來決定從哪裡啟動哪個 UEFI 應用。(例如, EFI 分區位於哪塊磁盤或分區。
接下來,加載並運行第二階段引導程序(又名引導管理器)。GRUB[GRand Unified Boot] 是 Linux 中最常使用的引導管理器。今天大部分使用的系統中都能找到它兩個中的其中一個版本。
GRUB 有效配置文件: /boot/grub/menu.lst(舊發行版, EFI/UEFI 固件不支持)。
GRUB2 配置文件: 通常是 /etc/default/grub。
盡管 LFCS 考試目標沒有明確要求了解 GRUB 內部知識,但如果你足夠大膽並且不怕把你的系統搞亂(為了以防萬一,你可以先在虛擬機上進行嘗試)你可以運行:
# update-grub
為了使更改生效,你需要以 root 用戶修改 GRUB 的配置。
首先, GRUB 加載默認的內核以及 initrd 或 initramfs 鏡像。補充一句,initrd 或者 initramfs 幫助完成硬件檢測、內核模塊加載、以及發現掛載根目錄文件系統需要的設備。
一旦真正的根目錄文件系統啟動,為了顯示用戶界面,內核就會執行系統和服務管理器(init 或 systemd,進程號 PID 一般為 1)開始普通用戶態的引導程序。
init 和 systemd 都是管理其它守護進程的守護進程(後台進程),它們總是最先啟動(系統引導時),最後結束(系統關閉時)。
Systemd 和 Init
自啟動服務(SysVinit)
Linux 中運行等級通過控制運行哪些服務來以不同方式使用系統。換句話說,運行等級控制著當前執行狀態下可以完成什麼任務(以及什麼不能完成)。
傳統上,這個啟動過程是基於起源於 System V Unix 的形式,通過執行腳本啟動或者停止服務從而使機器進入指定的運行等級(換句話說,是一個不同的系統運行模式)。
在每個運行等級中,獨立服務可以設置為運行、或者在運行時關閉。一些主流發行版的最新版本中,已經移除了標准的 System V,而用一個稱為 systemd(表示系統守護進程)的新服務和系統管理器代替,但為了兼容性,通常也支持 sysv 命令。這意味著你可以在基於 systemd 的發行版中運行大部分有名的 sysv 初始化工具。
推薦閱讀: Linux 為什麼用 ‘systemd’ 代替 ‘init’
除了啟動系統進程,init 還會查看 /etc/inittab 來決定進入哪個運行等級。
| Runlevel | Description | 0停止系統。運行等級 0 是一個用於快速關閉系統的特殊過渡狀態。1別名為 s 或 S,這個運行等級有時候也稱為維護模式。在這個運行等級啟動的服務由於發行版不同而不同。通常用於正常系統操作損壞時低級別的系統維護。2多用戶。在 Debian 系統及其衍生版中,這是默認的運行等級,還包括了一個圖形化登錄(如果有的話)。在基於紅帽的系統中,這是沒有網絡的多用戶模式。3在基於紅帽的系統中,這是默認的多用戶模式,運行除了圖形化環境以外的所有東西。基於 Debian 的系統中通常不會使用這個運行等級以及等級 4 和 5。4通常默認情況下不使用,可用於自定制。5基於紅帽的系統中,支持 GUI 登錄的完全多用戶模式。這個運行等級和等級 3 類似,但是有可用的 GUI 登錄。6重啟系統。要在運行等級之間切換,我們只需要使用 init 命令更改運行等級:init N(其中 N 是上面列出的一個運行等級)。 請注意這並不是運行中的系統切換運行等級的推薦方式,因為它不會給已經登錄的用戶發送警告(因而導致他們丟失工作以及進程異常終結)。
相反,應該用 shutdown 命令重啟系統(它首先發送警告信息給所有已經登錄的用戶,並鎖住任何新的登錄;然後再給 init 發送信號切換運行等級)但是,首先要在 /etc/inittab 文件中設置好默認的運行等級(系統引導到的等級)。
因為這個原因,按照下面的步驟切當地切換運行等級。以 root 用戶在 /etc/inittab 中查找下面的行。
id:2:initdefault:
並用你喜歡的文本編輯器,例如 vim(本系列的 LFCS 系列第二講:如何安裝和使用純文本編輯器 vi/vim),更改數字 2 為想要的運行等級。
然後,以 root 用戶執行
# shutdown -r now
最後一個命令會重啟系統,並使它在下一次引導時進入指定的運行等級,並會執行保存在 /etc/rc[runlevel].d 目錄中的腳本以決定應該啟動什麼服務、不應該啟動什麼服務。例如,在下面的系統中運行等級 2。
在 Linux 中更改運行等級
使用 chkconfig 管理服務
為了在啟動時啟動或者停用系統服務,我們可以在 CentOS / openSUSE 中使用 chkconfig 命令,在 Debian 及其衍生版中使用 sysv-rc-conf 命令。這個工具還能告訴我們對於一個指定的運行等級預先配置的狀態是什麼。
推薦閱讀: 如何在 Linux 中停止和停用不想要的服務
列出某個服務的運行等級配置。
# chkconfig --list [service name]
# chkconfig --list postfix
# chkconfig --list mysqld
列出運行等級配置
從上圖中我們可以看出,當系統進入運行等級 2 到 5 的時候就會啟動 postfix,而默認情況下運行等級 2 到 4 時會運行 mysqld。現在假設我們並不希望如此。
例如,我們希望運行等級為 5 時也啟動 mysqld,運行等級為 4 或 5 時關閉 postfix。下面分別針對兩種情況進行設置(以 root 用戶執行以下命令)。
為特定運行等級啟用服務# chkconfig --level [level(s)] service on
# chkconfig --level 5 mysqld on
為特定運行等級停用服務# chkconfig --level [level(s)] service off
# chkconfig --level 45 postfix off
啟用/停用服務
我們在基於 Debian 的系統中使用 sysv-rc-conf 完成類似任務。
使用 sysv-rc-conf 管理服務
配置服務自動啟動時進入指定運行等級,同時禁止啟動時進入其它運行等級。
我們可以用下面的命令查看啟動 mdadm 時的運行等級。
# ls -l /etc/rc[0-6].d | grep -E 'rc[0-6]|mdadm'
查看運行中服務的運行等級
我們使用 sysv-rc-conf 設置防止 mdadm 在運行等級2 之外的其它等級啟動。只需根據需要(你可以使用上下左右按鍵)選中或取消選中(通過空格鍵)。
# sysv-rc-conf
Sysv 運行等級配置
然後輸入 q 退出。
重啟系統並從步驟 1 開始再操作一遍。
# ls -l /etc/rc[0-6].d | grep -E 'rc[0-6]|mdadm'
驗證服務運行等級
從上圖中我們可以看出 mdadm 配置為只在運行等級 2 上啟動。
那關於 systemd 呢?
systemd 是另外一個被多種主流 Linux 發行版采用的服務和系統管理器。它的目標是允許系統啟動時多個任務盡可能並行(而 sysvinit 並非如此,sysvinit 一般比較慢,因為它每次只啟動一個進程,而且會檢查彼此之間是否有依賴,在啟動其它服務之前還要等待守護進程啟動),充當運行中系統動態資源管理的角色。
因此,服務只在需要的時候啟動,而不是系統啟動時毫無緣由地啟動(為了防止消耗系統資源)。
要查看你系統中運行的原生 systemd 服務和 Sysv 服務,可以用以下的命令。
# systemctl
查看運行中的進程
LOAD 一列顯示了單元(UNIT 列,顯示服務或者由 systemd 維護的其它進程)是否正確加載,ACTIVE 和 SUB 列則顯示了該單元當前的狀態。
顯示服務當前狀態的信息當 ACTIVE 列顯示某個單元狀態並非活躍時,我們可以使用以下命令查看具體原因。
# systemctl status [unit]
例如,上圖中 media-samba.mount 處於失敗狀態。我們可以運行:
# systemctl status media-samba.mount
查看服務狀態
我們可以看到 media-samba.mount 失敗的原因是 host dev1 上的掛載進程無法找到 //192.168.0.10/gacanepa 上的共享網絡。
啟動或停止服務
一旦 //192.168.0.10/gacanepa 上的共享網絡可用,我們可以再來嘗試啟動、停止以及重啟 media-samba.mount 單元。執行每次操作之後,我們都執行 systemctl stats media-samba.mout 來查看它的狀態。
# systemctl start media-samba.mount
# systemctl status media-samba.mount# systemctl stop media-samba.mount
# systemctl restart media-samba.mount
# systemctl status media-samba.mount
啟動停止服務
啟用或停用某服務隨系統啟動使用 systemd 你可以在系統啟動時啟用或停用某服務
# systemctl enable [service] # 啟用服務
# systemctl disable [service] # 阻止服務隨系統啟動
啟用或停用某服務隨系統啟動包括在 /etc/systemd/system/multi-user.target.wants 目錄添加或者刪除符號鏈接。
啟用或停用服務
你也可以用下面的命令查看某個服務的當前狀態(啟用或者停用)。
# systemctl is-enabled [service]
例如,
# systemctl is-enabled postfix.service
另外,你可以用下面的命令重啟或者關閉系統。
# systemctl reboot
# systemctl shutdown
Upstart
基於事件的 Upstart 是 /sbin/init 守護進程的替代品,它僅為在需要那些服務的時候啟動服務而生,(或者當它們在運行時管理它們),以及處理發生的實踐,因此 Upstart 優於基於依賴的 sysvinit 系統。
一開始它是為 Ubuntu 發行版開發的,但在紅帽企業版 Linux 6.0 中得到使用。盡管希望它能在所有 Linux 發行版中替代 sysvinit,但它已經被 systemd 超越。2014 年 2 月 14 日,Mark Shuttleworth(Canonical Ltd. 創建者)發布聲明之後的 Ubuntu 發行版采用 systemd 作為默認初始化守護進程。
由於 Sysv 啟動腳本已經流行很長時間了,很多軟件包中都包括了 Sysv 啟動腳本。為了兼容這些軟件, Upstart 提供了兼容模式:它可以運行保存在常用位置(/etc/rc.d/rc?.d, /etc/init.d/rc?.d, /etc/rc?.d或其它類似的位置)的Sysv 啟動腳本。因此,如果我們安裝了一個還沒有 Upstart 配置腳本的軟件,仍然可以用原來的方式啟動它。
另外,如果我們還安裝了類似 chkconfig 的工具,你還可以和在基於 sysvinit 的系統中一樣用它們管理基於 Sysv 的服務。
Upstart 腳本除了支持 Sysv 啟動腳本,還支持基於多種方式啟動或者停用服務;例如, Upstart 可以在一個特定硬件設備連接上的時候啟動一個服務。
使用 Upstart以及它原生腳本的系統替換了 /etc/inittab 文件和 /etc/init 目錄下和運行等級相關的以 .conf 作為後綴的 Sysv 啟動腳本目錄。
這些 *.conf 腳本(也稱為任務定義)通常包括以下幾部分:
進程描述
進程的運行等級或者應該觸發它們的事件
應該停止進程的運行等級或者觸發停止進程的事件
選項
啟動進程的命令
例如,
# My test service - Upstart script demo description "Here goes the description of 'My test service'" author "Dave Null <[email protected]>"
# Stanzas
#
# Stanzas define when and how a process is started and stopped
# See a list of stanzas here:http://upstart.ubuntu.com/wiki/Stanzas#respawn # When to start the service
start on runlevel [2345]
# When to stop the service
stop on runlevel [016]
# Automatically restart process in case of crash
respawn
# Specify working directory
chdir /home/dave/myfiles
# Specify the process/command (add arguments if needed) to run
exec bash backup.sh arg1 arg2
要使更改生效,你要讓 upstart 重新加載它的配置文件。
# initctl reload-configuration
然後用下面的命令啟動你的任務。
$ sudo start yourjobname
其中 yourjobname 是之前 yourjobname.conf 腳本中添加的任務名稱。
關於 Upstart 更完整和詳細的介紹可以參考該項目網站的 “Cookbook” 欄目。
總結
了解 Linux 啟動進程對於你進行錯誤處理、調整計算機系統以及根據需要運行服務非常有用。
在這篇文章中,我們分析了你按下電源鍵啟動機器的一刻到你看到完整的可操作用戶界面這段時間發生了什麼。我希望你能像我一樣把它們放在一起閱讀。歡迎在下面留下你的評論或者疑問。我們總是期待聽到讀者的回復。
作者:Gabriel Cánepa 譯者:ictlyh 校對:wxy