使用 kTLS 和 splice(2) 實現沙箱的零複製 TLS 入口
Tensorlake 重建了沙箱的網路入口架構,將資料路徑從 L7 反向代理遷移到 L4 位元組轉發,利用核心 TLS(kTLS)和 splice(2) 實現零複製,大幅提升吞吐量並降低 CPU 開銷。架構變化包括分離資料路徑和控制平面、使用 kTLS 在核心中完成加解密、透過位元組流監測實現自適應超時。效能測試顯示,單連線吞吐量從 1.12 GB/s 提升至 2.50 GB/s,每 GB 的 CPU 消耗從 0.90 CPU 秒降至 0.49 CPU 秒。
Tensorlake 的沙箱產品為 AI 代理提供了高效能執行環境,代理需要頻繁與沙箱通訊以執行上傳、下載和程序管理等操作。然而,原有的入口架構依賴於兩層 L7 反向代理,導致複雜的超時配置、高 CPU 開銷以及連線中斷問題。為此,團隊重新設計了入口網路,將資料路徑從 L7 代理遷移到 L4 位元組轉發,並引入核心 TLS(kTLS)和 splice(2) 系統呼叫,實現了近乎零開銷的資料傳輸。
在舊架構中,使用者流量首先透過邊緣閘道器進行 TLS 終止和認證,然後以 mTLS 方式轉發到第二層 L7 代理,後者再將請求轉發給沙箱內的應用。這一過程涉及兩次使用者態複製和完整的 HTTP 解析,效能受限且維護複雜。新架構將資料路徑抽象為一個獨立的 L4 轉發守護程序,與沙箱編排器分離,從而避免編排器升級時中斷即時連線。
新的資料路徑完全在 L4 層工作:邊緣閘道器終止 TLS 後,透過 mTLS 連線到主機上的 L4 轉發器,併傳送一個短幀,包含沙箱 ID 和目標地址。轉發器據此建立到沙箱應用的連線,然後使用 splice(2) 將兩個連線在核心中直接拼接。關鍵在於,轉發器在使用者態完成 TLS 1.3 握手後,透過 setsockopt(TLS_TX) 和 setsockopt(TLS_RX) 將金鑰安裝到 socket 中,讓核心接管記錄層。這樣,從閘道器套接字讀取的資料已經是解密後的明文,可以零複製地 spliced 到沙箱套接字;反之亦然。這一過程完全避免了使用者態緩衝。
由於移除了 L7 層,自適應超時機制改為基於位元組流監測。splice() 返回的位元組數被用於計量流量,轉發器定期向編排器報告,從而重置沙箱的空閒計時器。連線關閉也更加透明,半關閉和重置訊號都能直接傳遞。
效能測試顯示,新路徑的單連線吞吐量從 1.12 GB/s 提升到 2.50 GB/s,每 GB 的 CPU 消耗從 0.90 CPU 秒降低到 0.49 CPU 秒。有趣的是,大部分效能提升來自移除 L7 解析和緩衝,而 kTLS 本身貢獻了約 20% 的吞吐量提升。需要注意的是,這些測試是在單臺主機上進行的,多連線場景下聚合吞吐量可達 8.67 GB/s(69 Gbps)。團隊計劃未來進一步最佳化 splice 迴圈的序列化問題,並探索繞過 kTLS 直接在核心拼接的路徑。