云原生技術(shù)范式顛覆
——從Spring Cloud到
Service Mesh框架重構之路
神州信息
徐超
02.Service Mesh遷移方案
對于還未涉足Service Mesh 的企業(yè)或產(chǎn)品,其傳統微服務(wù)架構如若已采用 Spring Cloud 框架構建,此時(shí)向Service Mesh 框架遷移又該如何做?需要綜合考慮哪些因素?是否有依可據?
接下來(lái),就構建基于Spring Cloud向 Service Mesh 框架遷移提供一些建議方案和思路,供大家參考。
2.1
遷移場(chǎng)景
傳統微服務(wù)框架,以最為典型的Spring Cloud 框架為例進(jìn)行遷移說(shuō)明。首先,先看一下這樣的一個(gè)遷移場(chǎng)景,目前的微服務(wù)架構如下圖左邊部分:
● 應用是部署在虛擬機或物理機上。(服務(wù)還未容器化)。
● 框架是基于 Spring Cloud 框架開(kāi)發(fā)。(服務(wù)中包含的業(yè)務(wù)邏輯和 Spring Cloud 組件相依賴(lài),業(yè)務(wù)和框架高度耦合)
● 開(kāi)發(fā)語(yǔ)言以Java為主。(存在跨語(yǔ)言的問(wèn)題)
● 注冊中心采用的是 Consul 或 Eureka。(服務(wù)需引入注冊中心依賴(lài)包,存在一定的耦合)
目前開(kāi)源 Istio 已經(jīng)成為 Service Mesh 事實(shí)上的標準,更是新一代微服務(wù)架構發(fā)展的趨勢,因此公司希望嘗試遷移到 Istio 框架,希望最終形成類(lèi)似上圖的右邊部分。
2.2
遷移路徑
面對上述遷移場(chǎng)景,確定要引入 Service Mesh 前,需要徹底搞清楚 Service Mesh 遷移的具體路徑。
首先,要對自己項目做以下評估:
● 是否真的有必要引入遷移到 Service Mesh 上?
● 當前微服務(wù)架構下,是否面臨傳統微服務(wù)架構面臨的挑戰?
● 當前微服務(wù)架構,是否已經(jīng)阻礙或影響未來(lái)業(yè)務(wù)的發(fā)展?
● 公司或技術(shù)團隊,是否有能力、人力、精力來(lái)投入到 Service Mesh 的遷移?
其次,完成 Service Mesh 微服務(wù)平臺的搭建。當前所處階段是否已經(jīng)支持容器化和 Kubernetes。如果當前業(yè)務(wù)已經(jīng)運行在 Kubernetes 之上,則 Service Mesh 的遷移將會(huì )比較順暢;如果當前業(yè)務(wù)沒(méi)有運行在Kubernetes上,因 Service Mesh 當前典型的 Istio 框架對 Kubernetes 有著(zhù)過(guò)度依賴(lài),所以可能就無(wú)法直接從 Spring Cloud 遷移到 Istio 框架,即使定制修改 Istio 以接觸對 Kubernetes 的依賴(lài),將會(huì )付出很大的代價(jià)。這時(shí)通常有兩條遷移路徑可供選擇。
● 路徑一:非 Kubernetes 環(huán)境下,先接入 Sidecar
如果當前業(yè)務(wù)沒(méi)法快速容器化,同時(shí)又有引入 Service Mesh 的迫切需求,可采取先接入 Sidecar,來(lái)滿(mǎn)足當前業(yè)務(wù)的痛點(diǎn)需求。在引入 Sidecar 時(shí),要注意其未來(lái)的演進(jìn)方向,考慮后續可能繼續向 Service Mesh 遷移,一旦時(shí)機成熟并引入 Kubernetes 容器化后,則能夠順利由 Sidecar 的方式直接演進(jìn)到 Service Mesh。
Service Mesh 當前典型的 Istio 框架在非 Kubernetes 下沒(méi)有很好的支持(據說(shuō)未來(lái)會(huì )完全脫離對Kubernetes 的依賴(lài)),對 Istio 進(jìn)行定制化修改以支持非 Kubernetes 環(huán)境將會(huì )付出很大的代價(jià),非特別強烈的需求和強大的技術(shù)儲備,一般不建議這么做,特別是對于一些中小公司而言。
如果一定要在非 Kubernetes 環(huán)境下引入 Service Mesh,數據平面可使用 Envoy,控制平面可根據 XDS 協(xié)議進(jìn)行自研。
● 路徑二:先進(jìn)行 Kubernetes 容器化改造,再接入 Service Mesh
倘若公司有云平臺或容器化團隊,可采用公司資源共享的方式,先借助其他團隊來(lái)完成 Kubernetes 容器化改造,再接入 Service Mesh。
最后,基于構建的 Service Mesh 框架,將業(yè)務(wù)應用逐步遷移到 Service Mesh 。
2.3
遷移原則
在實(shí)施遷移時(shí),必須要時(shí)刻遵守以下遷移原則。
● 漸進(jìn)式遷移: 為避免 Service Mesh 遷移過(guò)程中的風(fēng)險,必須采用漸進(jìn)式遷移原則,每次只遷移少量服務(wù),待遷移后觀(guān)察足夠長(cháng)的時(shí)間,沒(méi)有問(wèn)題后再繼續遷移。
● 業(yè)務(wù)透明: 為減少 Service Mesh 遷移對業(yè)務(wù)的影響,減少業(yè)務(wù)的遷移阻力,遷移初期必須確保業(yè)務(wù)完全透明且不需要過(guò)多的變更和修改。
● 兼容性: 在遷移階段,必然會(huì )存在兩種模式( Spring Cloud 和 Service Mesh 框架)并存,在遷移過(guò)程中需要充分考慮兩者的兼容性,使得遷移前后網(wǎng)絡(luò )打通,至少能夠滿(mǎn)足未遷移和已遷移部分能夠通信。
2.4
遷移方案
從 Spring Cloud 向 Service Mesh 框架遷移,大體上分為四個(gè)步驟:Spring Cloud 架構分析、容器化改造、Service Mesh 微服務(wù)平臺搭建和應用遷移。
2.4.1 Spring Cloud架構分析
Spring Cloud 架構分析的目的在于重新了解當前微服務(wù)架構下的所有功能,便于在向 Service Mesh 遷移時(shí)做準備,考慮哪些功能需要遷移,哪些不需要遷移,哪些需要改造等。如下圖所示是基于 Spring Cloud 完整構建的微服務(wù)架構解決方案。
從上圖經(jīng)過(guò)分析,可以匯總得知它主要由以下幾部分組成:
● 代理&網(wǎng)關(guān):提供統一對外或對內的訪(fǎng)問(wèn)入口,包括路由、鑒權、限流、熔斷、降級等統一處理。
● 注冊中心:提供服務(wù)的注冊與發(fā)現功能。
● 應用服務(wù):覆蓋整個(gè)業(yè)務(wù)服務(wù),包括業(yè)務(wù)邏輯實(shí)現、框架SDK及外部組件依賴(lài)交互等。
● 中間件&數據存儲:為應用服務(wù)提供額外的支持能力。
● CI&CD:持續集成、持續部署。
上述這幾部分中哪些內容是我們可以去掉或者是基于 Service Mesh (以 Istio 為例)能夠去做的?經(jīng)過(guò)分析得知,可以替換的組件包括網(wǎng)關(guān)(Gateway 或者 Zuul,由 Ingress gateway 或者 egress 替換),熔斷器(hystrix,由 Sidecar 替換),注冊中心(Eureka 及 Eureka client,由 Polit,Sidecar 替換),負載均衡( Ribbon,由 Sidecar 替換)等。
此階段,我們能夠大致知道 Spring Cloud 中的哪些內容可以由 Istio 處理,哪些內容可以繼續沿用。
2.4.2 容器化改造
容器化改造,主要針對目前還未引入 Kubernetes 容器化的場(chǎng)景。在容器化改造之前,有必要知道改造的優(yōu)勢及要求。
容器化改造優(yōu)勢:
● 更?。簶O大的資源利用效率, 最大限度榨取和共享物理資源,多項目更能體現出容器化的優(yōu)勢,節約部署 IT 成本。
● 更快:秒級啟動(dòng),實(shí)現業(yè)務(wù)系統更快的開(kāi)發(fā)迭代和交付部署。
● 彈性:根據業(yè)務(wù)負載進(jìn)行彈性容器伸縮,彈性擴展。
● 方便:容器化業(yè)務(wù)部署支持藍綠/灰度/金絲雀等發(fā)布,回滾,更加靈活方便。
● 靈活:監控底層 node 節點(diǎn)健康狀態(tài),靈活調度至最優(yōu)節點(diǎn)部署。
● 強一致性:容器將環(huán)境和代碼打包在鏡像內,保證了測試與生產(chǎn)環(huán)境的強一致性。
容器化改造要求:
● 掌握 Docker 技術(shù):開(kāi)發(fā)人員需熟悉 Docker 容器化技術(shù),熟練編寫(xiě) Dockerfile 文件。
● 掌握 Kubernetes 編排系統:熟悉 Kubernetes 容器化編排系統,熟悉各組件資源清單編寫(xiě)、高可用、 RBAC 安全策略等。
容器化改造,主要分為以下兩個(gè)階段:
● 容器化構建:將基于 Spring Cloud 搭建的所有服務(wù)實(shí)現容器化構建,實(shí)現 Docker 鏡像打包。
● 容器化管理:基于 Kubernetes 或容器云平臺進(jìn)行服務(wù)容器的管理。
2.4.3 Service Mesh 微服務(wù)平臺搭建
Service Mesh 框架選取業(yè)界典型的 Istio 框架。
2.4.3.1 Istio基礎框架搭建
基于 Istio 框架搭建 Istio 基礎框架,在控制平面和數據平臺分別提供以下能力:
● 控制平面:提供服務(wù)?格控制指令下發(fā)、服務(wù)配置、權限控制等功能。
● 數據平臺:提供服務(wù)治理、服務(wù)監控及運維、流量管控等功能。
上述Spring Cloud的功能在 Istio 框架上都能找到對應的功能,并通過(guò)適當的資源清單配置即可完成。
Istio 架構圖如下:
至此,一個(gè) Istio 基礎框架搭建完成,能夠提供 Service Mesh 的所有能力。
2.4.3.2 Istio擴展和定制
在遷移路徑中已經(jīng)提及過(guò),對于非Kubernetes 環(huán)境,建議先引入 Sidecar,并采取 Istio 對虛擬機的支持方案,在虛擬機環(huán)境下運行。但如果有多平臺支持的場(chǎng)景,比如既有 Kubernetes 環(huán)境,又有虛擬機環(huán)境,需對 Istio 進(jìn)行定制化改造,去掉對 Kubernetes 的強依賴(lài)和耦合,增加對其他平臺的支持。(對于多平臺的支持,目前Istio 還未支持,但從 Istio 官方相關(guān)文檔可以看出,多平臺的支持最終肯定支持,我們只需拭目以待。)
Istio對 Kubernetes 的耦合主要有以下幾個(gè)方面,因此需要針對性的適配修改。
(1)API資源管理層對 Kubernetes API Server 的依賴(lài)
資源管理層是Istio 對 Kubernetes 依賴(lài)最大的地方。Istio 對核心資源的管理,是以 Kubernetes CRD 為基礎,并使用 kubectl 作為命令行操作入口,kubectl 調用 API Server,將資源存放在 etcd 中,并通過(guò) Kubernetes CRD 機制觸發(fā)資源變更事件通知,通知關(guān)心 Istio 資源變更事件的模塊進(jìn)行相關(guān)處理。
如需解除Istio對 Kubernetes 的綁定,則需要自行實(shí)現這一套API管理方式,并且做到平臺無(wú)關(guān)。
(2)通信訪(fǎng)問(wèn)層面對kube DNS 的依賴(lài)
通信層面,在客戶(hù)端發(fā)送請求前,先通過(guò)DNS 獲取服務(wù)的虛擬IP地址,Istio 的 DNS 實(shí)現沿用Kubernetes DNS 方案,基于 DNS 通過(guò)服務(wù)名實(shí)現直接訪(fǎng)問(wèn)。因此需要在 DNS 方案層面接觸和Kubernetes 的耦合,并使用平臺無(wú)關(guān)的 DNS 解決方案。
2.4.3.3 兩種框架并存
對于體量較大的業(yè)務(wù),不可能一次性遷移完成,需遵守“漸進(jìn)式遷移”原則,則實(shí)際遷移過(guò)程中可能面臨這樣的訴求:
● 一些存量老業(yè)務(wù)運行在虛擬機或者物理機上,暫時(shí)沒(méi)有容器化改造計劃,但希望通過(guò) Service Mesh 來(lái)做服務(wù)治理。
● 新上的業(yè)務(wù)或者存量的非關(guān)鍵業(yè)務(wù)可以做為試點(diǎn),先容器化、Service Mesh 化,其它業(yè)務(wù)依然采用原有的運行方式和微服務(wù)框架。
● 對于未遷移的存量應用和遷移完成的 Service Mesh 應用依然能保持業(yè)務(wù)上的互通。
面對上述這些真實(shí)而又合理的訴求,在進(jìn)行 Service Mesh 微服務(wù)平臺搭建時(shí),必然會(huì )存在兩種框架并存的場(chǎng)景,如下圖所示,左邊是未遷移的存量服務(wù),右邊是容器化并 Service Mesh 化的試點(diǎn)服務(wù),但這種模式服務(wù)間卻是互不相同,且無(wú)法統一治理。
然而兩種框架并存時(shí),如何服務(wù)間互通,統一治理?
在業(yè)內流行這樣一句話(huà):計算機科學(xué)領(lǐng)域的任何問(wèn)題都可以通過(guò)增加一個(gè)間接的中間層來(lái)解決。
同樣,我們可以針對 Service Mesh 的控制平面做些文章,通過(guò)自定義控制插件(WASM)將 Spring Cloud 框架中原有注冊中心的功能納入進(jìn)來(lái),由控制平面提供原有服務(wù)注冊與發(fā)現的能力,并結合 Istio 中入口網(wǎng)關(guān) Ingress 和 ServiceEntry 資源配置,以實(shí)現服務(wù)間互通,統一治理,整個(gè)實(shí)現邏輯架構如下圖所示。
至此,實(shí)現了基于Spring Cloud和 Istio 兩種框架的并存。
2.4.4 應用遷移
到這里,已經(jīng)完成了 Service Mesh 微服務(wù)平臺的搭建,在這樣的平臺上我們如何將Spring Cloud 應用逐步向 Service Mesh 遷移?
2.4.4.1 去除重疊功能
先來(lái)看一下 Spring Cloud 框架與 Istio 框架的功能重疊情況:
從上表功能對比分析,存在大量的重疊功能,需將Spring Cloud 與 Istio 中重疊功能去除,缺失功能保留,理論上可輕松去重。對于 Spring Cloud 而言,這些重疊功能大部分只需去除 pom.xml 中依賴(lài)包、相關(guān)配置及代碼中注解即可輕松完成,剩余一個(gè)相對干凈的應用。
2.4.4.2 應用注入
應用注入是指在將應用服務(wù)部署到網(wǎng)格時(shí),將 Sidecar 注入到應用服務(wù)中,以實(shí)現網(wǎng)格的代理。
Sidecar 注入,分為手動(dòng)注入和自動(dòng)注入:
● 手動(dòng)注入:通過(guò)手動(dòng)執行 istioctl kube-inject 來(lái)重新構造應用的 CRD yaml。
● 自動(dòng)注入:通過(guò) Kubernetes 的 mutable webhook 回調 istio-sidecar-injector 服務(wù)來(lái)重新構造應用的 CRD yaml。
如下圖所示:
無(wú)論是手動(dòng)注入還是自動(dòng)注入,Sidecar 注入的本質(zhì)是將運行 Sidecar 所需要的鏡像地址、啟動(dòng)參數、所連接的 Istio 集群及配置信息填充到注入模版,并添加到應用的 CRD yaml 中,最終通過(guò) Kubernetes 持久化資源并拉起應用和 Sidecar 的 POD。
此時(shí),應用已成功遷移部署到 Service Mesh 。
03.總結
正如《數字化的力量》一書(shū)中所說(shuō):
這種升級改造和技術(shù)范式的轉換并不是在一夜之間完成的,數字技術(shù)需要通過(guò)在社會(huì )經(jīng)濟的各個(gè)方面進(jìn)行逐步應用,通過(guò)量的積累進(jìn)而最終引起質(zhì)的飛躍,使我們從新的技術(shù)范式的形成階段進(jìn)入到穩定發(fā)展階段。
郭為.數字化的力量[M]. 北京:機械工業(yè)出版社,2022.
這篇文章從傳統微服務(wù)架構開(kāi)始一步步介紹到Service Mesh,并提出了傳統微服務(wù)架構面臨的挑戰,針對現狀,為了更好的滿(mǎn)足市場(chǎng)需求,而不被市場(chǎng)淘汰,介紹了傳統微服務(wù)如何平滑遷移到 Service Mesh 的過(guò)程,并給出了一些解決方案、步驟及思路,供大家參考。
參考資料
郭為.數字化的力量[M]. 北京:機械工業(yè)出版社,2022.
https://istio.io/latest/docs/concepts/what-is-istio/
劉俊海.Service Mesh微服務(wù)架構設計[M].北京:機械工業(yè)出版社,2019.
https://mp.weixin.qq.com/s/y9PZLgHhVcdsMuTzAyIMsQ
https://www.servicemesher.com/blog/service-mesh-rebuild-microservice-market/
https://mp.weixin.qq.com/s/-MszFJORuDJKf3V5ndyimw
https://www.servicemesher.com/blog/netease-yeation-service-mesh/
(下篇完)