聊聊最近很火的eBPF


如果非要說當前計算機領域最有前途的兩個基礎軟件技術,那非eBPF和wasm莫屬了。

什么是eBPF?
Linux內核一直是實現監視/可觀察性,網絡和安全性的理想場所。不幸的是,這通常是不切實際的,因為它需要更改內核源代碼或加載內核模塊,並導致彼此堆疊的抽象層。 eBPF是一項革命性的技術,可以在Linux內核中運行沙盒程序,而無需更改內核源代碼或加載內核模塊。通過使Linux內核可編程,基礎架構軟件可以利用現有的層,從而使它們更加智能和功能豐富,而無需繼續為系統增加額外的復雜性層。

eBPF導致了網絡,安全性,應用程序配置/跟蹤和性能故障排除等領域的新一代工具的開發,這些工具不再依賴現有的內核功能,而是在不影響執行效率或安全性的情況下主動重新編程運行時行為。

如果直接解釋eBPF,有點不明所以。那我們就看看有哪些基於eBPF的工程,這些工程或許你已經知道,或是已經經常使用,也許你會明白eBPF距離我們並不遙遠。

基於eBPF的項目
1:bcc

BCC是用於創建基於eBPF的高效內核跟蹤和操作程序的工具包,其中包括一些有用的命令行工具和示例。 BCC簡化了用C進行內核檢測的eBPF程序的編寫,包括LLVM的包裝器以及Python和Lua的前端。它還提供了用於直接集成到應用程序中的高級庫。

2:bpftrace

bpftrace是Linux eBPF的高級跟蹤語言。它的語言受awk和C以及DTrace和SystemTap等以前的跟蹤程序的啟發。 bpftrace使用LLVM作為后端將腳本編譯為eBPF字節碼,並利用BCC作為與Linux eBPF子系統以及現有Linux跟蹤功能和連接點進行交互的庫。

3:Cilium

Cilium是一個開源項目,提供基於eBPF的聯網,安全性和可觀察性。它是從頭開始專門設計的,旨在將eBPF的優勢帶入Kubernetes的世界,並滿足容器工作負載的新可伸縮性,安全性和可見性要求。

4:Falco

Falco是一種行為活動監視器,旨在檢測應用程序中的異常活動。 Falco在eBPF的幫助下審核Linux內核層的系統。它使用其他輸入流(例如容器運行時度量標准和Kubernetes度量標准)豐富了收集的數據,並允許連續監視和檢測容器,應用程序,主機和網絡活動。

5:Katran

Katran是一個C ++庫和eBPF程序,用於構建高性能的第4層負載平衡轉發平面。 Katran利用Linux內核中的XDP基礎結構來提供用於快速數據包處理的內核功能。它的性能與NIC接收隊列的數量成線性比例,並且使用RSS友好的封裝轉發到L7負載平衡器。

6:Sysdig

Sysdig是提供深層系統可見性的簡單工具,並具有對容器的原生支持。

其他基於eBPF技術的項目還有很多,比如kubectl-trace ,ply 等,這里不再贅述。

如何編寫一個eBPF程序?
在很多情況下,不是直接使用eBPF,而是通過Cilium,bcc或bpftrace等項目間接使用eBPF,這些項目在eBPF之上提供了抽象,並且不需要直接編寫程序,而是提供了指定基於意圖的定義的功能,然后使用eBPF實施。

如果不存在更高級別的抽象,則需要直接編寫程序。 Linux內核希望eBPF程序以字節碼的形式加載。雖然當然可以直接編寫字節碼,但更常見的開發實踐是利用LLVM之類的編譯器套件將偽C代碼編譯為eBPF字節碼。

在編寫eBPF程序之前,需要簡單了解幾個概念。

1)map(映射) :BPF最令人着迷的方面之一是,內核上運行的代碼和加載了該代碼的程序可以在運行時使用消息傳遞相互通信。

BPF映射是駐留在內核中的鍵/值存儲。任何BPF程序都可以訪問它們。在用戶態中運行的程序也可以使用文件描述符訪問這些映射。只要事先正確指定數據大小,就可以在映射中存儲任何類型的數據。內核將鍵和值視為二進制 blobs,它並不關心您在映射中保留的內容。

BPF驗證程序包括多種保護措施,以確保您創建和訪問映射的方式是安全的。當我們解釋如何訪問這些映射中的數據時,我們也將解釋這些保護措施。

當然BPF映射類型有很多,比如哈希表映射,數組映射,Cgroup 數組映射等,分別滿足不同的場景。

2)驗證器

BPF驗證程序也是在您的系統上運行的程序,因此,對其進行嚴格審查是確保其正確執行工作的目標。

驗證程序執行的第一項檢查是對VM即將加載的代碼的靜態分析。第一次檢查的目的是確保程序有預期的結果。為此,驗證程序將使用代碼創建有向循環圖(DAG)。驗證程序分析的每個指令將成為圖中的一個節點,並且每個節點都鏈接到下一條指令。驗證程序生成此圖后,它將執行深度優先搜索(DFS),以確保程序完成並且代碼不包含危險路徑。這意味着它將遍歷圖的每個分支,一直到分支的底部,以確保沒有遞歸循環。

這些是驗證器在第一次檢查期間可能拒絕您的代碼的情形,要求有以下幾個方面:

該程序不包含控制循環。為確保程序不會陷入無限循環,驗證程序會拒絕任何類型的控制循環。已經提出了在BPF程序中允許循環的建議,但是截至撰寫本文時,沒有一個被采用。
該程序不會嘗試執行超過內核允許的最大指令數的指令。此時,可執行的最大指令數為4,096。此限制是為了防止BPF永遠運行。在第3章,我們討論如何嵌套不同的BPF程序,以安全的方式解決此限制。
該程序不包含任何無法訪問的指令,例如從未執行過的條件或功能。這樣可以防止在VM中加載無效代碼,這也會延遲BPF程序的終止。
該程序不會嘗試越界。
驗證者執行的第二項檢查是BPF程序的空運行。這意味着驗證者將嘗試分析程序將要執行的每條指令,以確保它不會執行任何無效的指令。此執行還將檢查所有內存指針是否均已正確訪問和取消引用。最后,空運行向驗證程序通知程序中的控制流,以確保無論程序采用哪個控制路徑,它都會到達BPF_EXIT指令。為此,驗證程序會跟蹤堆棧中所有訪問過的分支路徑,並在采用新路徑之前對其進行評估,以確保它不會多次訪問特定路徑。經過這兩項檢查后,驗證者認為程序可以安全執行。

  1. hook : 由於eBPF是事件驅動的,所以ebpf是作用於具體的hook的。根據不同的作用,常用的有XDP,trace,套接字等。

4)幫助函數:eBPF程序無法調用任意內核功能。允許這樣做會將eBPF程序綁定到特定的內核版本,並使程序的兼容性復雜化。取而代之的是,eBPF程序可以調用幫助函數,該函數是內核提供的眾所周知且穩定的API。

總結
安全,網絡,負載均衡,故障分析,追蹤等領域都是eBPF的主戰場。

對於雲原生領域,Cilium 已經使用eBPF 實現了無kube-proxy的容器網絡。利用eBPF解決iptables帶來的性能問題。

整個eBPF生態發展比較好,社區已經提供了諸多工具方便大家編寫自己的eBPF程序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM