(點選上方公眾號,可快速關註)
來源:行思錄 ,
liudanking.com/arch/service-mesh-及其主流開源實現解析/
什麼是 Service mesh
Service Mesh 直譯過來是 服務網格,目的是解決系統架構微服務化後的服務間通訊和治理問題。服務網格由 sidecar 節點組成。在介紹 service mesh 之前,我們先來看一下什麼是 sidecar.
Sidecar 在軟體系統架構中特指邊車樣式。這個樣式的靈感來源於我們生活中的邊三輪:即在兩輪摩托車的旁邊新增一個邊車的方式擴充套件現有的服務和功能。在絕地求生吃雞遊戲中,摩托車是無敵的,應該也與這個樣式有關吧
這個樣式的精髓在於實現了資料面(業務邏輯)和控制面的解耦:原來兩輪摩托車的駕駛者集中註意力跑賽道,邊車上的領航員專註周圍資訊和地圖,專註導航。
具體到微服務架構中,即給每一個微服務實體(也可以是每個宿主機host)同步部署一個 sidecar proxy:
該 sidecar proxy 負責接管對應服務的入流量和出流量。並將微服務架構中以前有公共庫、framework實現的熔斷、限流、降級、服務發現、呼叫鏈分散式跟蹤以及立體監控等功能從服務中抽離到該 proxy 中:
當該 sidecar 在微服務中大量部署時,這些 sidecar 節點自然就形成了一個網格:
這就是我們說的 service mesh 了。對 service mesh 有了一個感性認識後,我們看一下 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 這個服務網路專註於處理服務和服務間的通訊。其主要負責構造一個穩定可靠的服務通訊的基礎設施,並讓整個架構更為的先進和 Cloud Native。在工程中,Service Mesh 基本來說是一組輕量級的與應用邏輯服務部署在一起的服務代理,並且對於應用服務是透明的。
Service Mesh的特點
-
是一個基礎設施
-
輕量級網路代理,應用程式間通訊的中間層
-
應用程式無感知,對應用程式透明無侵入
-
解耦應用程式的重試/超時、監控、追蹤和服務發現等控制層面的東西
Service Mesh 有哪些開源實現
Service Mesh 的概念從2016年提出至今,已經發展到了第二代。
第一代 service mesh 以 Linkerd 和 Envoy 為代表。
Linkerd 使用Scala編寫,是業界第一個開源的service mesh方案。作者 William Morgan 是 service mesh 的佈道師和踐行者。Envoy 基於C++ 11編寫,無論是理論上還是實際上,後者效能都比 Linkderd 更好。這兩個開源實現都是以 sidecar 為核心,絕大部分關註點都是如何做好proxy,並完成一些通用控制面的功能。 但是,當你在容器中大量部署 sidecar 以後,如何管理和控制這些 sidecar 本身就是一個不小的挑戰。於是,第二代 Service Mesh 應運而生。
第二代service mesh主要改進集中在更加強大的控制面功能(與之對應的 sidecar proxy 被稱之為資料面),典型代表有 Istio 和 Conduit。
ISTIO 解析
Istio 是 Google 和 IBM 兩位巨人聯合 Lyft 的合作開源專案。是當前最主流的service mesh方案,也是事實上的第二代 service mesh 標準。
Google 和 IBM 之所以要帶上小弟 Lyft 一起玩耍是因為他們不想從頭開始做資料面的元件,於是在 Istio 中,直接把 Lyft 家的 Envoy 拿來做 sidecar. 除了sidecar, Istio中的控制面元件都是使用Go編寫。Istio架構如下圖所示:
對於一個僅提供服務與服務之間連線功能的基礎設施來說,Istio的架構算不上簡單。但是架構中的各個元件的理念的確非常先進和超前。
-
Envoy: 扮演sidecar的功能,協調服務網格中所有服務的出入站流量,並提供服務發現、負載均衡、限流熔斷等能力,還可以收集大量與流量相關的效能指標。
-
Pilot: 負責部署在service mesh中的Envoy實體的生命週期管理。本質上是負責流量管理和控制,是將流量和基礎設施擴充套件解耦,這是Istio的核心。感性上,可以把Pilot看做是管理sidecar的sidecar, 但是這個特殊的sidacar並不承載任何業務流量。Pilot讓運維人員透過Pilot指定它們希望流量遵循什麼規則,而不是哪些特定的pod/VM應該接收流量。有了 Pilot 這個元件,我們可以非常容易的實現 A/B 測試和金絲雀Canary測試:
-
Mixer: Mixer在應用程式程式碼和基礎架構後端之間提供通用中介層。它的設計將策略決策移出應用層,用運維人員能夠控制的配置取而代之。應用程式程式碼不再將應用程式程式碼與特定後端整合在一起,而是與Mixer進行相當簡單的整合,然後Mixer負責與後端系統連線。也就是說,Mixer可以認為是其他後端基礎設施(如資料庫、監控、日誌、配額等)的sidecar proxy:
-
Istio-Auth: 提供強大的服務間認證和終端使用者認證,使用互動TLS,內建身份和證書管理。可以升級服務網格中的未加密流量,併為運維人員提供基於服務身份而不是網路控制來執行策略的能力。Istio的未來版本將增加細粒度的訪問控制和審計,以使用各種訪問控制機制(包括基於屬性和角色的訪問控制以及授權鉤子)來控制和監視訪問您的服務,API或資源的人員。
Istio 的很多設計理念的確非常吸引人,又有 Google 和 IBM 兩個巨人加持,理論上這條賽道上的其他選手都可以直接退賽回家了。但是 Istio 釋出的前幾個版本都在可用性和易用性上都差強人意。此外,service mesh 佈道師、 Linkerd 作者 William Morgan 也心有不甘。因此, William Morgan一方面在2017年7月11日,Linkerd 釋出版本 1.1.1,宣佈和 Istio 專案整合,一方面夜以繼日的開發Conduit.
CONDUIT 解析
Conduit 各方面的設計理念與 Istio 非常類似。但是作者拋棄了 Linkerd, 使用Rust重新編寫了sidecar, 叫做 Conduit Data Plane, 控制面則由Go編寫的 Conduit Control Plane接管:
從Conduit的架構看,作者號稱Conduit吸取了很多 Linkerd 的 Scala 的教訓,比 Linkerd 更快,還輕,更簡單,控制面功能更強可信度還是挺高的。與Istio比較,個人其實更喜歡Conduit的架構,一方面是它足夠簡單,另一方面對於要解決的問題足夠聚焦。
NGINMESH 湊熱鬧?
Service Mesh 最基礎的功能畢竟是 sidecar proxy. 提到 proxy 怎麼能夠少了 nginx? 我想nginx自己也是這麼想的吧 毫不意外,nginx也推出了其 service mesh 的開源實現:nginMesh.
不過,與 William Morgan 的死磕策略不同,nginMesh 從一開始就沒有想過要做一套完整的第二代Service Mesh 開源方案,而是直接宣佈相容Istio, 作為Istio的 sidecar proxy. 由於 nginx 在反向代理方面廣泛的使用,以及運維技術的相對成熟,nginMesh在sidecar proxy領域應該會有一席之地。
反思
對於大規模部署微服務(微服務數>1000)、內部服務異構程度高(互動協議/開發語言型別>5)的場景,使用service mesh是合適的。但是,可能大部分開發者面臨的微服務和內部架構異構複雜度是沒有這麼高的。在這種情況下,使用service mesh就是一個case by case的問題了。
理論上,service mesh 實現了業務邏輯和控制的解耦。但是這並不是免費的。由於網路中多了一跳,增加了效能和延遲的開銷。另一方面,由於每個服務都需要sidecar, 這會給本來就複雜的分散式系統更加複雜,尤其是在實施初期,運維對service mesh本身把控能力不足的情況下,往往會使整個系統更加難以管理。
本質上,service mesh 就是一個成規模的sidecar proxy叢集。那麼如果我們想漸進的改善我們的微服務架構的話,其實有針對性的部署配置gateway就可以了。該gateway的粒度可粗可細,粗可到整個api總入口,細可到每個服務實體。並且 Gateway 只負責進入的請求,不像 Sidecar 還需要負責對外的請求。因為 Gateway 可以把一組服務給聚合起來,所以服務對外的請求可以交給對方服務的 Gateway。於是,我們只需要用一個只負責進入請求的 Gateway 來簡化需要同時負責進出請求的 Sidecar 的複雜度。
小結:service mesh不是銀彈。對於大規模部署、異構複雜的微服務架構是不錯的方案。對於中小規模的微服務架構,不妨嘗試一下更簡單可控的gateway, 在確定gateway已經無法解決當前問題後,再嘗試漸進的完全service mesh化。
擴充套件閱讀
-
年度盤點2017之Service Mesh:群雄逐鹿烽煙起
http://www.servicemesh.cn/?/article/27
-
微博 Service Mesh 實踐
https://zhuanlan.zhihu.com/p/32430051
-
Pattern: Service Mesh
http://philcalcado.com/2017/08/03/pattern_service_mesh.html
看完本文有收穫?請轉發分享給更多人
關註「ImportNew」,提升Java技能