導(dǎo)讀
eBPF是Linux內(nèi)核革命性技術(shù),能夠安全高效地擴展內(nèi)核能力,應(yīng)用廣泛,尤其是在云原生可觀測性領(lǐng)域的應(yīng)用已經(jīng)成為行業(yè)熱點。在滴滴云原生環(huán)境中,eBPF技術(shù)進行了業(yè)務(wù)實踐和內(nèi)源共建,HuaTuo eBPF 平臺快速落地并取得初步收益,目前已經(jīng)支持云原生關(guān)鍵組件,諸如服務(wù)訪問關(guān)系拓撲、容器安全、宿主機安全、網(wǎng)絡(luò)診斷、根因定位等業(yè)務(wù),HuaTuo也是滴滴開源委員會的精品孵化項目。希望本文為業(yè)界開發(fā)者提供一種如何將eBPF 技術(shù)快速應(yīng)用到云原生場景的落地方式,共同提升云原生系統(tǒng)深度可觀測性。
1?
BPF 技術(shù)的前世
Berkeley Packet Filter BPF 伯克利報文過濾器,最初構(gòu)想提出于 1993 年,Steven McCanne 和 Van Jacobson 的論文《The BSD packet filter: a new architecture for user-level packet capture》。其目標(biāo)提供一種新的高效過濾網(wǎng)絡(luò)報文的方法。最初BPF 只附著在Linux 內(nèi)核網(wǎng)絡(luò)套接字上,當(dāng)套接字綁定BPF字節(jié)碼后,每接收一次報文都會執(zhí)行該字節(jié)。內(nèi)核根據(jù)BPF字節(jié)碼返回值決定是否允許網(wǎng)絡(luò)報文通過。
從指令集角度,BPF 起初的架構(gòu)比較簡單,只有一個32位寬度累加器A,一個32位寬度寄存器X,以及16x32bit 數(shù)組內(nèi)存空間。但BPF 實現(xiàn)了加載、存儲、跳轉(zhuǎn)、運算四類指令。BPF 起初還沒有即時編譯器JIT,所有這些指令完全在內(nèi)核小巧的虛擬機中運行,即便如此性能已經(jīng)完全碾壓其他報文過濾器。
BPF使用起來也比較方便,我們可以通過tcpdump、libpcap或者bpf_asm 生成BPF字節(jié)碼,通過setsockopt SO_ATTACH_FILTER加載到內(nèi)核。如下所示實現(xiàn)ICMP報文過濾,只需要根據(jù)L2/L3報文頭漂移量判斷協(xié)議號是否符合條件。
BPF 最先在sk_filter 落地使用,后續(xù)在netfilter、seccomp、team 驅(qū)動等網(wǎng)絡(luò)子系統(tǒng)都有應(yīng)用,但應(yīng)用方向依舊在網(wǎng)絡(luò)報文處理。
2?
BPF 技術(shù)的今生
BPF 最核心的思想實現(xiàn)了內(nèi)核可編程,即在不改動源碼,重新編譯內(nèi)核的情況下,實現(xiàn)高效擴展內(nèi)核能力。2013 年,Alexei Starovoitov 對 BPF 進行改造,增加新特性,改善其性能。BPF 的進一步發(fā)展,為內(nèi)核帶來了巨大的改變,使內(nèi)核具備了更加強大、可編程的動態(tài)變化的能力。這種能力在各種需要定制化的應(yīng)用場景中,將發(fā)揮巨大的價值,既可以用于擴展功能,也可以用于優(yōu)化性能。新版本被命名為 eBPF (“extended BPF”),以前的 BPF 變成 cBPF(“classic” BPF),后續(xù)篇章中BPF特指該項技術(shù)。
首先指令集角度,eBPF 是一種精簡指令集,支持R0-R9 10個64bit 通用寄存器。其中R0寄存器用于內(nèi)核函數(shù)的返回值,R1-R5寄存器用于內(nèi)核函數(shù)的參數(shù)傳遞,這和x86_64、aarch64 類似。eBPF 支持兩種指令集編碼格式,64位寬度的基礎(chǔ)編碼,128位寬度的寬指令編碼(該指令編碼在基礎(chǔ)編碼之后附加64位立即數(shù)實現(xiàn))。此外,eBPF 也豐富了四類指令集。
Just In Time, ?JIT 編譯器,BPF 指令會被內(nèi)核的 JIT 編譯器動態(tài)編譯為物理機原生指令,實現(xiàn)運行效率的“零”損耗。該特性在cBPF 時期由Eric Dumazet 實現(xiàn),只支持x86-64架構(gòu)。eBPF 根據(jù)自身指令特點再次擴展該編譯器,eBPF 指令不僅僅可以JIT 成物理機CPU原生指令,同時可以翻譯成一些設(shè)備如某些智能網(wǎng)卡的特定指令。這樣諸如智能網(wǎng)卡的設(shè)備可以通過eBPF的方式實現(xiàn)可編程。
除了對指令層面豐富和擴展,eBPF 也增加了基于鍵值對的數(shù)據(jù)存儲機制,可用于實現(xiàn)內(nèi)核用戶態(tài)的數(shù)據(jù)存儲和交換。eBPF 新增比較豐富的BPF Helper函數(shù),這使 BPF 程序可以訪問內(nèi)核功能,擴展BPF 能力,同時保持 BPF 程序和內(nèi)核的安全隔離。?
隨著BPF 功能增強,該技術(shù)不再局限于在內(nèi)核網(wǎng)絡(luò)子系統(tǒng),也逐步應(yīng)用于動態(tài)追蹤、事件檢測、性能分析優(yōu)化、IO 子系統(tǒng)、進程調(diào)度、文件子系統(tǒng)等等。應(yīng)用場景也從具體的點擴展到面:可觀測性、Tracing、安全、性能分析和根因分析等等。同時也涌現(xiàn)出大批優(yōu)秀的開源項目如Bcc、Cilium、bpftrace、Falco、Katran、Pixie。
3?
滴滴生產(chǎn)環(huán)境的業(yè)務(wù)痛點
在數(shù)據(jù)中心有很多基礎(chǔ)服務(wù),這些服務(wù)在穩(wěn)定性、生產(chǎn)效能、可擴展性、安全等發(fā)揮著重要作用,這些基礎(chǔ)設(shè)施在實際落地時都面臨著不同程度的挑戰(zhàn)。
流量回放測試
云原生的規(guī)模越來越大,承載的業(yè)務(wù)種類,業(yè)務(wù)流量和規(guī)模也都在急劇地擴大,軟件測試也面臨極大的挑戰(zhàn),包括測試環(huán)境搭建和測試用例的編寫和維護等。流量回放測試是一種全新的測試方法。通過在線下測試環(huán)境進行回放,實現(xiàn)回歸測試,流量回放能夠完整的復(fù)現(xiàn)線上復(fù)雜的業(yè)務(wù)訪問場景,極大地提高項目迭代效率、加速業(yè)務(wù)回歸測試進度,保證業(yè)務(wù)研發(fā)質(zhì)量提升。項目面臨的挑戰(zhàn):
業(yè)務(wù)編程語言繁多,基礎(chǔ)庫種類版本繁多。
業(yè)務(wù)網(wǎng)絡(luò)模型不統(tǒng)一(php單進程處理,golang協(xié)程處理,其他編程語言多線程/進程)。
對特定業(yè)務(wù)定制化,難以提升覆蓋度,并且成本較高。
業(yè)務(wù)有感,在穩(wěn)定性上較難保障。?
服務(wù)訪問拓撲
隨著微服務(wù)架構(gòu)的興起,服務(wù)數(shù)量日漸增多,服務(wù)之間的依賴關(guān)系變得越來越復(fù)雜。服務(wù)鏈路的可觀測性對業(yè)務(wù)穩(wěn)定性保障有很重要的意義。它能夠清晰地展示服務(wù)接口之間的訪問關(guān)系,以及諸如性能、延遲、超時等業(yè)務(wù)指標(biāo)。線上出現(xiàn)問題的時候,依據(jù)服務(wù)拓撲關(guān)系能夠快速地定位問題節(jié)點。項目面臨的挑戰(zhàn):
業(yè)務(wù)種類量大,人工梳理成本高易出錯。
通過推廣特定SDK依靠 metric 以及日志中服務(wù)調(diào)用關(guān)系進行串聯(lián)的方式推動難度大,在生產(chǎn)環(huán)境中容易出現(xiàn)斷鏈的情況。?
容器安全
在云原生的大勢所趨下,越來越多的企業(yè)選擇擁抱云原生,容器已經(jīng)成為應(yīng)用交付的標(biāo)準(zhǔn),也是云原生時代計算資源和配套設(shè)施的交付單元。容器的使用日益普及,容器安全問題日益凸顯。滴滴針對容器安全有一套完整的方案,其中一些核心的痛點就通過eBPF 技術(shù)解決。?
內(nèi)核根因定位
滴滴云原生平臺的容器部署密度、超賣比都較高,在共享內(nèi)核容器虛擬化場景下容易出現(xiàn)資源不合理使用導(dǎo)致的問題。傳統(tǒng)的內(nèi)核指標(biāo)偏向于基本、整體、粗粒度層面的統(tǒng)計檢測,同時傳統(tǒng)的定位工具資源消耗較多,性能影響較大。因此徹底確定內(nèi)核根因,需要對內(nèi)核子系統(tǒng)進行深度觀測,以及實現(xiàn)常態(tài)化觀測,解決事中事后出現(xiàn)的突發(fā)、超時、毛刺等棘手問題。
4?
滴滴HuaTuo eBPF 平臺實踐
eBPF 技術(shù)能夠很好的解決上述出現(xiàn)的語言依賴痛點,同時eBPF 和動態(tài)追蹤技術(shù)結(jié)合對實現(xiàn)深度觀測內(nèi)核提供支撐。但實際落地過程中需要回答如下問題:
在需求多的情況下,如何快速的滿足這些需求,提升研發(fā)效能快速落地?
目前行業(yè)中雖有落地案例,但規(guī)模相對較小,如何實現(xiàn)從點到面的落地,如何保證宿主機穩(wěn)定性?
如何統(tǒng)一觀測和保障插樁點性能損耗,出現(xiàn)問題如何快速回退、降級、止損??
平臺建設(shè)
基于如上考慮我們研發(fā)了eBPF 平臺,業(yè)務(wù)可以直接使用平臺提供的通用能力,只需要關(guān)注自身邏輯實現(xiàn)即可。平臺建設(shè)過程中重點圍繞著提升研發(fā)效能,提供業(yè)務(wù)視角,保障穩(wěn)定性和保障性能等維度。
提升研發(fā)效能
早期用戶需要關(guān)心如何解析BPF 字節(jié)碼,如何加載到內(nèi)核,創(chuàng)建KV Map 以及將特定的Section 代碼附著到特定的運行節(jié)點。最后用戶還需要關(guān)注如何從內(nèi)核獲取數(shù)據(jù)。平臺重要的功能是將底層的技術(shù)細節(jié)屏蔽,類似的上述功能只需要調(diào)用bpfload和bpfmap 接口即可。
提供業(yè)務(wù)視角
業(yè)務(wù)和平臺,業(yè)務(wù)和業(yè)務(wù)之間的發(fā)布規(guī)律不同。最終我們采用BPF Obj字節(jié)碼的方式將業(yè)務(wù)的邏輯和平臺解耦,業(yè)務(wù)根據(jù)需求調(diào)用平臺接口即可。同時平臺需要考慮標(biāo)準(zhǔn)化,支持其他開源組件定義的SEC,這樣就能夠兼容已有的BPF字節(jié)碼,直接在平臺運行。
保障穩(wěn)定性
作為新的技術(shù)落地,需要重點關(guān)注宿主穩(wěn)定性問題。穩(wěn)定的保障主要從內(nèi)核層,框架側(cè),以及和業(yè)務(wù)感知的方面建立。
保障性能
所有的BPF 代碼都是運行在內(nèi)核態(tài),因此過多的耗時依然會對系統(tǒng)造成影響。事件驅(qū)動,共享內(nèi)存,ringbuf 生產(chǎn)消費等方式在該平臺都有應(yīng)用。
平臺組成
BPF字節(jié)碼管理
首先是解析ELF能力,包括SEC、Map、變量、結(jié)構(gòu)體的定義。通過SEC能夠清楚BPF Prog 類型以及可以自動加載的Hook 附著點等。通過Map的定義解析出其類型,大小,Key 類型,Value 類型等信息。
高性能數(shù)據(jù)處理
平臺支持業(yè)務(wù)類型較多,因此需要從各個維度考慮性能保障。首先在內(nèi)核側(cè)對probe hook點動態(tài)評測,提供熔斷機制。在平臺側(cè)提供高性能數(shù)據(jù)通信,ringbuf 生產(chǎn)消費方式減低延遲。
穩(wěn)定性管理
平臺設(shè)計初衷是解決線上問題保證業(yè)務(wù)穩(wěn)定性,因此平臺自身實現(xiàn)了事件熔斷和自愈功能。當(dāng)檢測到宿主BPF 出現(xiàn)異常,平臺會自動unload bpf從而避免當(dāng)前BPF造成過高的負載。除了實現(xiàn)事件的熔斷和自愈,同時限制平臺使用的系統(tǒng)資源如cpu、mem。
容器信息管理
實現(xiàn)該功能主要基于如下因素:1. 所有業(yè)務(wù)運行在容器,參數(shù)的傳遞,業(yè)務(wù)的識別都需要該信息。2. 內(nèi)核cgroup信息需要和容器信息進行聚合。
平臺使用
平臺除了API 接口,還提供了命令行方式,這樣非常態(tài)運行BPF OBJ或者調(diào)試OBJ 都可以在該平臺運行。
代碼示例如下:
編譯:
?
?
clang -O2 -g -target bpf -c $(NAME).bpf.c -o $(NAME).o
?
?
運行:平臺自動解析BPF 定義的結(jié)構(gòu)體并打印到stdout。
5?
滴滴業(yè)務(wù)落地實踐
在滴滴很多業(yè)務(wù)已經(jīng)接入HuaTuo eBPF 平臺,例如服務(wù)測試回歸、容器安全、主機安全、服務(wù)訪問拓撲、網(wǎng)絡(luò)診斷,內(nèi)核根因定位等等。下面主要以內(nèi)核根因定位為例進行講解。?
內(nèi)核根因定位背景
現(xiàn)今,降本增效是廣大互聯(lián)網(wǎng)公司的主題,在滴滴容器部署密度,超賣比都較高,共享內(nèi)核容器技術(shù)在這種情景下很難避免由于資源不合理使用影響到其他業(yè)務(wù)的情況。在發(fā)生故障時第一舉措是止損,容器漂移,這樣問題現(xiàn)場就丟失了,線下復(fù)現(xiàn)問題的難度大,人力機器的成本很高。此外,線上偶發(fā)的毛刺、耗時和超時等問題沒有規(guī)律可循,綜上原因常態(tài)觀測是一個非常強的需求。
內(nèi)核根因定位思路
根據(jù)可觀測性三大支柱(如下圖所示),首先我們建立起內(nèi)核深度觀測指標(biāo),這些指標(biāo)更加細粒度,能夠反映出內(nèi)核各子系統(tǒng)健康狀態(tài)。建立這些指標(biāo)時會從不同的角度評測合理性、性能影響,最終實現(xiàn)常態(tài)觀測。其次,事件驅(qū)動實現(xiàn)獲取內(nèi)核異常日志上下文,我們關(guān)心內(nèi)核各子系統(tǒng)在異常路徑,慢路徑等出錯狀態(tài)收集。異常事件是解決內(nèi)核問題根因的關(guān)鍵。隨著底層基礎(chǔ)能力的建立,我們可以將這些信息就行匯總、分析、最終給出分析報告。
內(nèi)核根因定位平臺
我們將內(nèi)核根因定位平臺分為四部分:
內(nèi)核數(shù)據(jù)采集。該部分主要實現(xiàn)內(nèi)核核心指標(biāo)采集,以及內(nèi)核異常上下文的收集。
內(nèi)核數(shù)據(jù)聚合。該部分主要實現(xiàn)將內(nèi)核觀測數(shù)據(jù)和容器/Pod信息進行匯總并上傳到存儲設(shè)備。
數(shù)據(jù)分析層。該部分主要將收集到的數(shù)據(jù)進行處理,對上提供分析服務(wù)。
數(shù)據(jù)展示層。主要分析診斷中心、觀測中心、日志中心、分析報告、以及報警中心等。
6?
未來規(guī)劃展望
eBPF內(nèi)核技術(shù)在滴滴云原生場景進行了大規(guī)模多場景的落地實踐,未來HuaTuo eBPF平臺會服務(wù)更多的業(yè)務(wù)線。如今,我們正尋求合適的基金會進行項目孵化,一起和行業(yè)開發(fā)者共建、共享。最近幾年,eBPF 技術(shù)雖然有比較大的發(fā)展,但在某些場景中的功能還不夠完善,比如在性能上進行優(yōu)化、CPU調(diào)度等在離線混部場景中深入探索等,期待后續(xù)與大家持續(xù)交流探討。
編輯:黃飛
?
評論
查看更多