前言
計算機軟件技術(shù)發(fā)展到現(xiàn)在,軟件架構(gòu)的演進無不朝著讓開發(fā)者能夠更加輕松快捷地構(gòu)建大型復(fù)雜應(yīng)用的方向發(fā)展。容器技術(shù)最初是為了解決運行環(huán)境的不一致問題而產(chǎn)生的,隨著不斷地發(fā)展,圍繞容器技術(shù)衍生出來越來越多的新方向。
最近幾年,云計算領(lǐng)域不斷地出現(xiàn)很多新的軟件架構(gòu)模式,其中有一些很熱門的概念名詞如:云原生、函數(shù)計算、Serverless、ServiceMesh等等,而本文將初窺一下ServiceMesh的面紗。下面結(jié)合自己的理解盡量以通俗的話進行敘述。
背景和定義
微服務(wù)及服務(wù)治理
在微服務(wù)之前的軟件開發(fā)中,往往通過一個應(yīng)用的方式將所有的模塊都包括進去,并一起編譯、打包、部署、運維。這種方式存在很多問題,由于單個應(yīng)用包含的東西太多,其中某個模塊出現(xiàn)問題或者需要更新那么整個應(yīng)用就需要重新部署。這種方式給開發(fā)和運維帶來了很大的麻煩。隨著應(yīng)用的逐漸復(fù)雜,單個應(yīng)用涉及的東西就會越來越多,慢慢地大家發(fā)現(xiàn)了其中很多的缺點,開始對服務(wù)進行劃分,將一個大的應(yīng)用按照不同的維度進行劃分從而產(chǎn)生很多個小的應(yīng)用,各應(yīng)用之間會形成一個調(diào)用關(guān)系,每個小的應(yīng)用由不同的開發(fā)負(fù)責(zé),大家各自部署和運維,這樣微服務(wù)就出現(xiàn)了。
由于微服務(wù)中各應(yīng)用部署在不同的機器上,服務(wù)之間需要進行通信和協(xié)調(diào),相比單個應(yīng)用來說會麻煩很多。在同一個應(yīng)用內(nèi)不同方法之間的調(diào)用由于在相同的內(nèi)存中,在代碼編譯打包時已經(jīng)進行了鏈接,因此調(diào)用是可尋址且快速的。微服務(wù)下不同服務(wù)之間的調(diào)用涉及到不同進程或者機器之間的通信,一般需要通過第三方中間件的方式作為中介和協(xié)調(diào),由于種種這些,面向微服務(wù)出現(xiàn)了很多中間件包括服務(wù)治理的框架。通過服務(wù)治理工具可以管理其接入的所有應(yīng)用,使得服務(wù)之間的通信和協(xié)調(diào)更加簡單高效。
容器及容器編排
最初容器技術(shù)是為了解決應(yīng)用運行環(huán)境不一致的問題而出現(xiàn)的,避免在本地環(huán)境或者測試環(huán)境能夠跑通,等發(fā)到生產(chǎn)環(huán)境卻出現(xiàn)問題。通過容器將程序及其依賴一起打包到鏡像中去,將程序的鏡像在任何安裝并運行了容器軟件的機器上啟動若干的容器,每個容器就是應(yīng)用運行時的實例,這些實例一般擁有完全相同的運行環(huán)境和參數(shù)。使得不管在任何機器上應(yīng)用都可以表現(xiàn)出一樣的效果。這給開發(fā)、測試、運維帶來了極大的便利,不再需要為不同機器上構(gòu)建相同的運行環(huán)境而頭大。且鏡像可以Push到鏡像倉庫,這使得應(yīng)用可以進行很方便的遷移和部署。Docker就是一個應(yīng)用廣泛的容器技術(shù)。目前越來越多的應(yīng)用以微服務(wù)的方式并通過容器進行部署,給了軟件開發(fā)極大的活力。
與微服務(wù)和服務(wù)治理的關(guān)系類似,越來越多的應(yīng)用通過容器進行部署,使得集群上的容器數(shù)量急劇增加,通過人工的管理和運維這些容器已經(jīng)變得很艱難且低效,為了解決諸多容器及容器之間的關(guān)系出現(xiàn)了很多編排工具,容器編排工具能夠管理容器的整個生命周期。如Docker官方出的docker-compose和docker swarm,這兩個工具能實現(xiàn)批量容器的啟動和編排,但功能較為簡單,不足以支撐大型的容器集群。Google基于內(nèi)部大量的容器管理經(jīng)驗,開源出了Kubernetes項目,Kubernetes(K8S)是針對Google集群上每周億級別的容器而設(shè)計的,具有很強大的容器編排能力和豐富的功能。K8S通過定義了很多資源,這些資源以聲明式的方式進行創(chuàng)建,可以通過JSON或者YAML文件表示一個資源,K8S支持多種容器,但主流的是Docker容器,K8S提供了容器接入的相關(guān)標(biāo)準(zhǔn),只要容器實現(xiàn)了該標(biāo)準(zhǔn)就可以被K8S所編排。由于K8S的功能較多,不在此一一敘述,有興趣可以參考官方文檔或者ATA上搜索相關(guān)文章。
當(dāng)某個公司的應(yīng)用已經(jīng)完全微服務(wù)化后,選擇以容器的方式部署應(yīng)用,此時可以在集群上部署K8S,通過K8S提供的能力進行應(yīng)用容器的管理,運維可以也可以面向K8S進行工作。由于K8S是目前使用最廣泛的容器編排工具,因此成為了容器編排的一個標(biāo)準(zhǔn)了,目前集團內(nèi)部也有自己的容器和容器編排工具。
面向以K8S為代表的容器管理方式衍生出了一些新的技術(shù)。
云原生
最近兩年云原生被炒的很火,可以在各處看到很多大佬對云原生的高談闊論,下面直接拋出CNCF對云原生的定義:
云原生技術(shù)有利于各組織在公有云、私有云和混合云等新型動態(tài)環(huán)境中,構(gòu)建和運行可彈性擴展的應(yīng)用。云原生的代表技術(shù)包括容器、服務(wù)網(wǎng)格、微服務(wù)、不可變基礎(chǔ)設(shè)施和聲明式API。
這些技術(shù)能夠構(gòu)建容錯性好、易于管理和便于觀察的松耦合系統(tǒng)。結(jié)合可靠的自動化手段,云原生技術(shù)使工程師能夠輕松地對系統(tǒng)作出頻繁和可預(yù)測的重大變更。
在我看來,通過微服務(wù)的方式開發(fā)應(yīng)用,以容器進行部署,使用K8S等容器編排工具進行容器集群的管理,使得開發(fā)運維都面向K8S,這就是云原生。云原生可以方便的構(gòu)建應(yīng)用,并對應(yīng)用進行完整的監(jiān)控,以及在應(yīng)用針對不同流量時能進行快速的擴容和縮容。如下圖:
云原生主要包括四個部分:
- 微服務(wù)
- 容器
- 持續(xù)集成和交付
- DevOps
PS:總是覺得云原生這個叫法太抽象了,很難讓人通過名字想到這是個啥東西。
ServiceMesh的定義
前面講了微服務(wù)、容器、容器編排、云原生等,其實就是為了得出什么是ServiceMesh,自己總結(jié)了一下:SeviceMesh是云原生下的微服務(wù)治理方案。
當(dāng)我們通過微服務(wù)的方式將應(yīng)用以容器的形式部署在K8S上后,服務(wù)之間調(diào)用和治理其實有新的方案,可以不需要依賴傳統(tǒng)的微服務(wù)治理框架。ServiceMesh通過對每個應(yīng)用在其Pod中啟動一個Sidecar(邊車)實現(xiàn)對應(yīng)用的透明代理,所有出入應(yīng)用的流量都先經(jīng)過該應(yīng)用的Sidecar,服務(wù)之間的調(diào)用轉(zhuǎn)變成了Sidecar之間的調(diào)用,服務(wù)的治理轉(zhuǎn)變成了對Sidecar的治理。在ServiceMesh中Sidecar是透明的,開發(fā)無感知的,之前一直覺得奇怪,總覺得一個應(yīng)用要讓別人發(fā)現(xiàn)它從而調(diào)用它,總得引入一些庫然后進行主動的服務(wù)注冊,不然啥都不做,別人咋知道這個應(yīng)用的存在,為什么在ServiceMesh中就可以省去這些,做到對開發(fā)者完全地透明呢?這個的實現(xiàn)依賴于容器編排工具,通過K8S進行應(yīng)用的持續(xù)集成和交付時,在啟動應(yīng)用Pod后,其實已經(jīng)通過Yaml文件的形式向K8S注冊了自己的服務(wù)以及聲明了服務(wù)之間的關(guān)系,ServiceMesh通過和K8S進行通信獲取集群上所有的服務(wù)信息,通過K8S這個中間者實現(xiàn)了對開發(fā)者的透明。如下圖所示,是ServiceMesh的一個基本結(jié)構(gòu),包括數(shù)據(jù)平面和控制平面。
這種方式存在很多好處,我們可以發(fā)現(xiàn)在這種模式下應(yīng)用的語言其實不會對整個服務(wù)治理過程有什么影響,對于ServiceMesh來說,它只關(guān)心Pod或者說是Pod中的容器實例,并不需要在乎容器中應(yīng)用的實現(xiàn)語言是啥,Sidecar和其負(fù)責(zé)的容器在同一個Pod中。這樣ServiceMesh就可以實現(xiàn)跨語言,這也是目前很多傳統(tǒng)的服務(wù)治理框架的一大缺點,而且采用傳統(tǒng)的服務(wù)治理,需要對應(yīng)用引入大量的依賴,這樣就會造成依賴之間的各種沖突,集團通過Pandora對應(yīng)用的各種依賴進行隔離。再者傳統(tǒng)的服務(wù)治理門檻較高,需要開發(fā)者對整個架構(gòu)有一定的了解,且發(fā)現(xiàn)問題排查較為麻煩。這也造成了開發(fā)和運維之間的界限不清,在ServiceMesh中開發(fā)只需要交付代碼,運維可以基于K8S去維護整個容器集群。
發(fā)展現(xiàn)狀
通過目前查閱的資料來看,ServiceMesh一詞最早出現(xiàn)在2016年,最近兩年被炒的很火,螞蟻金服已經(jīng)有了自己的一套完整的ServiceMesh服務(wù)框架–SofaMesh,集團很多團隊也在進行相應(yīng)的跟進。
從歷史發(fā)展的路線來看,程序的開發(fā)方式經(jīng)歷了很多的變化,但總的方向是變得越來越簡單了,現(xiàn)在我們在集團內(nèi)進行開發(fā),可以很簡單的構(gòu)建一個支撐較大QPS的服務(wù),這得益于集團的整個技術(shù)體系的完整和豐富以及強大的技術(shù)積淀。
我們下面來看看應(yīng)用開發(fā)到底經(jīng)歷了啥?
發(fā)展歷史
主機直接階段
如上圖,這一階段應(yīng)該是最古老的階段,兩臺機器通過網(wǎng)線直接連接,一個應(yīng)用包含了你能想到的所有的功能,包括兩臺機器的連接管理,這時還沒有網(wǎng)絡(luò)的概念,畢竟只能和通過網(wǎng)線直接連接在一起的機器進行通信。
網(wǎng)絡(luò)層的出現(xiàn)
如上圖,隨著技術(shù)的發(fā)展,網(wǎng)絡(luò)層出現(xiàn)了,機器可以和通過網(wǎng)絡(luò)連接的其他所有機器進行通信,不再限制于必須要網(wǎng)線直連兩臺機器。
集成到應(yīng)用程序內(nèi)部的流量控制
如上圖,由于每個應(yīng)用所在環(huán)境和機器配置不一樣,接受流量的能力也不相同,當(dāng)A應(yīng)用發(fā)送的流量大于了B應(yīng)用的接受能力時,那么無法接收的數(shù)據(jù)包必定會被丟棄,這時就需要對流量進行控制,最開始流量的控制需要應(yīng)用自己去實現(xiàn),網(wǎng)絡(luò)層只負(fù)責(zé)接收應(yīng)用下發(fā)的數(shù)據(jù)包并進行傳輸。
流量控制轉(zhuǎn)移到網(wǎng)絡(luò)層
如上圖,慢慢地大家發(fā)應(yīng)用中的網(wǎng)絡(luò)流量控制是可以轉(zhuǎn)移到網(wǎng)絡(luò)層的,所以網(wǎng)絡(luò)層中的流量控制出現(xiàn)了,我想大概就是指TCP的流量控制吧,這樣還能保證可靠的網(wǎng)絡(luò)通信。
應(yīng)用程序的中集成服務(wù)發(fā)現(xiàn)和斷路器
如上圖,開發(fā)者通過在自己的代碼模塊中實現(xiàn)服務(wù)發(fā)現(xiàn)和斷路器。
專門用于服務(wù)發(fā)現(xiàn)和斷路器的軟件包/庫
如上圖,開發(fā)者通過引用第三方依賴去實現(xiàn)服務(wù)發(fā)現(xiàn)和斷路器。
出現(xiàn)了專門用于服務(wù)發(fā)現(xiàn)和斷路器的開源軟件
如上圖,基于各種中間件去實現(xiàn)服務(wù)發(fā)現(xiàn)和斷路器。
ServiceMesh出現(xiàn)
最終到了現(xiàn)在,ServiceMesh大法誕生,進一步解放了生產(chǎn)力,提高了軟件整個生命周期的效率。
ServiceMesh市場競爭
雖然直到2017年底,ServiceMesh才開始較大規(guī)模被世人了解,這場微服務(wù)市場之爭也才顯現(xiàn),但是其實ServiceMesh這股微服務(wù)的新勢力,早在 2016年初就開始萌芽:
2016年1月,離開Twitter的基礎(chǔ)設(shè)施工程師William Morgan和Oliver Gould,在github上發(fā)布了Linkerd 0.0.7版本,業(yè)界第一個ServiceMesh項目就此誕生。Linkerd基于Twitter的Finagle開源項目,大量重用了Finagle的類庫,但是實現(xiàn)了通用性,成為了業(yè)界第一個ServiceMesh項目。而Envoy是第二個ServiceMesh項目,兩者的開發(fā)時間差不多,在2017年都相繼成為CNCF項目。2017年5月24日,Istio 0.1 release版本發(fā)布,Google和IBM高調(diào)宣講,社區(qū)反響熱烈,很多公司在這時就紛紛站隊表示支持Istio。Linkerd的風(fēng)光瞬間被蓋過,從意氣風(fēng)發(fā)的少年一夜之間變成過氣網(wǎng)紅。當(dāng)然,從產(chǎn)品成熟度上來說,linkerd作為業(yè)界僅有的兩個生產(chǎn)級ServiceMesh實現(xiàn)之一,暫時還可以在Istio成熟前繼續(xù)保持市場。但是,隨著Istio的穩(wěn)步推進和日益成熟,外加第二代ServiceMesh的天然優(yōu)勢,Istio取代第一代的Linkerd只是個時間問題。自從在2016年決定委身于Istio之后,Envoy就開始了一條波瀾不驚的平穩(wěn)發(fā)展之路,和Linkerd的跌宕起伏完全不同。在功能方面,由于定位在數(shù)據(jù)平面,因此Envoy無需考慮太多,很多工作在Istio的控制平面完成就好,Envoy從此專心于將數(shù)據(jù)平面做好,完善各種細(xì)節(jié)。在市場方面,Envoy和Linkerd性質(zhì)不同,不存在生存和發(fā)展的戰(zhàn)略選擇,也沒有正面對抗生死大敵的巨大壓力。
從Google和IBM聯(lián)手決定推出Istio開始,Istio就注定永遠(yuǎn)處于風(fēng)頭浪尖,無論成敗,Istio面世之后,贊譽不斷,尤其是ServiceMesh技術(shù)的愛好者,可以說是為之一振:以新一代ServiceMesh之名橫空出世的Istio,對比Linkerd,優(yōu)勢明顯。同時產(chǎn)品路線圖上有一大堆令人眼花繚亂的功能。假以時日,如果Istio能順利地完成開發(fā),穩(wěn)定可靠,那么這會是一個非常美好、值得憧憬的大事件,
Istio介紹
Istio是目前最熱的ServiceMesh開源項目,Istio主要分為兩個部分:數(shù)據(jù)平面和控制平面。Istio實現(xiàn)了云原生下的微服務(wù)治理,能實現(xiàn)服務(wù)發(fā)現(xiàn),流量控制,監(jiān)控安全等。Istio通過在一個Pod里啟動一個應(yīng)用和Sidecar方式實現(xiàn)透明代理。Istio是一個拓展性較高的框架,其不僅可以支持K8S,還可以支持其他如Mesos等資源調(diào)度器。如下圖所示,為Istio的整體架構(gòu):
- 邏輯上分為數(shù)據(jù)平面(上圖中的上半部分)和控制平面(上圖中的下半部分)。
- 數(shù)據(jù)平面由一組以 Sidecar 方式部署的智能代理(Envoy)組成。這些代理可以調(diào)節(jié)和控制微服務(wù)及 Mixer 之間所有的網(wǎng)絡(luò)通信。
- 控制平面負(fù)責(zé)管理和配置代理來路由流量。此外控制平面配置 Mixer 以實施策略和收集遙測數(shù)據(jù)。
- Pilot是整個架構(gòu)中的抽象層,將對接K8S等資源調(diào)度器的步驟進行抽象并以適配器的形式展現(xiàn),并和用戶以及Sidecar交互。
- Galley負(fù)責(zé)資源配置為驗證。
- Citadel用于生成身份,及密鑰和證書管理
- 核心功能包括流量控制、安全控制、可觀測性、多平臺支持、可定制化。
Mixer
Mixer同樣是一個可拓展的模塊,其負(fù)責(zé)遙感數(shù)據(jù)的采集以及集成了一些后端服務(wù)(BAAS),Sidecar會不斷向Mixer報告自己的流量情況,Mixer對流量情況進行匯總,以可視化的形式展現(xiàn),此外Sidecar可以調(diào)用Mixer提供的一些后端服務(wù)能力,例如鑒權(quán)、登錄、日志等等,Mixer通過適配器的方式對接各種后端服務(wù)。
In-process Adapter形式
之前版本的Isito采用這種將后端服務(wù)適配器集成在Mixer內(nèi)部的形式,這種方式會有一個問題,就是某個后端服務(wù)適配器出現(xiàn)問題即會影響整個Mixer模塊,但由于適配器和Mixer集成在一起,在同一個進程內(nèi),方法的調(diào)用會很快。
Out-of-process Adapter形式
目前版本的Istio將Adapter移到Mixer外部,這樣可以實現(xiàn)Mixer與Adapter的解耦,當(dāng)Adapter出現(xiàn)問題并不會影響Mixer,但這種方式同樣也存在問題,即Adapter在Mixer外,是兩個不同的進程,二者之間的調(diào)用是通過RPC的方式,這種方式比同進程內(nèi)部的方法調(diào)用會慢很多,因此性能會受到影響。
Pilot
- Envoy API負(fù)責(zé)和Envoy的通訊, 主要是發(fā)送服務(wù)發(fā)現(xiàn)信息和流量控制規(guī)則給Envoy。
- Abstract Model 是 Pilot 定義的服務(wù)的抽象模型, 以從特定平臺細(xì)節(jié)中解耦, 為跨平臺提供基礎(chǔ)。
- Platform Adapter則是這個抽象模型的實現(xiàn)版本, 用于對接外部的不同平臺如k8s/mesos等。
- Rules API提供接口給外部調(diào)用以管理 Pilot, 包括命令行工具Istioctl以及未來可能出現(xiàn)的第三方管理界面。
Galley
Galley 原來僅負(fù)責(zé)進行配置驗證, 1.1 后升級為整個控制面的配置管理中心, 除了繼續(xù)提供配置驗證功能外, Galley還負(fù)責(zé)配置的管理和分發(fā), Galley 使用 網(wǎng)格配置協(xié)議(Mesh Configuration Protocol) 和其他組件進行配置的交互.
Istio 創(chuàng)造了50多個CRD, 其復(fù)雜度可見一斑, 所以有人說面向k8s編程近似于面向yaml編程.早期的Galley 僅僅負(fù)責(zé)對配置進行運行時驗證, Istio 控制面各個組件各自去list/watch 各自關(guān)注的配置。越來越多且復(fù)雜的配置給Istio用戶帶來了諸多不便, 主要體現(xiàn)在:
- 配置的缺乏統(tǒng)一管理, 組件各自訂閱, 缺乏統(tǒng)一回滾機制, 配置問題難以定位。
- 配置可復(fù)用度低, 比如在1.1之前, 每個Mixer adpater 就需要定義個新的CRD。
- 配置的隔離, ACL 控制, 一致性, 抽象程度, 序列化等等問題都還不太令人滿意
隨著Istio功能的演進, 可預(yù)見的Istio CRD數(shù)量還會繼續(xù)增加, 社區(qū)計劃將Galley 強化為Istio配置控制層, Galley 除了繼續(xù)提供配置驗證功能外, 還將提供配置管理流水線, 包括輸入, 轉(zhuǎn)換, 分發(fā), 以及適合Istio控制面的配置分發(fā)協(xié)議(MCP)。
Citadel
將服務(wù)拆分為微服務(wù)之后,在帶來各種好處的同時,在安全方面也帶來了比單體時代更多的需求,畢竟不同功能模塊之間的調(diào)用方式從原來單體架構(gòu)中的方法調(diào)用變成了微服務(wù)之間的遠(yuǎn)程調(diào)用:
- 加密:為了不泄露信息,為了抵御中間人攻擊,需要對服務(wù)間通訊進行加密。
- 訪問控制:不是每個服務(wù)都容許被任意訪問,因此需要提供靈活的訪問控制,如雙向 TLS 和細(xì)粒度的訪問策略。
- 審計:如果需要審核系統(tǒng)中哪些用戶做了什么,則需要提供審計功能。
Citadel 是 Istio 中負(fù)責(zé)安全性的組件,但是 Citadel 需要和其他多個組件配合才能完成工作:
- Citadel:用于密鑰管理和證書管理,下發(fā)到Envoy等負(fù)責(zé)通訊轉(zhuǎn)發(fā)的組件。
- Envoy:使用從Citadel下發(fā)而來的密鑰和證書,實現(xiàn)服務(wù)間通訊的安全,注意在應(yīng)用和Envoy之間是走Localhost,通常不用加密。
- Pilot:將授權(quán)策略和安全命名信息分發(fā)給Envoy。
- Mixer:負(fù)責(zé)管理授權(quán),完成審計等。
Istio支持的安全類功能有:
- 流量加密:加密服務(wù)間的通訊流量。
- 身份認(rèn)證:通過內(nèi)置身份和憑證管理可以提供強大的服務(wù)間和最終用戶身份驗證,包括傳輸身份認(rèn)證和來源身份認(rèn)證,支持雙向TLS。
- 授權(quán)和鑒權(quán):提供基于角色的訪問控制(RBAC),提供命名空間級別,服務(wù)級別和方法級別的訪問控制。
阿里云雙11億元補貼提前領(lǐng),進入抽取iPhone 11 Pro:https://www.aliyun.com/1111/2019/home?utm_content=g_1000083110
作者:彭家浩,花名毅忻,阿里巴巴淘系技術(shù)部開發(fā)工程師,熱愛云計算。
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報,一經(jīng)查實,本站將立刻刪除。