Linux開機啟動分析與系統配置
在業務運維中,經常需要做系統環境配置,環境配置要在當前執行環境中生效,也要持久化依然重啟生效。
通常,大家都會想到在/etc/rc.local
中去新增業務自定義程式碼,但是也會發現,有些配置重啟無法生產生效。 而且rc.local中會出現大量的複雜的業務邏輯程式碼。修改系統配置、啟動業務程式等邏輯都會存在這個檔案中,呼叫關係複雜,維護很痛苦。
一些case :
1. 開啟iptables之後, 偶爾會遇到 `nf_conntrack: table full, dropping packet` 的資訊,並且業務無法訪問機器,這個是由於iptables的連線跟蹤表空間被使用完,無法對新建的連線建立跟蹤, 預設系統配置 `nf_conntrack_max=65535`。如果要放大這個配置,需要做:
(a) modprobe nf_conntrack
(b) sysctl -w "net.netfilter.nf_conntrack_max=100000" && sysctl -w "net.nf_conntrack_max=100000"
當前環境生效,開機啟動後無效
寫在rc.local ? 如果需要修改的引數是有 100個呢?
2. 業務需要系統引數修改。比如open_file_limit、dirty_ratio等等引數, 直接使用sed / echo的命令看起來都不合適.
使用 echo : `echo "fs.file-max=655350" >> /etc/sysctl.conf `。sysctl中可能出現2個相同的配置項。
使用 sed : `sed `。。。這個命令好難寫。。。
兩種方式都會侵入修改系統本身的/etc/sysctl.conf。 如果需要恢復系統本身的配置呢?
3. 一個機器上執行著多個業務程式,都需要開機啟動,相互之間啟動有依賴順序。
使用rc.local 。每個元件rpm包安裝之後,rpm包內修改rc.local檔案, 解除安裝時候刪除rc.local 中的配置。 rc.local中刪除開機啟動的語句就會非常難寫。而且對安裝的順序嚴格要求。
曾經有幸看到過一些業務中看到rc.local中看到這樣的程式碼:
1 sysarg=1
...
50 sysarg=2
...
100 sysarg=3
在業務的發展中,檔案中不斷地增加程式碼。rc.local越來越臃腫且不可維護。
如何簡化配置管理,更優雅的方式去支援業務,就需要關注下主機開機啟動的細節,利用系統預留的介面達到目的。
有幾個常用的關注點:
- Linux 服務啟動方式
- 核心模組 啟動方式
- sysctl 配置生效
- rc.local
1. 主機啟動過程
主機啟動過程:
- 主機加電,從MBR開始引導系統
- 啟動核心
- 初始化系統配置
- 啟動服務
- 啟動使用者終端
本次主要的關注點在 3、4 流程。
1.1 啟動核心
一個機器上可以安裝多個核心。具體機器啟動中使用引導哪個核心,是在 /boot/grub/grub.conf
檔案中定義
比如一個機器grub檔案舉例default
引數是選擇哪個核心作為預設啟動項
timeout
引數是指開機啟動時等待使用者選擇的時間
核心啟動可以帶多個引數,可以通過配置引數達到想要的啟動結果。
1.2 初始化系統配置
核心引導完成之後,就開始初始化系統配置。
這個功能的實現其實是呼叫 /etc/rc.sysinit
指令碼完成。
這個過程包括
(1)獲取網路環境與主機型別。首先會讀取網路環境設定檔案"/etc/sysconfig/network",獲取主機名稱與預設閘道器等網路環境。
(2)測試與載入記憶體裝置/proc及usb裝置/sys。除了/proc外,系統會主動檢測是否有usb裝置,並主動載入usb驅動,嘗試載入usb檔案系統。
(3)決定是否啟動SELinux。
(4)介面裝置的檢測與即插即用(pnp)引數的測試。
(5)使用者自定義模組的載入。使用者可以再"/etc/sysconfig/modules/*.modules"加入自定義的模組,此時會載入到系統中。
(6)載入核心的相關設定。按"/etc/sysctl.conf"這個檔案的設定值配置功能。
(7)設定系統時間(clock)。
(8)設定終端的控制檯的字形。
(9)設定raid及LVM等硬碟功能。
(10)以方式檢視檢驗磁碟檔案系統。
(11)進行磁碟配額quota的轉換。
(12)重新以讀取模式載入系統磁碟。
(13)啟動quota功能。
(14)啟動系統隨機數裝置(產生隨機數功能)。
(15)清楚啟動過程中的臨時檔案。
(16)將啟動資訊載入到"/var/log/dmesg"檔案中。
閱讀rc.sysinit
的程式碼, 關注核心模組的載入
和 sysctl配置
關於核心模組的載入
需要在/etc/sysconfig/modules/
建立*.modules
檔案,並且具有可執行許可權。在開機啟動過程中,會自動的被執行。
關於sysctl配置
在 /etc/rc.sysinit
中有呼叫 apply_sysctl
的函式。
在/etc/init.d/functions
指令碼中有大量的被呼叫方法,其中
可以看到
- 使用
sysctl -p /etc/sysctl.conf
將預設的引數刷入系統 - 從
/etc/sysctl.d/
目錄下讀取檔案,如果檔案是正常檔案,就執行sysctl -p $file
的方式載入配置檔案。
1.3 Linux 服務啟動
在系統引數配置完成之後,就可以啟動系統程式了。
Linux有個啟動等級的概念。
在/etc/inittab
中有定義
總共有 0-6
7個啟動登記, 預設的啟動啟動登記是 3
。每種啟動登記分別代表不同的啟動功能。
0 系統停止
1 單使用者系統,不需要登陸
2 多使用者系統但不支援NFS,命令列模式登陸
3 完整多使用者模式,命令列模式登陸
4 未用
5 X11圖形模式,圖形模式登陸
6 重新啟動系統
對於Linux Service,
-
/etc/init.d/
目錄下存放具體執行的執行的服務命令 , -
chkconfig
命令管理著Linux Service的在各個啟動等級下的是否啟動的配置。 - 系統通過
$service start
$service stop
$service status
的方式呼叫服務。
如何實現的呢?
系統啟動的過程中, 通過執行 /etc/rc.d/rc $RUNLEVEL
的方式啟動程式
在/etc/rc.d/rc
檔案中。
可以看到:
-
首先,迴圈執行
/etc/rc$runlevel.d/K*
的所有檔案都執行一遍$file stop
。比如: runlevel是 3,那麼`/etc/rc3.d/K*`的檔案列表是:
可以看出來,其實就是按照檔名排序後的順序,就是執行的順序。 每個檔案又其實是 `/etc/init.d/`目錄下檔案的軟連
-
接著,同上,迴圈執行
/etc/rc$runlevel.d/S*
的所有檔案都執行一遍$file start
即。將所有S開頭的檔案都執行一遍 start 方法 rc.local 什麼時候執行呢 可以看到,S99local 軟連到 /etc/rc.local 檔案, 即rc.local是最後一個要啟動 指令碼。
Linux系統就這樣管理器Linux服務的啟動。所有的檔名都是以 [KS]+<數字><程式名>
的方式命名,最終都軟鏈到目標可執行檔案。
現在那麼很多問題都解釋的清楚了。
(a) chkconfig
是怎麼管理linux服務的?
通過給不同的執行等級目錄`/etc/rc{$runlevel}.d` 增加和刪除對應的軟鏈,達到控制啟動的效果。如果是啟動,新檔案則已S開頭,如果是停止,新檔案則已K開頭。
(b) S
K
後面的數字是做什麼的?
在編寫服務的時候,啟動指令碼頭部,一般會後這樣的說明。
chkconfig: - 85 15
chkconfig 後面的兩個數字,分別代表該服務本身在註冊到系統中後,系統啟動時被執行的順序。可選項[20-80], 第一個數字是start的配置,數字越大,啟動的越晚, 第二個數字是stop的配置, 數字越小,執行的越找。
對於基礎服務,應該是start 的配置較小,stop 的配置較大。
對於應用服務,應該是start 的配置較大,stop 的配置較小。
現在我們知道, 其實就是生成的檔名的排序的問題。
(c) Linux的多個啟動等級是如何實現的?
觀察 /etc/rc3.d/ 和 /etc/rc0.d 下的檔案列表。
rc0.d 目錄下存在大量的 K 開頭的stop 呼叫,start 呼叫 也是 S00killall 、 S01halt 這樣的關機操作。
rc3.d 目錄下有 很多 start 呼叫,
S55sshd
S58ntpd
S90crond
S99local
通過這樣啟動系統服務,達到機器可用的效果。
由此控制了不同的啟動登記帶來的不同操作
依賴此,我們也可以定義自己的啟動登記。
2. 常見問題解決方案
線上部署的過程中,需要調整系統引數,引數包括各個方面,調整的方式也不同,需要找到合適的方式。
優雅的引數設定方式: 要易於設定,易於清理。 不能侵入系統檔案.
所有的引數配置環境包括: 存量、增量、當前環境、重啟環境
- 存量 : 已經線上上執行的主機,引數需要熱修改。
- 增量 : 以後新部署的業務,保證引數配置正確。
- 當前環境 : 在當前機器的執行環境中,引數設定生效。
- 重啟環境 : 設定配置,使機器重新啟動後引數設定依然生效。
2.1 磁碟 io scheduler 調整
Linux 儲存裝置的 預設IO 排程策略是 cfq
, 在DB 場景下, 需要 調整成 deadline
模式,使每個IO請求都能在deadline前得到滿足。
- 當前環境 :
echo `deadline` > /sys/block/$disk/queue/scheduler
- 重啟環境 :
grubby --grub --update-kernel=ALL --args="elevator=deadline"
通過給 echo 修改核心變數,修改當前執行環境的配置,通過grubby 命令修改 grub.conf,設定核心載入引數, 這樣當機器重啟的時候,自動的會把每個裝置的 IO schedular 變成 deadline 。
2.2 分割槽掛在引數 data=writeback
Linux /etc/fstab檔案中記錄了每個分割槽被開機掛在的引數。
ext4檔案系統掛載的時候,預設引數使用 data=order
模式,可以通過 cat /proc/mounts
來檢視。
場景:PostgreSQL 在使用者請求的時候,會頻繁的建立和釋放臨時檔案,在請求量大的時候,機器的IO會hang, 是因為ext4檔案系統在記錄檔案的時候,需要多次硬碟IO,為了保證資料的一致性,以同步的方式記錄後設資料/日誌/資料,導致機器IO跟不上,需要把掛在引數修改成 data=writeback
模式,可以非同步記錄檔案的後設資料、資料,提高效能。
- 存量 : 安裝熱修改的hotfix 。
-
增量 :
umount /data
-
sed -i "s/noatime/noatime,data=writeback/" /etc/fstab
#修改fstab, 中裝置的掛載引數 mount -a
__注__: 關於 ext4的引數的更多資訊,請自行搜尋
2.3 系統引數 sysctl 修改
很多情況下都是需要修改系統引數,來調優系統. 很容易想到的是 /etc/sysctl.conf
。 不管是 echo 或者sed 的方式都會破壞 sysctl.conf
的可讀性,入侵性太大,且需要求變更修改的時候,會很麻煩。根據/etc/rc.sysinit
的指令碼我們知道他的載入方式.可以採用這樣的方式。
- 編寫一個和
/etc/sysctl.conf
類似的mysysconf
檔案,其中定義了業務關心的,需要求改的引數列表. mkdir -p /etc/sysctl.d
cp mysysconf /etc/sysctl.d
sysctl -p /etc/sysctl.d/mysysconf
增量/存量/當前環境/重啟環境均可生效。
2.4 nf_conntrack_max
引數修改
當時用iptable的時候, 預設nf_conntrack_max
的配置值是 65536,當請求多的時候,機器上就會報 : nf_conntrack: table full, dropping packet
機器也會連不上,是由於nf_conntrack中的雜湊表滿了, 這種就需要放大 nf_conntrack_max
的值。
如果直接修改sysctl, sysctl -p 的時候會提示: error: "net.nf_conntrack_max" is an unknown key
所以需要先 modprobe nf_conntrack
, 然後才能刷 系統引數.
推薦的方式:
- 編寫
my.modules
檔案,內容:modprobe nf_conntrack
-
cp my.modules /etc/sysconfig/modules/&&chmod +x /etc/sysconfig/modules/my.modules
#參見/etc/rc.sysinit
核心模組的載入方式。 -
sh /etc/sysconfig/modules/my.modules
# 在當前環境中,載入核心模組 -
cp mysysconf /etc/sysctl.d/
#系統配置引數其中定義了nf_conntrack_max
為更大的值 -
sysclt -p /etc/sysctl.d/mysysconf
在當前系統中使配置生效
2.5 開機啟動管理:Linux Service
當機器上部署多個服務時,服務管理就是一個問題。
改造應用, 讓應用以Linux 標準服務方式,交給chkconfig 管理,還可以自定義開機器元件之間的啟動順序。
如何可以,儘量不用rc.local
參考 :http://blog.chinaunix.net/uid-23069658-id-3142047.html
相關文章
- linux系統開機啟動流程Linux
- Linux系統上配置redis開機自啟LinuxRedis
- Linux 系統開機啟動項清理Linux
- Linux開機自啟動配置Linux
- Linux 獲取系統開機/啟動時間Linux
- 配置虛擬機器中的Linux系統與開啟網路服務虛擬機Linux
- [Oracle]設定Oracle隨Linux系統開機啟動OracleLinux
- Linux系統詳解 第六篇:系統的啟動、登入、登出與開關機薦Linux
- Linux開機自啟配置Linux
- oracle配置開機自啟動Oracle
- Linux下XWindow系統啟動指令碼分析(轉)Linux指令碼
- Linuxfirewalld配置與systemctl開啟啟動配置(轉載)Linux
- Linux開機啟動(bootstrap)Linuxboot
- macos系統怎麼取消開機啟動項Mac
- 開機自動啟動ORACLE ON LinuxOracleLinux
- Linux系統最有必要保留的5個開機自啟動服務!Linux
- 從啟動開始保障LINUX系統安全(轉)Linux
- linux 主機mail 系統配置.LinuxAI
- oracle 隨系統開啟,自動啟動Oracle
- Android系統啟動流程(四)Launcher啟動過程與系統啟動流程Android
- iOS作業系統-- App啟動流程分析與優化iOS作業系統APP優化
- linux設定開機啟動Linux
- Linux 新增開機自啟動Linux
- mac系統,php-fpm加入開機啟動項MacPHP
- Linux啟動流程與Grub的配置(轉)Linux
- Linux系統啟動流程圖Linux流程圖
- Linux系統啟動過程Linux
- Linux配置開機自啟動執行指令碼方法有哪些?Linux指令碼
- Linux下開機自動啟動OracleLinuxOracle
- linux開機自動啟動指令碼Linux指令碼
- linux下開機自動開啟單機oracleLinuxOracle
- Linux Oracle 隨系統自動啟動LinuxOracle
- Laravel Event——事件系統的啟動與執行原始碼分析Laravel事件原始碼
- Win7系統設定為系統啟動開機減負提速Win7
- Win10系統怎麼禁止qq開機自動啟動Win10
- linux系統相關概念與配置Linux
- 【Linux】建立linux開機啟動檔案Linux
- win10系統如何關閉autodesk開機啟動Win10