編寫說明 編寫單位:浪潮電子信息產業股份有限公司、阿里云計算有限公司 參編組織:龍蜥社區 編寫組成員:蘇志遠、吳棟、方浩、王傳國、梁媛、黃吉旺、毛文安、程書意、甄鵬、李宏偉、彭彬彬 前言 eBPF 的誕生是 BPF 技術的一個轉折點,使得 BPF 不再僅限于網絡棧,而是成為內核的一個頂級子系統。在內核發展的同時,eBPF 繁榮的生態也進一步促進了 eBPF 技術的蓬勃發展。隨著內核的復雜性不斷增加,eBPF以安全、穩定、零侵入、方便的內核可編程性等特點成為實現內核定制與功能多樣性的最佳選擇,為內核提供了應對未來挑戰的基礎。 本白皮書重點介紹eBPF技術的概念、技術實踐以及發展趨勢。本書首先梳理了eBPF的架構和重要技術原理,然后分析了eBPF在多種典型應用場景的使用方案,并進一步對eBPF技術的發展趨勢做了探討。 目錄 eBPF簡介 .................................................................................................................. 6 eBPF技術介紹 .......................................................................................................... 7 2.1 eBPF架構 ....................................................................................................... 7 2.1.1 eBPF加載過程 ................................................................................... 8 2.1.2 JIT編譯 .............................................................................................. 9 2.1.3 掛載與執行 ...................................................................................... 10 2.2 eBPF常見的開發框架 ................................................................................. 17 2.2.1 BCC ................................................................................................... 17 2.2.2 bpfTrace ........................................................................................... 18 2.2.3 libbpf ................................................................................................. 18 2.2.4 libbpf-bootstrap .............................................................................. 19 2.2.5 cilium-ebpf ....................................................................................... 19 2.2.6 Coolbpf ............................................................................................. 19 eBPF的應用場景與實踐 ........................................................................................ 23 3.1 基于eBPF的系統診斷 ............................................................................... 23 3.1.1 系統診斷面臨挑戰 .......................................................................... 23 3.1.2 基于eBPF的系統診斷方案 ........................................................... 28 3.2 基于eBPF的虛擬化IO全鏈路時延監測 ................................................ 34 3.2.1 虛擬化IO全路徑分析主要面臨的挑戰 ....................................... 34 3.2.2 基于bpftrace虛擬化IO路徑追蹤解決方案 ............................... 36 3.3 基于eBPF的網絡性能優化 ....................................................................... 41 3.3.1 Linux網絡性能優化面臨的技術挑戰 ............................................ 41 3.3.2 基于eBPF的Linux內核網絡性能優化解決方案....................... 44 3.4 基于eBPF的主機安全 ............................................................................... 53 3.4.1 傳統解決方案面臨挑戰 .................................................................. 53 3.4.2 基于eBPF的新一代主機安全解決方案 ....................................... 54 挑戰與展望 ............................................................................................................. 63 eBPF簡介 eBPF簡介 eBPF是一項起源于Linux內核的革命性技術,可以在特權上下文中(如操作系統內核)運行沙盒程序。它可以安全有效地擴展內核的功能,并且不需要更改內核源代碼或加載內核模塊。 內核因具有監督和控制整個系統的特權,一直是實現可觀察性、安全性和網絡功能的理想場所。同時,由于對穩定性和安全性的高要求,內核發展相對緩慢,與內核之外實現的功能相比,創新速度較慢。 eBPF從根本上改變了上述情況,它允許在內核中運行沙箱程序,即通過運行eBPF程序向正在運行中的操作系統添加額外的功能,并通過驗證引擎和即時編譯器保證安全性和執行效率,由此衍生出了一系列的產品和項目,涉及下一代網絡、可觀察性和安全技術。 如今,eBPF在多種應用場景中起到重要作用:在現代數據中心和云原生環境中提供高性能網絡和負載均衡,以低開銷提取細粒度的安全可觀察性數據,幫助應用程序開發人員跟蹤應用程序的運行狀態,高效進行性能故障定位,保證應用程序和容器運行時安全等。 eBPF引領的創新才剛剛開始,一切皆有可能。 eBPF技術介紹 eBPF技術介紹 2.1 eBPF架構 eBPF包括用戶空間程序和內核程序兩部分,用戶空間程序負責加載BPF字節碼至內核,內核中的BPF程序負責在內核中執行特定事件,用戶空間程序與內核BPF程序可以使用map結構實現雙向通信,這為內核中運行的BPF程序提供了更加靈活的控制。eBPF的工作邏輯如下: 1、eBPF Program通過LLVM/Clang編譯成eBPF定義的字節碼; 2、通過系統調用bpf()將字節碼指令傳入內核中; 3、由Verifier檢驗字節碼的安全性、合規性; 4、在確認字節碼程序的安全性后,JIT Compiler會將其轉換成可以在當前系統運行的機器碼; 5、根據程序類型的不同,把可運行機器碼掛載到內核不同的位置/HOOK點; 6、等待觸發執行,其中不同的程序類型、不同的HOOK點的觸發時機是不相同的;并且在eBPF程序運行過程中,用戶空間可通過eBPF map與內核進行雙向通信; eBPF技術介紹 圖2-1-1 eBPF基本架構與使用示意圖 2.1.1 eBPF加載過程 編譯得到的BPF字節碼文件,經過字節碼讀取、重定位和Verifier等過程,加載到內核中。 1、字節碼讀取 通常eBPF字節碼文件都是ELF格式,各section中保存著字節碼所有的信息,包括字節碼指令、map定義、BTF信息,以及需要重定位的變量和函數等;eBPF加載時,依照ELF格式讀取字節碼文件,把各種信息按照一定的格式保存起來。 2、重定位 重定位是指在編譯、加載的過程中把字節碼中一些臨時數據以更準確的信息進行替換,比如用map句柄替換map索引,用map地址替換map句柄。經過多輪重定位,可以確保eBPF程序在內核中運行所需數據的正確性和完整性。需要重定位的對象有:map、函數調用、Helper函數調用、字段、Extern內核符號和kconfig。 eBPF技術介紹 重定位操作主要分為2類: 1)BPF基礎設施提供了一組有限的“穩定接口”,通過convert_ctx_access對CTX進行轉換,實現內核版本升級時的穩定性和兼容性。 2)CO-RE采用(BTF)非硬編碼的形式對成員在結構中的偏移位置進行描述,解決不同版本之間的差異性問題。 3、Verifier Verifier是一個靜態代碼安全檢查器,用于檢查eBPF程序的安全性,保證eBPF程序不會破壞內核,影響內核的穩定性。 安全檢查主要分成兩個階段。 第一個階段檢查函數的深度和指令數,通過使用深度優先遍歷,來檢查是否為有向無環圖(DAG)。 第二個階段檢查每條bytecode指令,根據指令的分類(class),檢查其操作寄存器的讀寫屬性、內存訪問是否越界、BPF_CALL是否符合接口協議等。 指針的安全性檢查在第二個階段實現,每次把指針加載到寄存器時都會進行指針類型的判定,根據指針類型定義確定讀寫屬性和大小,實現針對指針操作的安全性檢查;未識別的指針類型不允許解引用。 2.1.2 JIT編譯 執行字節碼是一個模擬CPU執行機器碼的過程,在運行時需要先把指令依次翻譯成機器碼之后才能運行,所以比機器碼的執行效率低很多。JIT(Just In Time)的 eBPF技術介紹 中文意思是即時編譯,主要為了解決虛擬機運行中間碼時效率不高的問題。 JIT編譯在執行前先把中間碼編譯成對應的機器碼并緩存起來,從而運行時能夠直接執行機器碼,這樣就解決了每次執行都需要進行中間碼解析的問題,如下圖所示: 圖2-1-2 JIT的作用示意圖 2.1.3 掛載與執行 eBPF在內核提供了大量的掛載點,算上kprobe掛載點,幾乎可以在內核代碼的