Service Mesh 在超大规模场景下的落地挑战
作者 | 至簡? 阿里云高級技術專家
隨著微服務軟件架構在互聯網企業的廣泛實踐,新一代微服務軟件架構技術悄然興起,Service Mesh 便是其中之一。
根據 Linkerd CEO Willian Morgan 對 Service Mesh 的定義,Service Mesh 是一層處理服務間通信的基礎設施。云原生應用有著復雜的服務拓撲,Service Mesh 保證請求可以在這些拓撲中安全且可靠地穿梭,對整個服務網絡進行觀測和高效查錯,以及通過靈活的流量治理能力為新功能上線提供高效的驗證手段。在實際應用當中,Service Mesh 通常是由一系列輕量級的網絡代理(又被稱為 Sidecar)組成的,它們部署在應用進程的邊上且對應用進程完全無感。
國內 Service Mesh 早期實踐基本分為先建設數據層后建設控制層和同時建設兩類,從后續發展看,隨著對服務運營能力要求的提高,控制層會越來越重要。在實際落地方面,眾多企業都在積極探索 Service Mesh 在大規模場景下的應用。
阿里巴巴高級技術專家至簡在 KubeCon 2020 阿里巴巴云原生專場分享了《Service Mesh 在超大規模場景下的落地挑戰》,基于阿里巴巴的落地實踐,分享一些經驗和思路。以下是部分內容整理。
分布式應用架構在阿里巴巴的現狀
阿里巴巴圍繞電商業務構建了龐大的微服務軟件架構應用生態,包括了天貓、淘寶、菜鳥、高德等。其次,整個微服務體系是通過 Dubbo RPC 連接在一起,MetaQ 用于服務之間的異步解耦。
目前阿里巴巴主要的技術棧還是 Java,圍繞 Java 構建了相當健全的微服務治理能力,其他技術棧的微服務治理能力相對弱很多。在服務可見性這塊,阿里巴巴是完全沒有隔離的。Dubbo RPC 仍是接口級服務發現,1 個應用如果提供 10 個接口,那么就會有 10 個服務是可以被發現的,如果這個應用有 n 臺機器,那么 10 個服務就會產生 10*n 個服務端點元信息,這種重復數據導致規模問題被放大。
另外一點值得跟大家分享的是,目前阿里巴巴也正經歷著應用的 SDK 升級之痛,SDK 中包含了中間件和應用層的一些公共模塊,由中間件統一以 Pandora 包的形式交付給業務方使用。在應用數非常龐大的情形下,SDK 升級是一份相當繁重的工作,甚至涉及到集團層面的大協同。為此,我們希望通過 Service Mesh 先將中間件的那些能力下沉到 Sidecar,將這塊升級工作從 Pandora 中剝離出來,借助 Service Mesh 的流量無損熱升級能力讓業務對中間件升級完全無感。
Service Mesh 面臨的挑戰
- Service Mesh 面臨的第一個挑戰就是新技術如何平滑演進;
Service Mesh 在大規模場景下的落地在業界的案例還相當 少,根源在于該技術本身還沒有完全成熟。在技術走向成熟的持續迭代過程中,如何平滑演進是一個很有挑戰的任務。挑戰在于需要以終為始地規范技術架構的演進,一步一步地向終態架構演進。
- 第二個挑戰是發展的過程中如何協調好技術和業務的平衡;
技術團隊希望快速迭代向前發展兌現價值,而業務團隊每年有自己的業務目標,如何協調好兩者的發展關系是個不小的挑戰。代表新技術的團隊其發展思路通常會更激進,而業務團隊會因為“穩定壓倒一切”而偏保守,短期內調和好這一矛盾或許需要自頂向下的決策力量,否則業務挑戰年年有而可能擠壓技術的發展空間,導致技術發展緩慢而無法更好地服務于業務的發展。
- 第三個挑戰是技術向前演進時如何處置歷史包袱;
每一次技術的演進都意味著對原有技術體系的升級,這就不可避免地需要處置過往累積下來的技術債。新技術發展的難點往往不在于其“新”,而在于包袱太重而導致新技術演進困難,很可能因為演進太慢而嚴重影響了新技術的發展。
- 第四個挑戰就是克服超大規模所帶來的問題;
前面講到的 Dubbo 因為是接口級服務發現,使得服務發現的數據規模非常大,給控制平面的端點數據推送能力帶去了巨大挑戰。
- 最后一個挑戰是 Sidecar 的規模化運維。
在超大規模場景下,大量的應用機器意味著有等量的 Sidecar 需要運維,如何在部署、灰度、升級以及保障安全生產是一個很大的挑戰。
新技術在架構上平滑演進是關鍵
新技術的不成熟很可能在相當長的一段時間內是常態,演進的關鍵在于如何實現新技術架構的平滑演進,避免出現推倒重來這種勞命傷財之事。為此,基于這一考量,我們一共經歷了“起步”、“三位一體”和“規模化落地”三大階段,而每一個階段采用了不同的軟件架構或部署方案。
在起步階段,Istio 控制平面的 Pilot 組件放在一個單獨的容器中,同時當作一個獨立的進程和 Sidecar 部署在一個 Pod 里。采用這樣的方式,使得對開源的 Envoy 和 Pilot 可以做最小的改動而加速落地,也方便我們基于開源的版本做能力增強和反哺。這一方案的缺點在于,每個 Pod 中都包含了一個 Pilot 進程,增大了應用所在機器上的資源消耗,因在服務規模并不大的情形下資源消耗相對小而可以忽視這一缺點。
在三位一體階段,Pilot 進程從業務 Pod 中抽離了出來變成了一個獨立的集群,在 Sidecar 和 Pilot 之間仍是 xDS 協議。這一架構雖節省了應用所在機器的資源消耗,但必須正視規模化落地的問題。xDS 中有一個叫 EDS(Endpoint Discovery Service)的協議,Pilot 通過 EDS 向 Sidecar 推送服務發現所需使用到的機器 IP(又被稱之為 Endpoint)信息,在阿里的大規模場景下因為有大量的端點需要通過 Pilot 推送給 Sidecar,導致 Sidecar 的 CPU 消耗相當大,讓人擔心業務進程因為 Sidecar 對資源的爭搶而受影響。這一規模化問題并非在起步階段的技術方案中不存在,只不過因為那時落地應用的服務規模小而沒有成為瓶頸。
為了解決規模化落地的問題,我們設計出了規模化落地的技術架構。
在這一架構中,雖然還是 Sidecar 對接 Pilot 集群,但是 Pilot 集群只提供 xDS 中的 LDS/CDS/RDS 這些標準的服務,而 EDS 采用 Sidecar 直接對接服務注冊中心解決。值得強調,雖然Sidecar直接對服務接注冊中心,但是它仍然沿用了 Envoy 里面對 EDS 所抽象的數據結構和服務模型,只是在數據的獲取上對接注冊中心來實現。之所以 Sidecar 直接對接服務注冊中心能解決走 EDS 所存在的規模化問題,根源在于阿里巴巴的服務注冊中心具備了增量推送的能力。
在這三種架構中,未來的終態一定是采用三位一體的架構,且數據平面和控制平面也一定是并重發展。由于阿里巴巴今天的服務規模非常龐大而沒辦法一步到位做到三位一體。通過規模化落地這一過渡方案,仍然有助于我們更好地反哺開源社區,通過盡早大規模落地會讓我們清楚地知道開源方案仍存在的問題,從而讓我們能為開源方案的完善做出更大的貢獻。
業務與技術協同發展 —— 飛行中更換引擎
業務與技術的協同發展首先要回答好一個問題,即新技術帶給業務的價值是什么。從業務的角度,采納新技術最開始考慮的一定是短期價值,然后才是放眼看長遠價值。
Service Mesh 對于業務所帶去的短期價值是:
-
中間件能力下沉,下沉的過程中去除歷史包袱輕裝上陣;
-
業務對中間件升級無感,中間件資源消耗可量化、優化可度量。
從長遠來看,完全解決阿里巴巴面臨的 Pandora/SDK 升級之痛是需要相當長的一段時間,而 Service Mesh 在流量治理這塊的新價值也需要規模化落地達到一定水平后才能兌現,基礎技術對業務的價值需要具備長遠的眼光。Service Mesh 的長遠價值有:
-
業務與基礎技術全面解耦,業務更聚集于自身而加速創新,基礎技術獨立演進而加速迭代;
-
對微服務生態完成標準化、體系化的收口與治理,收斂故障和促進安全生產,加速應用功能正確性的驗證效率;
-
為多種編程語言的應用提供微服務治理能力,完善并豐富云原生多編程語言的應用生態;
-
共建全球事實標準,通過阿里云的產品落實客戶 IT 設施的多云和混合云戰略,加速中國社會乃至全球的數字化轉型。
明確了技術的價值之后,業務與技術協同發展接下來的挑戰在于,需要技術演進的過程中完全不影響業務,這好比給一架高速運行的飛機換引擎。為此,新技術的落地方案需要考慮對業務無侵入,換句話說規避業務應用新技術的改造成本。
為了應用 mesh 化時對業務無感,在以 RPC 流量做 mesh 化為切入點的背景下,我們設計了動態流量無損透明攔截的技術方案。上圖示例說明了應用 mesh 化前后的三種狀態。在“過去”,流量是直接通過 RPC SDK 在 Provider 和 Consumer 之間互通的,SDK 直接跟中間件的服務注冊中心、配置中心對接。
到了“現在”,Service Mesh 直接被插入到了應用和中間件之間,SDK 不做任何的變化,但通過 iptables 將 SDK 的流量攔截到 Sidecar 中。由于 iptables 是否開啟和關閉流量攔截是可以通過運維控制臺從應用或機器維度進行控制的,這就使得在 mesh 技術自身出現問題的情形下可以方便禁用,讓應用回退到通過 SDK 直連的方式互通。
面向“未來”,當 Service Mesh 技術完全成熟時,SDK 需要從“胖”變“瘦”,那時并不需要 SDK 中存在下沉到 Sidecar 的那些能力,從而節約重復功能所導致的資源開銷。
下圖示例說明了打開和關閉流量透明攔截功能的關鍵流程。其中應用進程中包含了 RPC SDK 而沒有區分表達,Traffic Interceptor、Pilot Agent 和 Envoy 三個組件在同一個容器中,所有組件共享同一個 Pod。OneOps Core 是基于 K8s 所構建的中心化 mesh 運維 Operator,收到控制臺(圖中標識為小人的 Operator 指代)調用開啟或關閉流量透明攔截的接口后,通過調用 Pilot Agent 所提供的接口完成對 Pod 中應用流量的操作。
為了保證打開和關閉透明攔截功能時無業務流量的調用損失,請注意圖中紅色標識出的二大塊流程。開啟流量攔截時:Pilot Agent 將調用 RPC SDK 的 offline 接口(消息 2.1.1),間接完成從服務注冊中心對本機做去注冊摘除流量;然后調用 Traffic Interceptor 組件所提供的接口開啟流量攔截功能(消息 2.1.2);最后再調用 RPC SDK 的 online 接口將本機注冊到服務注冊中心(消息 2.1.3)。
關閉流量攔截時:Pilot Agent 將調用 Envoy 的優雅關閉接口(消息 4.1.1),Envoy 會在 RPC SDK 與 Envoy 建立的連接上透傳這一消息(即 Envoy 會調用 RPC SDK 的優雅關閉接口,上圖并沒有表達出),告訴 RPC SDK 不要再向已建立的這一長連接上發送任何 RPC 請求;隨后 Pilot Agent 調用 Traffic Interceptor 接口關閉流量攔截功能(消息 4.1.2);最后,Envoy 的優雅關閉接口被調用時會啟動一個延時 15 秒的定時器,確保 RPC SDK 與 Envoy 間已建立的長連接上還沒有完成處理的請求有足夠的時間處理完以免出現流量有損,當定時器到期后 Envoy 會主動關閉與 RPC SDK 所建立的連接(消息 6)。
為了讓 mesh 技術自身的迭代對業務無感,我們設計了流量無損熱升級方案,確保 Sidecar 可以隨時對業務無感升級。設計流量無損熱升級方案的核心考量是投入產出比,以最小的工程成本構建一個容易做到穩定的技術方案,下圖示例了站在 Consumer 視角(即 Consumer 側的 Envoy 進行升級,Consumer 代表流量調用的發起方)所觀測到的熱升級流程。
當 Envoy 有一個新版本需要升級時(圖中標識為 v2),通過運維控制臺可以設置這個新版本的鏡像信息,通過 OpenKruise 的 SidecarSet 可以拉到這一鏡像并將鏡像中的新版本 Envoy 二進制程序拉起。隨后,新版本 Envoy 會向老版本 Envoy(路中標識為v1)發起熱升級流程。
熱升級大致包含如下幾個流程:老版本進程中所有的偵聽 fd 通過進程間通訊的方式交給新版本進程(消息 5.1),由新版本進程繼續在之上進行偵聽(消息 5.1.1),換句話說,之后所有在這些被偵聽端口上新建的連接都會發生在新版本進程中;老版本進程調用 RPC SDK 的優雅關閉接口(消息 5.3),告訴 RPC SDK 不要再已建立的連接上發起新的調用,如果要發起新調用則必須重新建立連接,顯然新連接將與新版本進程建立,隨后的調用流量將全部進到新版本進程;老版本進程向 RPC SDK 發起優雅關閉接口調用的同時會建立一個時延 15 秒的定時器,確保與 RPC SDK 所建立的連接在這 15 秒中都處理完,定時器到期后關閉這一連接并退出老版本進程(消息 5.4),從而結束整個熱升級流程。
下圖是從 Provider 視角(即 Provider 側的 Envoy 進行升級,Provider 代表提供相應服務能力的被調用方)所觀察到的升級流程。不難看出,紅色標識出的部分與前一張圖是完全一樣的,熱升級流程完全無需基于 Envoy 的 Consumer 或 Provider 身份做特殊的處理。畢竟,現實中每個應用大多會同時承擔 Consumer 和 Provider 兩種角色。
上圖有一個點值得特別指出,Envoy 需要實現序號為 5.3 的優雅關閉消息,并將這一消息透傳給 RPC SDK(圖中并沒有表達)。
發展新技術是償還技術債的重要契機
不少新技術的出現多少會引發我們的糾結,在新技術所創造的短期價值不那么有吸引力的情形下,似乎舊技術不改變就不會帶來風險。但經驗表明,不改變的后果是包袱會越積越重,由此所帶來的技術債的潛在風險最終都不可忽視。
技術債是軟件的本質屬性,因為無法做到已有架構能一直百分百優雅實現新需求。換句話說,技術債對于一個長期提供服務的軟件來說是一直存在的,只不過存在大小之別和何時償還的問題。
阿里巴巴對分布式系統的探索有超過十年的積累,為了做應用的服務化改造提出了 HSF RPC 開發框架并將之開源為 Dubbo。基于框架思維所構建的 RPC 協議為了更好地滿足不同業務對服務路由的定制化訴求,提供了通過 Groovy 腳本進行定制的能力。然而,這種靈活的手段在向 Service Mesh 這一平臺技術演進時將帶來流量治理隱患。
我們認為,平臺思維下構建的 Service Mesh 得限制過于靈活的定制能力,避免平臺出現“窟窿”而無法有效、有力地完成全局最優的治理。為此,我們將去除 Groovy 腳本當作是一項技術債加以償還。Groovy 腳本帶來的問題主要有兩個:
-
過于靈活且導致了開發框架與應用代碼的耦合;
-
給流量治理能力下沉留下了潛在隱患。
為了去除 Groovy 腳本,我們擴展了 Istio 的 VirtualService 和 DestinationRule,抽象出按應用名、方法和參數路由的能力。下圖示例說明了某應用基于應用名做路由在 Groovy 腳本和 Service Mesh 下的具體實現。
由于單個應用的 Service Mesh 化并非一刀切的一次性完成,存在一個應用的部分機器先 mesh 化做灰度的場景。為此,需要在去 Groovy 腳本這件事上,讓新舊技術方案能同時無縫工作,背后是兩種形式的路由表達如何做好同步,背后就涉及控制臺收口和格式轉化等問題需要妥善解決。
系統性解決超大規模問題
為了最終解決阿里巴巴在 Service Mesh 落地過程中所面臨的大規模問題,我們從三個方面著手:
-
Service Mesh 技術自身的持續優化:需要從 CPU 開銷、內存占用和時延三大維度進行持續優化,通過軟硬件結合等技術手段做到應用 Service Mesh 化前后零新增成本甚至下降;
-
Dubbo 實現應用級服務發現而非接口級:通過應用級服務發現將使得控制平面向數據平面推送的服務元數據有數量級下降,讓 Service Mesh 的控制平面向數據平面推送的數據急劇下降。
-
服務注冊數據進行單元封閉并分級治理:動機依然是降低 Service Mesh 控制平面向數據平面推送的數據量,通過單元封閉讓全局服務元數據通過局部化而減少。
這三方面在阿里巴巴分別有相應的團隊在探索解決,這里主要分享 Service Mesh 技術本身。阿里巴巴對 Service Mesh 技術的探索策略是“借力開源,反哺開源”。
-
“借力”體現于整體技術方案采納的是開源的 Istio(控制平面) + Envoy(數據平面),在工程實踐中特別注意自有代碼與開源代碼做充分的解耦,以及頻繁跟進開源社區發布的新版本;
-
“反哺”表現在我們積極將性能優化、bugfix 等代碼提交給開源社區。
至今,在 Istio 開源社區我們提交了 9 個 PR,解決性能問題和 bugfix;在 Envoy 開源社區我們提交了 14 個 PR,包含內存開銷下降 50% 的優化、新增對 Dubbo 和 RocketMQ 協議的支持等內容。此外,我們曾與 Istio 社區共同探索實現了 EGDS (Endpoint Group Discovery Service),作為 EDS 的增強,但由于 Envoy 社區擔心該 feature 通用性不足而最終沒能接受而完成這次反哺。這一“失敗”不只體現了我們反哺社區的意愿和熱情,也是更好融入開源社區的一次很好的學習機會。
在 EGDS 并不能很好解決在“三位一體”方案下的大規模落地問題的情形下,我們重新調整了落地方案,形成了本文前面所講到的讓 Envoy 直接對接服務注冊中心的“規模化落地”方案。下圖展示了兩個方案的 CPU 開銷數據比較。
圖中深藍色代表的是規模化落地方案,橙色代表的是三位一體的方案,測試數據表明三位一體方案在設定的越大規模壓測場景下因服務元數據推送給 Envoy 所帶去的 CPU 開銷是規模化落地方案的三倍。
進一步地,我們比對了非 mesh 方案和規模化落地 mesh 方案因服務元數據推送所導致的 CPU 開銷(如下圖所示)。數據表明,非 mesh 方案(圖中橙色表示)因 Java 進程在數據推送場景下存在 GC 而使得 CPU 開銷要顯著地高于規模化落地 mesh 方案(圖中深藍色表示),這是因 Envoy 采用 C++ 編程語言而獲得的優勢。
后續我們會考慮參與共建 Envoy 社區所提出的 LEDS 協議,讓 Istio + Envoy 的三位一體方案天然地能運用于阿里巴巴的大規模場景。
除了 CPU 開銷的優化,我們在內存優化方面也取得了巨大的進展。同樣服務規模的情形下,Envoy 的內存開銷從之前超過 3G 優化至 500M 左右。此外,壓測數據表明應用 mesh 化完成后整體內存開銷比 mesh 化前更低。
Sidecar 的規模化運維
Sidecar 的規模化運維也是很具挑戰的一件事,內容包含 Sidecar 的部署、灰度、升級,以及需要構建相應的監控和報警設施。
Sidecar 的部署、灰度、升級我們全面基于由阿里巴巴開源的 OpenKruise 中的 SidecarSet 實現。SidecarSet 提供了對 Sidecar 進行部署、灰度和升級的通用能力,能很好地運用于 Service Mesh 而省去了重復建設。
當然,流量無損熱升級這樣的能力并非 SidecarSet 原生提供的,需要從 Service Mesh 層面去增強。在 Sidecar 的運維和流量治理這塊,監控和報警全面采用了阿里云上的 Prometheus 和 ARMS 兩大云產品,一旦當下服務于阿里巴巴內部的 Service Mesh 技術將來要通過產品化輸送給阿里云上的客戶時會更加方便。
在運維管控上,我們全新構建了云原生 OneOps 運維系統。OneOps 包含控制臺和 OneOps Core 兩大子系統。后者是基于 K8s 構建的運維 Operator,通過 CRD 的形式暴露給控制臺調用接口。OneOps Core 可以多區域部署,而控制臺是全局集中部署的,這樣方便運維人員在同一個控制臺上能無縫地管理多個區域的 Service Mesh。目前 OneOps 已具備管理包含了 Sidecar 和 Ingress Gateway在內的東西南北向流量的能力。
總結
本文總結了阿里巴巴大規模落地 Service Mesh 所面臨并克服的技術挑戰,希望這些內容對行業同仁在這一技術的探索和學習有所幫助。現階段,阿里巴巴對于 Service Mesh 的探索更多停留于解決歷史包袱和完成應用與中間件的解耦,仍沒有在服務流量治理方面做出新價值和新體驗,期待未來能盡早給大家分享這方面的內容。
Service Mesh 是云原生的關鍵技術,對于阿里巴巴來說,我們篤定這是分布式應用微服務軟件架構的未來。正因如此,CTO 魯肅也站臺 Service Mesh 技術,并做出了未來整個經濟體全面走 Istio + Envoy 方案的技術決策。在構建阿里巴巴全球商業操作系統的道路上,Service Mesh 是面向未來五年、甚至十年的技術。
期待更多對分布式應用相關技術挑戰有熱情的志同道合之士加入共建與共創,在創變的道路上我們共同成長、共同收獲。如果您有意向,請將簡歷發送至 zhijian.ly@alibaba-inc.com,我們在深圳、上海和杭州都有 Service Mesh 的職位長期開放。
另外,業界首個兼容 Istio 全托管云產品的阿里云服務網格(ASM)已對外發布,可免費體驗:https://servicemesh.console.aliyun.com/
課程推薦
去年,CNCF 與 阿里云聯合發布了《云原生技術公開課》已經成為了 Kubernetes 開發者的一門“必修課”。
今天,阿里云再次集結多位具有豐富云原生實踐經驗的技術專家,正式推出《云原生技術實踐公開課》。課程內容由淺入深,專注講解“ 落地實踐”。還為學習者打造了真實、可操作的實驗場景,方便驗證學習成果,也為之后的實踐應用打下堅實基礎。點擊鏈接查看課程:https://developer.aliyun.com/learning/roadmap/cloudnative2020
“阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的公眾號。”
總結
以上是生活随笔為你收集整理的Service Mesh 在超大规模场景下的落地挑战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 4 个场景揭秘,如何低成本让容器化应用
- 下一篇: Kubernetes 容器网络模型和典型