Service Mesh 初體驗

前言

計算機軟件技術發展到如今,軟件架構的演進無不朝着讓開發者可以更加輕鬆快捷地構建大型複雜應用的方向發展。容器技術最初是爲了解決運行環境的不一致問題而產生的,隨着不斷地發展,圍繞容器技術衍生出來愈來愈多的新方向。git

最近幾年,雲計算領域不斷地出現不少新的軟件架構模式,其中有一些很熱門的概念名詞如:雲原生、函數計算、Serverless、ServiceMesh等等,而本文將初窺一下ServiceMesh的面紗。下面結合本身的理解儘可能以通俗的話進行敘述。github

背景和定義

微服務及服務治理

在微服務以前的軟件開發中,每每經過一個應用的方式將全部的模塊都包括進去,並一塊兒編譯、打包、部署、運維。這種方式存在不少問題,因爲單個應用包含的東西太多,其中某個模塊出現問題或者須要更新那麼整個應用就須要從新部署。這種方式給開發和運維帶來了很大的麻煩。隨着應用的逐漸複雜,單個應用涉及的東西就會愈來愈多,慢慢地你們發現了其中不少的缺點,開始對服務進行劃分,將一個大的應用按照不一樣的維度進行劃分從而產生不少個小的應用,各應用之間會造成一個調用關係,每一個小的應用由不一樣的開發負責,你們各自部署和運維,這樣微服務就出現了。docker

因爲微服務中各應用部署在不一樣的機器上,服務之間須要進行通訊和協調,相比單個應用來講會麻煩不少。在同一個應用內不一樣方法之間的調用因爲在相同的內存中,在代碼編譯打包時已經進行了連接,所以調用是可尋址且快速的。微服務下不一樣服務之間的調用涉及到不一樣進程或者機器之間的通訊,通常須要經過第三方中間件的方式做爲中介和協調,因爲種種這些,面向微服務出現了不少中間件包括服務治理的框架。經過服務治理工具能夠管理其接入的全部應用,使得服務之間的通訊和協調更加簡單高效。編程

容器及容器編排

最初容器技術是爲了解決應用運行環境不一致的問題而出現的,避免在本地環境或者測試環境可以跑通,等發到生產環境卻出現問題。經過容器將程序及其依賴一塊兒打包到鏡像中去,將程序的鏡像在任何安裝並運行了容器軟件的機器上啓動若干的容器,每一個容器就是應用運行時的實例,這些實例通常擁有徹底相同的運行環境和參數。使得無論在任何機器上應用均可以表現出同樣的效果。這給開發、測試、運維帶來了極大的便利,再也不須要爲不一樣機器上構建相同的運行環境而頭大。且鏡像能夠Push到鏡像倉庫,這使得應用能夠進行很方便的遷移和部署。Docker就是一個應用普遍的容器技術。目前愈來愈多的應用以微服務的方式並經過容器進行部署,給了軟件開發極大的活力。後端

與微服務和服務治理的關係相似,愈來愈多的應用經過容器進行部署,使得集羣上的容器數量急劇增長,經過人工的管理和運維這些容器已經變得很艱難且低效,爲了解決諸多容器及容器之間的關係出現了不少編排工具,容器編排工具可以管理容器的整個生命週期。如Docker官方出的docker-compose和docker swarm,這兩個工具能實現批量容器的啓動和編排,但功能較爲簡單,不足以支撐大型的容器集羣。Google基於內部大量的容器管理經驗,開源出了Kubernetes項目,Kubernetes(K8S)是針對Google集羣上每週億級別的容器而設計的,具備很強大的容器編排能力和豐富的功能。K8S經過定義了不少資源,這些資源以聲明式的方式進行建立,能夠經過JSON或者YAML文件表示一個資源,K8S支持多種容器,但主流的是Docker容器,K8S提供了容器接入的相關標準,只要容器實現了該標準就能夠被K8S所編排。因爲K8S的功能較多,不在此一一敘述,有興趣能夠參考官方文檔或者ATA上搜索相關文章。安全

當某個公司的應用已經徹底微服務化後,選擇以容器的方式部署應用,此時能夠在集羣上部署K8S,經過K8S提供的能力進行應用容器的管理,運維能夠也能夠面向K8S進行工做。因爲K8S是目前使用最普遍的容器編排工具,所以成爲了容器編排的一個標準了,目前集團內部也有本身的容器和容器編排工具。網絡

面向以K8S爲表明的容器管理方式衍生出了一些新的技術。架構

雲原生

最近兩年雲原生被炒的很火,能夠在各處看到不少大佬對雲原生的高談闊論,下面直接拋出CNCF對雲原生的定義:框架

