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