OpenStack計費項目Cloudkitty系列詳解(一)


雲計算是一種按需付費的服務模式,雖然OpenStack前期在計量方面走了些“彎路”,但現在的ceilometer、gnocchi、aodh、panko項目的穩步並進算是讓其峰回路轉。然而,目前來看OpenStack的計費項目Cloudkitty並未柳暗花明,為此,借助本文向大家介紹Cloudkitty的架構、用戶使用指導、開發以及社區方面的最新動態,希望可以吸引更多方面的關注、使用和社區參與。

當前upstream版本Cloudkitty可以完成虛擬機實例(compute)、雲硬盤(volume)、鏡像(image)、網絡進出流量(network.bw.in, network.bw.out)、浮動IP(network.floating)的計費。得益於Cloudkitty的巧妙而優秀的設計,軟件插件化思想更是體現的淋漓盡致,使得添加新的計費源異常容易,版本升級也十分方便。同樣也能方便將Cloudkitty用於cloudstack、VMWare等環境中。
Cloudkitty主要依賴於遙測相關的項目,包括ceilometer和gnocchi,甚至是將要使用panko;計費策略和hashmap計費模型是其核心;模塊插件化是其設計靈魂;接下來的三個部分內容將帶您逐步探索。
第一部分:Cloudkitty架構詳解本部分為理論架構篇,將會詳細介紹當前Cloudkitty的整體架構,包括計費服務的對象獲取(Tenant Fetcher)、計費數據源的收集(Collector)、計費引擎(Rating)的實現,計費費用數據的存儲(Storage);另外將重點介紹hashmap計費模型。
 一、計費服務對象Tenant FetcherTenant Fetcher是用來獲取合法的計費服務對象,即Cloudkitty要知道需要對誰的資源進行計費。當前具體實現了從csv文件中獲取和keystone中獲取兩種方式,分別對應FakeFetcher類和KeystoneFetcher類,均實現了父類的get_tenants抽象方法。所以只要繼承基類BaseFetcher實現get_tenants方法,並配置tenant_fetcher后端,就能處理xls文件完成從Excel文檔中獲取需要計費的租戶信息。
Keystone是默認的獲取計費租戶的方式,同時支持V2和V3版本。具體邏輯是檢查Cloudkitty用戶是否在某個tenant內並擁有rating角色。所以在使用Cloudkitty時,一般對於想要計費的租戶需要執行命令’keystone user-role-add --user cloudkitty --role rating --tenant demo’,將Cloudkitty用戶加入租戶並賦予rating角色。
 二、計費源數據收集Collector和統一化Transformer單純從計費角度來看,計費源主要有兩類,一類是靜態資源,比如虛擬機實例、鏡像、雲硬盤、浮動IP;一類是動態資源,比如網絡流量。對於靜態資源一旦被創建,那么它的單價就固定,只需根據其生命周期按時間長短計費即可;對於動態資源需要統計計量情況進行計算費用。這就意味着計費的數據源應該包括event和measurement兩部分,但當前Cloudkitty在計費數據收集方面沒有加入事件分析能力。
這一步除了計費源數據的收集,還有一個十分重要的工作就是把這些數據轉化為統一格式輸入給計費引擎。Cloudkitty中的transformer模塊將針對不同collector的不同類型的服務數據進行格式統一。這里需要特別說明的是transformer過程一般情況下分為兩個階段:

第一個階段是將資源數據通過對應的CeilometerTransformer或者GnocchiTransformer進行轉換。

第二階段是使用CloudKittyFormatTransformer統一數據格式為data = [{'usage': {'service_type': [{'vol': {'unit': xx, 'qty': xxx}, 'desc': {'xxx': 'xxx',…, 'metadata': {‘xxx’: ’xxx’}}}]}, 'period': {'begin': xxxxx, 'end': xxxxx}}]交付給計費引擎。當然在不需要對資源數據進行轉化的情況下,也可以直接使用CloudKittyFormatTransformer將數據轉化為計費引擎所能識別的格式。


collector和transformer模塊分別有多種實現,collector實現了ceilometer,fake,gnocchi和 meta四種方式,transformer實現了CeilometerTransformer,GnocchiTransformer以及通用的CloudKittyFormatTransformer三種方式。所以這兩個模塊分別提供了get_collector和get_transformers方法,根據后端配置動態選擇對應的插件,具體是使用stevedore模塊的driver方式和extension方式加載實現的。
每種collector的實現最終都會通過retrieve函數將歸一化的數據發送給計費引擎。對於ceilometer和fake,這個retrieve函數會根據不同的服務調用get_compute,get_image,get_volume,get_network_bw_in,get_network_bw_out,get_network_floating,這六個方法就分別對應着cloudkitty的計費服務compute, image, volume, network.bw.in, network.bw.out, network.floating。而每個方法獲得相關服務數據后會做transformer處理返回給計費引擎,最終計費引擎根據計費模型計算出具體費用再將費用數據存儲起來便完成了整個計費流程。

對於gnocchi,它的retrieve函數則有所不同,gnocchi直接使用自己的metric.get_measures和resource.search方法獲得相關資源數據。這恰恰也體現了cloudkitty collector模塊的插件化,並且實現上非常靈活,意味着如果想為CloudStack,Eucalyptus,OpenNebula等IaaS平台添加collector插件也是件愉快而輕松的事。


  三、計費引擎RatingOrchestrator類是Cloudkitty計費引擎的具體實現,支持多線程,支持多種計費模型同時運行,並能指定優先級。在計費策略上Cloudkitty采用的是周期輪詢計費的方式,默認是每一小時對雲環境中所需計費的資源進行費用核算,並將費用數據持久化存儲起來。還有一個大周期是當月內,如果rated_data_frames表中的數據是空的時候,每次啟動cloudkitty-processor就會重新計算當月內每小時的費用(這對調試Cloudkitty也很有幫助)。
