天天看點

Linux開機啟動分析與系統配置

在業務運維中,經常需要做系統環境配置,環境配置要在目前運作環境中生效,也要持久化依然重新開機生效。

通常,大家都會想到在<code>/etc/rc.local</code>中去添加業務自定義代碼,但是也會發現,有些配置重新開機無法生産生效。 而且rc.local中會出現大量的複雜的業務邏輯代碼。修改系統配置、啟動業務程序等邏輯都會存在這個檔案中,調用關系複雜,維護很痛苦。

一些case :

曾經有幸看到過一些業務中看到rc.local中看到這樣的代碼:

在業務的發展中,檔案中不斷地增加代碼。rc.local越來越臃腫且不可維護。

如何簡化配置管理,更優雅的方式去支援業務,就需要關注下主機開機啟動的細節,利用系統預留的接口達到目的。

有幾個常用的關注點:

linux 服務啟動方式

核心子產品 啟動方式

sysctl 配置生效

rc.local

主機啟動過程:

主機加電,從mbr開始引導系統

啟動核心

初始化系統配置

啟動服務

啟動使用者終端

本次主要的關注點在 3、4 流程。

一個機器上可以安裝多個核心。具體機器啟動中使用引導哪個核心,是在 <code>/boot/grub/grub.conf</code> 檔案中定義

比如一個機器grub檔案舉例

Linux開機啟動分析與系統配置

<code>default</code> 參數是選擇哪個核心作為預設啟動項

<code>timeout</code> 參數是指開機啟動時等待使用者選擇的時間

核心啟動可以帶多個參數,可以通過配置參數達到想要的啟動結果。

核心引導完成之後,就開始初始化系統配置。

這個功能的實作其實是調用 <code>/etc/rc.sysinit</code> 腳本完成。

這個過程包括

閱讀<code>rc.sysinit</code>的代碼, 關注<code>核心子產品的加載</code> 和 <code>sysctl配置</code>

關于核心子產品的加載

Linux開機啟動分析與系統配置

需要在<code>/etc/sysconfig/modules/</code> 建立<code>*.modules</code> 檔案,并且具有可執行權限。在開機啟動過程中,會自動的被執行。

關于sysctl配置

在 <code>/etc/rc.sysinit</code> 中有調用 <code>apply_sysctl</code>的函數。

Linux開機啟動分析與系統配置

在<code>/etc/init.d/functions</code> 腳本中有大量的被調用方法,其中

Linux開機啟動分析與系統配置

可以看到

使用 <code>sysctl -p /etc/sysctl.conf</code> 将預設的參數刷入系統

從 <code>/etc/sysctl.d/</code>目錄下讀取檔案,如果檔案是正常檔案,就執行<code>sysctl -p $file</code> 的方式加載配置檔案。

在系統參數配置完成之後,就可以啟動系統程序了。

linux有個啟動等級的概念。

在<code>/etc/inittab</code> 中有定義

Linux開機啟動分析與系統配置

總共有 <code>0-6</code> 7個啟動登記, 預設的啟動啟動登記是 <code>3</code>。每種啟動登記分别代表不同的啟動功能。

對于linux service,

<code>/etc/init.d/</code> 目錄下存放具體執行的執行的服務指令 ,

<code>chkconfig</code> 指令管理着linux service的在各個啟動等級下的是否啟動的配置。

系統通過 <code>$service start</code> <code>$service stop</code> <code>$service status</code>的方式調用服務。

如何實作的呢?

系統啟動的過程中, 通過執行 <code>/etc/rc.d/rc $runlevel</code> 的方式啟動程序

在<code>/etc/rc.d/rc</code> 檔案中。

Linux開機啟動分析與系統配置

可以看到:

首先,循環執行 <code>/etc/rc$runlevel.d/k*</code>的所有檔案都執行一遍 <code>$file stop</code>。

Linux開機啟動分析與系統配置

接着,同上,循環執行<code>/etc/rc$runlevel.d/s*</code> 的所有檔案都執行一遍 <code>$file start</code>

linux系統就這樣管理器linux服務的啟動。所有的檔案名都是以 <code>[ks]+&lt;數字&gt;&lt;程式名&gt;</code>的方式命名,最終都軟鍊到目标可執行檔案。

現在那麼很多問題都解釋的清楚了。

(a) <code>chkconfig</code> 是怎麼管理linux服務的?

(b) <code>s</code> <code>k</code>後面的數字是做什麼的?

(c) linux的多個啟動等級是如何實作的?

Linux開機啟動分析與系統配置