雲原生技術有利於各組織在公有云、私有云和混合雲等新型動態環境中,構建和運行可彈性擴展的應用。雲原生的表明技術包括容器、服務網格、微服務、不可變基礎設施和聲明式API。
這些技術可以構建容錯性好、易於管理和便於觀察的鬆耦合系統。結合可靠的自動化手段,雲原生技術使工程師可以輕鬆地對系統做出頻繁和可預測的重大變動。

在我看來,經過微服務的方式開發應用,以容器進行部署,使用K8S等容器編排工具進行容器集羣的管理,使得開發運維都面向K8S,這就是雲原生。雲原生能夠方便的構建應用,並對應用進行完整的監控,以及在應用針對不一樣流量時能進行快速的擴容和縮容。以下圖:less

雲原生主要包括四個部分:

  • 微服務
  • 容器
  • 持續集成和交付
  • DevOps

PS:老是以爲雲原生這個叫法太抽象了,很難讓人經過名字想到這是個啥東西。

ServiceMesh的定義

前面講了微服務、容器、容器編排、雲原生等,其實就是爲了得出什麼是ServiceMesh,本身總結了一下:SeviceMesh是雲原生下的微服務治理方案

當咱們經過微服務的方式將應用以容器的形式部署在K8S上後,服務之間調用和治理其實有新的方案,能夠不須要依賴傳統的微服務治理框架。ServiceMesh經過對每一個應用在其Pod中啓動一個Sidecar(邊車)實現對應用的透明代理,全部出入應用的流量都先通過該應用的Sidecar,服務之間的調用轉變成了Sidecar之間的調用,服務的治理轉變成了對Sidecar的治理。在ServiceMesh中Sidecar是透明的,開發無感知的,以前一直以爲奇怪,總以爲一個應用要讓別人發現它從而調用它,總得引入一些庫而後進行主動的服務註冊,否則啥都不作,別人咋知道這個應用的存在,爲何在ServiceMesh中就能夠省去這些,作到對開發者徹底地透明呢?這個的實現依賴於容器編排工具,經過K8S進行應用的持續集成和交付時,在啓動應用Pod後,其實已經經過Yaml文件的形式向K8S註冊了本身的服務以及聲明瞭服務之間的關係,ServiceMesh經過和K8S進行通訊獲取集羣上全部的服務信息,經過K8S這個中間者實現了對開發者的透明。以下圖所示,是ServiceMesh的一個基本結構,包括數據平面和控制平面。

這種方式存在不少好處,咱們能夠發如今這種模式下應用的語言其實不會對整個服務治理過程有什麼影響,對於ServiceMesh來講,它只關心Pod或者說是Pod中的容器實例,並不須要在意容器中應用的實現語言是啥,Sidecar和其負責的容器在同一個Pod中。這樣ServiceMesh就能夠實現跨語言,這也是目前不少傳統的服務治理框架的一大缺點,並且採用傳統的服務治理,須要對應用引入大量的依賴,這樣就會形成依賴之間的各類衝突,集團經過Pandora對應用的各類依賴進行隔離。再者傳統的服務治理門檻較高,須要開發者對整個架構有必定的瞭解,且發現問題排查較爲麻煩。這也形成了開發和運維之間的界限不清,在ServiceMesh中開發只須要交付代碼,運維能夠基於K8S去維護整個容器集羣。

發展示狀

經過目前查閱的資料來看,ServiceMesh一詞最先出如今2016年,最近兩年被炒的很火,螞蟻金服已經有了本身的一套完整的ServiceMesh服務框架--SofaMesh,集團不少團隊也在進行相應的跟進。

從歷史發展的路線來看,程序的開發方式經歷了不少的變化,但總的方向是變得愈來愈簡單了,如今咱們在集團內進行開發,能夠很簡單的構建一個支撐較大QPS的服務,這得益於集團的整個技術體系的完整和豐富以及強大的技術積澱。

咱們下面來看看應用開發到底經歷了啥?

發展歷史

主機直接階段

如上圖,這一階段應該是最古老的階段,兩臺機器經過網線直接鏈接,一個應用包含了你能想到的全部的功能,包括兩臺機器的鏈接管理,這時尚未網絡的概念,畢竟只能和經過網線直接鏈接在一塊兒的機器進行通訊。

網絡層的出現

如上圖,隨着技術的發展,網絡層出現了,機器能夠和經過網絡鏈接的其餘全部機器進行通訊,再也不限制於必需要網線直連兩臺機器。

集成到應用程序內部的流量控制

如上圖,因爲每一個應用所在環境和機器配置不同,接受流量的能力也不相同,當A應用發送的流量大於了B應用的接受能力時,那麼沒法接收的數據包一定會被丟棄,這時就須要對流量進行控制,最開始流量的控制須要應用本身去實現,網絡層只負責接收應用下發的數據包並進行傳輸。

