Istio 在百度百億級流量⽣產環境的研發實踐

Service Mesh 從誕生至今短短數年,就以席捲之勢成爲了雲原生時代的通信設施標準,被奉爲 “下一代微服務”。然而由於像 Istio 這樣 Service Mesh 中的佼佼者,其在對異構基礎環境支持、私有協議支持、複雜流量調度策略、產品化和易用性、性能和可靠性等方面還存在諸多限制和缺陷,Service Mesh 的落地一直以來都令人談虎色變。

2021 年 QCon(北京)全球軟件開發者大會上,百度 陳鵬 分享了結合 Service Mesh 在百度公司 Feed、手機百度、百度地圖等百億量級流量的核心生產環境大規模落地的真實案例,分享了關於上述 Service Mesh 落地的諸多痛點問題的深入思考和實踐經驗。

以下是演講內容整理,以饗讀者。

決定業務有沒有必要上 Service Mesh,在什麼程度上使用 Service Mesh,最重要的依據是業務現狀。所以今天我會先分享百度服務治理的現狀,再分享百度在落地 Istio 時遇到的問題,以及百度是如何解決的。

百度的 Service Mesh 經歷了三個階段:內部探索、跟進探索、擁抱開源。

2013 年,百度研發了獨立的 Sidecar 和 Proxy 代理一些流量,這是 Service Mesh 在百度的萌芽;2016 年,百度網盤大規模落地的 UFC 系統和現在 Service Mesh 的理念和架構功能已經非常相似了,也是用 Proxy 代理流量控制中心;2016 年的 9 月份,Service Mesh 的概念首次被提出後,百度立刻意識到了它會帶來的變革。所以 2017 年,百度採用 Go 語言自研了一套 Service Mesh 系統—— BMesh 。

與此同時,社區發展迅速。2018 年的 7 月, Service Mesh 的明星產品可用於生產環境的 Istio 1.0 版本發佈了。面臨這個情況,百度最終決定擁抱開源。因此 2019 年,百度研發了基於社區的 Istio + Envoy 的解決方案,目前已經大規模落地了。

1 爲什麼要引入 Service Mesh?

Service Mesh 主要可以解決三種問題:

第二,服務治理週期長。分佈式的能力總和業務進程耦合在一起,所以無論是技術庫的維護升級,還是調整策略,服務治理的週期都非常長,成本也非常高。

第三,服務產品能力非常弱。大部分服務都是以配置文件爲主,沒有接入配置中心,可視化能力非常弱,沒有平臺化或產品化的功能,如配置變更版本追溯的能力,審查、審計的能力等,用戶體驗很差。

2Istio 在生產環境落地面臨的問題的百度解決方案

那麼這些問題,百度是如何解決的呢?我們先看第一個問題, Istio 對 Kubernetes 的深度依賴。

對 Kubernetes 的依賴問題

Istio 對 Kubernetes 依賴分爲三部分,第一部分是 Sidecar 的注入和管理。

Kubernetes 的 PaaS 的可編程性和接口比較好,但是我們自己的 PaaS 或類似平臺缺乏這樣好的規範或接口,這樣的話如何注入 Sidecar 呢?注入之後,如何大規模自動化管理 Sidecar 呢?面對這些問題,百度落地 Istio 時聯合了內部的 PaaS 團隊,進行了支持 Sidecar 模式的聯動研發。

Istio 對 Kubernetes 依賴的第二部分,是 Istio 的各類配置依賴了 Kubernetes 各種組件,尤其是依賴了 API Server 和 etcd 做流量調度策略的存儲。API Server 和 etcd 是可以進行獨立部署的,所以百度保留了這部分組件。

最頭疼的是第三個問題,Istio 依賴於 Kubernetes 的服務和流量模型,比如說服務調用基於虛擬的 ClusterIP,比如流量劫持使用了 Iptables 或 IPVS。

由於一些性能穩定性、可管控性等等的原因,百度的生產環境是無法使用 Iptables,內部的服務發現也沒有用 Kubernetes 的方式,所以這個問題是最棘手的,決定了百度的流量到底能不能夠讓 Mesh 接管。面對這個問題,百度選擇了研發新的流量劫持模式——基於 Naming 的流量劫持。

在傳統的這種軟硬件環境下如何做 Mesh 流量的接管

基於 Naming 的流量劫持

百度的流量劫持模式是基於百度微服務體系的私有 Naming 系統的。

圖中左側是 Consumer ,右側是 Provide。正常 Consumer 調用 Provide 時,會去註冊中心或本地的 Agent 查找下游的服務實例列表。

接入 Mesh 以後,第一步,我們會在 Mesh 的上層用戶產品—— Console 上定義一個連接關係。圖中定義的連接關係是 Consumer 會訪問 Provide。借鑑 Kubernetes 的 ClusterIP 的概念,我們會給它分配一個本地迴環地址。圖中舉例的本地的迴環地址是 127.1.1.1,代表了訪問的連接關係。

