eBPF 如何簡化服務網格

本文譯自 How eBPF Streamlines the Service Mesh[1]。

今天有幾個服務網格的產品和項目,承諾簡化應用微服務之間的連接,同時提供額外的功能,如安全連接、可觀察性和流量管理。但正如我們在過去幾年中反覆看到的那樣,對服務網格的興奮已經被對額外的 [2] 複雜性 [3] 和開銷的 [4] 實際擔憂所抑制 [5]。讓我們來探討一下 eBPF[6] 是如何讓我們精簡服務網格 [7],使服務網格的數據平面更有效率,更容易部署。

Sidecar 問題

今天的 Kubernetes 服務網格解決方案要求你在每一個應用 pod 上添加一個代理 sidecar 容器,如 Envoy[8] 或 Linkerd-proxy[9]。這是正確的:即使在一個非常小的環境中,比如說有 20 個服務,每個服務運行五個 pod,分佈在三個節點上,你也有 100 個代理容器。無論代理的實現多麼小和有效,這種純粹的重複都會耗費資源。

每個代理使用的內存與它需要能夠通信的服務數量有關。Pranay Singhal 寫了他配置 Istio 的經驗 [10],將每個代理的消耗從 1GB 左右減少到更合理的 60-70MB。但是,即使在我們的小環境中,在三個節點上有 100 個代理,這種優化配置仍然需要每個節點 2GB 左右。

來自 redhat.com/architect/why-when-service-mesh——每個微服務都有自己的代理 sidecar

爲什麼我們需要所有這些 sidecar?這種模式允許代理容器與 pod 中的應用容器共享一個網絡命名空間。網絡命名空間是 Linux 內核的結構,它允許容器和 pod 擁有自己獨立的網絡堆棧,將容器化的應用程序相互隔離。這使得應用之間互不相干,這就是爲什麼你可以讓儘可能多的 pod 在 80 端口上運行一個 web 應用 —— 網絡命名空間意味着它們各自擁有自己的 80 端口。代理必須共享相同的網絡命名空間,這樣它就可以攔截和處理進出應用容器的流量。

引入 eBPF

eBPF[11] 是一種內核技術,允許自定義程序在內核中運行。這些程序在響應事件時運行,有成千上萬個可能的事件,eBPF 程序可以被附加到這些事件上。這些事件包括軌跡點、進入或退出任何功能(在內核或用戶空間)或對服務網格來說很重要的 —— 抵達的網絡數據包。

重要的是,每個節點只有一個內核;在一個節點上運行的所有容器(也就是所有的 pod)共享同一個內核。如果你在內核中添加一個 eBPF 程序到一個事件中,它將被觸發,無論哪個進程引起該事件,無論它是在應用容器中運行還是直接運行在主機上。

每臺主機一個內核

這就是爲什麼 eBPF 對於 Kubernetes 中的任何一種 instrumentation 來說都是如此令人興奮的技術 —— 你只需要在每個節點上添加一次 instrumentation ,所有的應用程序 pod 都會被覆蓋。無論你是在尋求可觀察性、安全性還是網絡,由 eBPF 驅動的解決方案都可以在不需要 sidecar 的情況下對應用進行檢測。

基於 eBPF 的 Cilium[12] 項目(最近 以孵化級別加入雲計算基金會 [13])將這種 “無 sidecar” 模式帶到了服務網格的世界。除了傳統的 sidecar 模型,Cilium 還支持每個節點使用一個 Envoy 代理實例運行服務網格的數據平面。使用我們前面的例子,這就把代理實例的數量從 100 個減少到只有 3 個。

用無 sidecar 代理模式減少代理實例

減少 YAML

在 sidecar 模型中,指定每個應用 pod 的 YAML 需要被修改以添加 sidecar 容器。這通常是自動化的 —— 例如,使用一個 mutating webhook,在每個應用 pod 部署的時候注入 sidecar。

以 Istio 爲例,這需要標記 [14] Kubernetes 命名空間和 / 或 pod,以定義是否應該注入 sidecar—— 當然也需要爲集羣啓用 mutating webhook。

但如果出了問題怎麼辦?如果命名空間或 pod 的標籤不正確,那麼 sidecar 將不會被注入,pod 將不會被連接到服務網格。更糟糕的是,如果攻擊者破壞了集羣,並能夠運行一個惡意的工作負載 —— 例如,一個加密貨幣礦工,他們將不太可能標記它,以便它加入服務網格。它不會通過服務網格提供的流量觀察能力而被發現。

相比之下,在支持 eBPF 的無 sidecar 代理模型中,pod 不需要任何額外的 YAML 就可以被檢測。相反,一個 CRD 被用來在集羣範圍內配置服務網格。即使是已經存在的 pod 也可以成爲服務網格的一部分,而不需要重新啓動。

如果攻擊者試圖通過直接在主機上運行工作負載來繞過 Kubernetes 編排,eBPF 程序可以檢測並控制這一活動,因爲這一切都可以從內核看到。

