【譯】何時(以及何時不)使用 eBPF

原文地址:https://www.tigera.io/blog/ebpf-when-and-when-not-to-use-it/

本文介紹了 eBPF 的一些基本應用場景,主要和內核函數,iptables 對比,讓大家能理解 eBPF 應該在那些場景下使用,那些場景下不建議使用。我認爲可以作爲入門 eBPF 的必修課,學習一個技術,必須知道這個技術擅長那些場景,不擅長那些場景,在學習和使用上纔不至於走彎路。

前言

擴展伯克利包過濾器 (eBPF) 是 Linux 內核的一個相對較新的特性,這個特性讓許多 DevOps、SRE 和工程師感到眼前一亮。但是它是滿足所有 Linux 內核需求的一站式解決方案嗎?所以本文中我們要分析看看 eBPF 在哪些方面做得很好,以及它與標準 Linux iptables 的對比如何。

eBPF 是什麼?

eBPF 是 Linux 內核中一個已經可用的特性,它允許在內核中運行一個虛擬機。這個虛擬機可以讓你安全地將程序加載到內核中並執行,這樣就可以靈活的在用戶層定義各種內核中的操作了。那爲什麼這很重要呢?

在過去,對內核進行功能更改是非常困難的:可以調用一些內核 api 來獲取數據,但不能影響內核內部的內容或執行代碼。如果要這樣做,那你需要向 Linux 社區提交一個補丁,然後等待它被批准。而使用 eBPF,可以將程序加載到內核中,並讓內核在一些情況下執行你的程序,比如收到一個數據包或者其他的事件發生。

有了 eBPF,內核及其行爲變得高度可定製,不再是固定的了。如果在合適的情況下使用這種能力,將是非常有價值的。

如何使用 eBPF?

eBPF 有幾個使用場景,包括流量控制、創建網絡策略、連接時長負載平衡和可觀察性。

流量控制

如果沒有 eBPF,數據包使用標準的 Linux 網絡路徑到達最終目的地。如果一個數據包出現在 A 點,並且你知道這個數據包需要到達 B 點,那麼你可以通過優化 Linux 內核中的網絡路徑將數據包直接發送到 B 點來。使用 eBPF,你就可以利用額外的上下文在內核中進行這些更改,這樣數據包就可以繞過複雜的路由,直接到達最終目的地。

這在 Kubernetes 容器環境中尤其有用,因爲其中有許多網絡。(除了主機網絡堆棧,每個容器都有自己的迷你網絡堆棧)當流量進來時,它通常被路由到一個容器堆棧,並且在從主機堆棧到達那裏的過程中必須經過一個複雜的路徑。可以使用 eBPF 繞過此複雜的路由。

創建網絡策略

在創建網絡策略時,有兩種情況可以使用 eBPF:

連接時長負載平衡

在 Kubernetes 中進行負載均衡服務連接時,一個端口需要與服務進行通信,因此需要進行 NAT 轉換。一個數據包被髮送到一個虛擬 IP,該虛擬 IP 將其轉換爲目的 IP 是支持該服務的 pod 上;然後 pod 響應虛擬 IP,返回的數據包被轉發回源地址。

通過使用 eBPF,可以使用已加載到內核的 eBPF 程序在連接開始處理的地方進行負載平衡,從而避免這種包轉換。由於目的網絡地址轉換(DNAT)不需要在包處理路徑上做處理,因此所有來自服務連接的 NAT 開銷都被優化掉了。

可觀察性

使用 eBPF 實現可觀察性的兩種有用方法:收集統計信息和深入調試內核。eBPF 程序可以附加到內核中許多不同的函數上,可以訪問這些函數正在處理的數據,也允許修改這些數據。例如,使用 eBPF,如果建立了網絡連接,則可以在創建套接字時觸發一個調用。爲什麼將套接字調用作爲事件接收很重要?因爲 eBPF 在打開套接字的程序的上下文中提供了這些函數調用,因此可以獲得關於哪個進程打開了它,以及套接字發生了什麼事情。

性能的代價

那麼 eBPF 比標準的 Linux iptables 更有效嗎?簡單來說:要分情況來看。

如果要對 iptables 在大量 IP 地址 (即 ipset) 的進行網絡策略時的工作方式進行微基準測試,iptables 在很多情況下比 eBPF 更好。但是如果想在 Linux 內核中做一些事情,比如需要更改內核中的數據包流向,那麼 eBPF 將是更好的選擇。標準的 Linux iptables 是一個複雜的系統,當然有它的侷限性,但同時它提供了操控流量的能力;如果你知道如何編寫 iptables 規則,那麼你可以做很多事情。eBPF 允許將自己的程序加載到內核中,並可以根據你的需要定製影響內核中的行爲,因此它比 iptables 更靈活,因爲它不侷限於是一組規則。

另外需要考慮的是,雖然 eBPF 允許運行程序、添加邏輯、重定向流向和繞過處理 (這是肯定的優勢),但它是一個虛擬機,因此必須轉換爲字節碼運行。相比之下,Linux 內核的 iptables 運行的是已經編譯好的代碼。

正如你所看到的,eBPF 和 iptables 並不是一個直接的比較。我們需要評估的是性能,這裏需要關注的兩個關鍵因素是延遲(速度)和消耗。如果 eBPF 非常快,但佔用了 80% 的資源,那麼它就像蘭博基尼——一輛昂貴的跑車。如果這對你有用,那太好了 (也許你真的喜歡昂貴的跑車)。只要記住,更多的 CPU 使用就意味着你要在雲提供商這裏花更多的錢。因此,雖然蘭博基尼可能比很多其他汽車都快,但如果你需要遵守日常通勤的速度限制,它可能不是最好的花錢方式。

何時使用 eBPF(何時不使用)

使用 eBPF,你可以獲得性能——但這是有代價的。你需要通過計算性能的代價,並從 eBPF 的功能角度決定你是否接受,要從而找到兩者之間的平衡。

來看一些使用 eBPF 有意義的具體情況,以及一些不建議使用 eBPF 的情況。

✘ 何時不用 eBPF
✔ When to use eBPF

總結

eBPF 是 iptables 的替代品嗎?我想不完全是。很難想象所有東西在 eBPF 中都能像在 iptables 中一樣高效地工作。目前,這兩種功能是共存的,取決於用戶如何權衡代價和性能,並根據他們的特定需求決定何時使用哪個功能。

我們相信正確的解決方案是利用 eBPF 加上 Linux 內核中的現有機制來實現你想要的結果。既然我們已經確定 eBPF 和 iptables 都是有用的,那麼在我們看來,唯一符合邏輯的事情就是同時支持兩者。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/gsohsQNXO7p7NMLkCDaaow