1. 程式人生 > >Rainbond外掛體系設計簡介_Kubernetes中文社群

Rainbond外掛體系設計簡介_Kubernetes中文社群

過去幾年,利用容器打包和部署程式碼的方式日益流行,越來越多企業開始測試或是已經在生產環境中運行了微服務架構應用,開始直接面對和解決分散式服務化架構演變中出現的各種問題。
在這樣的趨勢和大環境下,無伺服器PaaS Rainbond圍繞著服務的拓展、監控、治理等角度,進行了一系列思考和嘗試,外掛體系正是其中的重要一環。

Rainbond的外掛體系抽象集中在平臺的業務層面,理論基礎源於Kubernetes的pod機制和一部分容器概念。針對平臺業務層面對kubernetes容器編排進行抽象,轉變為一個對使用者體驗友善的Rainbond外掛產品的過程,方便使用者在不需要懂Kubernetes原理的情況下使用。

設計原則

Rainbond外掛體系的設計遵循易於理解和易於使用的原則:

易於理解

在Rainbond外掛體系中,外掛使用的過程即主容器與init或sidecar等容器結合的過程,原理是將外掛容器以sidecar容器(大部分)的形式編排至主應用的pod中,共享主應用容器的網路和環境變數,因此可以外掛化實現某些附加功能,例如對主應用進行流量分析等。

Pod

Pod是Kubernetes中模組化容器服務的例項,由一個或多個共享資源的容器組合而成,共享包括檔案系統、核心名稱空間和IP地址等資源。它是Kubernetes叢集中排程的原子單元,通過提供更高層次的抽象,實現靈活的部署和管理模式。

在以下Rainbond(www.rainbond.com)部署pod描述檔案片段中,我們可以看到該pod中包含兩個containers:394d2f238a603bf01eb5215e23237691(主容器)與22dc8b12aeaf417fa7bd6466c136b9f4(副容器),兩者通過pod機制捆綁在一起,共同完成該server提供的服務。
kubectl describe pod -n b314b3e7e44e45a082a0d00e125e88bf b314b3e7e44e45a082a0d00e125e88bf
Containers: 394d2f238a603bf01eb5215e23237691: Container ID: docker://44018fa19a268c1f9ea5b20e9793290cbd89b167bd1fc9017a04ecbd9606d379 Image: goodrain.me/tomcat:latest_gr237691 Image ID: docker-pullable://goodrain.me/

[email protected]: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/
[email protected]
:d2b20d7eec4da05d953fb7862b9c9ead76797ea5542bff4b93cf2bc98331d279 Port: State: Running Started: Sun, 21 Jan 2018 14:56:36 +0800 Ready: True Restart Count: 0 Limits: memory: 64Mi Requests: memory: 64Mi

init容器

一個pod可以封裝多個容器,應用執行在這些容器之中;同時,pod可以有一個或者多個init容器,init容器在應用容器啟動之前啟動。如果某個pod的init容器啟動執行失敗,Kubernetes將不斷重啟pod,直到init容器啟動執行成功為止。當然,我們可以設定pod restartPolicy值為Never,阻止它重複啟動。

sidecar容器

利用pod中容器可以共享儲存和網路的能力,sidecar容器得以擴充套件並增強“主要”容器,與之共存並使其工作得更好。在上面pod描述檔案片段中,22dc8b12aeaf417fa7bd6466c136b9f4就是一個sidecar型別的容器,用來協助分析主容器的一些效能指標。

易於使用

Rainbond外掛體系易於使用的原則體現在類應用化、繫結使用、獨有的變數作用域等方面。

類應用化

Rainbond外掛體系為外掛設計了與應用類似的生命週期,包含建立、啟用、關閉等模式,與Rainbond平臺使用者操作應用的習慣保持一致。同時,Rainbond外掛體系簡化了外掛建立型別,支援基於docker image和dockerfile建立,建立外掛比建立應用更加簡單。 外掛建立流程設計如下圖所示:

需要注意的是,當一個外掛版本固定後,其記憶體、版本資訊、外掛變數無法再做修改,這些元素僅作用於當前外掛版本。需要修改外掛變數等元素時,對外掛進行重新構建,重複建立流程即可。

繫結使用 外掛的建立和使用過程步驟相對獨立,使用者可以使用當前租戶下建立的外掛和其他團隊(或租戶)分享到雲市的外掛(初期Rainbond將陸續為使用者提供數款外掛)。 如果使用者沒有建立自己的外掛,在使用外掛前,需要先將他人分享在雲市的外掛安裝至本地。這個過程會將分享出來的外掛元資料儲存至使用者租戶下,相當於使用者“建立”了這個外掛(並沒有耗時的構建過程)。 建立完成後,使用者可以對外掛進行鍼對性設定,目前可以設定變數和外掛生效與否(後續會增加記憶體設定,滿足主應用複雜情況下附加功能對應記憶體的需求)。記憶體的限制將在pod建立時進行限制,外掛變數生效與實時修改在下文中會繼續介紹。