接着我們會把這個連接關係下發給 Consumer 側的 Sidecar,即代理 Envoy。Envoy 會監聽 127.1.1.1 的地址,服務會監聽另外的端口。

第三步我們會聯動 Envoy 和 Naming Agent。Envoy 會把自己的監聽的地址註冊到 Naming Agent 裏僞裝自己。此時業務的 Naming Lib 去訪問 Naming Agent 拿下游,拿到的是本地 Envoy 的地址。圖中 Envoy 把自己註冊成了 Provide ,地址是 127.1.1.1:8000,不是真實下游 Provider 的 10.1.1.2:3000。

第四步 Consumer 會發出請求,而第五步返回的是 127.1.1.1 的 8000 端口。**此時的核心思想是 Envoy “欺騙” Naming Agent 自己是下游的實例,把流量導到自己。**Consumer 以爲它請求的是真正的 Provide ,實際上是把流量發給了本地的 Envoy。Envoy 收到以後,會去真正的 Naming Agent 裏做解析。

這樣可以實現在 Sidecar 側做服務發現。這樣做是因爲策略配置變更頻率低,而服務端點的這種實例狀態信息的變化頻率高,控制面做服務發現壓力很大。

另外第 7 步裏 Envoy 去請求下游時,Inbound 的流量是可選的。圖中既可以請求 Provide 真實監聽的 3000 端口,也可以請求 Envoy 監聽的 3001 端口。這樣,出口流量必須經過 Envoy ,但是入口流量卻不一定。

這是因爲業務方會擔心多過一次 Envoy ,會影響耗時和性能。而 Envoy 的能力,**比如說負載均衡、超時、重試、熔斷等都集中在上游,下游的功能很少,所以我們把下游做成了可選的模式。**當然,如果你希望擁有 Envoy 全部功能,而且對性能不那麼敏感的話,可以在 Consumer 和 Provide 側都接入 Sidecar。

原生 Istio 會給任何 Sidecar 推送全集羣所有服務的信息,比如 Consumer 可能只需訪問一個服務 Provide,而 Istio 會給它所有服務的信息,這對 Consumer 自身的 Sidecar 資源開銷和控制面推送的壓力都很大。

而我們的方案定義了 Link 模型,這樣可以做到精準下發,Consumer 只會收到 Provide 相關的配置,XDS 的推送量可以從 O(N) 降到 O(1),Envoy 的內存佔用也會大幅度減少。

面對故障,我們在 Envoy 和 Naming Agent 之間設置了一個非常敏感的 HeartBeat——心跳探活機制(上圖中紅色的部分)。一旦檢測到 Sidecar 故障,我們會及時地去掉 Envoy 註冊的僞裝實例,Consumer 服務會在下一次解析週期裏近乎實時地回退到直連模式。因此業務方不必擔心 Envoy 是否掛了。

因爲 Naming Lib 適用範圍很廣,所以通過修改 Naming Lib 做流量劫持的方案適用範圍也很廣。而且在沒有使用容器網絡的主機網絡下,我們通過收集由 PaaS 動態分配的端口,也可以使用這套方案。

融合 Envoy 和 bRPC 的性能優化

在毫秒級別的請求、資源緊張、CPU 內存敏感的場景下,Envoy 無法滿足業務方的需求。所以我們基於 bRPC 和 Envoy 各自具有獨到的優勢,做了深度二次開發。

bRPC 實現了一個非常高性能的用戶態的線程,不完全等同於 Go 語言的協程,但是和用戶態很相像,有高性能的 IOBuf 庫,可以高效地做 Socket 處理。它還有優秀的 IO 機制,擅長處理長尾等等場景。

而 Envoy 的擴展機制非常靈活,在 L3、L4、L7 層都提供了很多 Filter 擴展機制;此外, Envoy 本身也實現了非常多豐富的策略,再加上它有 XDS 協議,可以進行動態地配置分發。

我們融合了這兩套系統的優點。我們使用 bRPC 的內核組件重構了 Envoy。融合之後,平均延時和 CPU 開銷⼤幅降低,效果如下圖所示:

⽀持私有協議和⾼級策略

面對原生 Istio 不支持私有協議或一些高級策略的問題,百度也進行了相關優化。

因爲 Istio 的擴展架構比較靈活,所以百度基於 Istio + Envoy 的擴展機制,全面支持了大多數私有協議,包括百度內部標準協議 Baidu STD、一些比較老的 Nshead、HTTP、Java 生態的 Dubbo 協議等。

Istio 每新增一種協議,都需要制定一種語法,描述該協議流量分發方式。百度把這些協議統一爲了標準的協議框架,減少了很多的重複開發。真正在數據面做流量轉發時,我們可以根據請求 HEAD 的特性做協議嗅探。

高級策略方面,百度在 Envoy 裏做了加強版的 BackupRequest——DynamicBP。

BackupRequest 的核心是快速重試:在一個請求還沒有回來時,就發出一個新的請求,優先使用先回來的請求結果。重試在很多場景下是高危的,而且在延時不太穩定的場景下,很難確定該在什麼時候進行重試。

