LFCS 系列第七講:通過 SysVinit、Systemd 和 Upstart 管理系統自啟動程式和服務

2 贊 回覆發表於2016-05-20

幾個月前, Linux 基金會宣佈 LFCS (Linux 基金會認證系統管理員) 認證誕生了,這個令人興奮的新計劃定位於讓來自全球各地的初級到中級的 Linux 系統管理員得到認證。這其中包括維護已經在執行的系統和服務的能力、第一手的問題查詢和分析能力、以及決定何時向開發團隊提交問題的能力。

Linux Foundation Certified Sysadmin – Part 7

第七講: Linux 基金會認證系統管理員

下面的視訊簡要介紹了 Linux 基金會認證計劃。

本講是系列教程中的第七講,在這篇文章中,我們會介紹如何管理 Linux 系統自啟動程式和服務,這是 LFCS 認證考試要求的一部分。

管理 Linux 自啟動程式

Linux 系統的啟動程式包括多個階段,每個階段由一個不同的圖示塊表示。下面的圖示簡要總結了啟動過程以及所有包括的主要元件。

Linux Boot Process

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

Backup MBR in Linux

在 Linux 中備份 MBR

恢復 MBR

# dd if=mbr.bkp of=/dev/sda bs=512 count=1

Restore MBR in Linux

在 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 and Init

Systemd 和 Init

自啟動服務(SysVinit)

Linux 中執行等級通過控制執行哪些服務來以不同方式使用系統。換句話說,執行等級控制著當前執行狀態下可以完成什麼任務(以及什麼不能完成)。

傳統上,這個啟動過程是基於起源於 System V Unix 的形式,通過執行指令碼啟動或者停止服務從而使機器進入指定的執行等級(換句話說,是一個不同的系統執行模式)。

在每個執行等級中,獨立服務可以設定為執行、或者在執行時關閉。一些主流發行版的最新版本中,已經移除了標準的 System V,而用一個稱為 systemd(表示系統守護程式)的新服務和系統管理器代替,但為了相容性,通常也支援 sysv 命令。這意味著你可以在基於 systemd 的發行版中執行大部分有名的 sysv 初始化工具。

除了啟動系統程式,init 還會檢視 /etc/inittab 來決定進入哪個執行等級。

RunlevelDescription
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。

Change Runlevels in Linux

在 Linux 中更改執行等級

使用 chkconfig 管理服務

為了在啟動時啟動或者停用系統服務,我們可以在 CentOS / openSUSE 中使用 chkconfig 命令,在 Debian 及其衍生版中使用 sysv-rc-conf 命令。這個工具還能告訴我們對於一個指定的執行等級預先配置的狀態是什麼。

列出某個服務的執行等級配置。

# chkconfig --list [service name]
# chkconfig --list postfix
# chkconfig --list mysqld

Listing Runlevel Configuration

列出執行等級配置

從上圖中我們可以看出,當系統進入執行等級 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

在 Linux 中啟用/停用服務Enable Disable Services in Linux

啟用/停用服務

我們在基於 Debian 的系統中使用 sysv-rc-conf 完成類似任務。

使用 sysv-rc-conf 管理服務

配置服務自動啟動時進入指定執行等級,同時禁止啟動時進入其它執行等級。

  1. 我們可以用下面的命令檢視啟動 mdadm 時的執行等級。

    # ls -l /etc/rc[0-6].d | grep -E 'rc[0-6]|mdadm'
    

    檢視執行中服務的執行等級Check Runlevel of Service Running

    檢視執行中服務的執行等級

  2. 我們使用 sysv-rc-conf 設定防止 mdadm 在執行等級2 之外的其它等級啟動。只需根據需要(你可以使用上下左右按鍵)選中或取消選中(通過空格鍵)。

    # sysv-rc-conf
    

    Sysv 執行等級配置SysV Runlevel Config

    Sysv 執行等級配置

    然後輸入 q 退出。

  3. 重啟系統並從步驟 1 開始再操作一遍。

    # ls -l /etc/rc[0-6].d | grep -E 'rc[0-6]|mdadm'
    

    驗證服務執行等級Verify Service Runlevel

    驗證服務執行等級

    從上圖中我們可以看出 mdadm 配置為只在執行等級 2 上啟動。

那關於 systemd 呢?

systemd 是另外一個被多種主流 Linux 發行版採用的服務和系統管理器。它的目標是允許系統啟動時多個任務儘可能並行(而 sysvinit 並非如此,sysvinit 一般比較慢,因為它每次只啟動一個程式,而且會檢查彼此之間是否有依賴,在啟動其它服務之前還要等待守護程式啟動),充當執行中系統動態資源管理的角色。

因此,服務只在需要的時候啟動,而不是系統啟動時毫無緣由地啟動(為了防止消耗系統資源)。

要檢視你係統中執行的原生 systemd 服務和 Sysv 服務,可以用以下的命令。

# systemctl

在 Linux 中檢視執行中的程式Check All Running Processes in Linux

檢視執行中的程式

LOAD 一列顯示了單元(UNIT 列,顯示服務或者由 systemd 維護的其它程式)是否正確載入,ACTIVE 和 SUB 列則顯示了該單元當前的狀態。

顯示服務當前狀態的資訊

當 ACTIVE 列顯示某個單元狀態並非活躍時,我們可以使用以下命令檢視具體原因。

# systemctl status [unit]

例如,上圖中 media-samba.mount 處於失敗狀態。我們可以執行:

# systemctl status media-samba.mount

檢視 Linux 服務狀態Check Linux Service Status

檢視服務狀態

我們可以看到 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 <dave.null@example.com>"
# 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 啟動程式對於你進行錯誤處理、調整計算機系統以及根據需要執行服務非常有用。

在這篇文章中,我們分析了你按下電源鍵啟動機器的一刻到你看到完整的可操作使用者介面這段時間發生了什麼。我希望你能像我一樣把它們放在一起閱讀。歡迎在下面留下你的評論或者疑問。我們總是期待聽到讀者的回覆。


via: http://www.tecmint.com/linux-boot-process-and-manage-services/

作者:Gabriel Cánepa 譯者:ictlyh 校對:wxy

本文由 LCTT 原創翻譯,Linux中國 榮譽推出

相關文章