eBPF 支持的網絡效率

支持 eBPF 的網絡允許數據包走捷徑,繞過內核的部分網絡堆棧,這可以使 Kubernetes 網絡的性能得到顯著改善 [15]。讓我們看看這在服務網格數據平面中是如何應用的。

在 eBPF 加速、無 sidecar 的服務網格模型中,網絡數據包通過的路徑要短得多

在服務網格的情況下,代理在傳統網絡中作爲 sidecar 運行,數據包到達應用程序的路徑相當曲折:入站數據包必須穿越主機 TCP/IP 棧,通過虛擬以太網連接到達 pod 的網絡命名空間。從那裏,數據包必須穿過 pod 的網絡堆棧到達代理,代理將數據包通過迴環接口轉發到應用程序。考慮到流量必須在連接的兩端流經代理,與非服務網格流量相比,這將導致延遲的顯著增加 [16]。

基於 eBPF 的 Kubernetes CNI 實現,如 Cilium,可以使用 eBPF 程序,明智地鉤住內核中的特定點,沿着更直接的路線重定向數據包。這是可能的,因爲 Cilium 知道所有的 Kubernetes 端點和服務的身份。當數據包到達主機時,Cilium 可以將其直接分配到它所要去的代理或 Pod 端點。

網絡中的加密

如果一個網絡解決方案能夠意識到 Kubernetes 服務,並在這些服務的端點之間提供網絡連接,那麼它能夠提供服務網格數據平面的能力就不足爲奇。但這些能力可以超越基本的連接。一個例子是透明加密。

通常使用服務網格來確保所有的應用流量都是經過認證和加密的。這是通過雙向 TLS(mTLS)實現的;服務網格代理組件作爲網絡連接的端點,並與其遠程對等物協商一個安全的 TLS 連接。這種連接對代理之間的通信進行加密,而不需要對應用程序做任何改變。

但在應用層管理的 TLS 並不是實現組件間認證和加密流量的唯一方法。另一個選擇是在網絡層加密流量,使用 IPSec 或 WireGuard[17]。因爲它在網絡層操作,這種加密不僅對應用程序完全透明,而且對代理也是透明的 —— 它可以在有或沒有服務網格時啓用。如果你使用服務網格的唯一原因是提供加密,你可能想考慮網絡級加密。它不僅更簡單,而且還可以用來驗證和加密節點上的任何流量 —— 它不只限於那些啓用了 sidecar 的工作負載。

eBPF 是服務網格的數據平面

現在,eBPF 在 Linux 生產發行版使用的內核版本中得到廣泛支持,企業可以利用它來獲得更有效的網絡解決方案,並作爲服務網格的更有效的數據平面。

去年,我代表 CNCF[18] 的技術監督委員會,對服務網格領域的整合和清晰化做了一些 預測 [19]。在同一主題演講中,我談到 eBPF 有可能成爲更多項目和更廣泛部署能力的基礎。這兩個想法現在正結合在一起,因爲 eBPF 似乎是服務網格數據平面的自然路徑。

引用鏈接

[1] How eBPF Streamlines the Service Mesh: https://thenewstack.io/how-ebpf-streamlines-the-service-mesh/
[2] 額外的: https://nowei.github.io/projects/svc_mesh_measurement_final_report.pdf
[3] 複雜性: https://engineering.hellofresh.com/everything-we-learned-running-istio-in-production-part-2-ff4c26844bfb
[4] 開銷的: https://pklinker.medium.com/performance-impacts-of-an-istio-service-mesh-63957a0000b
[5] 擔憂所抑制: https://medium.com/geekculture/watch-out-for-this-istio-proxy-sidecar-memory-pitfall-8dbd99ea7e9d
[6] eBPF: https://ebpf.io/
[7] 服務網格: https://thenewstack.io/category/service-mesh/
[8] Envoy: https://www.envoyproxy.io/
[9] Linkerd-proxy: https://linkerd.io/
[10] 經驗: https://medium.com/geekculture/watch-out-for-this-istio-proxy-sidecar-memory-pitfall-8dbd99ea7e9d
[11] eBPF: http://ebpf.io/
[12] Cilium: http://cilium.io/
[13] 以孵化級別加入雲計算基金會: https://www.cncf.io/blog/2021/10/13/cilium-joins-cncf-as-an-incubating-project/
[14] 標記: https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#controlling-the-injection-policy
[15] 性能得到顯著改善: https://cilium.io/blog/2021/05/11/cni-benchmark
[16] 顯著增加: https://linkerd.io/2021/05/27/linkerd-vs-istio-benchmarks/#latency-at-20-rps
[17] IPSec 或 WireGuard: https://cilium.io/blog/2021/05/11/cni-benchmark#the-cost-of-encryption---wireguard-vs-ipsec
[18] CNCF: https://cncf.io/?utm_content=inline-mention
[19] 預測: https://youtu.be/bESogtuHwX0

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