DynamicBP 會動態計算一段時間間隔的超時比例,藉此設置重試時間。比如說對超過 99 分位值的長尾 Request ,才進行 BackupRequest。這能避免雪崩,更安全。

由於 Mesh 的控制面可以對網絡行爲進行動態地編程、修改配置、實施生效,服務治理效率會大幅提升。之前大規模的服務治理調整需要耗費半年時間,現在只需要幾天,明顯提升了故障容忍的可用性。

除此之外,百度實現了和測試、混沌相關的流量複製、流量鏡像和一些其它高級負載均衡策略。這樣業務方接入 Mesh 後,不僅能力不會變少,還獲得了一些新的策略。線上實際效果如下圖所示:

此外,Mesh 與框架語言無關的特點可以賦能其它的框架和語言。所有框架和語言可以共享在 Mesh 裏實現的策略。比如下圖中的框架原先不具備某種高級的能力,所以前面抖動比較厲害,接入 Mesh 以後複用在 Mesh 裏移植的能力,穩定性大幅度提升。

如何解決 Istio 原⽣產品能⼒缺失

Istio 原生產品的能力本來就有缺失。比如 CRD 接口非常多,但是官方管理接口的 Kiali 基本上不可用;還有配置動態分發的安全問題,以前改配置有和 PaaS 結合的審計系統,接入 Mesh 後的監管問題。

面對這些問題,百度聚合了豐富的服務治理策略,可以讓不瞭解 Mesh 的人,在良好的 UI 體驗下完成服務治理。

一方面,百度集成了很多運維場景問題的解決方案,比如說跨機房切流,如何實時把流量切到其它機房,甚至按比例切流;再比如實時地關掉某一個鏈路的服務網格的開關;還有如何快速故障⽌損等等。

另一方面,如果 Mesh 上線後有任何問題,業務方可以一鍵回滾到對任何指定版本,及時地規避在線上遇到的問題。

當然,百度對任何一次服務變更都有詳細的記錄,會清晰地展示出操作者、操作時間、操作詳情以及概述,便於審計或追查。

百度在 Mesh 上還做了很多平臺化的工作。比如混沌平臺可以和控制平面對接,負責調度任務,進行效果評估,而服務網格負責執行策略。圖中 App1 調用 App2 邊車 時,需要注入一個延時故障或一個百分比故障驗證特定的 App2-3 實例。這時混沌平臺可以通過監控平臺收集反饋指標。

再比如線上運維。線上運維最頭疼的就是容量壓測,直接壓測可能會把服務壓垮,所以常常需要在大半夜流量低時去壓測,運維人員也會非常辛苦。有了 Mesh 以後,可以利用 Mesh 精準的動態分流能力,讓容量壓測平臺對接 Mesh。如下圖所示,可以對下游某一個服務的實例,按百分比進行導流,讓它接受比較大的流量。根據小部分實例的容量上限和實例的佔比,就可以計算出服務在線上真實環境的容量水平。

百度智能云云原⽣微服務平臺支持以上所有功能、協議擴展、性能優化,還支持公有云和私有化部署,感興趣的同學可以去看一下。

3 百度 Service Mesh 落地經驗總結  

這裏是一張百度 Service Mesh 的全景圖,要想做 Service Mesh 落地,就要打通圖中的所有環節。

當前百度使用 Mesh 的業務很多,包括手機百度 /Feed、百度地圖、小程序、好看視頻等。切入 Mesh 的服務體量有幾千個,實例數在 10 萬左右,每天流量的 PV 是百億級別。

通過接入 Mesh ,百度實現了跨語言統一的服務治理,提升了服務的可用性,微服務治理的週期從月級縮短到了分鐘級。同時,服務變更的效率提升了 10 倍以上,再加上產品化、平臺化等等的產品,運維人員的體驗也明顯提升了。

Istio 落地的核心要素總共有四個方面:務實、性能、穩定性和體驗。這四個方面中最重要的是務實,也就是必須要適配公司的基礎設施,實現公司生產環境裏使用的策略或協議。這決定了能不能接 Mesh,後面三個方面不過是接入規模或體驗的問題。

Istio 社區關注的是透明、安全性、可觀察性、可擴展性等特性,百度關注的是 Istio 落地時的性能、流量治理策略、Sidecar 管理的可管控性、以及複雜網絡或底層基礎設施環境的支持。

未來,百度希望和社區繼續融合,持續地跟進社區的新版本,引⼊社區⾼級擴展特性,同時百度也會向社區貢獻性能優化和策略擴展相關的經驗,和社區共建 Istio 生態。

嘉賓介紹

陳鵬,百度雲原⽣技術專家,現負責百度 Service Mesh 的研發和落地,對服務網格以及雲原生有深入研究。見證了百度 Service Mesh 從無到有,從摸索到大規模落地演變過程。致力於推動 Service Mesh 在多種場景下的落地。

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