一文讀懂 eBPF 對 Kubernetes 可觀測的重要性
在 Linux 內(nèi)核中工作是實現(xiàn)安全性、網(wǎng)絡(luò)和可觀察性特性的理想選擇。然而,這并不是沒有挑戰(zhàn)。無論是修改內(nèi)核源代碼,還是添加模塊,開發(fā)人員傳統(tǒng)上發(fā)現(xiàn)他們要與難以調(diào)試的復(fù)雜基礎(chǔ)設(shè)施和抽象層作斗爭。Extended BPF[2](eBPF)解決了這兩個問題。
Extended Berkeley Packet Filter(eBPF)是一種內(nèi)核技術(shù)(從 Linux 4.x 開始),它允許程序在無需更改內(nèi)核源代碼,或添加額外模塊的情況下運行。你可以將其視為 Linux 內(nèi)核中的輕量級沙箱虛擬機(VM),程序員可以在其中運行 BPF 字節(jié)碼,從而利用特定的內(nèi)核資源。
使用 eBPF 消除了更改內(nèi)核源代碼的需要,并簡化了軟件利用現(xiàn)有層的能力。因此,它是一項強大的技術(shù),有可能從根本上改變網(wǎng)絡(luò)、可觀察性和安全性等服務(wù)的交付方式。
下面詳細介紹一下它是什么,它是如何工作的,以及何時考慮實施它。
eBPF 是如何工作
eBPF 程序是事件驅(qū)動的,并附加到代碼路徑上。代碼路徑包含特定的觸發(fā)器(稱為鉤子),這些觸發(fā)器在傳遞附加的 eBPF 程序時執(zhí)行它們。鉤子的一些例子包括網(wǎng)絡(luò)事件、系統(tǒng)調(diào)用、函數(shù)項和內(nèi)核追蹤點。
當觸發(fā)時,代碼首先被編譯為 BPF 字節(jié)碼。然后,字節(jié)碼在運行之前會被驗證,以確保它不會創(chuàng)建循環(huán)。這個步驟可以防止程序無意或故意損害 Linux 內(nèi)核。
在鉤子上觸發(fā)程序之后,它就會進行助手調(diào)用。這些助手調(diào)用是為 eBPF 配備許多用于訪問內(nèi)存的特性的函數(shù)。助手調(diào)用需要由內(nèi)核預(yù)先定義,但是存在的函數(shù)列表在不斷增長[3]。
eBPF 最初被用作過濾網(wǎng)絡(luò)數(shù)據(jù)包時,提高可觀察性和安全性的一種方法。然而,隨著時間的推移,它成為了一種使用戶提供的代碼實現(xiàn)更安全、更方便和性能更好的方法。
eBPF 的優(yōu)點
eBPF 通常用于追蹤[4]用戶空間進程,它的優(yōu)點在這里很明顯。這是一個安全和有用的方法來確保:
- 速度和性能。eBPF 可以將包處理從內(nèi)核空間轉(zhuǎn)移到用戶空間。同樣,eBPF 是即時(JIT)編譯器。編譯字節(jié)碼后,將調(diào)用 eBPF,而不是為每個方法調(diào)用字節(jié)碼的新解釋。
- 低侵入性。當作為調(diào)試器使用時,eBPF 不需要停止程序來觀察其狀態(tài)。
- 安全。程序?qū)嶋H上是沙箱化的,這意味著內(nèi)核源代碼仍然受到保護并且沒有改變。驗證步驟確保資源不會被運行無限循環(huán)的程序堵塞。
- 方便。創(chuàng)建鉤子內(nèi)核函數(shù)的代碼比構(gòu)建和維護內(nèi)核模塊的工作要少。
- 統(tǒng)一的追蹤。eBPF 為你提供了一個用于追蹤流程的單一、強大且可訪問的框架。這增加了可見性和安全性。
- 可編程性。使用 eBPF 有助于增加環(huán)境的特性豐富度,而無需添加額外的層。同樣,由于代碼直接在內(nèi)核中運行,因此可以在 eBPF 事件之間存儲數(shù)據(jù),而不像其他追蹤程序那樣轉(zhuǎn)儲數(shù)據(jù)。
- 表達能力。eBPF 具有表達性,能夠執(zhí)行通常只能在高級語言中找到的功能。
eBPF 的最佳實踐
由于 eBPF 是一項如此新的技術(shù),許多東西仍未被探索。隨著技術(shù)的發(fā)展,圍繞 eBPF 的最佳實踐仍在不斷發(fā)展。雖然沒有明確的最佳實踐集存在,但你可以做一些事情來確保有效、高效的程序。
如果你正在為你的生態(tài)系統(tǒng)使用 eBPF,我們建議你:
- 使用LLVM Clang[5]將 C 編譯成字節(jié)碼。當 eBPF 首次出現(xiàn)時,需要手工編寫和組裝程序。然后,開發(fā)人員使用內(nèi)核的匯編程序生成字節(jié)碼。幸運的是,現(xiàn)在不再需要這樣做了。Clang 提供了 C 語言的前端基礎(chǔ)設(shè)施和工具。
- 編寫 BPF 程序時請使用 BCC 工具包。BPF Compiler Collection[6](BCC)是一個工具包,可以幫助你創(chuàng)建高效的內(nèi)核追蹤和操作程序。它特別適合于性能分析和網(wǎng)絡(luò)流量控制相關(guān)的任務(wù)。
eBPF 的缺點
盡管 eBPF 功能強大,但它并不是適合每個項目或生態(tài)系統(tǒng)的靈丹妙藥。eBPF 確實有一些明顯的缺點,這可能會使它在某些實例中工作起來令人沮喪。一些開發(fā)人員可能會發(fā)現(xiàn) eBPF 不適合使用,原因如下:
- 它僅限于 Linux 和一個最新的內(nèi)核。eBPF 是在 Linux 內(nèi)核中開發(fā)的,并且是完全面向 Linux 內(nèi)核的。這使得它比其他追蹤器更難攜帶。此外,你需要一個相當新的內(nèi)核。如果你運行的是比 v4.13 更老的版本,你將無法使用它。
- 沙箱程序是有限的。eBPF 通過限制程序可以訪問的資源來提高安全性。然而,通過限制程序可以訪問的操作系統(tǒng)部分,功能也可能受到限制。
eBPF 的常用情況
eBPF 在云原生應(yīng)用[7]中正迅速獲得關(guān)注。因此,eBPF 最常用于兩種情況:
- 需要使用內(nèi)核追蹤實現(xiàn)可觀察性。在這種情況下,eBPF 更快、更準確。這里不涉及上下文切換[8],而且 eBPF 程序是基于事件的,因此沒有特定的觸發(fā)器就不會運行任何程序——你不會錯過任何事件。
- 傳統(tǒng)的安全監(jiān)控不起作用。eBPF 在分布式和基于容器的環(huán)境中得到了廣泛的應(yīng)用,包括Kubernetes[9]。在這些環(huán)境中,eBPF 可以縮小可見性差距,因為它可以提供對 HTTP 通信的可見性。
你可能還會發(fā)現(xiàn) eBPF 被部署用于其他安全措施,包括:
- 防火墻
- 設(shè)備驅(qū)動程序
- 網(wǎng)絡(luò)性能監(jiān)控
New Relic 和 eBPF
Pixie[10](早前被 New Relic 收購了)是一個開源的 kubernetes-native-in-cluster 可觀察平臺,它提供了 Kubernetes 工作負載的即時可見性,無需手動檢測。eBPF 提供了 Pixie 平臺背后的大部分魔力。如前所述,eBPF 允許在觸發(fā)事件時運行受限制的代碼。這個事件可以是內(nèi)核空間(kprobes)或用戶空間(uprobes)中的函數(shù)調(diào)用。Pixie 同時使用 uprobes 和 kprobes 來支持跨服務(wù)和應(yīng)用程序的可觀察性。
Pixie 利用 eBPF 自動獲取遙測數(shù)據(jù),其邊緣機制能將這些數(shù)據(jù)與 Kubernetes 元數(shù)據(jù)連接起來,在保持數(shù)據(jù)局部性的同時提供可見性。這種可見性補充了 New Relic 強大的 Kubernetes 可觀測性解決方案。從 5 月底開始,你將能夠?qū)?Pixie 生成的遙測數(shù)據(jù)發(fā)送到 New Relic One,獲得可擴展的留存率、強大的可視化、高級關(guān)聯(lián)和智能警報功能。
eBPF 是有效的可觀察性
eBPF 是一種新技術(shù),它改進了 Linux 內(nèi)核中的可觀察性、聯(lián)網(wǎng)和安全性。它消除了更改內(nèi)核源代碼或添加模塊的需要,因此你可以創(chuàng)建更豐富的基礎(chǔ)設(shè)施來支持你的系統(tǒng),而不會使其過于復(fù)雜。
總結(jié)
我們了解了 eBPF 是什么,它是如何工作的,以及為什么它在分布式環(huán)境中如此有用。通過從內(nèi)核層進行監(jiān)控,許多與云中的可觀測性相關(guān)的挑戰(zhàn)都得到了解決。你可以在數(shù)據(jù)中享受更深入的可見性、更多的上下文和更準確的信息。