零代价修复海量服务器的内核缺陷——UCloud内核热补丁技术揭秘
下述為UCloud資深工程師邱模炯在InfoQ架構(gòu)師峰會(huì)上的演講——《UCloud云平臺(tái)的內(nèi)核實(shí)踐》中非常受關(guān)注的內(nèi)核熱補(bǔ)丁技術(shù)的一部分。給大家揭開了UCloud云平臺(tái)內(nèi)核技術(shù)的神秘面紗。
?
如何零代價(jià)修復(fù)海量服務(wù)器的Linux內(nèi)核缺陷?
?
對(duì)于一個(gè)擁有成千上萬臺(tái)服務(wù)器的公司,Linux內(nèi)核缺陷導(dǎo)致的死機(jī)屢見不鮮。讓工程師們糾結(jié)的是,到底要不要通過給服務(wù)器升級(jí)內(nèi)核來修復(fù)缺陷?升級(jí)意味者服務(wù)器重啟、業(yè)務(wù)中斷以及繁重的準(zhǔn)備工作;不升級(jí)則擔(dān)心服務(wù)器死機(jī),同樣造成業(yè)務(wù)中斷和繁重的善后工作。
?
而在今天的云計(jì)算時(shí)代,一臺(tái)宿主機(jī)往往運(yùn)行多個(gè)云主機(jī),每一次重啟不管是主動(dòng)升級(jí)還是被動(dòng)死機(jī),都意味著中斷其上運(yùn)行的所有云主機(jī)。因此,宿主機(jī)內(nèi)核缺陷的修復(fù)更加棘手。
?
而作為一個(gè)支撐著上萬家企業(yè)用戶IT基礎(chǔ)架構(gòu)的云服務(wù)商,UCloud云平臺(tái)上的海量宿主機(jī)又是如何修復(fù)內(nèi)核缺陷的呢?
?
邱模炯透露,如果按照傳統(tǒng)的重啟方式來修復(fù),那么無論是對(duì)于UCloud或是用戶,都意味著繁重的運(yùn)維和業(yè)務(wù)中斷。但是,UCloud通過“內(nèi)核熱補(bǔ)丁技術(shù)”——即給運(yùn)行中的內(nèi)核打上二進(jìn)制補(bǔ)丁,UCloud已經(jīng)做到了零代價(jià)免重啟修復(fù)海量服務(wù)器的內(nèi)核缺陷!目前為止,UCloud對(duì)所發(fā)現(xiàn)的上游內(nèi)核10+個(gè)缺陷全以熱補(bǔ)丁方式修復(fù),累計(jì)數(shù)萬臺(tái)次,無一例失敗且無任何副作用;理論上避免了相應(yīng)次數(shù)的宿主機(jī)重啟及所隱含的云主機(jī)業(yè)務(wù)中斷。這項(xiàng)技術(shù)在UCloud已經(jīng)成熟。
?
UCloud內(nèi)核熱補(bǔ)丁技術(shù)揭秘
?
UCloud的熱補(bǔ)丁技術(shù)基于多年前的開源ksplice加以定制優(yōu)化而來,通過加載一個(gè)特殊準(zhǔn)備的熱補(bǔ)丁模塊來修復(fù)內(nèi)核。其過程如下圖所示:
?
?
?
熱補(bǔ)丁模塊由ksplice程序編譯生成,包含有缺陷的二進(jìn)制指令和修復(fù)后的二進(jìn)制指令(這些二進(jìn)制按函數(shù)級(jí)別組織);模塊加載后,自動(dòng)定位到內(nèi)核的缺陷處并以修復(fù)指令動(dòng)態(tài)替換缺陷指令。
?
ksplice熱補(bǔ)丁模塊的創(chuàng)建原理見下圖:
?
首先獲取一份運(yùn)行中內(nèi)核對(duì)應(yīng)的源碼并編譯出二進(jìn)制,稱為pre對(duì)象;打上源碼補(bǔ)丁再次編譯,稱為post對(duì)象。而運(yùn)行中的內(nèi)核二進(jìn)制稱為run對(duì)象。post和pre逐條指令比較并找出存在差異的函數(shù),之后把這些差異合并為內(nèi)核模塊形式的熱補(bǔ)丁。
?
創(chuàng)建好的熱補(bǔ)丁模塊在加載到內(nèi)核時(shí)還會(huì)做些檢驗(yàn)工作:對(duì)比pre和run對(duì)象。只有通過檢驗(yàn)才能成功加載進(jìn)內(nèi)核。pre-run比較的目的是為了辨別編譯過程差異是否過大以致于不能打入post對(duì)象的熱補(bǔ)丁;更重要的是,從pre-run差異中提取的關(guān)鍵信息才能把post對(duì)象的熱補(bǔ)丁順利打入運(yùn)行中內(nèi)核。
?
熱補(bǔ)丁模塊加載到內(nèi)核后,便自動(dòng)進(jìn)行內(nèi)核修復(fù)。也就是使用熱補(bǔ)丁中的二進(jìn)制指令替換有缺陷的二進(jìn)制指令。這里ksplice利用了Linux內(nèi)核的stop_machine機(jī)制:停止所有CPU的執(zhí)行,只留下主CPU進(jìn)行二進(jìn)制指令替換。值得注意的是,stop_machine后如果發(fā)現(xiàn)任何一個(gè)線程棧的內(nèi)容與熱補(bǔ)丁存在沖突,就需要退出指令替換以避免系統(tǒng)崩潰。所以并非所有熱補(bǔ)丁都能打入內(nèi)核,有些頻繁使用的內(nèi)核函數(shù)(如schedule, hrtimer相關(guān))就無法熱補(bǔ)丁,重試次數(shù)再多也無濟(jì)于事。
?
ksplice同時(shí)支持對(duì)內(nèi)核和模塊進(jìn)行熱補(bǔ)丁,也支持熱補(bǔ)丁后疊加熱補(bǔ)丁,靈活方便。不過也存在一些缺陷:stop_machine期間整個(gè)系統(tǒng)處于中斷狀態(tài),雖然單次中斷小于1ms,但有些時(shí)候多次重試的累計(jì)中斷也不小;另外,有些頻繁使用的函數(shù)無法打入熱補(bǔ)丁。
?
kpatch和kgraft
kpatch和kgraft均是近期新出現(xiàn)的內(nèi)核熱補(bǔ)丁技術(shù),前者屬于Redhat公司,后者SuSE。兩者原理和ksplice大致相同,都想合并進(jìn)Linux內(nèi)核,內(nèi)核社區(qū)正在爭(zhēng)議對(duì)比。
?
kpatch原理和前面講的ksplice很接近。最大的區(qū)別在于二進(jìn)制指令替換,stop_machine停止所有CPU執(zhí)行后ksplice直接修改,而kpatch則借助ftrace機(jī)制來觸發(fā)替換。目前的實(shí)現(xiàn)上,kpatch有較大局限性,不支持對(duì)模塊打熱補(bǔ)丁,不支持函數(shù)靜態(tài)變量等。
?
kgraft原理也基本一樣。主要的差異有兩點(diǎn):
?
1)熱補(bǔ)丁生成方法不同;
2)熱補(bǔ)丁打入內(nèi)核過程里kgraft用到了RCU漸進(jìn)方法。得益于RCU方法,kgraft無需像ksplice和kpatch一樣調(diào)用stop_machine并檢查線程棧的沖突。不過它的缺點(diǎn)也緣于RCU,涉及到數(shù)據(jù)結(jié)構(gòu)改變時(shí),kgraft更難通過編寫輔助代碼打入熱補(bǔ)丁,這限制了kgraft的應(yīng)用范圍。
?
有關(guān)kpatch和kgraft的詳細(xì)情況請(qǐng)分別參考Redhat和SuSE網(wǎng)站的技術(shù)資料。
?
除了免重啟修復(fù),熱補(bǔ)丁還用于內(nèi)核開發(fā)過程的性能分析和故障定位。比如,加上性能統(tǒng)計(jì)代碼生成熱補(bǔ)丁,就可以在線分析感興趣的性能問題;加入額外調(diào)試代碼捕捉運(yùn)行中內(nèi)核的異常。這些非常有用,更是海量服務(wù)器里捕捉不可重現(xiàn)內(nèi)核異常的不二法寶。由于熱補(bǔ)丁不需要重啟服務(wù)器,既可打入也可撤銷,所以不會(huì)有副作用。
?
UCloud對(duì)開源Ksplice的優(yōu)化主要在以下三個(gè)方面:
?
支持高版本內(nèi)核
熱補(bǔ)丁技術(shù)與內(nèi)核緊密耦合。不同版本的內(nèi)核在指令結(jié)構(gòu)體,符合表結(jié)構(gòu)體和一些特性上(比如早期內(nèi)核沒有ftrace)有所不同,直接影響熱補(bǔ)丁成敗。UCloud研究了各版本內(nèi)核的區(qū)別,使得同一份ksplice支持各個(gè)版本的Linux內(nèi)核。值得一提的是,解決了ftrace與ksplice不兼容的問題。
?
允許熱修復(fù)頻繁調(diào)用的函數(shù)
不管什么樣的熱補(bǔ)丁技術(shù),兩種類型的內(nèi)核函數(shù)難以熱補(bǔ)丁:頻繁使用的內(nèi)核函數(shù)如schedule, hrtimer;經(jīng)常處于線程棧內(nèi)核部分頂部的函數(shù),如sys_poll, sys_read。UCloud更改了ksplice相關(guān)內(nèi)核代碼和用戶態(tài)工具,成功解除了這些限制,比如UCloud現(xiàn)網(wǎng)服務(wù)器已打入了三個(gè)hrtimer熱補(bǔ)丁。
?
減少業(yè)務(wù)中斷時(shí)間
ksplice是在stop_machine后替換二進(jìn)制指令的。雖然單次stop_machine對(duì)業(yè)務(wù)造成的中斷在一毫秒左右,但有些頻繁使用的內(nèi)核函數(shù)需要大量重試才能碰到合適的熱補(bǔ)丁時(shí)機(jī),于是會(huì)造成最長(zhǎng)達(dá)上百毫秒的中斷。UCloud在此做過一點(diǎn)優(yōu)化,使得業(yè)務(wù)中斷時(shí)間控制在十毫秒級(jí)別。
?
海量服務(wù)器環(huán)境下熱補(bǔ)丁技術(shù)可用來零代價(jià)且無副作用地修復(fù)內(nèi)核缺陷,而且內(nèi)核開發(fā)也因熱補(bǔ)丁能走得更遠(yuǎn)更好。以前因?yàn)槿狈o助分析手段和懼怕內(nèi)核BUG,即使適合在內(nèi)核實(shí)現(xiàn)的特性也被告誡移到用戶態(tài)實(shí)現(xiàn),然而有了熱補(bǔ)丁,相關(guān)觀念也可以適當(dāng)調(diào)整,內(nèi)核開發(fā)也可以更加大膽和跳脫。
轉(zhuǎn)載于:https://www.cnblogs.com/UCloud/p/3868467.html
總結(jié)
以上是生活随笔為你收集整理的零代价修复海量服务器的内核缺陷——UCloud内核热补丁技术揭秘的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。