正確入門Service Mesh:起源、發展和現狀

雲棲號資訊:【點擊查看更多行業資訊
在這裏您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

image

阿里妹導讀:Service Mesh早已不是一個新興的概念,但大家對Service Mesh的探索依然火熱。本文將依次講解Service Mesh的定義(什麼是Service Mesh)、起因(爲什麼需要Service Mesh)和現狀(Service Mesh的主流實現),希望通過淺顯易懂的介紹,儘量幫助大家更好地理解Service Mesh。

引言

隨着雲原生時代的來臨,微服務架構與容器化部署模式越來越流行,從原來的新潮詞彙慢慢演變成爲現代IT企業的技術標配。曾經被認爲理所當然的巨無霸單體應用,被擁抱了微服務的架構師們精心拆分成了一個又一個小而獨立的微服務,接着再被擁抱了容器化的工程師們打包成了自帶依賴的Docker鏡像,最後通過某種神祕的DevOps流水線持續運送到前線 —— 也就是無人不知的 —— 風暴降生·谷歌之子·打碎鐐銬者·雲時代操作系統·Kubernetes —— 之中部署和運行。

聽上去似乎一切都很美好?顯然不是,這世上永遠沒有免費的午餐。所有美好的東西都會有它的陰暗面,微服務也不例外:

  • 原來只需要部署和管理單個應用,現在一下裂變成了好幾個,運維管理成本成倍上升。
  • 原來各個模塊之間的交互可以直接走應用內調用(進程間通信),現在都給拆分到了不同進程甚至節點上,只能使用複雜的RPC通訊。

難道辛辛苦苦落地了微服務,只能一邊在老闆面前強撐着“沒問題,一切安好”,另一邊默默忍受着研發與運維的私下抱怨?顯然也不是。對於以“偷懶”著稱的程序員們,辦法總是比困難多。比如上面第1個問題,雲原生所倡導的DevOps和容器化,就是一劑幾乎完美的解藥:通過自動化的CI/CD流水線,多應用的集成構建部署變得更加快捷;通過Docker鏡像和K8s編排,多應用的資源調度運維管理也變得不那麼痛苦。至於第2個問題,那就該看本文的主角 —— Service Mesh(服務網格),是如何力挽狂瀾,近乎完美地解決微服務之間的通訊問題了。

什麼是 Service Mesh?

Service Mesh 誕生

從概念到落地?不,是從落地到概念。

image

時間回到2016年9⽉29⽇,那是一個即將放假迎來普天同慶的日子(是說我們)。在Buoyant公司內部一次關於微服務的分享會上,“Service Mesh” ,這個接下來幾年佔據各種雲原生頭條的 buzz word,就這麼被造出來了。不得不說,起名真是門藝術,Micro-Services -> Service Mesh,多麼承前啓後和順其自然啊,光看名字就能很形象地理解這玩意兒所做的事情:把微服務的各個service(服務)節點,用一張mesh(網格)連接起來。就這樣,原本被拆散得七零八落的微服務們,又被 Service Mesh 這張大網緊密得連接到了一起;即使依然天各一方(進程間隔離),但也找回了當年一起擠在單體應用內抱團撒歡的親密感(通信更容易)。

最難得的是,這麼好的一個概念居然不是從PPT裏走出來的,人家是真的有貨(這讓廣大PPT創業者們情何以堪):2016年1⽉15⽇,Service Mesh的第一個實現Linkerd [1]就已經完成了初次發佈,緊接着次年1月23日 加入了CNCF,同年4月25日發佈了 1.0版本。對於Buoyant公司而言,這也許只是無心插柳的一小步,但卻是雲原生領域邁向成熟的一大步。幾年後的今天,Service Mesh 概念早已深入人心,各種生產級實現和大規模實踐也已遍地開花,但請不要忘記這一切背後的功臣、Service Mesh革命先驅、Buoyant公司CEO —— William Morgan,以及他對Service Mesh的定義和思考:What's a service mesh? And why do I need one?[2]

Service Mesh 定義

別廢話了,我沒工夫聽你說這麼多,請用一句話跟我解釋 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.

這就是上面那位又帥又能寫的CEO,對Service Mesh的權威定義。我把其中一些重點詞彙做了高亮:

  • “dedicated infrastructure layer”:Service Mesh 不是用來解決業務領域問題的,而是一層專門的基礎設施(中間件)。
  • “service-to-service communication”:Service Mesh 的定位很簡單也很清晰,就是用來處理服務與服務之間的通訊。
  • “reliable delivery of requests”:服務間通訊爲什麼需要特殊處理?因爲網絡是不可靠的,Service Mesh 的願景就是讓服務間的請求傳遞變得可靠。
  • “cloud native application”:Service Mesh 從一開始就是爲現代化的雲原生應用而生,瞄準了未來的技術發展趨勢。
  • “network proxies”:具體 Service Mesh 應該怎麼實現?典型方式都是通過一組輕量級的網絡代理,在應用無感知的情況下偷偷就把這事給幹了。
  • “deployed alongside application code”:這些網絡代理一定是跟應用部署在一起,一對一近距離貼心服務(比房產中介專一得多);否則,如果應用與代理之間也還是遠程不靠譜通訊,這事兒就沒完了。