流量控制轉移到網絡層

如上圖,慢慢地你們發應用中的網絡流量控制是能夠轉移到網絡層的,因此網絡層中的流量控制出現了,我想大概就是指TCP的流量控制吧,這樣還能保證可靠的網絡通訊。

應用程序的中集成服務發現和斷路器

如上圖,開發者經過在本身的代碼模塊中實現服務發現和斷路器。

專門用於服務發現和斷路器的軟件包/庫

如上圖,開發者經過引用第三方依賴去實現服務發現和斷路器。

出現了專門用於服務發現和斷路器的開源軟件

如上圖,基於各類中間件去實現服務發現和斷路器。

ServiceMesh出現

最終到了如今,ServiceMesh大法誕生,進一步解放了生產力,提升了軟件整個生命週期的效率。

ServiceMesh市場競爭

雖然直到2017年末,ServiceMesh纔開始較大規模被世人瞭解,這場微服務市場之爭也才顯現,可是其實ServiceMesh這股微服務的新勢力,早在 2016年初就開始萌芽:

2016年1月,離開Twitter的基礎設施工程師William Morgan和Oliver Gould,在github上發佈了Linkerd 0.0.7版本,業界第一個ServiceMesh項目就此誕生。Linkerd基於Twitter的Finagle開源項目,大量重用了Finagle的類庫,可是實現了通用性,成爲了業界第一個ServiceMesh項目。而Envoy是第二個ServiceMesh項目,二者的開發時間差很少,在2017年都相繼成爲CNCF項目。2017年5月24日,Istio 0.1 release版本發佈,Google和IBM高調宣講,社區反響熱烈,不少公司在這時就紛紛站隊表示支持Istio。Linkerd的風光瞬間被蓋過,從意氣風發的少年一晚上之間變成過氣網紅。固然,從產品成熟度上來講,linkerd做爲業界僅有的兩個生產級ServiceMesh實現之一,暫時還能夠在Istio成熟前繼續保持市場。可是,隨着Istio的穩步推動和日益成熟,外加第二代ServiceMesh的自然優點,Istio取代第一代的Linkerd只是個時間問題。自從在2016年決定委身於Istio以後,Envoy就開始了一條波瀾不驚的平穩發展之路,和Linkerd的跌宕起伏徹底不一樣。在功能方面,因爲定位在數據平面,所以Envoy無需考慮太多,不少工做在Istio的控制平面完成就好,Envoy今後專心於將數據平面作好,完善各類細節。在市場方面,Envoy和Linkerd性質不一樣,不存在生存和發展的戰略選擇,也沒有正面對抗生死大敵的巨大壓力。

從Google和IBM聯手決定推出Istio開始,Istio就註定永遠處於風頭浪尖,不管成敗,Istio面世以後,讚譽不斷,尤爲是ServiceMesh技術的愛好者,能夠說是爲之一振:以新一代ServiceMesh之名橫空出世的Istio,對比Linkerd,優點明顯。同時產品路線圖上有一大堆使人眼花繚亂的功能。假以時日,若是Istio能順利地完成開發,穩定可靠,那麼這會是一個很是美好、值得憧憬的大事件,

Istio介紹

Istio是目前最熱的ServiceMesh開源項目,Istio主要分爲兩個部分:數據平面和控制平面。Istio實現了雲原生下的微服務治理,能實現服務發現,流量控制,監控安全等。Istio經過在一個Pod裏啓動一個應用和Sidecar方式實現透明代理。Istio是一個拓展性較高的框架,其不只能夠支持K8S,還能夠支持其餘如Mesos等資源調度器。以下圖所示,爲Istio的總體架構:

  • 邏輯上分爲數據平面(上圖中的上半部分)和控制平面(上圖中的下半部分)。
  • 數據平面由一組以 Sidecar 方式部署的智能代理(Envoy)組成。這些代理能夠調節和控制微服務及 Mixer 之間全部的網絡通訊。
  • 控制平面負責管理和配置代理來路由流量。此外控制平面配置 Mixer 以實施策略和收集遙測數據。
  • Pilot是整個架構中的抽象層,將對接K8S等資源調度器的步驟進行抽象並以適配器的形式展示,並和用戶以及Sidecar交互。
  • Galley負責資源配置爲驗證。
  • Citadel用於生成身份,及密鑰和證書管理
  • 核心功能包括流量控制、安全控制、可觀測性、多平臺支持、可定製化。

Mixer

Mixer一樣是一個可拓展的模塊,其負責遙感數據的採集以及集成了一些後端服務(BAAS),Sidecar會不斷向Mixer報告本身的流量狀況,Mixer對流量狀況進行彙總,以可視化的形式展示,此外Sidecar能夠調用Mixer提供的一些後端服務能力,例如鑑權、登陸、日誌等等,Mixer經過適配器的方式對接各類後端服務。

