作者
鐘華,騰訊云專家工程師,Istio project member、contributor,專注于容器和服務網格,在容器化和服務網格生產落地方面具有豐富經驗,目前負責 Tencent Cloud Mesh 研發作業,
Istio 在大規模場景下 xDS 性能瓶頸
xDS 是 istio 控制面和資料面 envoy 之間的通信協議,x 表示包含多種協議的集合,比如:LDS 表示監聽器,CDS 表示服務和版本,EDS 表示服務和版本有哪些實體,以及每個服務實體的特征,RDS 表示路由,可以簡單的把 xDS 理解為,網格內的服務發現資料和治理規則的集合,xDS 資料量的大小和網格規模是正相關的,
當前 istio 下發 xDS 使用的是全量下發策略,也就是網格里的所有 sidecar,記憶體里都會有整個網格內所有的服務發現資料,比如下圖,雖然 workload 1 在業務邏輯上只依賴 service 2, 但是 istiod 會把全量的服務發現資料(service 2、3、4)都發送給 workload 1,

這樣的結果是,每個 sidecar 記憶體都會隨著網格規模增長而增長,下圖是我們對網格規模和記憶體消耗做的一個性能測驗,x 軸是網格規模,也就是包含多少個服務實體,y 軸是單個 envoy 的記憶體消耗,可以看出,如果網格規模超過 1萬個實體,單個 envoy 的記憶體超過了 250 兆,而整個網格的開銷還要再乘以網格規模大小,

Istio 當前優化方案
針對這個問題,社區提供了一個方案,就是 Sidecar 這個 CRD,這個配置可以顯式的定義服務之間的依賴關系,或者說可見性關系,比如下圖這個配置的意思就是 workload 1 只依賴 service 2 ,這樣配置以后,istiod 只會下發 service 2 的資訊給 workload 1,

這個方案本身是有效的,但這種方式在大規模場景下很難落地:首先這個方案需要用戶提前配置服務間完整的依賴關系,大規模場景下的服務依賴關系很難梳理清楚,而且通常依賴關系也會隨著業務的變化而變化,
Aeraki Lazy xDS
針對上述問題,TCM 團隊設計了一套無入侵的 xDS 按需加載方案,并開源到 github Aeraki 專案,這是 Lazy xDS 具體的實作細節:

我們在網格里增加2個組件,一個是 Lazy xDS Egress,Egress 充當類似網格模型中默認網關角色,另一個是 Lazy xDS Controller,用來分析并補全服務間的依賴關系,
-
首先配置 Egress 的服務中轉能力:Egress 會獲取網格內所有服務資訊,并配置所有 HTTP 服務的路由,這樣充當默認網關的 Egress 就可以轉發網格內任意 HTTP 服務的流量,
-
第2步,對于開啟了按需加載特性的服務(圖中 Workload 1),利用 envoyfilter,將其訪問網格內 http 服務的流量,都路由到 egress,
-
第3步,利用 istio sidecar CRD,限制 Workload 1 的服務可見性,
-
經過步驟3后,Workload 1 初始只會加載最小化的 xDS,
-
當 Workload 1 發起對 Service 2 的訪問時,(因為步驟2)流量會轉發到 Egress,
-
(因為步驟 1)Egress 會分析接收到的流量特征,并將流量轉發到 Service 2,
-
Egress 會將訪問日志,異步地上報給 Lazy xDS Controller,上報服務是利用 Access Log Service,
-
Lazy xDS Controller 會對接收到的日志進行訪問關系分析,然后把新的依賴關系(Workload 1 -> Service 2)表達到 sidecar CRD 中,
-
同時 Controller 還會將(步驟2) Workload 1 需要轉發 Service 2 流量到 Egress 的規則去除,這樣未來 workload 1 再次訪問 Service 2 就會是直連,
-
(因為步驟 8)istiod 更新可見性關系,后續會將 Service 2 的服務資訊發給 Workload 1,
-
Workload 1 通過 xDS 接收到 Service 2 的服務資訊,
-
當 Workload 1 再次發起對 Service 2 的訪問,流量會直達 Service 2(因為步驟9),
這個方案的好處:
-
首先不需要用戶提前配置服務間的依賴,而且服務間依賴是允許動態的增加的,
-
最終每個 envoy 只會獲得自身需要的 xDS,性能最優,
-
這個實作對用戶流量影響也比較小,用戶的流量不會阻塞,性能損耗也比較小,只有前幾次請求會在 Egress 做中轉,后面都是直連的,
-
此方案對 istio 和 envoy 沒有任何入侵,我們沒有修改 istio/envoy 原始碼,使得這套方案能很好的適應未來 istio 的迭代,
目前我們只支持七層協議服務的按需加載,原因是流量在 Egress 這里中轉的時候,Egress 需要通過七層協議里的 header 判斷原始目的地,純 TCP 協議是沒有辦法設定額外的 header,不過因為 istio 主要目的就是為了做七層流量的治理,當網格的大部分請求都是七層的,這個情況目前可以接受的,
Lazy xDS 性能測驗
測驗方案

在同一網格內的不同 namespace 中,我們創建了 2 組 book info,左邊 namespace lazy-on 中 productpage 開啟按需加載,右邊 namespace lazy-off 保持默認情況,
然后在這個網格內,我們逐漸增加服務數量,使用的是 istio 官方負載測驗工具集(以下簡稱「負載服務」),每個 namespace 里有 19 個服務, 其中4個 tcp 服務,15個 http 服務,每個服務初始 pod 數目為 5,共95個 pod(75 個http,20 個tcp),我們逐漸增加負載服務的 namespace 數量, 用于模擬網格規模增長,
性能對比
首先是 CDS 和 EDS 的對比,下圖每組資料代表負載服務 namespace 的增加,每組資料里 4 個值:前 2 個值是開啟按需加載后的 CDS 和 EDS,后面 2個值是沒開啟按需加載的 CDS 和 EDS,

接下來是記憶體對比,綠色資料表示開啟按需加載后 envoy 的記憶體消耗,紅色的是未開啟的情況,900 pods 規模 mesh,envoy 記憶體減少 14M ,降低比例約 40%;一萬 pods 規模 mesh,envoy 記憶體減少約 150M,降低比例約 60%,

隨著服務可見性的限制,envoy 不會再接收全量的 xDS 更新,下圖是在測驗周期內 envoy 接收到 CDS 更新次數的對比,開啟按需加載后,更新次數從 6 千次降低到了 1 千次,

小結
Lazy xDS 已經在 github 開源,請訪問 lazyxds README了解如何使用,
Lazy xDS 功能還在持續演進,未來我們將支持多集群模式、ServiceEntry 按需加載等功能,
如果您希望了解更多關于 Aeraki 的內容,歡迎訪問 Github 主頁:https://github.com/aeraki-framework/aeraki
關于我們
更多關于云原生的案例和知識,可關注同名【騰訊云原生】公眾號~
福利:
①公眾號后臺回復【手冊】,可獲得《騰訊云原生路線圖手冊》&《騰訊云原生最佳實踐》~
②公眾號后臺回復【系列】,可獲得《15個系列100+篇超實用云原生原創干貨合集》,包含Kubernetes 降本增效、K8s 性能優化實踐、最佳實踐等系列,
③公眾號后臺回復【白皮書】,可獲得《騰訊云容器安全白皮書》&《降本之源-云原生成本管理白皮書v1.0》
【騰訊云原生】云說新品、云研新術、云游新活、云賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/390279.html
標籤:其他
下一篇:2021年想做的最后掙扎