Service Mesh 形態

想致富,先修路;但大馬路可不是給馬走的,是給更現代化的汽車。

image

左邊這張圖是Linkerd的部署示意圖,其中每個微服務所處的主機(host)或容器組(pod)中都會部署一個Linkerd代理軟件,用於代理微服務應用實例之間的RPC調用。對於應用而言,這一切都是無感知的:它還是照常發起自己的RPC調用,只是不再需要關心對端服務方的地址,因爲服務發現都由代理節點給cover了。

右邊是一張更高維和抽象的大圖,可以更形象地理解 Service Mesh 的邏輯形態 —— 想象這就是一個生產級的大規模微服務集羣,其中部署了上百個服務實例以及對應的 Service Mesh 代理節點;所有微服務之間的通訊都會流經這些密密麻麻的代理節點,它們共同組成了一張川流不息的現代化交通網格。

爲什麼需要 Service Mesh ?

微服務的崛起

The Big Bang:大爆炸後的混亂之治。

image

大多數人都曾經歷過那個單體應用爲王的時代。所謂“單體”(Monolithic),就是把所有組件都塞在同一個應用內,因此這些組件天然就緊密聯繫在一起:基於相同技術棧開發、訪問共享的數據庫、共同部署運維和擴容。同時,這些組件之間的通訊也趨向於頻繁和耦合 —— 不過就是一句函數調用的事,何樂而不爲。這樣做本身並沒什麼錯,畢竟那時的軟件系統相對簡單,可能一個人寫個兩萬行代碼的單體應用,就能輕鬆搞定所有業務場景。

天下大事,分久必合,合久必分。現代化軟件系統的複雜度不斷提升,協作人數也越來越多,單體應用的固有侷限性開始暴露。就彷彿宇宙大爆炸前的那個奇點,單體應用開始加速膨脹,最終在幾年前達到了臨界點,然後“砰”的一聲就炸開了。就這樣,微服務時代王者降臨,讓軟件開發重新變得“小而美”:

  • 單⼀職責:拆分後的單個微服務,通常只負責單個高內聚自閉環功能,因此很易於開發、理解和維護。
  • 架構靈活:不同微服務應用之間在技術選型層面幾乎是獨立的,可以⾃由選擇最適合的技術棧。
  • 部署隔離:相比巨無霸單體應用,單個微服務應用的代碼和產物體積大大減少,更容易持續集成和快速部署;同時,通過進程級別的隔離,也不再像單體應用一樣只能同生共死,故障隔離效果顯著提升。
  • 獨⽴擴展:單體應用時代,某個模塊如果存在資源瓶頸(e.g. CPU/內存),只能跟隨整個應用一起擴容,白白浪費很多資源。微服務化後,擴展的粒度細化到了微服務級別,可以更精確地按需獨立擴展。

但顯然,微服務也不是銀彈。大爆炸雖然打破了單體應用的獨裁統治,但那一聲聲炸裂之後的微服務新宇宙,顯然也不會立即就塵埃落定,而是需要經歷很長一段時間的混亂之治。適應了單體時代的開發者們,被迫需要擁抱微服務所帶來的一系列變化。其中最大的變化,就是服務間通訊:

如何找到服務的提供⽅?

微服務通訊必須走遠程過程調用(HTTP/REST本質上也屬於RPC),當其中一個應用需要消費另一個應用的服務時,無法再像單體應用一樣通過簡單的進程內機制(e.g. Spring的依賴注入)就能獲取到服務實例;你甚至都不知道有沒有這個服務方。

如何保證遠程調⽤的可靠性?

既然是RPC,那必然要走IP網絡,而我們都知道網絡(相比計算和存儲)是軟件世界裏最不可靠的東西。雖然有TCP這種可靠傳輸協議,但頻繁丟包、交換機故障甚至電纜被挖斷也常有發生;即使網絡是好的,如果對方機器宕機了,或者進程負載過高不響應呢?

如何降低服務調⽤的延遲?

網絡不只是不可靠,還有延遲的問題。雖然相同系統內的微服務應用通常都部署在一起,同機房內調用延遲很小;但對於較複雜的業務鏈路,很可能一次業務訪問就會包括數十次RPC調用,累積起來的延遲就很可觀了。

如何保證服務調⽤的安全性?

