服務網格的eBPF ? 是的,但 Envoy Proxy 將繼續存在

語言: CN / TW / HK

服務網格的eBPF ? 是的,但 Envoy Proxy 將繼續存在

Solo.io 的目標是為 我們的客戶 提供有關 應用程式網路和服務連線 相關的解決方案。 早在10月 ,我們就宣佈了使用 eBPF 增強我們的企業服務網格產品(Gloo Mesh Enterprise)的計劃,以優化網路、可監測性和安全性方面的功能。eBPF在服務網格中能發揮多大的作用呢?服務代理的角色如何變化?在這篇部落格中,我們將深入探討eBPF在服務網格資料平面的作用以及各種資料層架構之間的權衡。

告別服務代理?

服務網格為服務提供複雜的應用網路行為,例如服務發現、流量路由、彈性(超時/重試/斷路)、身份驗證/授權、可監測性(日誌記錄/指標/跟蹤)等。我們可以用 eBPF 將所有這些功能重寫到核心中嗎?

簡單回答:這將非常困難,可能不是正確的方法。eBPF 是一個事件處理模型,對它的執行方式有一些限制。你可以將 eBPF 模式視為核心的“功能即服務”。例如,在核心中安全執行之前,必須完全瞭解和驗證 eBPF 執行路徑。eBPF 程式不能有任意迴圈,其中的驗證者不知道程式何時停止執行。簡而言之,eBPF 是圖靈不完整的。

七層協議(如各種協議編碼器、重試、資料頭操作等)單獨在 eBPF 中實現可能非常複雜,並且沒有更好的核心原生支援。也許這種支援會有,但這可能需要數年時間,並且不會在舊版本上提供。在許多方面,eBPF 是 O(1) 複雜度的理想選擇(例如檢查資料包、操作一些資料位並在途中傳送它)。實現像 HTTP/2 和 gRPC 這樣的複雜協議可能是O(n)複雜度並且非常難以除錯。那麼這些7層功能可以駐留在哪裡呢?

Envoy 代理 已成為服務網格實現的標準,並且對我們大多數客戶所需的第七層功能有很好的支援。儘管 eBPF 和核心可用於改進網路的執行(短路最佳路徑、解除安裝 TLS/mTLS、可監測性收集等),但複雜的協議協商、解析和使用者擴充套件仍可以保留在使用者空間中。對於第七層的複雜性,Envoy 仍然是服務網格的資料平面。

共享代理 對比 Sidecar 代理?

嘗試優化服務網格的資料路徑時的另一個考慮因素,是為每個工作負載執行一個旁路代理,還是為每個節點使用單個共享代理。例如,當執行具有數百個pod和數千個節點的大型叢集時,共享代理模型可以圍繞記憶體和配置的開銷進行優化。但這是適合每個人的正確方法嗎?絕對不是。對於許多企業使用者來說,一些記憶體開銷值得通過旁路代理來獲得更好的租賃和工作負載隔離。

兩種架構都有其在記憶體和網路開銷、租用、操作和簡單性方面的優勢和權衡,並且都可以受益於基於eBPF的優化。然而,並不是只有這兩個架構。讓我們從以下維度深入研究全部選項:

  • 記憶體/CPU 開銷 — 為七層代理配置路由和叢集資訊,包含代理特定的配置組成,這些配置可能很冗長;特定工作負載需要通訊的服務越多,它需要的配置就越多。
  • 功能隔離 — 應用程式很挑剔,往往需要對連線池、套接字緩衝區、重試語義/預算、外部身份驗證和速率限制進行每個工作負載的優化。我們看到自定義資料路徑的需求很大,這就是我們引入 Wasm 擴充套件的原因。除錯這些功能和行為也變得很苛刻。我們需要找到一種方法來隔離工作負載之間的這些特性。
  • 安全粒度 — 零信任理念的很大一部分是在執行時根據當前上下文建立對等點的信任;通常希望將這些信任邊界的範圍儘可能小。
  • 升級影響 — 服務網格是非常重要的基礎設施,因為它位於請求路徑上;我們需要對服務網格資料平面元件進行非常可控的升級,以最大限度地減少中斷。

讓我們看看四種可能的架構,其中 eBPF 用於優化和縮短網路路徑,並利用 Envoy 代理來實現七層功能。對於每種架構,我們都會根據開銷、隔離、安全性和升級來評估在何處執行第七層代理的好處和權衡。

Sidecar 代理(服務代理)

在這個模型中,我們為每個應用程式例項部署了一個 sidecar 代理。Sidecar 具有代表工作負載路由流量所需的所有配置,並且可以根據工作負載進行定製。

對於許多工作負載和代理,此配置會在工作負載例項之間重複,並且可能會產生“次優”的資源開銷。

該模型確實提供了最佳的特徵隔離,以減少任何嘈雜鄰居在爆炸半徑內的影響。配置錯誤或特定應用緩衝區/連線池/超時被隔離到特定的工作負載。使用Lua 或 Wasm 的擴充套件(可能會關閉代理)也受限於特定的工作負載。

