您好,登錄后才能下訂單哦!
如何理解Istio在FreeWheel微服務(wù)中的實(shí)踐,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
FreeWheel的微服務(wù)之痛
FreeWheel是一家數(shù)字視頻解決方案公司,我們核心業(yè)務(wù)系統(tǒng)可以理解為一個(gè)Web ERP。最初核心業(yè)務(wù)系統(tǒng)完全基于Rails,是一個(gè)典型的三層架構(gòu),但這個(gè)大型單體應(yīng)用在發(fā)展了近十年以后,維護(hù)成本越來(lái)越大,而且難以擴(kuò)展。2016年FreeWheel開(kāi)始遷移到微服務(wù)架構(gòu),所有的業(yè)務(wù)功能都用Golang來(lái)重寫(xiě),同時(shí)引入了Kubernetes作為服務(wù)的部署平臺(tái)。
但在遷移到微服務(wù)之后,F(xiàn)reeWheel面臨很多通信方面的矛盾。一方面,平臺(tái)層的運(yùn)維開(kāi)始和應(yīng)用層的改動(dòng)互相牽制。有時(shí)升級(jí)核心網(wǎng)絡(luò)設(shè)備,整個(gè)系統(tǒng)都會(huì)被波及。另一方面,隨著應(yīng)用層越來(lái)越快的迭代,模塊之間開(kāi)始互相牽制,進(jìn)而影響了客戶,同時(shí)也降低了應(yīng)用迭代的效率。歸結(jié)起來(lái)是兩方面的問(wèn)題:一個(gè)是通信的控制,另外一個(gè)是通信的可見(jiàn)性,可以理解成監(jiān)控。
最初我們嘗試用一個(gè)中心化的服務(wù)網(wǎng)關(guān)Gateway來(lái)解決這種矛盾。但隨著遷移微服務(wù)的模塊越來(lái)越多,這種服務(wù)出現(xiàn)了兩個(gè)矛盾:一個(gè)是服務(wù)和服務(wù)之間的流量互相影響,第二個(gè)是在微服務(wù)中服務(wù)網(wǎng)關(guān)的配置有很多個(gè)性化的地方,大鍋飯帶來(lái)了復(fù)雜的配置管理,漸漸難以為繼。
在這樣的背景下,F(xiàn)reeWheel切換到了Service Mesh解決方案,選擇了Istio。
FreeWheel選擇Istio解決方案的主要原因,是因?yàn)镕reeWheel的技術(shù)棧是Golang和Kubernetes,Istio是目前最合適的選擇。
02
Istio的架構(gòu)和基本原理
首先來(lái)看一下Istio的架構(gòu)和基本原理。Istio有四個(gè)核心模塊:
1. 反向代理模塊: Istio Proxy劫持Pod的所有流量,管理Service Mesh里面的通信。同時(shí),管理Mesh內(nèi)外邊界交互的流量也是反向代理。
2. Pilot模塊: 管理所有Service Mesh的動(dòng)態(tài)配置。
3. Citadel模塊: 主要是自動(dòng)維護(hù)服務(wù)之間通信的證書(shū)。
4. Mixer模塊: 在Kubernetes部署了兩組服務(wù):一組服務(wù)提供授權(quán)和容量檢查的能力,另外一組Policy提供數(shù)據(jù)采集的能力,通過(guò)該服務(wù)將數(shù)據(jù)匯總。
如果從整個(gè)系統(tǒng)設(shè)計(jì)上看,也可以分成四個(gè)板塊:
1. 反向代理。
2. 網(wǎng)絡(luò)安全,目前主要兼容Spiffe標(biāo)準(zhǔn)實(shí)現(xiàn)。
3. 為C++實(shí)現(xiàn)的Proxy接入K8s的動(dòng)態(tài)配置管理。
4. 對(duì)于Attribute的有限狀態(tài)機(jī)模型,授權(quán)、容量、管理監(jiān)控等所有的基礎(chǔ)。
03
Istio管理下的微服務(wù)
Service Mesh部署pod之后,發(fā)生了什么?
1. 創(chuàng)建Pod之前,首先由Sidecar Injector來(lái)將自定義的initContainer, sidecar container、volume添加到Pod中,這里的volume是Istio自帶的通信安全相關(guān)的,Istio為Pod維護(hù)了動(dòng)態(tài)的認(rèn)證密鑰。
2. 接下來(lái)創(chuàng)建容器啟動(dòng)Pod,其中initContainer先為當(dāng)前Pod生成流量劫持的iptables規(guī)則。
3. 然后啟動(dòng)Pod中的sidecar和實(shí)際應(yīng)用容器。
4. 接下來(lái)sidecar和Pilot建立連接接受動(dòng)態(tài)配置和更新;和Mixer(policy)建立連接來(lái)檢查授權(quán)、容量等;和Mixer(telemetry)建立連接來(lái)上報(bào)流量相關(guān)的監(jiān)控元數(shù)據(jù)。
Pod啟動(dòng)完成并且接入Service Mesh后,這里面還有兩個(gè)組件:
Galley:實(shí)現(xiàn)對(duì)動(dòng)態(tài)配置的校驗(yàn)。
Citadel:檢查Pod中mount的secret的有效性,并自動(dòng)為Pod分發(fā)合法的證書(shū)。
04
FreeWheel如何充分利用Istio?
FreeWheel已經(jīng)有一套復(fù)雜的自定義認(rèn)證、授權(quán)機(jī)制,為了充分利用Istio,我們通過(guò)擴(kuò)展Istio來(lái)整合這些系統(tǒng),涉及兩方面:
擴(kuò)展Sidecar:加入認(rèn)證支持,提供了對(duì)業(yè)務(wù)系統(tǒng)的認(rèn)證支持,將用戶相關(guān)信息以header的形式傳入Mesh,后續(xù)的授權(quán)、監(jiān)控、限流都可以用Istio原生的機(jī)制來(lái)完成。
擴(kuò)展Mixer:選擇一部分流量來(lái)應(yīng)用對(duì)應(yīng)的授權(quán)邏輯。
擴(kuò)展Sidecar接入認(rèn)證
FreeWheel原本就有一個(gè)簡(jiǎn)單的服務(wù)網(wǎng)關(guān)實(shí)現(xiàn),將認(rèn)證邏輯抽取到這個(gè)模塊中,認(rèn)證完成之后在反向代理中為下游的服務(wù)插入一些header,比如認(rèn)證后得到的用戶信息等。
Istio沒(méi)有開(kāi)發(fā)這種對(duì)請(qǐng)求完全定制的接口,所以要想修改請(qǐng)求和響應(yīng)的內(nèi)容,就必須要定義反向代理。我們沒(méi)有替換Envoy,改為在它下面接一個(gè)反向代理來(lái)實(shí)現(xiàn),這個(gè)反向代理同時(shí)還接入了配置管理服務(wù),可以利用原生的k8s配置管理接口來(lái)實(shí)現(xiàn)動(dòng)態(tài)配置管理。不過(guò)需要注意的是,Sidecar里面的容器的流量默認(rèn)是不被Iptables劫持的,如果需要納入流量劫持,需要顯式指定Aannotation來(lái)包含端口或者CIDR。
接入Sidecar其實(shí)就是修改Istio-system/istio-sidecar-injector的ConfigMap,并加入自定義的反向代理。
這個(gè)反向代理很簡(jiǎn)單,寫(xiě)死了token和用戶信息的映射關(guān)系,如果上游傳入了token,就將用戶信息塞到header中傳給下游,然后流量被轉(zhuǎn)發(fā)給應(yīng)用服務(wù),在反向代理和應(yīng)用服務(wù)之間還有一個(gè)檢查授權(quán)、容量的過(guò)程,這是通過(guò)定制Mixer來(lái)實(shí)現(xiàn)的。
通過(guò)在Sidecar中增加FreeWheel自定義認(rèn)證支持,下游可以充分利用Istio提供的授權(quán)、限流、監(jiān)控接口。不過(guò)在Sidecar Injector用了一段時(shí)間以后,發(fā)現(xiàn)里面有兩個(gè)問(wèn)題:
Sidecar沒(méi)有K8s自動(dòng)注入的secret,也無(wú)法通過(guò)容器內(nèi)環(huán)境變量自動(dòng)建立Master連接,需要管理額外的Kubernetes。
Sidecar內(nèi)的服務(wù)流量默認(rèn)是不被劫持的,如果需要劫持需要添加額外的Annotation。
擴(kuò)展Mixer接入授權(quán)
我們?yōu)閷?shí)現(xiàn)高度定制的請(qǐng)求和響應(yīng)內(nèi)容時(shí),用Sidecar實(shí)現(xiàn)擴(kuò)展,但服務(wù)在授權(quán)、自定義限流的時(shí)候,很多類似的功能并不需要修改請(qǐng)求響應(yīng),只是在請(qǐng)求到達(dá)下游服務(wù)之前算一下,結(jié)果拒絕,或者通過(guò)。這時(shí)候就可以通過(guò)Mixer來(lái)擴(kuò)展。
Mixer是一個(gè)高度可定制的狀態(tài)機(jī)模型,Envoy提供兩個(gè)接口:Report 和Check。這兩個(gè)接口會(huì)在連接和請(qǐng)求的不同生命后期被多次調(diào)用,我們經(jīng)常用到的Quota,Metrics,Tracing 之類的功能都是通過(guò)它來(lái)實(shí)現(xiàn)的。
下圖為Mixer的基本原理,Template是對(duì)Proxy上報(bào)的Attribute的特定處理機(jī)制的框架,支持四類:
Preprocess: 匯總流量相關(guān)元數(shù)據(jù)和環(huán)境(k8s)相關(guān)的元數(shù)據(jù)。
Report: 上報(bào)數(shù)據(jù)。
Check: 決策是否允許當(dāng)前訪問(wèn)。
Quota: 決策容量是否足夠。
Mixer的基本原理
FreeWheel是如何擴(kuò)展Mixer的呢?
首先,增加了一個(gè)adapter來(lái)實(shí)現(xiàn)授權(quán)的模板。其實(shí),F(xiàn)reeWheel已有一個(gè)默認(rèn)的RBAC模板。但新增一個(gè)授權(quán)能力的時(shí)候,我們希望做到絕對(duì)可控。比如,通過(guò)一個(gè)動(dòng)態(tài)配置,在只有某一部分user或訪問(wèn)某一類URL的時(shí)候打開(kāi)這個(gè)授權(quán),其他的時(shí)候則把它關(guān)掉。
Mixer提供了一種非常靈活的模型,讓Handler可以在流量中動(dòng)態(tài)地選擇一部分來(lái)引入額外的機(jī)制(如權(quán)限控制、限流等),在應(yīng)用運(yùn)維中這是很重要的能力,只要是不修改請(qǐng)求、響應(yīng)的功能都可以采用擴(kuò)展Mixer來(lái)實(shí)現(xiàn)。
這里,mymock會(huì)完全拒絕所有被匹配到的流量:
mymock Handler的基本原理
在擴(kuò)展Mixer的過(guò)程中有三個(gè)關(guān)鍵要素:
1. Handler的配置。這是一個(gè)默認(rèn)行為,讓checknothing匹配到user1的時(shí)候返回到400,然后全部拒絕。
2. 系統(tǒng)進(jìn)程instance。這是每個(gè)模塊固定的東西,定義了這種輸入以后,里面可以有一個(gè)黑盒,是面向?qū)ο蟮母拍睢?/p>
3. RUL。當(dāng)用戶身份是user1的時(shí)候,instance會(huì)被handler來(lái)處理。如果要擴(kuò)展,第一步需要定義handler的數(shù)據(jù)結(jié)構(gòu);第二步,實(shí)現(xiàn)time的接口,這里有兩個(gè)接口;第三把定義的handler的文件里面相關(guān)go的接口通過(guò)代碼生成。最后,注冊(cè)到mixer里面,重新編譯打包mixer以后就可以直接用了。
需要注意的是,mixer接入的是授權(quán)的policy模塊,可能會(huì)影響服務(wù)網(wǎng)格(Service Mesh)不工作。因此,重新部署這些模塊的時(shí)候,如果不能忍受短時(shí)間的宕機(jī),則可能需要做一些灰度發(fā)布的機(jī)制。
對(duì)于Istio配置管理,我們也發(fā)現(xiàn)一些性能瓶頸和局限性。
Kubernetes和對(duì)etcd配置管理存在性能瓶頸。單個(gè)Resource控制在K級(jí)別,能夠比較正常的工作,一旦到達(dá)萬(wàn)級(jí)別可能會(huì)出現(xiàn)不工作,比如好幾萬(wàn)的單個(gè)Resource。
Istio配置本身的局限性。首先是防抖動(dòng)處理,集群里面部署變化再快,都不會(huì)阻塞Istio。其次Istio其他的配置沒(méi)有防抖動(dòng)處理,一旦用程序插入的時(shí)候一定要做限流。最后Istio用了CRD無(wú)法做到的兼容性設(shè)計(jì),所以升級(jí)CRD也沒(méi)有辦法做到平滑的升級(jí)。
FreeWheel未來(lái)將怎么做?
首先是Service Contract,封裝Istio以及平臺(tái)層其他配置的復(fù)雜度,抽象出一個(gè)安全,高效的應(yīng)用運(yùn)維體系,為未來(lái)技術(shù)上的改進(jìn)留出空間。
然后是Chaos Testing,解決復(fù)雜的微服務(wù)系統(tǒng)的持續(xù)運(yùn)營(yíng)和風(fēng)險(xiǎn)控制問(wèn)題。這個(gè)也是目前比較火的一個(gè)主題。
現(xiàn)場(chǎng)問(wèn)答
1. 對(duì)于Service Mesh外部流量進(jìn)入,在Kubernetes有Ingress,在微服務(wù)Service Mesh的應(yīng)用里面也有一個(gè)Gateway的情況下,它里面是把Gateway轉(zhuǎn)到Service Mesh,這三個(gè)怎么聯(lián)動(dòng)讓外部的流量能夠順暢地進(jìn)去?
答:很簡(jiǎn)單。Service Mesh可以理解成是一個(gè)封閉的盒子,你所有的外部的Ingress以前該怎么運(yùn)作還怎么運(yùn)作,我們現(xiàn)在就討論在Service Mesh里面是怎么運(yùn)作的。如果把它看作一個(gè)黑盒,現(xiàn)在你有一個(gè)Ingress,可以把它轉(zhuǎn)到Istio里面的Ingress Gateway,過(guò)去流量會(huì)直接轉(zhuǎn)發(fā)到各個(gè)Pod,是直接打到Pod,由Pod上Sidecar,再轉(zhuǎn)給應(yīng)用。
2. 您剛才說(shuō)的Sidecar里的應(yīng)該是直接把Pod里面的流量屏蔽掉,只能通過(guò)Service Mesh里面的Gateway流量才能夠進(jìn)到Pod里面?
答:不會(huì)。你說(shuō)的這個(gè)流量轉(zhuǎn)發(fā)其實(shí)并沒(méi)有任何的限制,Service Mesh里面每一個(gè)反向代理都可以承擔(dān)Ingress Gateway的功能,僅僅是路由配置的問(wèn)題。如果把這個(gè)弄好了,在任何一個(gè)Service Mesh上都可以配置這個(gè)功能。這個(gè)反向代理是一模一樣的。
3. 我用Istio的Gateway,Kubernetes里面的Ingress關(guān)掉,能夠跟外部之間聯(lián)系。
答:這個(gè)才是Istio比較推薦的模式,你管理這個(gè)集群外部進(jìn)來(lái)流量的時(shí)候直接走Ingress Gateway,可以做到很好的限制。
4. 你們?cè)诼涞氐倪^(guò)程中有沒(méi)有遇到一些坑?
答:有。我們一開(kāi)始試圖把業(yè)務(wù)的權(quán)限數(shù)據(jù)直接轉(zhuǎn)成原生的數(shù)據(jù)結(jié)構(gòu),因?yàn)槲覀兿胗盟鼇?lái)做權(quán)限控制。但是后來(lái)發(fā)現(xiàn)它掌控不了那么大的數(shù)據(jù)量。第二個(gè)坑是Istio對(duì)它的一些Resource是沒(méi)有防抖動(dòng)處理的,可能會(huì)導(dǎo)致這個(gè)Service Mesh行為很不穩(wěn)定,在客戶端一定要做限流。
另外從長(zhǎng)遠(yuǎn)看,Istio的這些模塊目前都還是單點(diǎn),可能導(dǎo)致Service Mesh不可用。我們以前也有遇到過(guò)跑了三個(gè)月莫名其妙出問(wèn)題了,維護(hù)這種監(jiān)控系統(tǒng)要頻繁地做演習(xí)。我們公司現(xiàn)在一個(gè)月做一次演習(xí),會(huì)定時(shí)在一個(gè)主生產(chǎn)環(huán)境里把問(wèn)題拿出來(lái),然后檢查各個(gè)環(huán)節(jié)有沒(méi)有正常工作,這也是我們未來(lái)會(huì)發(fā)展的一個(gè)事情。
關(guān)于如何理解Istio在FreeWheel微服務(wù)中的實(shí)踐問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。