網絡不只是不可靠和有延遲,還是不安全的。互聯網時代,你永遠不知道屏幕對面坐的是人還是狗;同樣,微服務間通訊時,如果直接走裸的通訊協議,你也永遠不知道對端是否真的就是自己人,或者傳輸的機密信息是否有被中間人偷聽。

服務通訊:石器時代

毛主席說:自己動手,豐衣足食。

image

爲了解決上述微服務引入的問題,最早那批喫螃蟹的工程師們,開始了各自的造輪子之旅:

  • 服務發現(Service Discovery):解決“我想調用你,如何找到你”的問題。
  • 服務熔斷(Circuit Breaker):緩解服務之間依賴的不可靠問題。
  • 負載均衡(Load Balancing):通過均勻分配流量,讓請求處理更加及時。
  • 安全通訊:包括協議加密(TLS)、身份認證(證書/簽名)、訪問鑑權(RBAC)等。

用自己的代碼解決問題,這確實是程序員們能幹出來的事,沒毛病。But,時間都去哪了?

  • 重複造輪子:需要編寫和維護⼤量非功能性代碼,如何集中精力專注業務創新?
  • 與業務耦合:服務通訊邏輯與業務代碼邏輯混在一起,動不動還會遇到點匪夷所思的分佈式bug。

服務通訊:摩登時代

社會主義精神:共享和複用。

image

更有思想覺悟的那批工程師們坐不住了:你們這是違背了共享和複用原則,對不起GNU那幫祖師爺!於是,各種高質量、標準化、期望能大一統的精品輪子們應運而生,包括 Apache Dubbo(手動置頂)、Spring Cloud、Netflix OSS、gRPC 等等等。

這些可複用的類庫和框架,確確實實帶來了質量和效率上的大幅提升,但是足夠好使了嗎?Not enough:

  • 並非完全透明:程序員們仍然需要正確理解和使⽤這些庫,上手成本和出錯概率依然很高。
  • 限制技術選擇:使用這些技術後,應用很容易就會被對應的語⾔和框架強綁定(vendor-lock)。
  • 維護成本高:庫版本升級,需要牽連應⽤一起重新構建和部署;麻煩不說,還要祈禱別出故障。

服務通訊:新⽣代

Service Mesh:我只是一個搬運工而已。

image

Service Mesh 的誕生,徹底解決了上述所有問題。聽上去很神奇,究竟是如何辦到的呢?簡單來說,Service Mesh 就是通過 Sidecar模式[3] ,將上述類庫和框架要乾的事情從應用中徹底剝離了出來,並統一下沉到了基礎設施層。這是一種什麼思想?這是一種古老操作系統中早就有了的抽象和分層思想(應用程序並不需要關心網絡協議棧),也是一種現代雲計算平臺自底向上逐步託管的軟件服務化思想(IaaS -> CaaS -> PaaS -> SaaS)。

上述幾張 Service Mesh 的演進圖,參考自 Service Mesh Pattern[4] 一文。

Service Mesh 主流實現

注:以下內容來自於資料蒐集整理,僅供參考,更進一步學習請以最新權威資料爲準。

主流實現概覽

image

Service Mesh 的主流實現包括:

  • Linkerd:背後公司是Buoyant,開發語⾔使用Scala,2016年1⽉15日初次發佈,2017年1⽉23日加入CNCF,2018年5⽉1⽇發佈1.4.0版本。
  • Envoy:背後公司是Lyft,開發語言使用C++ 11,2016年9月13日初次發佈,2017年9⽉14日加⼊CNCF,2018年3月21日發佈1.6.0版本。
  • Istio:背後公司是Google和IBM,開發語言使用Go,2017年5⽉月10日初次發佈,2018年3⽉31日發佈0.7.1版本。
  • Conduit:背後公司也是Buoyant,開發語言使用Rust和Go,2017年12月5日初次發佈,2018年4⽉27日發佈0.4.1版本。

Linkerd 簡介

image

Linkerd的核心組件就是一個服務代理,因此只要理清它的請求處理流程,就掌握了它的核心邏輯:

  • 動態路由:根據上游服務請求參數,確定下游目標服務;除了常規的服務路由策略,Linkerd還可以通過這一層動態路由能力,支持灰度發佈、A/B測試、環境隔離等非常有價值的場景。
  • 服務發現:確定目標服務後,下一步就是獲取對應的實例的地址列表(e.g. 查詢service registry)。
  • 負載均衡:如果列表中有多個地址,Linkerd會通過負載均衡算法(e.g. Least Loaded、Peak EWMA)選擇其中⼀個合適的低延遲實例。
  • 執行請求:發送請求到上一步所選擇的實例,並記錄延遲和響應結果。
  • 重試處理:如果請求未響應,則選擇另⼀個實例重試(前提:Linkerd知道該請求是冪等的)。
  • 熔斷處理:如果發往某個實例的請求經常失敗,則主動從地址列表中剔除該實例。
  • 超時處理:如果請求超期(在給定的deadline時間點之前仍未返回),則主動返回失敗響應。
  • 可觀測性:Linkerd會持續收集和上報上述各種行爲數據,包括Metrics和Tracing。

