首先,看到Service Mesh這個詞,相信很多同學都聽說過這個詞,但是具體它是幹什麼的,每個人就各有各的理解了。我第一次系統地了解Service Mesh的時候,也是通過幫同事買課返現,意外地看到這個名詞,旺盛的好奇心迫使我點了進去。然後,不多時,我便一頭霧水的走了出來。啊這,裡面的彎彎繞繞比盥洗室之主還複雜啊!於是乎,在經過一段時間的學習,對Service Mesh有所了解之後,我決定寫下這篇文章與大家分享我的理解。
一、什麼是Service Mesh開門見山,先站在前輩的肩膀上給出定義:
Service Mesh這個詞的發明人,Buoyant的CEO William Morgan 如此解釋:服務網格是一個基礎設施層,用於處理服務間通信。雲原生應用有著複雜的服務拓撲,服務網格保證請求在這些拓撲中可靠地穿梭。在實際應用當中,服務網格通常是由一系列輕量級的網絡代理組成的,它們與應用程式部署在一起,但對應用程式透明。
Service Mesh,中文名叫作服務網格,用於處理服務間通信的基礎設施層,通常是一組與應用一起部署,但對應用透明的輕量級網絡代理。簡單來說就是將可以配置的代理層和服務部署在一起,作為微服務基礎設施層接管服務間的流量,並提供通用的服務註冊發現、負載均衡、身份驗證、精準路由、服務鑑權等基礎功能。
Service Mesh與傳統基礎設施層不同之處在於,它形成了一個分布式的互連代理網絡,以sidecar形式部署在服務兩側,服務對於代理無感知,且服務間所有通信都由代理進行路由。它最重要的變革,就是引入了數據面和控制面的概念,通過sidecar模式(原意是摩託車的邊車,用到軟體架構中,就是Sidecar應用是連接到父應用,並為其擴展或增強功能)將原本在SDK中的代碼獨立出來,用控制面代替配置中心的部分功能,以透明代理的形式提供安全、快速、可靠的服務間通信,同時也能實現微服務所需的基本組件功能。
實際上,Service Mesh 需要的基礎組件和傳統的微服務並沒有太大的差別,很多公司選擇自研控制面的原因,很多就是出於兼容老的微服務的基礎組件的考慮好的,我們總結一下之前的發言,Service Mesh到底是做什麼的:
數據面:代理了服務的所有通信。
控制面:運行期間的服務控制,如流量控制和配置管理等。
二、Service Mesh 的演進歷程1、sidecar時代Netflix是最早採用微服務的公司之一。為了跟上其增長速度,Netflix決定從龐大而單一的數據中心轉向基於雲的微服務架構,以實現高可用,大規模和速度。基於其成功案例,Netflix開源了許多工具/技術,為微服務架構提供支持。這個時候 Netflix發現開發多語言的SDK要耗費大量的人力,畢竟在Spring Cloud中的組件可不是一般的多,為每個語言開發一套,顯然所需花費的人力物力太大。於是乎,就想到了使用sidecar模式,把SDK裡的功能轉移到sidecar中。
所謂sidecar,其實就是一個部署在本地的代理伺服器,它既接管了入口流量,也接管了出口流量。把所有的sidecar組合到一起,就成了服務網格(Service Mesh)。
2、初代 Service Mesh在sidecar模式中,更多的是為了解決公司非主力語言的SDK開發問題,採取Adapter模式,非主力語言通過sidecar連接,而主力語言還是正常使用SDK的方式。
雖然sidecar能夠解決一些微服務時代的SDK問題,但許多一直存在於微服務架構中的問題卻沒有辦法處理。
1、缺乏統一的管控手段。比如 sidecar 的服務治理相關配置文件的維護,可能需要運維手動維護、無法集中管理,因為這個原因,控制面誕生了。2、雖然框架本身屏蔽了分布式系統通信的一些通用功能實現細節,但開發者卻要花更多精力去掌握和管理複雜的框架本身,在實際應用中,去追蹤和解決框架出現的問題也絕非易事(追蹤服務本身的問題倒還可以引入鏈路追蹤之類的方法)。3、框架以lib庫的形式和服務聯編,複雜項目依賴時的庫版本兼容問題非常棘手,同時,框架庫的升級也無法對服務透明,服務會因為和業務無關的lib庫升級而被迫升級隨著技術不斷發展,大家慢慢意識到統一流量處理模型的重要性,於是誕生了第一代Service Mesh,其中比較出名的是Linkerd和Envoy。在這一代Service Mesh中,它將分布式服務的通信抽象為單獨一層,在這一層中實現負載均衡、服務發現、認證授權、監控追蹤、流量控制等分布式系統所需要的功能,作為一個和服務對等的代理服務,和服務部署在一起,接管服務的流量,通過代理之間的通信間接完成服務之間的通信請求。這樣之前所說的sidercar未能解決的問題也得到了解決。
3、第二代 Service Mesh由於第一代Service Mesh由一系列獨立運行的單機代理服務構成,為了降低開發運維人員的維護成本,提供統一的上層運維入口,演化出了集中式的控制面板,所有的單機代理組件通過和控制面板交互進行網絡拓撲策略的更新和單機數據的匯報。新一代Service Mesh,比如大家熟知的Istio了。它引入了控制面的概念,讓Service Mesh成為完全體,如下圖所示:
Istio使用Envoy作為數據面,控制面和Kubernetes 深度綁定,早期版本將流量治理的功能放在 mixer 中,形成了一套完整的 Service Mesh 解決方案。控制面負責了資源管理、配置下發、證書管理等功能,解決了數據面配置難以管理的問題。
至此,我們也大體地對Service Mesh有了初步的印象,接下來,咱一起分析分析,Service Mesh到底解決了傳統微服務架構中的哪些痛點吧!
三、Service Mesh的優勢1、語言無關早在sidecar時代,Netflix將SDK的功能集成到sidecar中就體現了Service Mesh的優勢。雖然我們在微服務架構也經常提到這個優點,但是對於傳統的微服務架構而言,Service Mesh 做到了真正的語言無關:傳統的微服務架構要為各種語言開發SDK,而Service Mesh將SDK的功能集成到sidecar中,實現了真正的語言無關性。
2、只關注業務邏輯Service Mesh與傳統微服務相比,屏蔽了分布式系統通信的複雜性,將可以配置的代理層和服務部署在一起,作為微服務基礎設施層接管服務間的流量,並提供通用的服務註冊發現、負載均衡、身份驗證、精準路由、服務鑑權等基礎功能。
3、基礎設施獨立演進傳統微服務架構中,業務代碼和框架、SDK等全都混合在一起,框架想要升級就會變得非常困難而且被動,一個地方有變動,所有相關的項目都需要升級。當微服務的數量變多時,想要在公司內推動框架的全量升級基本上就和重構差不多了(正好我們公司的項目在升級重構)。而Service Mesh 架構將框架中和業務無關的通用功能放在sidecar中,升級時只要升級sidecar就可以了,這樣做到了基礎設施的獨立演進。
當然,這樣也會導致Service Mesh拉長了網絡請求的軌跡,在一套標準的雲原生環境裡,我們的流量可能需要先經過這麼幾個步驟:
集群外的負載均衡器 → 集群網關 → Service Mesh的Ingress → Sidecar → 業務服務而且,後續鏈路每多一個業務服務,都會額外流經一個 Sidecar,即便如此多的基礎設施名義上是為了保障業務穩定性,但每一個節點,也都同樣會帶來額外的隱患,一定程度上會降低通信系統性能,並增加系統資源開銷。
4、簡化系統網關的功能實際上 sidecar 本身就是一個網關,或者說是反向代理,自然可以將以前 Nginx/Kong 之類的系統網關遷移到sidecar上來,這樣就可以維護一套統一的代碼。更進一步,可以將以前邊緣網關的工作,比如鑑權、trace初始化等工作下沉到 sidecar 上,進一步簡化系統網關的功能。但是,同時額外引入的大量Service Mesh服務實例的運維和管理也是一個挑戰。
四、一點感觸整體來看,如果業務還處在一個起步階段,還是不適合使用Service Mesh來進行開發,因為架構演進的一個重要的原則,就是組織架構要和技術架構相匹配,Service Mesh適合重構更勝於從零開始。
記得在剛剛學習Service Mesh的時候,有大佬曰:Service Mesh是微服務時代的TCP協議,歷史總是驚人的相似。為了解決端到端的字節碼通信問題,TCP協議誕生,讓多機通信變得簡單可靠;微服務時代,Service Mesh應運而生,屏蔽了分布式系統的諸多複雜性,讓開發者可以回歸業務,聚焦真正的價值。
到底是忠實於技術,還是回歸於業務,對於我這樣的普通程式設計師而言,還是太過遙遠,但是卻能讓我們慢慢地看清自己的道路。
正如我的籤名所言,一步一天,是為通天,不積跬步,又如何能通向自己的夢想呢?