獨有的變數作用域

注入到容器內的變數設計為有兩類:共用變數與外掛變數。

共用變數就是主容器的變數,為使外掛參與甚至擴充套件主應用的功能,在pod建立過程中將主應用的環境變數注入到了外掛容器中;外掛變數則僅作用在該外掛容器內部,防止外掛間的變數重複與混用。

Rainbond外掛體系的工作過程

外掛的構建生成

使用者填入外掛相關資訊後,Rainbond將根據這些資訊生成外掛建立任務,傳送至Rainbond訊息元件中,由任務發現器處理該任務訊息。Rainbond的builder元件接受任務後,將會對外掛進行構建,生成外掛容器映象。一個外掛容器映象對應一個構建版本,關聯其相應的功能特色。在Rainbond中,外掛將以一個構建完成後的映象來進行流通。類似於應用,外掛也可以在Rainbond及雲市中進行分享。

外掛與應用關聯及生效過程

參照外掛使用文件,在應用的外掛tab中點選安裝後,會對外掛的當前最新版本與應用標記為關聯。此時重啟應用,在pod建立時,會對外掛進行判斷,若存在外掛,則進行PluginContainerCreate,pod的container list中將會包含主容器與外掛容器。

代理網路

網路代理外掛在Rainbond中又名servicemesh, 是一個功能增強容器,在pod中與主容器共享網路。

網路代理外掛要完成其功能需要完全代理主容器的網路, 接管主容器的出入口。結構如圖:


網路代理分為出口網路模式、入口網路模式兩種。

出口網路模式

出口網路模式(示意圖中訪問tomcat應用為出口網路模式),圖中service mesh1 plugin通過discover_service獲取tomcat應用的網路資訊,包括listen ports,routers,endpoints等。這些資訊由discoverservice通過watching kubernetes叢集中tomcat應用的services和endpoints資源獲取。discover_service API相關請檢視相關程式碼 _https://github.com/goodrain/rainbond/blob/master/pkg/node/api/router/discoverRouter.go
在service mesh1 plugin獲取所需的下游應用資訊後則開始監聽本地對應tomcat的埠,代理當前應用訪問tomcat的請求,例如curl http://tomcat。 為何上述請求可以由pod內的容器代理呢?這是由於dns_service將tomcat這類規則域名解析至本地,路由及負載均衡則全權交由service mesh1 plugin進行,即客戶端負載均衡的模式。

入口網路模式

入口網路模式較之於出口模式類似(示意圖中由外網訪問進入main container為入口網路模式),複雜之處在於是對當前應用使用者設定埠的轉發,由於本地監聽所以無法和主容器監聽相同的埠。

在處理這種場景時,將service mesh1 plugin的監聽埠進行了轉化,在開啟外掛時會隨機生成一個不重複的埠port_outer1供給外層監聽,service mesh1 plugin繼續轉發主應用的原埠,在生成k8s的service和pod資源時由新埠替代原埠,並標註對應關係。

在外網負載均衡註冊這個應用的外網埠訪問時會使用port_outer1來進行註冊。分配給使用者使用的域名則基於原埠與新埠的對映規則保持不變,使用者並無感知

動態配置與資源發現

相關元件discover_service

下圖為Rainbond提供的服務治理外掛配置:

使用者在控制檯將應用與外掛首次關聯(安裝)後,外掛就會對應當前應用產生配置。經由region端儲存至資料中心的etcd中。修改配置相應的設定,進行更新操作,則會修改對應服務的外掛資源。
分散式服務化架構面臨的問題很多,想要實現服務化,服務治理是一個比較關鍵的點。在提供治理服務的基礎上,配置則需要實現實時生效和聯動。因此在rainbond設計中將外掛的配置資源放置在了discover_service中,由該發現服務來支援動態配置。

在Kubernetes建立pod時,外掛容器的env中注入了一個相關的環境變數DISCOVER_URL,該變數的值為外掛可以通過GET請求獲取資源的url。後續使用者在使用平臺建立自己所需的功能外掛時,這個變數也是你的外掛獲取資源所必須的。
相關程式碼請檢視 https://github.com/goodrain/rainbond/blob/master/pkg/worker/appm/pod.go

關於Rainbond

Rainbond是國內首個開源的無伺服器PaaS,深度整合基於Kubernetes的容器管理、多型別CI/CD應用構建與交付、多資料中心的資源管理等技術,提供雲原生應用全生命週期解決方案,構建應用與基礎設施、應用之間及基礎設施之間的互聯互通生態體系。

點選檢視Rainbond專案原始碼文件,歡迎Watch、STAR、FORK、參與貢獻!