Cloudkitty當前的計費模型有三個,分別是noop,hashmap和pyscripts。
1、noop模型為空,僅作為測試用;2、hashmap是當前Cloudkitty實用價值最高,最容易使用,最接近實際案例的計費模型,后文將單獨做詳細介紹;3、pyscripts計費模型提供了使用python代碼定制計費的接口,用戶可以直接將含有計費邏輯的python腳本上傳給cloudkitty實現定制化的計費,所以pyscripts計費模型使用門檻較高。 計費模型的設計和實現相對比較復雜,首先計費模型要具有enabled和priority屬性並能設置,借助stevedore作為插件注冊到cloudkitty.rating.processors命名空間內;其次要實現抽象方法process執行具體的費用計算邏輯;最后還需要借助pecan提供對外使用的Rest API接口。但是hashmap計費模型目前能完成絕大部分實際場景需求的計費工作,后文將對它做詳細介紹。關於大家關心的按秒計費,需要加入event分析后才比較容易實現,這塊內容將在第三部分提到,也是我接下來的主要計划。
 四、費用數據的存儲Storage前面提到Cloudkitty的計費引擎是周期性計算資源費用的,而這個周期可以根據實際情況修改,只要能在一個計費周期內完成所有資源的費用計算即可。對應一項資源的服務默認在一個小時的計費周期下,一個月內就會有720條的費用數據生成,如果將計費周期調得更小,雲環境中的需要計費的資源更多,那么將會對費用數據的存儲帶來挑戰,它會直接影響到數據的使用效果,因此費用數據的存儲也是一個重要的環節。 Cloudkitty的storage目前支持sqlalchemy和gnocchi_hybrid兩種方式存放費用數據,因為它們都是通過插件方式實現的,所以具體采用哪種可以通過配置文件指定,再通過get_storage方法獲得具體storage實例,十分靈活方便。 Storage的具體實現過程包括:(1)通過抽象方法get_time_frame從存儲后端中的數據來確定下一個時間范圍。(2)通過append方法將費用數據記入提交緩存,期間可能會通過get_tenants函數和_dispatch函數做預處理或加工。(3)通過commit函數將費用數據寫入到后端存儲持久化。這個過程會做_pre_commit,_commit,_post_commit一系列的工作確保數據被可靠地存儲。(4)對外提供get_total方法,返回費用情況。 sqlalchemy和gnocchi_hybrid的數據格式或者說表的結構都包括begin, end, unit, qty, res_type, rate, tenant_id和對資源描述相關的字段。實際上兩種后端存儲都是基於SQL實現的,所以隨着時間的推移和雲環境中需要計費資源的增加,費用數據的增加同樣會出現之前類似ceilometer用SQL存儲measurement數據帶來性能瓶頸的問題。所以將費用數據存儲在gnocchi中是必須的,詳見https://review.openstack.org/#/c/319425/
 五、hashmap計費模型Hashmap計費模型是Cloudkitty的核心,其數據結構如下圖所示,接着是hashmap計費模型中的幾個元素及核心概念。

  • Hashmap Group:一個Group表示一組計費規則,例如你可以創建多個計費規則,將它們分成兩組來分別為instance和volume計費,避免計費規則混亂。

 

  • Hashmap Service:一個Service將計費規則映射到具體的數據collector,例如compute,volume,image,network.bw.in,network.bw.out,network.floating。

 

  • Hashmap Field:一個Field通常是指某個資源元數據metadata字典中的一個字段。例如對於instance,可以指定Field為flavor,availability_zone等;對於volume可以指定Field為volume_type,availability_zone和status等。既可以為Field指定mapping類型的計費規則也能指定Threshold類型的計費規則。

 

  • Hashmap Mapping: 一個Mapping是指某個最終的計費規則,mapping這類計費規則可以為某個服務指定價格,也可以為Field指定價格。例如你可以指定compute服務的基礎價格Flat=10$,這會適用於所有的雲主機;同時你也能具體指定flavor name,value=m1.tiny,Rate=1.2,則flavor為m1.tiny的雲主機價格就為10$*1.2=12$,value=m1.medium,Flat=20$,則flavor為m1.medium的雲主機價格就是20$;再例如指定volume的基礎單價為2$,選定Field為volume_type,SATA類型打九五折value=sata,Rate=0.95,則sata盤的單價就是2$*0.95=1.9$;SAS為標准雲硬盤不打折,則不用設定,單價依然為2$;SSD為高速硬盤應加價0.2倍value=ssd,Rate=1.2,則ssd盤的單價就是2$*1.2=2.4$。

 

  • Hashmap Threshold:Threshold是另外一種最終計費規則,threshold這類計費規則更適用於基於level的Rate價格。例如雲硬盤基礎單價為2$(可用mapping設定),如果用戶購買超過50GB,可以打九折Level=50,Rate=0.9,此時單價為2$*0.9=1.8$;超過100GB打八折Level=100,Rate=0.8,此時單價為2$*0.8=1.6$。


通過以上介紹和具體舉例,說明hashmap計費模型具有較廣泛的使用范圍,能滿足實際需求中較復雜的計費場景。總結一下hashmap計費模型,它可以直接為資源或者服務設定價格(Flat或者Rate);也能根據資源的Field設定mapping和threshold類型的價格(Flat或者Rate);還能根據資源某字段的Level設定價格(Rate為主)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM