0. 前言
今年的2月22日,OpenStack發(fā)布了15個(gè)版本Ocata。走過了7年的發(fā)展歲月的OpenStack已經(jīng)成為了云計(jì)算領(lǐng)域中最火熱的項(xiàng)目之一,并逐漸成為IaaS的事實(shí)標(biāo)準(zhǔn),私有云項(xiàng)目的部署首選。OpenStack社區(qū)可能自己都沒有想到其發(fā)展會(huì)如此之迅速,部署規(guī)模如此之大,以至于最開始對(duì)大規(guī)模OpenStack集群的部署支持以及持續(xù)可擴(kuò)展性似乎并沒有考慮完備。
眾所周知,OpenStack每一個(gè)項(xiàng)目都會(huì)有數(shù)據(jù)庫(kù)的訪問以及消息隊(duì)列的使用,而數(shù)據(jù)庫(kù)和消息隊(duì)列是整個(gè)OpenStack擴(kuò)展的瓶頸。尤其是消息隊(duì)列,伴隨著集群規(guī)模的擴(kuò)展,其性能下降是非常明顯的。通常情況下,當(dāng)集群規(guī)模擴(kuò)展到200個(gè)節(jié)點(diǎn),一個(gè)消息可能要在十幾秒后才會(huì)響應(yīng),集群的整體性能大大下降[1],英國(guó)電信主管Peter Willis聲稱一個(gè)獨(dú)立OpenStack集群只能最多管理500個(gè)計(jì)算節(jié)點(diǎn)[2]。
當(dāng)處理大規(guī)模問題時(shí),我們自然會(huì)想到分而治之策略,其思想是將一個(gè)規(guī)模為N的問題分解為K個(gè)規(guī)模較小的子問題,這些子問題相互獨(dú)立且與原問題性質(zhì)相同,解決了子問題就能解決原問題。社區(qū)提出的多Region、多Cells以及Cascading等方案都是基于分而治之策略,但它們又有所區(qū)別,主要體現(xiàn)在分治的層次不一樣,多Region和Cascading方案思想都是將一個(gè)大的集群劃分為一個(gè)個(gè)小集群,每個(gè)小集群幾乎是一個(gè)完整的OpenStack環(huán)境,然后通過一定的策略把小集群統(tǒng)一管理起來,從而實(shí)現(xiàn)使用OpenStack來管理大規(guī)模的數(shù)據(jù)中心。
在Grizzly版本引入的Nova Cells概念,其思想是將不同的計(jì)算資源劃分為一個(gè)個(gè)的Cell,每個(gè)Cell都使用獨(dú)立的消息隊(duì)列和數(shù)據(jù)庫(kù)服務(wù),從而解決了數(shù)據(jù)庫(kù)和消息隊(duì)列的瓶頸問題,實(shí)現(xiàn)了規(guī)模的可擴(kuò)展性。遺憾的是,目前社區(qū)還沒有一個(gè)非常完美的OpenStack大規(guī)模部署方案,以上提到的方案都存在各自的優(yōu)點(diǎn)和缺點(diǎn),實(shí)際部署時(shí)應(yīng)根據(jù)物理資源的分布情況、用戶資源需求等因素綜合選擇。本文接下來將談?wù)凮penStack大規(guī)模部署問題,討論前面提到的各個(gè)方案的優(yōu)缺點(diǎn)以及分別適用的場(chǎng)景。
1. 單集群優(yōu)化策略
1.1 使用獨(dú)立的數(shù)據(jù)庫(kù)和消息隊(duì)列
前面提到限制OpenStack規(guī)模增長(zhǎng)的最主要因素之一就是由于數(shù)據(jù)庫(kù)和消息隊(duì)列的性能瓶頸,因此如果能夠有效減輕數(shù)據(jù)庫(kù)以及消息隊(duì)列的負(fù)載,理論上就能繼續(xù)增長(zhǎng)節(jié)點(diǎn)數(shù)量。各個(gè)服務(wù)使用獨(dú)立的數(shù)據(jù)庫(kù)以及消息隊(duì)列顯然能夠有效減小數(shù)據(jù)庫(kù)和消息隊(duì)列的負(fù)載。在實(shí)踐中發(fā)現(xiàn),以下服務(wù)建議使用獨(dú)立的數(shù)據(jù)庫(kù)以及消息隊(duì)列:
1.Keystone: 用戶以及其它API服務(wù)的認(rèn)證都必須經(jīng)過Keystone組件,每次Token驗(yàn)證都需要訪問數(shù)據(jù)庫(kù),隨著服務(wù)的增多以及規(guī)模的增大,數(shù)據(jù)庫(kù)的壓力將會(huì)越來越大,造成Keystone的性能下降,拖垮其它所有服務(wù)的API響應(yīng)。因此為Keystone組件配置專門的數(shù)據(jù)庫(kù)服務(wù),保證服務(wù)的高性能。
2.Ceilometer:Ceilometer是一個(gè)資源巨耗型服務(wù),在收集消息和事件時(shí)會(huì)發(fā)送大量的消息到隊(duì)列中,并頻繁寫入數(shù)據(jù)庫(kù)。為了不影響其它服務(wù)的性能,Ceilometer通常都搭配專有的數(shù)據(jù)庫(kù)服務(wù)和消息隊(duì)列。
3.Nova: OpenStack最活躍的主體就是虛擬機(jī),而虛擬機(jī)的管理都是由Nova負(fù)責(zé)的。幾乎所有對(duì)虛擬機(jī)的操作都需要通過消息隊(duì)列發(fā)起RPC請(qǐng)求,因此Nova是隊(duì)列的高生產(chǎn)者和高消費(fèi)者,當(dāng)集群規(guī)模大時(shí),需要使用獨(dú)立的消息隊(duì)列來支撐海量消息的快速傳遞。
4.Neutron:Neutron管理的資源非常多,包括網(wǎng)絡(luò)、子網(wǎng)、路由、Port等,數(shù)據(jù)庫(kù)和消息隊(duì)列訪問都十分頻繁,并且數(shù)據(jù)量還較大,使用的獨(dú)立的數(shù)據(jù)庫(kù)服務(wù)和消息隊(duì)列既能提高Neutron本身的服務(wù)性能,又能避免影響其它服務(wù)的性能。
1.2 使用Fernet Token
前面提到每當(dāng)OpenStack API收到用戶請(qǐng)求時(shí)都需要向Keystone驗(yàn)證該Token是否有效,Token是直接保存在數(shù)據(jù)庫(kù)中的,增長(zhǎng)速率非???,每次驗(yàn)證都需要查詢數(shù)據(jù)庫(kù),并且Token不會(huì)自動(dòng)清理而越積越多,導(dǎo)致查詢的性能越來越慢,Keystone驗(yàn)證Token的響應(yīng)時(shí)間會(huì)越來越長(zhǎng)。所有的OpenStack服務(wù)都需要通過Keystone服務(wù)完成認(rèn)證,Keystone的性能下降,將導(dǎo)致其它所有的服務(wù)性能下降,因此保證Keystone服務(wù)的快速響應(yīng)至關(guān)重要。除此之外,如果部署了多Keystone節(jié)點(diǎn),還需要所有的節(jié)點(diǎn)同步Token,可能出現(xiàn)同步延遲而導(dǎo)致服務(wù)異常。為此社區(qū)在Kilo版本引入了Fernet Token,與UUID Token以及PKI Token不同的是它是基于對(duì)稱加密技術(shù)對(duì)Token加密,只需要擁有相同加密解密文件,就可以對(duì)Token進(jìn)行驗(yàn)證,不需要持久化Token,也就無需存在數(shù)據(jù)庫(kù)中,避免了對(duì)數(shù)據(jù)庫(kù)的IO訪問,創(chuàng)建Token的速度相對(duì)UUID Token要快,不過驗(yàn)證Token則相對(duì)要慢些[3]。因此在大規(guī)模OpenStack集群中建議使用Fernet Token代替?zhèn)鹘y(tǒng)的Token方案。
以上優(yōu)化策略能夠一定程度上減少消息隊(duì)列和數(shù)據(jù)庫(kù)的訪問,從而增大節(jié)點(diǎn)部署規(guī)模,但其實(shí)并沒有根本解決擴(kuò)展問題,隨著部署規(guī)模的增長(zhǎng),總會(huì)達(dá)到瓶頸,理論上不可能支持無限擴(kuò)展。
2. 多Region方案
OpenStack支持將集群劃分為不同的Region,所有的Regino除了共享Keystone、Horizon、Swift服務(wù),每個(gè)Region都是一個(gè)完整的OpenStack環(huán)境,其架構(gòu)如下:
部署時(shí)只需要部署一套公共的Keystone和Horizon服務(wù),其它服務(wù)按照單Region方式部署即可,通過Endpoint指定Region。用戶在請(qǐng)求任何資源時(shí)必須指定具體的區(qū)域。采用這種方式能夠把分布在不同的區(qū)域的資源統(tǒng)一管理起來,各個(gè)區(qū)域之間可以采取不同的部署架構(gòu)甚至不同的版本。其優(yōu)點(diǎn)如下:
1.部署簡(jiǎn)單,每個(gè)區(qū)域部署幾乎不需要額外的配置,并且區(qū)域很容易實(shí)現(xiàn)橫向擴(kuò)展。
2.故障域隔離,各個(gè)區(qū)域之間互不影響。
3.靈活自由,各個(gè)區(qū)域可以使用不同的架構(gòu)、存儲(chǔ)、網(wǎng)絡(luò)。
但該方案也存在明顯的不足:
1.各個(gè)區(qū)域之間完全隔離,彼此之間不能共享資源。比如在Region A創(chuàng)建的Volume,不能掛載到Region B的虛擬機(jī)中。在Region A的資源,也不能分配到Region B中,可能出現(xiàn)Region負(fù)載不均衡問題。
2.各個(gè)區(qū)域之間完全獨(dú)立,不支持跨區(qū)域遷移,其中一個(gè)區(qū)域集群發(fā)生故障,虛擬機(jī)不能疏散到另一個(gè)區(qū)域集群中。
3.Keystone成為最主要的性能瓶頸,必須保證Keystone的可用性,否則將影響所有區(qū)域的服務(wù)。該問題可以通過部署多Keystone節(jié)點(diǎn)解決。
OpenStack多Region方案通過把一個(gè)大的集群劃分為多個(gè)小集群統(tǒng)一管理起來,從而實(shí)現(xiàn)了大規(guī)模物理資源的統(tǒng)一管理,它特別適合跨數(shù)據(jù)中心并且分布在不同區(qū)域的場(chǎng)景,此時(shí)根據(jù)區(qū)域位置劃分Region,比如北京和上海。而對(duì)于用戶來說,還有以下好處:
1.用戶能根據(jù)自己的位置選擇離自己最近的區(qū)域,從而減少網(wǎng)絡(luò)延遲,加快訪問速度。
2.用戶可以選擇在不同的Region間實(shí)現(xiàn)異地容災(zāi)。當(dāng)其中一個(gè)Region發(fā)生重大故障時(shí),能夠快速把業(yè)務(wù)遷移到另一個(gè)Region中。
但是需要注意的是,多Region本質(zhì)就是同時(shí)部署了多套OpenStack環(huán)境,確切地說并沒有解決單OpenStack集群的大規(guī)模部署問題。
3. OpenStack Cascading方案以及Trio2o項(xiàng)目
OpenStack Cascading方案[9]是由國(guó)內(nèi)華為提出的用于支持場(chǎng)景包括10萬主機(jī)、百萬虛機(jī)、跨多DC的統(tǒng)一管理的大規(guī)模OpenStack集群部署。它采取的策略同樣是分而治之,即把原來一個(gè)大的OpenStack集群拆分成多個(gè)小集群,并把拆分的小集群級(jí)聯(lián)起來統(tǒng)一管理,其原理如圖:
1.只有最頂層的OpenStack暴露標(biāo)準(zhǔn)OpenStack API給用戶,其包含若干個(gè)子OpenStack集群。
2.底層的OpenStack負(fù)責(zé)實(shí)際的資源分配,但不暴露API給用戶,而必須通過其之上的OpenStack調(diào)度。
用戶請(qǐng)求資源時(shí),首先向頂層OpenStack API發(fā)起請(qǐng)求,頂層的OpenStack會(huì)基于一定的調(diào)度策略選擇底層的其中一個(gè)OpenStack,被選中的底層OpenStack負(fù)責(zé)實(shí)際的資源分配。
該方案號(hào)稱支持跨多達(dá)100個(gè)DC,支持10萬個(gè)計(jì)算節(jié)點(diǎn)部署規(guī)模,能同時(shí)運(yùn)行100萬個(gè)虛擬機(jī)[10]。但該方案目前仍處于開發(fā)和測(cè)試階段,尚無公開的實(shí)際部署案例。目前該方案已經(jīng)分離出兩個(gè)獨(dú)立的big-tent項(xiàng)目,一個(gè)是Tricircle,專門負(fù)責(zé)網(wǎng)絡(luò)相關(guān)以及對(duì)接Neutron,另一個(gè)項(xiàng)目是Trio2o,為多Region OpenStack集群提供統(tǒng)一的API網(wǎng)關(guān)。
4. Nova Cells方案
前面提到的OpenStack多Region方案是基于OpenStack環(huán)境切分,它對(duì)用戶可見而非透明的,并且單集群依然不具備支撐大規(guī)模的能力和橫向擴(kuò)展能力。而Nova Cells方案是針對(duì)服務(wù)級(jí)別劃分的,其最終目標(biāo)是實(shí)現(xiàn)單集群支撐大規(guī)模部署能力和具備靈活的擴(kuò)展能力。Nova Cells方案是社區(qū)支持的方案,因此本文將重點(diǎn)介紹,并且會(huì)總結(jié)下在實(shí)際部署中遇到的問題。
4.1 Nova Cells架構(gòu)和原理介紹
Nova Cells模塊是OpenStack在G版本中引入的,其策略是將不同的計(jì)算資源劃分成一個(gè)個(gè)Cell,并以樹的形式組織,如圖所示:
(圖2 Nova Cell架構(gòu))
從圖中看出,Cells的結(jié)構(gòu)是樹形的,一個(gè)Cell可能包含若干子Cell,以此逐級(jí)向下擴(kuò)展。每個(gè)Cell都有自己獨(dú)立的消息隊(duì)列和數(shù)據(jù)庫(kù),從而解決了消息隊(duì)列和數(shù)據(jù)庫(kù)的性能瓶頸問題,Cell與Cell之間主要通過Nova-Cells負(fù)責(zé)通信,一層一層通過消息隊(duì)列傳遞消息,每個(gè)Cell都需要知道其Parent Cell以及所有孩子Cells的消息隊(duì)列地址,這些信息可以保存到該Cell的數(shù)據(jù)庫(kù)中,也可以通過json文件指定:
{
"parent": {
"name": "parent",
"api_url": "http://api.example.com:8774",
"transport_url": "rabbit://rabbit.example.com",
"weight_offset": 0.0,
"weight_scale": 1.0,
"is_parent": true
},
"cell1": {
"name": "cell1",
"api_url": "http://api.example.com:8774",
"transport_url": "rabbit://rabbit1.example.com",
"weight_offset": 0.0,
"weight_scale": 1.0,
"is_parent": false
},
"cell2": {
"name": "cell2",
"api_url": "http://api.example.com:8774",
"transport_url": "rabbit://rabbit2.example.com",
"weight_offset": 0.0,
"weight_scale": 1.0,
"is_parent": false
}}
根據(jù)節(jié)點(diǎn)所在樹中位置以及功能,分為兩種Cell類型:
1.api cell,非葉子節(jié)點(diǎn),該類型的Cell不包含計(jì)算節(jié)點(diǎn),但包括了一系列子Cells,子Cells會(huì)繼續(xù)調(diào)度直到到達(dá)葉子節(jié)點(diǎn),即Compute Vell中。其中最頂層的根節(jié)點(diǎn)通常也叫作Top Cell。
2.compute cell,葉子節(jié)點(diǎn),包含一系列計(jì)算節(jié)點(diǎn)。負(fù)責(zé)轉(zhuǎn)發(fā)請(qǐng)求到其所在的Nova-Conductor服務(wù)。
注意: 所有的Nova服務(wù)都隸屬于某個(gè)Cell中,所有的Cells都必須指定Cell類型。
每個(gè)Cell節(jié)點(diǎn)都有從根節(jié)點(diǎn)到該節(jié)點(diǎn)的唯一路徑,路徑默認(rèn)通過!分割,比如root!cell_1!cell_13,表示從root到cell_1再到cell_13。根節(jié)點(diǎn)的Cell類型一定是API就是說Cell對(duì)用戶是完全透明的,和不使用Cell時(shí)是完全一樣的。其中Nova-Cells服務(wù)是需要額外部署的新服務(wù),該服務(wù)主要負(fù)責(zé)創(chuàng)建虛擬機(jī)時(shí),從所有的孩子Cell中選擇其中一個(gè)子Cell作為虛擬機(jī)的Cell,子Cell會(huì)繼續(xù)執(zhí)行調(diào)度直到到達(dá)底層的Compute Cell中,最后轉(zhuǎn)發(fā)請(qǐng)求到目標(biāo)Compute Cell所在的Nova-Conductor服務(wù)中。因此采用Nova Cells方案后,Nova實(shí)際采用的是二級(jí)調(diào)度策略,第一級(jí)由Nova-Cells服務(wù)負(fù)責(zé)調(diào)度Cell,第二級(jí)由Nova-Scheduler服務(wù)負(fù)責(zé)調(diào)度計(jì)算節(jié)點(diǎn)。
Compute Cell節(jié)點(diǎn)擔(dān)任的職責(zé)類似于非Cell架構(gòu)的控制節(jié)點(diǎn),需要部署除Nova-API服務(wù)以外的所有其它Nova服務(wù),每個(gè)Cell相當(dāng)于一個(gè)完整的Nova環(huán)境,擁有自己的Nova-Conductor、Nova-Scheduler等服務(wù)以及數(shù)據(jù)庫(kù)服務(wù)和消息隊(duì)列服務(wù),并且包含若干計(jì)算節(jié)點(diǎn),每個(gè)Cell的組件只服務(wù)于其自身所在的Cell,而不是整個(gè)集群,因此天生具備支撐單集群大規(guī)模部署能力。增大規(guī)模時(shí),只需要相應(yīng)增加Cell即可,因此具有非常靈活的可擴(kuò)展能力。
子Cell的虛擬機(jī)信息會(huì)逐層向上同步復(fù)制到其父Cell中,Top Cell中包含了所有Cells的虛擬機(jī)信息,查看虛擬機(jī)信息時(shí),只需要從Top Cell數(shù)據(jù)庫(kù)查詢即可,不需要遍歷子Cell數(shù)據(jù)庫(kù)。對(duì)虛擬機(jī)進(jìn)行操作時(shí),如果不使用Cell,則只需要根據(jù)其Host字段,向宿主機(jī)發(fā)送RPC請(qǐng)求即可。如果使用了Cell,則需要首先獲取虛擬機(jī)的Cell信息,通過Cell信息查詢消息隊(duì)列地址,然后往目標(biāo)消息隊(duì)列發(fā)送RPC請(qǐng)求。
4.2 Nova Cell生產(chǎn)案例
Nova Cells方案很早就已經(jīng)存在一些生產(chǎn)案例了,其中CERN(歐洲原子能研究中心)OpenStack集群可能是目前公開的規(guī)模最大的OpenStack部署集群,截至2016年2月部署規(guī)模如下[7]:
1.單Region,33個(gè)Cell。
2.2個(gè)Ceph集群。
3.~5500個(gè)計(jì)算節(jié)點(diǎn),5300KVM和200Hyper-V,總包含140k Cores。
4.超過17000個(gè)虛擬機(jī)。
5.~2800個(gè)鏡像,占44TB存儲(chǔ)空間。
6.~2000個(gè)Volumes,已分配800TB。
7.~2200個(gè)注冊(cè)用戶,超過2500個(gè)租戶。
其Nova部署架構(gòu)如下圖:
圖3 CERN OpenStack集群Nova架構(gòu)
天河二號(hào)是國(guó)內(nèi)千級(jí)規(guī)模的典型案例之一,于2014年初就已經(jīng)在國(guó)家超算廣州中心并對(duì)外提供服務(wù),其部署規(guī)模如下[5]:
1.單Region,8個(gè)Cell。
2.每個(gè)Cell包含2個(gè)控制節(jié)點(diǎn)和126個(gè)計(jì)算節(jié)點(diǎn)。
3.總規(guī)模1152個(gè)物理節(jié)點(diǎn)。
4.一次能創(chuàng)建大約5000個(gè)左右虛擬機(jī)。
5.每秒可查詢約1000個(gè)虛擬機(jī)信息。
除了以上兩個(gè)經(jīng)典案例外,Rackspace、NeCTAR、Godaddy[6]、Paypal等也是采用了Nova Cells方案支持千級(jí)規(guī)模的OpenStack集群部署。這些生產(chǎn)案例實(shí)踐證明了使用Nova Cells支持大規(guī)模OpenStack集群的可能性。
4.3 Nova Cells遇到的坑
剛剛介紹了不少Nova Cells的成功生產(chǎn)案例,讓人不禁“蠢蠢欲動(dòng)”,想要小試牛刀。小編已經(jīng)架不住誘惑,于是專門申請(qǐng)了23臺(tái)物理服務(wù)器作為Nova Cells測(cè)試環(huán)境使用,實(shí)際部署時(shí)包含3個(gè)Cells,每個(gè)Cell包含7臺(tái)物理服務(wù)器,其中1臺(tái)控制節(jié)點(diǎn),一臺(tái)Ceph All-in-one節(jié)點(diǎn),剩余為5個(gè)計(jì)算節(jié)點(diǎn)。另外多余的兩臺(tái)分別作為Top Cell的控制節(jié)點(diǎn)和網(wǎng)絡(luò)節(jié)點(diǎn)。部署的OpenStack版本為Mitaka,使用社區(qū)原生代碼。在部署過程中遇到了大大小小不少坑,有些是配置問題,有些是Cells本身的問題。
1. 虛擬機(jī)永久堵塞在scheduling狀態(tài)
我們知道,每個(gè)Cell都使用自己的獨(dú)立數(shù)據(jù)庫(kù),因此配置Nova的數(shù)據(jù)庫(kù)時(shí),顯然需要配置其所在Cell的數(shù)據(jù)庫(kù)地址。而從Mitaka版本開始已經(jīng)把一些公共的數(shù)據(jù)從nova數(shù)據(jù)庫(kù)單獨(dú)分離出來一個(gè)數(shù)據(jù)庫(kù)nova_api(原因后面說明)。創(chuàng)建虛擬機(jī)時(shí)Nova-API不會(huì)把初始化數(shù)據(jù)直接保存到nova數(shù)據(jù)庫(kù)的instances表中,而是保存到nova_api數(shù)據(jù)庫(kù)的build_requests表,此時(shí)虛擬機(jī)狀態(tài)為scheduling。Nova API獲取虛擬機(jī)信息時(shí)會(huì)首先查詢nova_api的build_requests表,如果存在記錄,則直接返回虛擬機(jī)信息。正常流程下,當(dāng)執(zhí)行完調(diào)度后,Nova-Conductor會(huì)自動(dòng)刪除build_requests的虛擬機(jī)信息。但是在配置多Cell情況下,如果nova_api也是配置其所在Cell的數(shù)據(jù)庫(kù)地址,當(dāng)調(diào)度到Compute Cell中時(shí),Compute Cell數(shù)據(jù)庫(kù)的build_requests顯然找不到該虛擬機(jī)的信息,因?yàn)閷?shí)際上信息都保存在Top Cell中,因此Top Cell的build_requests中的虛擬機(jī)信息將永遠(yuǎn)不會(huì)被刪除。此時(shí)我們使用nova list查看的虛擬機(jī)信息是從build_requests拿到的過時(shí)數(shù)據(jù),因此我們查看虛擬機(jī)狀態(tài)永久堵塞在scheduling狀態(tài)。解決辦法是所有Cell的nova_api數(shù)據(jù)庫(kù)都配置使用同一個(gè)數(shù)據(jù)庫(kù),nova_api數(shù)據(jù)庫(kù)本來就是設(shè)計(jì)為保存公共數(shù)據(jù)的,為所有的Cell所共享。
2. 分配網(wǎng)絡(luò)失敗導(dǎo)致創(chuàng)建虛擬機(jī)失敗
解決了上一個(gè)問題后,發(fā)現(xiàn)仍然創(chuàng)建虛擬機(jī)失敗,虛擬機(jī)一直堵塞在spawning狀態(tài)直到變成error狀態(tài),在計(jì)算節(jié)點(diǎn)調(diào)用virsh list命令發(fā)現(xiàn)其實(shí)虛擬機(jī)已經(jīng)創(chuàng)建成功,只是狀態(tài)為pause。Nova-Compute現(xiàn)場(chǎng)日志如下:
2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [req-c2854f9b-9b00-45da-a2dd-561a3194c45d a8bfa47e180c41089e4232e76b16ac04 42e34b92273249ff9be85ef3d4fd38b8 - - -] [instance: 6a7377f5-86ac-4767-9110-29085de44e00] Failed to allocate network(s)2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] Traceback (most recent call last):2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] File "/usr/lib/python2.7/site-packages/nova/compute/manager.py", line 1920, in _build_and_run_instance2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] block_device_info=block_device_info)2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] File "/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 2596, in spawn2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] post_xml_callback=gen_confdrive)2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] File "/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 4858, in _create_domain_and_network2016-12-30 00:56:43.078 84245 ERROR nova.compute.manager [instance: 6a7377f5-86ac-4767-9110-29085de44e00] raise exception.VirtualInterfaceCreateException()
通過源碼發(fā)現(xiàn),正常流程下,創(chuàng)建虛擬機(jī)時(shí),Neutron完成虛擬網(wǎng)卡初始化后會(huì)通過Notification機(jī)制發(fā)送通知到消息隊(duì)列中,Libvirt會(huì)默認(rèn)一直等待Neutron虛擬網(wǎng)卡初始化成功的事件通知。在多Cell環(huán)境下,因?yàn)镃ell只是Nova的概念,其它服務(wù)并不能感知Cell的存在,而Nova的Cell使用了自己的消息隊(duì)列,Neutron服務(wù)發(fā)往的是公共消息隊(duì)列,因此Nova-Compute將永遠(yuǎn)收不到通知,導(dǎo)致等待事件必然超時(shí),Nova誤認(rèn)為創(chuàng)建虛擬網(wǎng)卡失敗了,因此創(chuàng)建虛擬機(jī)失敗。Godday和CERN同樣遇到了相同的問題,解決辦法為設(shè)置vif_plugging_is_fatal為false,表示忽略Neutron消息等待超時(shí)問題,繼續(xù)執(zhí)行后續(xù)步驟。另外需要設(shè)置等待的超時(shí)時(shí)間vif_plugging_timeout,因?yàn)槲覀円呀?jīng)確定肯定會(huì)超時(shí),因此設(shè)置一個(gè)較短的時(shí)間,避免創(chuàng)建虛擬機(jī)等待過長(zhǎng),Godday設(shè)置為5秒,可以作為參考。
3. nova show查看虛擬機(jī)的instance_name與計(jì)算節(jié)點(diǎn)實(shí)際名稱不一致。
這是因?yàn)閕nstance_name默認(rèn)模板為instance-x % id,其中id為虛擬機(jī)在數(shù)據(jù)庫(kù)中的主鍵id(注意不是UUID),它是自增長(zhǎng)的。比如id為63,轉(zhuǎn)化為十六進(jìn)制為3f,因此instance_name為instance-0000003f。在多Cell情況下,Top Cell保存了所有的虛擬機(jī)信息,而子Cell只保存了其管理Cell的虛擬機(jī)信息,保存的虛擬機(jī)數(shù)量必然不相等,因此同一虛擬機(jī)保存在Top Cell和子Cell的ID必然不相同。而我們使用Nova API獲取虛擬機(jī)信息是從Top Cell中獲取的,因此和虛擬機(jī)所在的Compute Cell中的instance_name不一致。解決辦法為修改instance_name_template值,使其不依賴于id值,我們?cè)O(shè)置為虛擬機(jī)UUID。
4.后端存儲(chǔ)問題
當(dāng)部署小規(guī)模OpenStack集群時(shí),我們通常都會(huì)使用Ceph分布式共享存儲(chǔ)作為Openstack的存儲(chǔ)后端,此時(shí)Glance、Nova和Cinder是共享存儲(chǔ)系統(tǒng)的,這能充分利用RBD image的COW(Copy On Write)特性,避免了鏡像文件的遠(yuǎn)程拷貝,加快了創(chuàng)建虛擬機(jī)和虛擬塊設(shè)備的速度。但當(dāng)規(guī)模很大時(shí),所有的節(jié)點(diǎn)共享一個(gè)Ceph集群必然導(dǎo)致Ceph集群負(fù)載巨大,IO性能下降。因此考慮每個(gè)Cell使用獨(dú)立的Ceph集群,Nova和Cinder共享Ceph集群,Glance是所有Cells的公共服務(wù),需要單獨(dú)部署并對(duì)接其它存儲(chǔ)設(shè)備。由于Glance和Nova不是共享存儲(chǔ)了,因此創(chuàng)建虛擬機(jī)時(shí)就不能直接Clone了,而必須先從Glance下載Base鏡像導(dǎo)入到Ceph集群中。創(chuàng)建虛擬機(jī)時(shí),首先看本地Ceph集群是否存在base鏡像,存在的話直接Clone即可,否則從遠(yuǎn)端Glance中下載到本地并導(dǎo)入到Ceph集群中,下次創(chuàng)建虛擬機(jī)時(shí)就能直接Clone了。存在的問題之一時(shí),目前RBD Image Backend并沒有實(shí)現(xiàn)緩存功能,因此需要自己開發(fā)此功能。問題之二,如何管理Cell內(nèi)部的Ceph鏡像緩存,Glance鏡像已經(jīng)刪除后,如果本地也沒有虛擬機(jī)依賴,則可以把Base鏡像刪除了,這需要定時(shí)任務(wù)來清理。問題之三,創(chuàng)建Volume時(shí)如何保證和虛擬機(jī)在同一個(gè)Cell中,因?yàn)椴煌腃ell是不同的Ceph集群,掛載就會(huì)有問題,其中一個(gè)可選方案是通過Available Zone(AZ)來限制,此時(shí)用戶在創(chuàng)建虛擬機(jī)和Volume時(shí)都必須指定AZ,當(dāng)用戶需要掛載Volume到其它Cell的虛擬機(jī)時(shí),必須先執(zhí)行遷移操作。
5.很多功能不能用
由于Nova Cells采用二級(jí)調(diào)度策略,在調(diào)度Cells時(shí)并不能拿到所有Hypervisor的信息,因此與之相關(guān)的功能都不能用或者出錯(cuò),比如主機(jī)集合、Server Group等,調(diào)度功能也大大受限,比如Compute Capabilities Filter、Numa Topology Filter、Trusted Filter等,這些Filters為什么不能用了?假如只有Cell1的主機(jī)滿足Compute Capabilities,但是在調(diào)度Cell時(shí)調(diào)度到了Cell2,由于Cell2沒有符合條件的主機(jī),因此必然會(huì)調(diào)度失敗,但顯然我們有合法的宿主機(jī)。另外,Nova Cells雖然對(duì)用戶是透明的,但其本身還是存在隔離的,目前不同Cells之間不支持虛擬機(jī)遷移操作,當(dāng)一個(gè)Cell出現(xiàn)故障時(shí),也不能疏散到其它Cell中。
6.虛擬機(jī)信息不一致
虛擬機(jī)信息被保存在多處,所有的子Cell都必須同步復(fù)制到Top Cell中,一旦同步出現(xiàn)問題導(dǎo)致數(shù)據(jù)不一致性,就可能出現(xiàn)非常棘手的問題。比如在Compute Cell中的某一個(gè)虛擬機(jī)由于某些原因狀態(tài)變成ERROR了,但沒有同步到Top Cell中,用戶看到的還是Active狀態(tài),但后續(xù)的所有操作都會(huì)失敗,運(yùn)維人員必須逐一檢查該虛擬機(jī)經(jīng)過的所有Cell的數(shù)據(jù)庫(kù)數(shù)據(jù),直到Compute Cell,發(fā)現(xiàn)狀態(tài)不一致,必須手動(dòng)修改數(shù)據(jù)庫(kù),這些操作都是十分危險(xiǎn)的,必須具有非常熟練的數(shù)據(jù)庫(kù)運(yùn)維能力。
4.4 Nova Cells”涅磐重生”
前面踩到的坑,社區(qū)也發(fā)現(xiàn)了這些問題,但由于這是由于Nova Cells的設(shè)計(jì)缺陷所導(dǎo)致的,要修復(fù)這些問題,只通過填填補(bǔ)補(bǔ)是不可能解決的,社區(qū)對(duì)這些問題的唯一反饋就是不建議在新的環(huán)境上部署Cells服務(wù),后續(xù)Cells相關(guān)文檔也不會(huì)再更新。目前社區(qū)已經(jīng)徹底放棄了該方案,如今Nova Cells開發(fā)已經(jīng)凍結(jié)了,意味著不會(huì)再開發(fā)任何新特性,也不會(huì)修復(fù)與之相關(guān)的Bug,后續(xù)的開發(fā)也不會(huì)保證Cells的兼容性。
So,Nova Cells已死?值得慶幸的是,Nova Cells其實(shí)并沒有徹底死去,而是涅槃重生了。從L版開始,社區(qū)扔掉原設(shè)計(jì)的同時(shí),吸取之前的教訓(xùn),開始著手重新設(shè)計(jì)Nova Cells并徹底重構(gòu)代碼。為了區(qū)分,之前的Nova Cells命名為Nova Cells v1,而新方案命名為Nova Cell v2。Nova Cells v2為了避免Nova Cells v1的問題,一開始就提出了幾個(gè)明確的設(shè)計(jì)原則和目標(biāo):
1.Nova全面支持Nova-Cells
之前Nova Cells是可選安裝的,開啟Nova Cells功能,必須額外安裝Nova-Cells服務(wù)以及額外配置,用戶對(duì)這個(gè)功能的了解和關(guān)注程度都是比較低的,而參與開發(fā)這一功能的開發(fā)者也很少[1],導(dǎo)致Cells的開發(fā)力度不夠,部署率低,成熟度低。而對(duì)于v2版本,Nova開始全面支持,廢棄原來的Nova-Cells服務(wù),不需要額外部署其它任何服務(wù),減少了部署的復(fù)雜度,也容易從原來的非Cells架構(gòu)中升級(jí)為Cells架構(gòu)。在N版之后,Nova Cells將成為必須部署方式,相當(dāng)于Nova的內(nèi)置功能,而不再是可選功能,這大大增加了用戶和開發(fā)者的關(guān)注度。
2.分離公共數(shù)據(jù),只存放一處
為了解決之前的數(shù)據(jù)一致性問題,在v2版本中,從M版開始把公共數(shù)據(jù)從原來的nova數(shù)據(jù)庫(kù)中分離出來,放在單獨(dú)的nova_api數(shù)據(jù)庫(kù)中,這些公共數(shù)據(jù)包括:
1.flavors;
2.quotas;
3.security group、rules;
4.key pairs;
5.tags;
6.migrations;
7.networks。
此方案解決了公共數(shù)據(jù)的不一致性問題。另外,Top Cell也不再保存虛擬機(jī)信息了,而僅僅保存其UUID與Cell之間映射表,虛擬機(jī)信息只保存在其所在的Cell中,Top Cell與Compute Cell之間不再需要復(fù)制同步。由于完整數(shù)據(jù)只存放一處,不存在數(shù)據(jù)不一致問題,拿到的數(shù)據(jù)保證是正確的。
3.支持Nova的所有功能
前面提到v1版本存在功能限制,除此之外,對(duì)Neutron的支持也缺乏測(cè)試和驗(yàn)證。而在v2設(shè)計(jì)目標(biāo)中強(qiáng)調(diào)將支持所有功能,無任何功能限制,并且全面支持Neutron集成,不再考慮Nova-Network。
最新的v2結(jié)構(gòu)已經(jīng)不是樹狀的了,而且沒有了Nova-Cells這個(gè)組件,其架構(gòu)如圖:
從架構(gòu)圖中可以看出,新版本的Nova Cells v2采用單級(jí)調(diào)度機(jī)制替代了原來的二級(jí)調(diào)度,由Nova-Scheudler服務(wù)負(fù)責(zé)調(diào)度Cell,同時(shí)負(fù)責(zé)選擇Cell中的主機(jī)。另外還設(shè)計(jì)了個(gè)額外的Cell0模塊,如果你在進(jìn)行虛擬機(jī)調(diào)度操作時(shí),調(diào)度到任何一個(gè)Cell都出錯(cuò),或者沒有可用Cell的話,這是系統(tǒng)會(huì)先將請(qǐng)求放置在Cell0中,Cell0中只有一個(gè)Nova DB,沒有消息隊(duì)列和Nova服務(wù)。
Nova Cell v2是一個(gè)革命性的變化,其設(shè)計(jì)目標(biāo)已經(jīng)非常明確,也是最期待的方案,但離完全實(shí)現(xiàn)還有一定的距離,目前還不支持多Cells調(diào)度,很多功能正在緊急開發(fā)中,目前還不能投入生產(chǎn)使用,不過社區(qū)后續(xù)會(huì)推出v1升級(jí)v2或者非Cell轉(zhuǎn)化為Cell架構(gòu)的工具。
不過Nova Cells v2也存在問題,我認(rèn)為:
查詢虛擬機(jī)信息時(shí),需要首先在Top Cell中拿到所有虛擬機(jī)的索引和Cell映射,然后需要往所有的Cells請(qǐng)求數(shù)據(jù),這可能導(dǎo)致查詢性能低下。
當(dāng)某個(gè)Cell出現(xiàn)故障時(shí),就拿不到這部分虛擬機(jī)信息了,這個(gè)問題該如何處理?
Cells之間通過消息隊(duì)列通信,如果跨DC部署,性能就會(huì)非常低下。
任何方案都不能是十全十美的,雖然Nova Cell v2也存在問題,但仍值得期待并給予厚望,希望Nova Cells v2不會(huì)讓我們失望,徹底解決OpenStack大規(guī)模部署問題。
總結(jié)與展望
本文首先介紹了大規(guī)模部署OpenStack存在的主要問題,引出數(shù)據(jù)庫(kù)和消息隊(duì)列是限制大規(guī)模部署的主要瓶頸,然后針對(duì)這個(gè)瓶頸問題介紹了一些組件優(yōu)化策略,最后詳細(xì)介紹了幾種OpenStack大規(guī)模部署的方案,分析了其特點(diǎn)和不足。針對(duì)大規(guī)模部署問題,Nova Cell v2和Trio2o都是比較值得期待的,其設(shè)計(jì)理念和目標(biāo)也比較明確,但是離實(shí)現(xiàn)和發(fā)展成熟還有一定的距離。Region方案只是共享認(rèn)證和Dashboard,實(shí)現(xiàn)統(tǒng)一管理多OpenStack環(huán)境,原則上不算是單OpenStack的大規(guī)模部署。Nova Cell v1已經(jīng)有不少大規(guī)模部署的案例,但社區(qū)已經(jīng)不再支持,并且不鼓勵(lì)在新的環(huán)境中部署。如果目前需要上線大規(guī)模OpenStack生產(chǎn)環(huán)境,有以下兩種方案:
1.使用Nova Cell v2,同時(shí)加入v2開發(fā),缺點(diǎn)是開發(fā)所有功能的周期不確定,也面臨很多變數(shù)。
2.使用Nova Cell v1,部署架構(gòu)有可供參考的案例,缺點(diǎn)是后續(xù)的所有問題都需要自己解決,得不到上游的支持。
當(dāng)然也可以先部署一套小規(guī)模的環(huán)境,等Cell v2開發(fā)完成后,使用升級(jí)工具調(diào)整架構(gòu),增加Cells功能。