In-process Adapter形式

以前版本的Isito採用這種將後端服務適配器集成在Mixer內部的形式,這種方式會有一個問題,就是某個後端服務適配器出現問題即會影響整個Mixer模塊,但因爲適配器和Mixer集成在一塊兒,在同一個進程內,方法的調用會很快。

Out-of-process Adapter形式

目前版本的Istio將Adapter移到Mixer外部,這樣能夠實現Mixer與Adapter的解耦,當Adapter出現問題並不會影響Mixer,但這種方式一樣也存在問題,即Adapter在Mixer外,是兩個不一樣的進程,兩者之間的調用是經過RPC的方式,這種方式比同進程內部的方法調用會慢不少,所以性能會受到影響。

Pilot

  • Envoy API負責和Envoy的通信, 主要是發送服務發現信息和流量控制規則給Envoy。
  • Abstract Model 是 Pilot 定義的服務的抽象模型, 以從特定平臺細節中解耦, 爲跨平臺提供基礎。
  • Platform Adapter則是這個抽象模型的實現版本, 用於對接外部的不一樣平臺如k8s/mesos等。
  • Rules API提供接口給外部調用以管理 Pilot, 包括命令行工具Istioctl以及將來可能出現的第三方管理界面。

Galley

Galley 原來僅負責進行配置驗證, 1.1 後升級爲整個控制面的配置管理中心, 除了繼續提供配置驗證功能外, Galley還負責配置的管理和分發, Galley 使用 網格配置協議(Mesh Configuration Protocol) 和其餘組件進行配置的交互.

Istio 創造了50多個CRD, 其複雜度可見一斑, 因此有人說面向k8s編程近似於面向yaml編程.早期的Galley 僅僅負責對配置進行運行時驗證, Istio 控制面各個組件各自去list/watch 各自關注的配置。愈來愈多且複雜的配置給Istio用戶帶來了諸多不便, 主要體如今:

  • 配置的缺少統一管理, 組件各自訂閱, 缺少統一回滾機制, 配置問題難以定位。
  • 配置可複用度低, 好比在1.1以前, 每一個Mixer adpater 就須要定義個新的CRD。
  • 配置的隔離, ACL 控制, 一致性, 抽象程度, 序列化等等問題都還不太使人滿意

隨着Istio功能的演進, 可預見的Istio CRD數量還會繼續增長, 社區計劃將Galley 強化爲Istio配置控制層, Galley 除了繼續提供配置驗證功能外, 還將提供配置管理流水線, 包括輸入, 轉換, 分發, 以及適合Istio控制面的配置分發協議(MCP)。

Citadel

將服務拆分爲微服務以後,在帶來各類好處的同時,在安全方面也帶來了比單體時代更多的需求,畢竟不一樣功能模塊之間的調用方式從原來單體架構中的方法調用變成了微服務之間的遠程調用:

  • 加密:爲了避免泄露信息,爲了抵禦中間人攻擊,須要對服務間通信進行加密。
  • 訪問控制:不是每一個服務都允許被任意訪問,所以須要提供靈活的訪問控制,如雙向 TLS 和細粒度的訪問策略。
  • 審計:若是須要審覈系統中哪些用戶作了什麼,則須要提供審計功能。

Citadel 是 Istio 中負責安全性的組件,可是 Citadel 須要和其餘多個組件配合才能完成工做:

  • Citadel:用於密鑰管理和證書管理,下發到Envoy等負責通信轉發的組件。
  • Envoy:使用從Citadel下發而來的密鑰和證書,實現服務間通信的安全,注意在應用和Envoy之間是走Localhost,一般不用加密。
  • Pilot:將受權策略和安全命名信息分發給Envoy。
  • Mixer:負責管理受權,完成審計等。

Istio支持的安全類功能有:

  • 流量加密:加密服務間的通信流量。
  • 身份認證:經過內置身份和憑證管理能夠提供強大的服務間和最終用戶身份驗證,包括傳輸身份認證和來源身份認證,支持雙向TLS。
  • 受權和鑑權:提供基於角色的訪問控制(RBAC),提供命名空間級別,服務級別和方法級別的訪問控制。

做者信息:彭家浩,花名毅忻,阿里巴巴淘系技術部開發工程師,熱愛雲計算。

附加信息

筆者工做於阿里巴巴淘系技術部開放平臺和聚石塔團隊,一個即專一技術也專一業務的團隊,咱們真誠地但願能有更多對雲計算、雲原生等方面有激情的小夥伴加入咱們!期待!

招聘詳情點擊這裏

阿里雲雙11億元補貼提早領,進入抽取iPhone 11 Pro:https://www.aliyun.com/1111/2...


本文做者:彭家浩

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索