如何理解Rainbond插件體系設(shè)計(jì),相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
成都創(chuàng)新互聯(lián)公司是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、微信小程序定制開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10多年以來,已經(jīng)為成百上千家PE包裝袋各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的成百上千家客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。
過去幾年,利用容器打包和部署代碼的方式日益流行,越來越多企業(yè)開始測試或是已經(jīng)在生產(chǎn)環(huán)境中運(yùn)行了微服務(wù)架構(gòu)應(yīng)用,開始直接面對和解決分布式服務(wù)化架構(gòu)演變中出現(xiàn)的各種問題。
在這樣的趨勢和大環(huán)境下,無服務(wù)器PaaS **Rainbond**圍繞著服務(wù)的拓展、監(jiān)控、治理等角度,進(jìn)行了一系列思考和嘗試,插件體系正是其中的重要一環(huán)。
Rainbond的插件體系抽象集中在平臺的業(yè)務(wù)層面,理論基礎(chǔ)源于Kubernetes的pod機(jī)制和一部分容器概念。針對平臺業(yè)務(wù)層面對kubernetes容器編排進(jìn)行抽象,轉(zhuǎn)變?yōu)橐粋€(gè)對用戶體驗(yàn)友善的Rainbond插件產(chǎn)品的過程,方便用戶在不需要懂Kubernetes原理的情況下使用。
Rainbond插件體系的設(shè)計(jì)遵循易于理解和易于使用的原則:
在Rainbond插件體系中,插件使用的過程即主容器與init或sidecar等容器結(jié)合的過程,原理是將插件容器以sidecar容器(大部分)的形式編排至主應(yīng)用的pod中,共享主應(yīng)用容器的網(wǎng)絡(luò)和環(huán)境變量,因此可以插件化實(shí)現(xiàn)某些附加功能,例如對主應(yīng)用進(jìn)行流量分析等。
Pod是Kubernetes中模塊化容器服務(wù)的實(shí)例,由一個(gè)或多個(gè)共享資源的容器組合而成,共享包括文件系統(tǒng)、內(nèi)核命名空間和IP地址等資源。它是Kubernetes集群中調(diào)度的原子單元,通過提供更高層次的抽象,實(shí)現(xiàn)靈活的部署和管理模式。
在以下Rainbond(www.rainbond.com)部署pod描述文件片段中,我們可以看到該pod中包含兩個(gè)containers:394d2f238a603bf01eb5215e23237691
(主容器)與22dc8b12aeaf417fa7bd6466c136b9f4
(副容器),兩者通過pod機(jī)制捆綁在一起,共同完成該server提供的服務(wù)。
kubectl describe pod -n b314b3e7e44e45a082a0d00e125e88bf b314b3e7e44e45a082a0d00e125e88bf Containers: 394d2f238a603bf01eb5215e23237691: Container ID: docker://44018fa19a268c1f9ea5b20e9793290cbd89b167bd1fc9017a04ecbd9606d379 Image: goodrain.me/tomcat:latest_gr237691 Image ID: docker-pullable://goodrain.me/tomcat@sha256:701d36cde0b55d07f59a65e525e258523aae46b033297f80b44b0b6c07fc0277 Port: 8080/TCP State: Running Started: Sun, 21 Jan 2018 14:56:35 +0800 Ready: True Restart Count: 0 Limits: cpu: 640m memory: 512Mi Requests: cpu: 120m memory: 512Mi 22dc8b12aeaf417fa7bd6466c136b9f4: Container ID: docker://4c8bd31c2ec2200ee323fb1abdd7b652544ce3d110b1621c36acab4bae434c77 Image: goodrain.me/tcm_20180117175939 Image ID: docker-pullable://goodrain.me/tcm_20180117175939@sha256:d2b20d7eec4da05d953fb7862b9c9ead76797ea5542bff4b93cf2bc98331d279 Port: State: Running Started: Sun, 21 Jan 2018 14:56:36 +0800 Ready: True Restart Count: 0 Limits: memory: 64Mi Requests: memory: 64Mi
一個(gè)pod可以封裝多個(gè)容器,應(yīng)用運(yùn)行在這些容器之中;同時(shí),pod可以有一個(gè)或者多個(gè)init容器,init容器在應(yīng)用容器啟動之前啟動。如果某個(gè)pod的init容器啟動運(yùn)行失敗,Kubernetes將不斷重啟pod,直到init容器啟動運(yùn)行成功為止。當(dāng)然,我們可以設(shè)定pod restartPolicy值為Never,阻止它重復(fù)啟動。
利用pod中容器可以共享存儲和網(wǎng)絡(luò)的能力,sidecar容器得以擴(kuò)展并增強(qiáng)“主要”容器,與之共存并使其工作得更好。在上面pod描述文件片段中,22dc8b12aeaf417fa7bd6466c136b9f4
就是一個(gè)sidecar類型的容器,用來協(xié)助分析主容器的一些性能指標(biāo)。
Rainbond插件體系易于使用的原則體現(xiàn)在類應(yīng)用化
、綁定使用
、獨(dú)有的變量作用域
等方面。
Rainbond插件體系為插件設(shè)計(jì)了與應(yīng)用類似的生命周期,包含創(chuàng)建、啟用、關(guān)閉等模式,與Rainbond平臺用戶操作應(yīng)用的習(xí)慣保持一致。同時(shí),Rainbond插件體系簡化了插件創(chuàng)建類型,支持基于docker image和dockerfile創(chuàng)建,創(chuàng)建插件比創(chuàng)建應(yīng)用更加簡單。
插件創(chuàng)建流程設(shè)計(jì)如下圖所示:
需要注意的是,當(dāng)一個(gè)插件版本固定后,其內(nèi)存、版本信息、插件變量無法再做修改,這些元素僅作用于當(dāng)前插件版本。需要修改插件變量等元素時(shí),對插件進(jìn)行重新構(gòu)建
,重復(fù)創(chuàng)建流程即可。
插件的創(chuàng)建和使用過程步驟相對獨(dú)立,用戶可以使用當(dāng)前租戶下創(chuàng)建的插件和其他團(tuán)隊(duì)(或租戶)分享到云市的插件(初期Rainbond將陸續(xù)為用戶提供數(shù)款插件)。
如果用戶沒有創(chuàng)建自己的插件,在使用插件前,需要先將他人分享在云市的插件安裝至本地。這個(gè)過程會將分享出來的插件元數(shù)據(jù)存儲至用戶租戶下,相當(dāng)于用戶“創(chuàng)建”了這個(gè)插件(并沒有耗時(shí)的構(gòu)建過程)。
創(chuàng)建完成后,用戶可以對插件進(jìn)行針對性設(shè)置,目前可以設(shè)置變量和插件生效與否(后續(xù)會增加內(nèi)存設(shè)定,滿足主應(yīng)用復(fù)雜情況下附加功能對應(yīng)內(nèi)存的需求)。內(nèi)存的限制將在pod創(chuàng)建時(shí)進(jìn)行限制,插件變量生效與實(shí)時(shí)修改在下文中會繼續(xù)介紹。
注入到容器內(nèi)的變量設(shè)計(jì)為有兩類:共用變量
與插件變量
。
共用變量就是主容器的變量,為使插件參與甚至擴(kuò)展主應(yīng)用的功能,在pod創(chuàng)建過程中將主應(yīng)用的環(huán)境變量注入到了插件容器中;插件變量則僅作用在該插件容器內(nèi)部,防止插件間的變量重復(fù)與混用。
Rainbond目前默認(rèn)為用戶提供性能分析和服務(wù)治理兩款插件,詳情訪問 http://www.rainbond.com/docs/stable/user-app-docs/myapps/myapp-platform-plugin.html查看。
以下我們以網(wǎng)絡(luò)代理插件為例,介紹Rainbond插件體系的工作過程。
用戶填入插件相關(guān)信息后,Rainbond將根據(jù)這些信息生成插件創(chuàng)建任務(wù),發(fā)送至Rainbond消息組件中,由任務(wù)發(fā)現(xiàn)器處理該任務(wù)消息。Rainbond的builder組件接受任務(wù)后,將會對插件進(jìn)行構(gòu)建,生成插件容器鏡像。一個(gè)插件容器鏡像對應(yīng)一個(gè)構(gòu)建版本,關(guān)聯(lián)其相應(yīng)的功能特色。在Rainbond中,插件將以一個(gè)構(gòu)建完成后的鏡像來進(jìn)行流通。類似于應(yīng)用,插件也可以在Rainbond及云市中進(jìn)行分享。
參照插件使用文檔,在應(yīng)用的插件tab中點(diǎn)擊安裝后,會對插件的當(dāng)前最新版本與應(yīng)用標(biāo)記為關(guān)聯(lián)。此時(shí)重啟應(yīng)用,在pod創(chuàng)建時(shí),會對插件進(jìn)行判斷,若存在插件,則進(jìn)行PluginContainerCreate
,pod的container list中將會包含主容器與插件容器。
網(wǎng)絡(luò)代理插件在Rainbond中又名servicemesh, 是一個(gè)功能增強(qiáng)容器,在pod中與主容器共享網(wǎng)絡(luò)。
網(wǎng)絡(luò)代理插件要完成其功能需要完全代理主容器的網(wǎng)絡(luò), 接管主容器的出入口。結(jié)構(gòu)如圖:
網(wǎng)絡(luò)代理分為出口網(wǎng)絡(luò)模式
、入口網(wǎng)絡(luò)模式
兩種。
出口網(wǎng)絡(luò)模式(示意圖中訪問tomcat應(yīng)用為出口網(wǎng)絡(luò)模式),圖中service mesh2 plugin通過discover_service
獲取tomcat應(yīng)用的網(wǎng)絡(luò)信息,包括listen ports,routers,endpoints等。這些信息由discover_service通過watching kubernetes集群中tomcat應(yīng)用的services和endpoints資源獲取。discover_service API相關(guān)請查看相關(guān)代碼 https://github.com/goodrain/rainbond/blob/master/pkg/node/api/router/discoverRouter.go
在service mesh2 plugin獲取所需的下游應(yīng)用信息后則開始監(jiān)聽本地對應(yīng)tomcat的端口,代理當(dāng)前應(yīng)用訪問tomcat的請求,例如curl http://tomcat
。
為何上述請求可以由pod內(nèi)的容器代理呢?這是由于DNS_service
將tomcat這類規(guī)則域名解析至本地,路由及負(fù)載均衡則全權(quán)交由service mesh2 plugin進(jìn)行,即客戶端負(fù)載均衡的模式。
入口網(wǎng)絡(luò)模式較之于出口模式類似(示意圖中由外網(wǎng)訪問進(jìn)入main container為入口網(wǎng)絡(luò)模式),復(fù)雜之處在于是對當(dāng)前應(yīng)用用戶設(shè)置端口的轉(zhuǎn)發(fā),由于本地監(jiān)聽所以無法和主容器監(jiān)聽相同的端口。
在處理這種場景時(shí),將service mesh2 plugin的監(jiān)聽端口進(jìn)行了轉(zhuǎn)化,在開啟插件時(shí)會隨機(jī)生成一個(gè)不重復(fù)的端口port_outer1
供給外層監(jiān)聽,service mesh2 plugin繼續(xù)轉(zhuǎn)發(fā)主應(yīng)用的原端口,在生成k8s的service和pod資源時(shí)由新端口替代原端口,并標(biāo)注對應(yīng)關(guān)系。
在外網(wǎng)負(fù)載均衡注冊這個(gè)應(yīng)用的外網(wǎng)端口訪問時(shí)會使用port_outer1
來進(jìn)行注冊。分配給用戶使用的域名則基于原端口與新端口的映射規(guī)則保持不變,用戶并無感知
相關(guān)組件discover_service
用戶在控制臺將應(yīng)用與插件首次關(guān)聯(lián)(安裝)后,插件就會對應(yīng)當(dāng)前應(yīng)用產(chǎn)生配置。經(jīng)由region端存儲至數(shù)據(jù)中心的etcd中。修改配置相應(yīng)的設(shè)置,進(jìn)行更新操作,則會修改對應(yīng)服務(wù)的插件資源。
分布式服務(wù)化架構(gòu)面臨的問題很多,想要實(shí)現(xiàn)服務(wù)化,服務(wù)治理是一個(gè)比較關(guān)鍵的點(diǎn)。在提供治理服務(wù)的基礎(chǔ)上,配置則需要實(shí)現(xiàn)實(shí)時(shí)生效和聯(lián)動。因此在rainbond設(shè)計(jì)中將插件的配置資源放置在了discover_service
中,由該發(fā)現(xiàn)服務(wù)來支持動態(tài)配置。
在Kubernetes創(chuàng)建pod時(shí),插件容器的env中注入了一個(gè)相關(guān)的環(huán)境變量DISCOVER_URL
,該變量的值為插件可以通過GET請求獲取資源的url。后續(xù)用戶在使用平臺創(chuàng)建自己所需的功能插件時(shí),這個(gè)變量也是你的插件獲取資源所必須的。
看完上述內(nèi)容,你們掌握如何理解Rainbond插件體系設(shè)計(jì)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!