什么是 Service mesh
Service Mesh 直譯過(guò)來(lái)是服務(wù)網(wǎng)格,目的是解決系統(tǒng)架構(gòu)微服務(wù)化后的服務(wù)間通信和治理問(wèn)題。服務(wù)網(wǎng)格由 sidecar 節(jié)點(diǎn)組成。在介紹 service mesh 之前,我們先來(lái)看一下什么是 sidecar.
Sidecar 在軟件系統(tǒng)架構(gòu)中特指邊車(chē)模式。這個(gè)模式的靈感來(lái)源于我們生活中的邊三輪:即在兩輪摩托車(chē)的旁邊添加一個(gè)邊車(chē)的方式擴(kuò)展現(xiàn)有的服務(wù)和功能。在絕地求生吃雞游戲中,摩托車(chē)是無(wú)敵的,應(yīng)該也與這個(gè)模式有關(guān)吧
這個(gè)模式的精髓在于實(shí)現(xiàn)了數(shù)據(jù)面(業(yè)務(wù)邏輯)和控制面的解耦:原來(lái)兩輪摩托車(chē)的駕駛者集中注意力跑賽道,邊車(chē)上的領(lǐng)航員專注周?chē)畔⒑偷貓D,專注導(dǎo)航。
具體到微服務(wù)架構(gòu)中,即給每一個(gè)微服務(wù)實(shí)例(也可以是每個(gè)宿主機(jī)host)同步部署一個(gè) sidecar proxy:
該 sidecar proxy 負(fù)責(zé)接管對(duì)應(yīng)服務(wù)的入流量和出流量。并將微服務(wù)架構(gòu)中以前有公共庫(kù)、framework實(shí)現(xiàn)的熔斷、限流、降級(jí)、服務(wù)發(fā)現(xiàn)、調(diào)用鏈分布式跟蹤以及立體監(jiān)控等功能從服務(wù)中抽離到該 proxy 中:
當(dāng)該 sidecar 在微服務(wù)中大量部署時(shí),這些 sidecar 節(jié)點(diǎn)自然就形成了一個(gè)網(wǎng)格:
這就是我們說(shuō)的 service mesh 了。對(duì) service mesh 有了一個(gè)感性認(rèn)識(shí)后,我們看一下 Linkerd 和 Conduit 的作者 William Morgan 在What’s a service mesh? And why do I need one?中是如何詮釋什么是 Service Mesh:
A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the service mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware.
Service Mesh 這個(gè)服務(wù)網(wǎng)絡(luò)專注于處理服務(wù)和服務(wù)間的通訊。其主要負(fù)責(zé)構(gòu)造一個(gè)穩(wěn)定可靠的服務(wù)通訊的基礎(chǔ)設(shè)施,并讓整個(gè)架構(gòu)更為的先進(jìn)和 Cloud Native。在工程中,Service Mesh 基本來(lái)說(shuō)是一組輕量級(jí)的與應(yīng)用邏輯服務(wù)部署在一起的服務(wù)代理,并且對(duì)于應(yīng)用服務(wù)是透明的。
Service Mesh的特點(diǎn)
是一個(gè)基礎(chǔ)設(shè)施
輕量級(jí)網(wǎng)絡(luò)代理,應(yīng)用程序間通訊的中間層
應(yīng)用程序無(wú)感知,對(duì)應(yīng)用程序透明無(wú)侵入
解耦應(yīng)用程序的重試/超時(shí)、監(jiān)控、追蹤和服務(wù)發(fā)現(xiàn)等控制層面的東西
Service Mesh 有哪些開(kāi)源實(shí)現(xiàn)
Service Mesh 的概念從2016年提出至今,已經(jīng)發(fā)展到了第二代。
第一代 service mesh 以Linkerd和Envoy為代表。
Linkerd 使用Scala編寫(xiě),是業(yè)界第一個(gè)開(kāi)源的service mesh方案。作者 William Morgan 是 service mesh 的布道師和踐行者。Envoy 基于C++ 11編寫(xiě),無(wú)論是理論上還是實(shí)際上,后者性能都比 Linkderd 更好。這兩個(gè)開(kāi)源實(shí)現(xiàn)都是以 sidecar 為核心,絕大部分關(guān)注點(diǎn)都是如何做好proxy,并完成一些通用控制面的功能。 但是,當(dāng)你在容器中大量部署 sidecar 以后,如何管理和控制這些 sidecar 本身就是一個(gè)不小的挑戰(zhàn)。于是,第二代 Service Mesh 應(yīng)運(yùn)而生。
第二代service mesh主要改進(jìn)集中在更加強(qiáng)大的控制面功能(與之對(duì)應(yīng)的 sidecar proxy 被稱之為數(shù)據(jù)面),典型代表有Istio和Conduit。
ISTIO 解析
Istio 是 Google 和 IBM 兩位巨人聯(lián)合 Lyft 的合作開(kāi)源項(xiàng)目。是當(dāng)前最主流的service mesh方案,也是事實(shí)上的第二代 service mesh 標(biāo)準(zhǔn)。
Google 和 IBM 之所以要帶上小弟 Lyft 一起玩耍是因?yàn)樗麄儾幌霃念^開(kāi)始做數(shù)據(jù)面的組件,于是在 Istio 中,直接把 Lyft 家的 Envoy 拿來(lái)做 sidecar. 除了sidecar, Istio中的控制面組件都是使用Go編寫(xiě)。Istio架構(gòu)如下圖所示:
對(duì)于一個(gè)僅提供服務(wù)與服務(wù)之間連接功能的基礎(chǔ)設(shè)施來(lái)說(shuō),Istio的架構(gòu)算不上簡(jiǎn)單。但是架構(gòu)中的各個(gè)組件的理念的確非常先進(jìn)和超前。
Envoy: 扮演sidecar的功能,協(xié)調(diào)服務(wù)網(wǎng)格中所有服務(wù)的出入站流量,并提供服務(wù)發(fā)現(xiàn)、負(fù)載均衡、限流熔斷等能力,還可以收集大量與流量相關(guān)的性能指標(biāo)。
Pilot: 負(fù)責(zé)部署在service mesh中的Envoy實(shí)例的生命周期管理。本質(zhì)上是負(fù)責(zé)流量管理和控制,是將流量和基礎(chǔ)設(shè)施擴(kuò)展解耦,這是Istio的核心。感性上,可以把Pilot看做是管理sidecar的sidecar, 但是這個(gè)特殊的sidacar并不承載任何業(yè)務(wù)流量。Pilot讓運(yùn)維人員通過(guò)Pilot指定它們希望流量遵循什么規(guī)則,而不是哪些特定的pod/VM應(yīng)該接收流量。有了 Pilot 這個(gè)組件,我們可以非常容易的實(shí)現(xiàn) A/B 測(cè)試和金絲雀Canary測(cè)試:
Mixer: Mixer在應(yīng)用程序代碼和基礎(chǔ)架構(gòu)后端之間提供通用中介層。它的設(shè)計(jì)將策略決策移出應(yīng)用層,用運(yùn)維人員能夠控制的配置取而代之。應(yīng)用程序代碼不再將應(yīng)用程序代碼與特定后端集成在一起,而是與Mixer進(jìn)行相當(dāng)簡(jiǎn)單的集成,然后Mixer負(fù)責(zé)與后端系統(tǒng)連接。也就是說(shuō),Mixer可以認(rèn)為是其他后端基礎(chǔ)設(shè)施(如數(shù)據(jù)庫(kù)、監(jiān)控、日志、配額等)的sidecar proxy:
Istio-Auth: 提供強(qiáng)大的服務(wù)間認(rèn)證和終端用戶認(rèn)證,使用交互TLS,內(nèi)置身份和證書(shū)管理。可以升級(jí)服務(wù)網(wǎng)格中的未加密流量,并為運(yùn)維人員提供基于服務(wù)身份而不是網(wǎng)絡(luò)控制來(lái)執(zhí)行策略的能力。Istio的未來(lái)版本將增加細(xì)粒度的訪問(wèn)控制和審計(jì),以使用各種訪問(wèn)控制機(jī)制(包括基于屬性和角色的訪問(wèn)控制以及授權(quán)鉤子)來(lái)控制和監(jiān)視訪問(wèn)您的服務(wù),API或資源的人員。
Istio 的很多設(shè)計(jì)理念的確非常吸引人,又有 Google 和 IBM 兩個(gè)巨人加持,理論上這條賽道上的其他選手都可以直接退賽回家了。但是 Istio 發(fā)布的前幾個(gè)版本都在可用性和易用性上都差強(qiáng)人意。此外,service mesh 布道師、 Linkerd 作者 William Morgan 也心有不甘。因此, William Morgan一方面在2017年7月11日,Linkerd 發(fā)布版本 1.1.1,宣布和 Istio 項(xiàng)目集成,一方面夜以繼日的開(kāi)發(fā)Conduit.
CONDUIT 解析
Conduit 各方面的設(shè)計(jì)理念與 Istio 非常類(lèi)似。但是作者拋棄了 Linkerd, 使用Rust重新編寫(xiě)了sidecar, 叫做Conduit Data Plane, 控制面則由Go編寫(xiě)的Conduit Control Plane接管:
從Conduit的架構(gòu)看,作者號(hào)稱Conduit吸取了很多 Linkerd 的 Scala 的教訓(xùn),比 Linkerd 更快,還輕,更簡(jiǎn)單,控制面功能更強(qiáng)可信度還是挺高的。與Istio比較,個(gè)人其實(shí)更喜歡Conduit的架構(gòu),一方面是它足夠簡(jiǎn)單,另一方面對(duì)于要解決的問(wèn)題足夠聚焦。
NGINMESH 湊熱鬧?
Service Mesh 最基礎(chǔ)的功能畢竟是 sidecar proxy. 提到 proxy 怎么能夠少了 nginx? 我想nginx自己也是這么想的吧?毫不意外,nginx也推出了其 service mesh 的開(kāi)源實(shí)現(xiàn):nginMesh.
不過(guò),與 William Morgan 的死磕策略不同,nginMesh 從一開(kāi)始就沒(méi)有想過(guò)要做一套完整的第二代Service Mesh 開(kāi)源方案,而是直接宣布兼容Istio, 作為Istio的 sidecar proxy. 由于 nginx 在反向代理方面廣泛的使用,以及運(yùn)維技術(shù)的相對(duì)成熟,nginMesh在sidecar proxy領(lǐng)域應(yīng)該會(huì)有一席之地。
反思
對(duì)于大規(guī)模部署微服務(wù)(微服務(wù)數(shù)>1000)、內(nèi)部服務(wù)異構(gòu)程度高(交互協(xié)議/開(kāi)發(fā)語(yǔ)言類(lèi)型>5)的場(chǎng)景,使用service mesh是合適的。但是,可能大部分開(kāi)發(fā)者面臨的微服務(wù)和內(nèi)部架構(gòu)異構(gòu)復(fù)雜度是沒(méi)有這么高的。在這種情況下,使用service mesh就是一個(gè)case by case的問(wèn)題了。
理論上,service mesh 實(shí)現(xiàn)了業(yè)務(wù)邏輯和控制的解耦。但是這并不是免費(fèi)的。由于網(wǎng)絡(luò)中多了一跳,增加了性能和延遲的開(kāi)銷(xiāo)。另一方面,由于每個(gè)服務(wù)都需要sidecar, 這會(huì)給本來(lái)就復(fù)雜的分布式系統(tǒng)更加復(fù)雜,尤其是在實(shí)施初期,運(yùn)維對(duì)service mesh本身把控能力不足的情況下,往往會(huì)使整個(gè)系統(tǒng)更加難以管理。
本質(zhì)上,service mesh 就是一個(gè)成規(guī)模的sidecar proxy集群。那么如果我們想漸進(jìn)的改善我們的微服務(wù)架構(gòu)的話,其實(shí)有針對(duì)性的部署配置gateway就可以了。該gateway的粒度可粗可細(xì),粗可到整個(gè)api總?cè)肟冢?xì)可到每個(gè)服務(wù)實(shí)例。并且 Gateway 只負(fù)責(zé)進(jìn)入的請(qǐng)求,不像 Sidecar 還需要負(fù)責(zé)對(duì)外的請(qǐng)求。因?yàn)?Gateway 可以把一組服務(wù)給聚合起來(lái),所以服務(wù)對(duì)外的請(qǐng)求可以交給對(duì)方服務(wù)的 Gateway。于是,我們只需要用一個(gè)只負(fù)責(zé)進(jìn)入請(qǐng)求的 Gateway 來(lái)簡(jiǎn)化需要同時(shí)負(fù)責(zé)進(jìn)出請(qǐng)求的 Sidecar 的復(fù)雜度。
小結(jié):service mesh不是銀彈。對(duì)于大規(guī)模部署、異構(gòu)復(fù)雜的微服務(wù)架構(gòu)是不錯(cuò)的方案。對(duì)于中小規(guī)模的微服務(wù)架構(gòu),不妨嘗試一下更簡(jiǎn)單可控的gateway, 在確定gateway已經(jīng)無(wú)法解決當(dāng)前問(wèn)題后,再嘗試漸進(jìn)的完全service mesh化。
擴(kuò)展閱讀