線上部署的過程中,需要調整系統參數,參數包括各個方面,調整的方式也不同,需要找到合适的方式。

優雅的參數設定方式: 要易于設定,易于清理。 不能侵入系統檔案.

所有的參數配置環境包括: 存量、增量、目前環境、重新開機環境

存量 : 已經線上上運作的主機,參數需要熱修改。

增量 : 以後新部署的業務,保證參數配置正确。

目前環境 : 在目前機器的運作環境中,參數設定生效。

重新開機環境 : 設定配置,使機器重新啟動後參數設定依然生效。

linux 儲存設備的 預設io 排程政策是 <code>cfq</code> , 在db 場景下, 需要 調整成 <code>deadline</code> 模式,使每個io請求都能在deadline前得到滿足。

目前環境 : <code>echo 'deadline' &gt; /sys/block/$disk/queue/scheduler</code>

重新開機環境 : <code>grubby --grub --update-kernel=all --args="elevator=deadline"</code>

通過給 echo 修改核心變量,修改目前運作環境的配置,通過grubby 指令修改 grub.conf,設定核心加載參數, 這樣當機器重新開機的時候,自動的會把每個裝置的 io schedular 變成 deadline 。

linux /etc/fstab檔案中記錄了每個分區被開機挂在的參數。

ext4檔案系統挂載的時候,預設參數使用 <code>data=order</code>模式,可以通過 <code>cat /proc/mounts</code>來檢視。

場景:postgresql 在使用者請求的時候,會頻繁的建立和釋放臨時檔案,在請求量大的時候,機器的io會hang, 是因為ext4檔案系統在記錄檔案的時候,需要多次硬碟io,為了保證資料的一緻性,以同步的方式記錄中繼資料/日志/資料,導緻機器io跟不上,需要把挂在參數修改成 <code>data=writeback</code> 模式,可以異步記錄檔案的中繼資料、資料,提高性能。

存量 : 安裝熱修改的hotfix 。

增量 :

<code>umount /data</code>

<code>sed -i "s/noatime/noatime,data=writeback/" /etc/fstab</code> #修改fstab, 中裝置的挂載參數

<code>mount -a</code>

__注__: 關于 ext4的參數的更多資訊,請自行搜尋

很多情況下都是需要修改系統參數,來調優系統. 很容易想到的是 <code>/etc/sysctl.conf</code>。 不管是 echo 或者sed 的方式都會破壞 <code>sysctl.conf</code>的可讀性,入侵性太大,且需要求變更修改的時候,會很麻煩。根據<code>/etc/rc.sysinit</code>的腳本我們知道他的加載方式.可以采用這樣的方式。

編寫一個和<code>/etc/sysctl.conf</code>類似的 <code>mysysconf</code> 檔案,其中定義了業務關心的,需要求改的參數清單.

<code>mkdir -p /etc/sysctl.d</code>

<code>cp mysysconf /etc/sysctl.d</code>

<code>sysctl -p /etc/sysctl.d/mysysconf</code>

增量/存量/目前環境/重新開機環境均可生效。

當時用iptable的時候, 預設<code>nf_conntrack_max</code>的配置值是 65536,當請求多的時候,機器上就會報 : <code>nf_conntrack: table full, dropping packet</code> 機器也會連不上,是由于nf_conntrack中的哈希表滿了, 這種就需要放大 <code>nf_conntrack_max</code>的值。

如果直接修改sysctl, sysctl -p 的時候會提示:

<code>error: "net.nf_conntrack_max" is an unknown key</code>

是以需要先 <code>modprobe nf_conntrack</code>, 然後才能刷 系統參數.

推薦的方式:

編寫 <code>my.modules</code>檔案,内容:

modprobe nf_conntrack

<code>cp my.modules /etc/sysconfig/modules/&amp;&amp;chmod +x /etc/sysconfig/modules/my.modules</code> #參見 <code>/etc/rc.sysinit</code> 核心子產品的加載方式。

<code>sh /etc/sysconfig/modules/my.modules</code> # 在目前環境中,加載核心子產品

<code>cp mysysconf /etc/sysctl.d/</code> #系統配置參數其中定義了 <code>nf_conntrack_max</code> 為更大的值

<code>sysclt -p /etc/sysctl.d/mysysconf</code> 在目前系統中使配置生效

當機器上部署多個服務時,服務管理就是一個問題。

改造應用, 讓應用以linux 标準服務方式,交給chkconfig 管理,還可以自定義開機器元件之間的啟動順序。

如何可以,盡量不用<code>rc.local</code>

繼續閱讀