從安全形度來看,我們直接發起和終止與應用程式的連線。我們可以使用服務網格的 mTLS 功能來證明連線兩端服務的身份,範圍縮小到應用程式程序級別。然後我們可以根據這個身份編寫細粒度的授權策略。此模型的另一個好處是,如果單個代理最終成為被攻擊的受害者,受攻擊的代理會被隔離到特定的工作負載;爆炸半徑是有限的。然後,不利的一面是,由於 sidecar 必須與工作負載一起部署,因此工作負載可能會選擇不注入 sidecar, 或者更糟糕的是,找到一種繞過 sidecar 的方法。

最後,在此模型中,可以按工作負載進行升級,並遵循僅影響特定工作負載的金絲雀方法。例如,我們可以將 Pod A 的資料平面升級到新版本,而不會影響節點上的其他任何工作負載。這樣做的缺點是注入 sidecar 仍然很棘手,如果版本之間有變化,它可能會影響應用程式例項。

每個節點共享代理

每個節點的共享代理引入了對大型叢集有意義的優化,在這些叢集中,記憶體開銷是首先要考慮的,並且需要分攤記憶體成本。在此模型中,不是為每個 sidecar 代理配置路由流量所需的路由和叢集,而是在單個代理中的節點上的所有工作負載之間共享該配置。

從功能隔離的角度來看,您最終會嘗試在一個程序(一個 Envoy 代理)中解決全部工作負載例項的全部問題,這可能會有缺點。例如,跨多個應用程式的配置是否會相互衝突或在代理中具有偏移行為?您能否安全地加載出於監管原因必須分開的密文或私鑰?您能否在不影響其他應用程式代理行為的情況下部署 Wasm 擴充套件?為一堆應用程式共享一個代理存在隔離問題,這可能會通過單獨的程序/代理更好地解決。

在每個節點共享代理的模型中,安全邊界也變成共享。例如,工作負載身份確認現在在節點級別處理,而不是實際工作負載級別。代理和工作負載之間的“最後一英里”會發生什麼?或者更糟糕的是,如果一個代表多個(數百個?)工作負載身份的共享代理遭到破壞,會發生什麼情況?

最後,如果升級存在版本衝突、配置衝突或擴充套件不相容等問題,升級每個節點的共享代理可能會影響節點上的所有工作負載。每次升級處理應用程式請求的共享基礎架構時,都必須小心。從好的方面來說,升級共享節點代理不必考慮注入sidecar的任何複雜性。

每個服務賬戶的共享代理(每個節點)

我們可以將代理細分到每個節點的特定服務賬戶,而不是為整個節點使用單個共享代理。在此模型中,我們為每個服務賬戶/身份部署一個“共享代理”,並且該服務賬戶/身份下的任何工作負載都使用該代理。使用該模型,我們可以避免一些注入sidecar的複雜性。

該模型可以在單個節點上存在相同身份的多個例項的情況下節省記憶體,並保持一定程度的特徵和嘈雜鄰居的隔離。這種模型在工作負載身份方面具有與sidecar相同的優點,但它確實具有共享代理的缺點:最後一英里連線會發生什麼?工作負載例項的身份驗證是如何建立的?為了改進這個模型,我們可以使用一個較小的“微代理”,它與應用程式工作負載例項一起存在,可以存進端到端 mTLS 到例項級別。在下一個模式中我們可以看到這一點。

使用微代理做共享遠端代理

在這個模型中,一個更小、更輕量級的“微代理”(uProxy)被部署為帶有工作負載例項的sidecar,它只處理mTLS(沒有第7層策略,更小的攻擊面)。當需要使用第7層策略時,流量會從工作負責例項通過第7層(Envoy)代理定向。第7層代理可以作為共享節點代理、每個服務賬戶甚至遠端代理來執行。此模型還允許在可能不需要這些策略時完全通過第7層代理(但會與應用程式例項保持mTLS發起/協商/終止)。

此模型減少了您在sidecar中看到的第7層策略的配置開銷,但可能會引入更多躍點。這些躍點可能(或可能不會)導致更多的呼叫延遲。對於某些呼叫,L7代理可能甚至不在資料路徑中,這會改善呼叫延遲。

由於uProxy仍與工作負載例項一起部署,因此該模型結合了隔離性和安全性的sidecar代理優勢。

從升級的角度來看,我們可以將L7代理無感的更新到應用程式,但是我們現在有更多的移動元件。我們還需要協調uProxy的升級,它與我們在第一模式中討論的sidecar架構有一些相同的缺點。

其他的想法

正如在 Service Mesh Con 2019 上的“ 關於服務網格資料平面的真相 ”中所討論的,代表資料平面的架構可能會有所不同,並且有不同的權衡利弊。在Solo.io,我們將eBPF視為優化服務網格的強大方法,並將Envoy代理視為資料平面的基石。與我們的許多客戶(不同規模,包括世界上一些最大的服務網格部署)合作,我們處於一個獨特的位置,可以幫助平衡優化、功能、可擴充套件性、可除錯性和使用者體驗之間的權衡利弊。

原文連結: eBPF for Service Mesh? Yes, but Envoy Proxy is here to stay