基於 eBPF 技術的開源項目 Kindling 之 HTTP 協議解析

Kindling 是一款基於 eBPF 技術的雲原生可觀測性開源項目。本文將主要介紹如何通過 Kindling 對 HTTP 協議進行解析。

在故障排查過程中,我們通常對請求性能、請求內容和返回內容感興趣。這使我們能知道請求和接收了什麼內容,是否有異常等基本信息。如何獲取請求的具體詳細信息,傳統方式是通過 tcpdump 獲取請求包數據,然後通過 wireshark 查看其具體協議內容。

tcpdump 雖然在生產環境中經常使用,但由於獲取的數據量和大小限制,不適合一直開啓,只有在排查問題時使用。而獲取的數據也無法直接查看,需下載到本地通過 wireshark 分析查看。基於 tcp 的諸多問題,所以 Kindling 通過 eBPF 方式實現請求的具體分析。

那麼 Kindling 是如何實現實時可用的協議解析功能呢?主要涉及 3 塊功能:

數據採集

先來查看下一個簡單的 HTTP 服務

HTTP 服務僞代碼

當接收到請求時會有 accept/read/write/close 等函數執行,這些函數最終執行內核的系統調用。

HTTP 服務接收請求流程圖

使用 strace 命令查看一次請求的系統調用情況

i3vgs8

從日誌中可分析出,請求通過 read 系統調用,日誌和響應都是通過 write 系統調用。

Kindling 已實現對系統事件調用進行抓取,並將相關的 read 和 write 系統調用轉換爲 Kindling 事件,最終生成 3 條事件。事件格式定義可參見 kindling_event.proto。

系統調用與 Kindling 事件映射

參數說明:

請求 / 響應關聯

常規的 TCP 請求都會用同一個 FD 進行通信,只需根據進程號和 FD 就能關聯同一個請求和響應。

請求 / 響應解析

雖然有了報文,但不同的協議定義的規範也不同。那麼如何知道該報文是什麼協議,並且用該協議進行解析呢?主要涉及 2 塊內容:

協議識別

通過特徵或關鍵字快速匹配協議,減少協議解析的次數,提升整體解析的性能。

HTTP 報文規範

對於 HTTP 請求來說,通過 HTTP 版本號 (HTTP/1.0 或 HTTP/1.1) 可以快速識別協議。

但由於抓包大小限制,如果一個請求的 URL 長度超過包的大小,那麼無法獲取後續的 HTTP 版本號,於是採用端口協議配置方式也能識別協議。

協議解析

協議解析是爲了產生指標用於後續分析,在解析過程中需根據協議自身的格式進行解析。

由於報文內容是 byte 數組格式,Kindling 提供了封裝好的 API 用於解析。

Vqm8MO

以 HTTP 協議爲例,可解析出如下信息:

解析 HTTP 請求

解析請求過程就是對請求進行逐幀解析,讀取到對應的屬性後最終將值存儲到 attribute 中

f4AviH

解析HTTP響應

解析響應跟解析請求類似,也是逐幀解析,將解析出的屬性存儲到 attribute 中。

此外,需考慮報文非法場景(狀態碼非數值),確保解析正常結束。

zRaC8w

歡迎對雲可觀測性感興趣的小夥伴加入 Kindling 大家庭

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