openEuler結合ebpf提升ServiceMesh服務體驗的探索

語言: CN / TW / HK

服務網格的前世今生

早期的微服務架構上存在著服務發現、負載均衡、授權認證等各種各樣的難題與挑戰。起初微服務踐行者們大多自己實現這麼一套分散式通訊系統來應對這些挑戰,但這無疑造成了業務功能的冗餘,解決此問題的方法就是將共有的分散式系統通訊程式碼提取出來設計成一套框架,以框架庫的方式供程式呼叫。但這個看似完美的方法卻存在著幾個致命的弱點:

  • 框架大部分對業務來說是侵入式修改,需要開發者學習如何使用框架
  • 框架無法做到跨語言使用
  • 處理複雜專案框架庫版本的依賴相容問題非常棘手,框架庫的升級經常導致業務的被迫升級。

隨著微服務架構的發展,以 Linkeerd/Envoy/NginxMesh 為代表的 sidecar 代理模式應運而生,這就是第一代的 serviceMesh。它作為一個基礎設施層,與業務程序完全解耦,和業務一起部署,接管業務件之間的通訊,將網路資料收發單獨抽象出一層,在這層集中處理了服務發現、負載均衡、授權認證等分散式系統所需要的功能,實現網路拓撲中請求的可靠傳輸,較為完美的解決了微服務框架庫中的問題。

但在軟體開發領域沒有萬能的銀彈。ServiceMesh 帶來了這麼多便利的同時,也不可避免的存在著一些問題。傳統方式下,客戶端到服務端的訊息僅需進出一次核心協議棧即可完成訊息傳遞,但在 sidecar 模式中,一般選擇使用核心的 iptables 能力劫持業務流量,這就造成了業務資料需要多次進出核心協議棧,導致業務時延增大,吞吐量變低。

openEuler 21.03 版本下進行 sidecar(envoy)模式基準測試發現,with-envoy 與 non-envoy 模式下,時延有大幅增加

利用 ebpf 能力加速 ServiceMesh

有沒有什麼方法可以在享受 ServiceMesh 提供便利服務的基礎上同時降低並消除網路時延帶來的影響呢?在這裡就不得不說下 ebpf 技術,ebpf 是在 kernel 中的一項革命性技術,旨在提供不修改核心程式碼或載入核心模組的基礎上更加安全有效的擴充套件核心的能力。使用 ebpf 能力短接核心網路協議棧來降低網路時延,提升 ServiceMesh 的使用體驗,這是目前業界通用的做法。

為了實現短接核心網路協議棧的目標,我們需要使用到 ebpf 提供的兩種能力,分別是:sockops 與 socket redirection,openEuler 使用的 kernel 版本為 5.10,已經支援了 ebpf 的這兩種能力。

  • sockops 提供了在 tcp socket 建立連線時將 socket 使用 key(一般是四元組)標識後儲存在 sockmap 資料結構中的能力
  • socket redirection 在傳輸 tcp 資料時支援使用 key 去 sockmap 中引用 socket,命中後可直接將資料轉發到此 socket 中
  • 對於未在 sockmap 中找到的 socket,正常將資料包通過核心網路協議棧傳送出去

將這些能力結合在一起,就可以在不經過核心網路協議棧的前提下直接將資料包轉發到對應的 socket 上,完成資料的一次傳輸,降低在核心網路協議棧上的時間消耗。

在 tcp socket 建立連線的過程中,實際上有兩次連線建立的過程,我們通常稱之為正向連線與反向連線。因正反向連線在建連過程中均需要通過 iptables 資訊來獲取實際的 ip 地址與埠號,openEuler 在 iptables 的工作原理上新增 helper 函式,將獲取對端資訊的能力下沉到核心中,可以在 ebpf 函式中主動獲取到 iptables 轉換過的地址。這樣我們可以建立一個輔助 map 用於存放正反向連線的對應關係並在 socket redirection 轉發時先從輔助 map 中尋找到對端的連線資訊,成功找到對端的連線資訊後再進行 socket 轉發動作。原理如下圖

通過 sockops 能力的加速,我們在 openEuler21.03 上實測的結果如下:

  • 測試環境:openEuler-21.03 / 5.10.0-4.17.0.28.oe1.x86_64
  • 組網:fortio-envoy-envoy:80-fortio_server:80
  • qps 提升約為 18%,平均時延提升 15%


下一步的工作:徹底消除 ServiceMesh 效能損耗

從 openEuler21.03 實際測試中可以看出,sockmap 對於 ServiceMesh 可以進行加速,但是加速的結果與不使用 ServiceMesh 相比仍然有較大差距。仔細分析,sockmap 並沒有消耗 socket buff 之間的資料拷貝,也沒有消耗 app/envoy 之間通訊時的上下文切換,那問題可能仍然出在 ServiceMesh 架構上。有沒有一種方法,既有 ServiceMesh 易管理、易部署的能力,又能消除其帶來的效能劣化影響?目前 openEuler sig-high-performance-network 正在嘗試這方面的工作,已經有了初步進展。有興趣加入我們一起完成這個目標嗎?可以訂閱以下郵件列表或新增微信聯絡我們~



本文分享自微信公眾號 - openEuler(openEulercommunity)。
如有侵權,請聯絡 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。