Envoy 簡介

image

Envoy是一個高性能的Service Mesh軟件,主要包含如下特性:

  • 高性能:基於本地代碼(C++ 11)實現;相比之下,Linkerd是基於Scala編寫,肯定要慢不少。
  • 可擴展:L4和L7層代理功能均基於可插拔的 Filter Chain 機制(類比 netfilter、servlet filter)。
  • 協議升級:支持雙向、透明的 HTTP/1 to HTTP/2 代理能力。
  • 其他能力:服務發現(符合最終一致性)、負載均衡(支持區域感知)、穩定性(重試、超時、熔斷、限速、異常檢測)、可觀測性(統計/日誌/追蹤)、易於調試等。

Istio 簡介

image

Istio是一個管控/數據平面分離的完整Service Mesh套件,包含如下組件:

  • Envoy:構成數據平⾯(其他組件共同構成控制平⾯);可被替換爲其他代理(e.g. Linkerd, nginMesh)。
  • Pilot:負責流量管理(Traffic Management),提供平臺獨⽴的服務模型定義、API以及實現。
  • Mixer:負責策略與控制(Policies & Controls),核⼼功能包括:前置檢查、配額管理、遙測報告。
  • Istio-Auth:支持多種粒度的RBAC權限控制;支持雙向SSL認證,包括身份識別、通訊安全、祕鑰管理。

Istio 組件 - Pilot

image

Pilot組件是Istio服務網格中的“領航員”,負責管理數據平面的流量規則和服務發現。一個典型的應用場景就是灰度發佈(or 金絲雀發佈、藍綠部署):開發者通過Pilot提供的規則API,下發流量路由規則到數據平面的Envoy代理,從而實現精準的多版本流量分配(e.g. 將1%的流量分配到新版本服務)。

Istio 組件 - Mixer

image

Mixer組件是Istio服務網格中的“調音師”,既負責落實各種流量策略(如訪問控制、限速),也負責對流量進行觀測分析(如日誌、監控、追蹤)。這些能力都是通過前文提到的Envoy Filter Chain擴展機制實現:Mixer會分別在“請求路由前”(Pre-routing)擴展點和“請求路由後”(Post-routing)擴展點掛載自己的Filter實現。

Istio 組件 - Auth

image

Auth組件是Istio服務網格中的“安全員”,負責處理服務節點之間通信的認證(Authentification)和鑑權(Authorization)問題。對於認證,Auth支持服務之間的雙向SSL認證,可以讓通訊的雙方都彼此認可對方的身份;對於鑑權,Auth支持流行的RBAC鑑權模型,可以實現便捷和細粒度的“用戶-角色-權限”多級訪問控制。

Conduit 簡介

image

Conduit是由Buoyant公司出品的下一代 Service Mesh。作爲Istio的挑戰者,Conduit的整體架構與Istio類似也明確區分了管控平面和數據平面,但同時它還具備如下關鍵特性:

  • 輕量快速:Conduit的數據平面是基於原生的Rust語言編寫,非常輕量、快速和安全(Rust相比C/C++的最大改進點就是安全性)。單個代理的實際內存消耗(RSS)小於10mb,延遲的p99分位點小於1ms,基本相當於能爲應用程序提供免費(無額外開銷)的Service Mesh功能。
  • 安全保障:Conduit構建之初就考慮了雲原生環境的安全性,包括Rust語言內存安全性、默認TLS加密等。
  • 端到端可見性:Conduit可以自動測量和聚合服務的成功率、延遲與請求容量數據,讓開發者在無需變更應用代碼就能獲取到服務的完整行爲視圖。
  • Kubernetes增強:Conduit爲K8s集羣添加了可靠性、可見性和安全性,同時給予了開發者對自己應用程序運行時行爲的完全控制。

結語

本文從雲原生時代所面臨的微服務通訊問題入手,依次介紹了Service Mesh的起源、發展和現狀,希望能幫助讀者建立一個初步的理解和認知。

【雲棲號在線課堂】每天都有產品技術專家分享!
課程地址:https://yqh.aliyun.com/live

立即加入社羣,與專家面對面,及時瞭解課程最新動態!
【雲棲號在線課堂 社羣】https://c.tb.cn/F3.Z8gvnK

原文發佈時間:2020-07-28
本文作者:楚衡
本文來自:“阿里技術公衆號”,瞭解相關信息可以關注“阿里技術

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章