新聞中心
這篇文章主要介紹OpenStack如何處理BUG,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)建站是一家專(zhuān)注于做網(wǎng)站、成都網(wǎng)站制作與策劃設(shè)計(jì),興隆臺(tái)網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:興隆臺(tái)等地區(qū)。興隆臺(tái)做網(wǎng)站價(jià)格咨詢(xún):18982081108
一.發(fā)現(xiàn)Bug:
?Nova中的虛擬機(jī)軟刪除(soft-delete)功能,是指在一段時(shí)間內(nèi),僅將數(shù)據(jù)庫(kù)中的某虛擬機(jī)記錄做一個(gè)標(biāo)記(status='SOFT-DELETE'),然后將虛擬化平臺(tái)(kvm等)中對(duì)應(yīng)的虛擬機(jī)實(shí)例置為關(guān)機(jī)狀態(tài),當(dāng)超過(guò)某一時(shí)間段后才將虛擬機(jī)實(shí)例真正刪除;該功能為云平臺(tái)用戶(hù)提供了“后悔時(shí)間”,可以在一定程度上挽回誤操作。默認(rèn)情況下,軟刪除功能是關(guān)閉的,其開(kāi)啟方式是在nova配置文件中添加"reclaim_instance_interval"選項(xiàng),并將其值設(shè)置為"后悔時(shí)間"的毫秒數(shù)。
?在描述具體Bug前,需要對(duì)openstack中的用戶(hù)管理方面的基本概念簡(jiǎn)單介紹一下。
?上圖是openstack用戶(hù)模型的簡(jiǎn)化版本,為了便于理解將不屬于keystone管理的quota也拿了過(guò)來(lái)。
?Bug就與軟刪除相關(guān)。具體場(chǎng)景是這樣的:假設(shè)OpenStack中有兩個(gè)項(xiàng)目和兩個(gè)用戶(hù):普通項(xiàng)目A其用戶(hù)a,管理員項(xiàng)目Admin其用戶(hù)為admin(用戶(hù)管理相關(guān)概念可以查閱keystone文檔),用戶(hù)a不慎將自己的一臺(tái)虛擬機(jī)刪除了,這時(shí)求助系統(tǒng)管理員看看有沒(méi)有辦法恢復(fù),好在系統(tǒng)開(kāi)啟的軟刪除功能,而且被刪除的虛擬機(jī)還在可回收的時(shí)間范圍內(nèi),這時(shí)管理員便以admin的身份登錄系統(tǒng),為用戶(hù)a恢復(fù)了虛擬機(jī),但是細(xì)心的管理員卻發(fā)現(xiàn)了一些不對(duì):其Admin項(xiàng)目下并沒(méi)有任何虛擬機(jī),但是其配額卻被使用了,難道這和剛才的操作有關(guān)?再來(lái)重試一下:普通用戶(hù)刪除虛擬機(jī),admin用戶(hù)來(lái)為其恢復(fù),這時(shí)配額又發(fā)生了變化,果然如此:被恢復(fù)的虛擬機(jī)的配額錯(cuò)誤的添加到了Admin項(xiàng)目下。該Bug在最新的kilo版本中仍然存在,感興趣的同學(xué)可以實(shí)驗(yàn)一下。
二.定位Bug:
?發(fā)現(xiàn)了Bug的存在,那就更進(jìn)一步,到代碼中找一下原因吧。
?如何確定問(wèn)題代碼的位置呢?這需要對(duì)Nova的項(xiàng)目結(jié)構(gòu)有大體的了解,我們來(lái)簡(jiǎn)單了解一下:
?上圖是nova架構(gòu)的極簡(jiǎn)版本,與本問(wèn)題無(wú)關(guān)的組件都沒(méi)有畫(huà)上去,恢復(fù)虛擬機(jī)的操作過(guò)程大致是這樣:
nova api接收到用戶(hù)請(qǐng)求,到數(shù)據(jù)庫(kù)中查詢(xún)虛擬機(jī)詳情,將該虛擬機(jī)所在的主機(jī)、名稱(chēng)等數(shù)據(jù)發(fā)送到消息隊(duì)列中;
nova compute服務(wù)在監(jiān)聽(tīng)到相關(guān)消息后,開(kāi)始執(zhí)行具體操作,將虛擬機(jī)在數(shù)據(jù)庫(kù)中的記錄做些調(diào)整,調(diào)用底層驅(qū)動(dòng)恢復(fù)虛擬機(jī)。
?既然軟刪除的功能層面沒(méi)有任何問(wèn)題,虛擬機(jī)的刪除和恢復(fù)過(guò)程都很順利,可見(jiàn)不會(huì)是驅(qū)動(dòng)的問(wèn)題,順著API層的代碼調(diào)用往下找,很快就可以定位了。直接看出問(wèn)題的代碼片段:
def restore(self, context, instance): # 該代碼做了刪減 flavor = instance.get_flavor() # 獲取quotas對(duì)象 num_instances, quotas = self._check_num_instances_quota( context, flavor, 1, 1) self._record_action_start(context, instance, instance_actions.RESTORE) try: if instance.host: instance.task_state = task_states.RESTORING instance.deleted_at = None instance.save(expected_task_state=[None]) self.compute_rpcapi.restore_instance(context, instance) else: instance.vm_state = vm_states.ACTIVE instance.task_state = None instance.deleted_at = None instance.save(expected_task_state=[None]) # 更新quotas quotas.commit()
?上面的這段代碼就是API層面上進(jìn)行虛擬機(jī)回收的主要方法,可以看到其中有明顯的配額操作(quotas),在解讀這段代碼前有必要先對(duì)nova中"context"的概念做個(gè)簡(jiǎn)介。不僅是nova,在openstack其他項(xiàng)目中都隨處可見(jiàn)這個(gè)"context",它是一個(gè)包裝了用戶(hù)請(qǐng)求信息的對(duì)象,包含用戶(hù)的項(xiàng)目和認(rèn)證信息等,通過(guò)它可以簡(jiǎn)便的進(jìn)行各項(xiàng)目之間的API調(diào)用和用戶(hù)信息的查詢(xún),API服務(wù)接收到用戶(hù)的每一次HTTP請(qǐng)求,都會(huì)創(chuàng)建一個(gè)新的context。
?回到這段代碼,我們重點(diǎn)關(guān)注對(duì)quotas所作的操作:在方法的第二行,通過(guò)了一個(gè)方法獲取了quotas,有在方法的結(jié)尾執(zhí)行了quotas.commit(),能夠獲取到的信息不多,我們?cè)倏匆幌芦@取quotas的方法:_check_num_instances_quota
# 這里只截取一部分 def _check_num_instances_quota(self, context, instance_type, min_count, max_count): req_cores = max_count * instance_type['vcpus'] vram_mb = int(instance_type.get('extra_specs', {}).get(VIDEO_RAM, 0)) req_ram = max_count * (instance_type['memory_mb'] + vram_mb) try: quotas = objects.Quotas(context) quotas.reserve(context, instances=max_count, cores=req_cores, ram=req_ram) ... return max_count, quotas
?這里可以看到獲取quotas的過(guò)程:通過(guò)當(dāng)前的context創(chuàng)建quotas對(duì)象,并且執(zhí)行了reserve操作; 我們知道context是由HTTP請(qǐng)求而來(lái),里面保存的是發(fā)請(qǐng)求的用戶(hù)的信息,所以這里的quotas對(duì)象的“所有者”也就是context中的用戶(hù)。
?結(jié)合Bug發(fā)生的場(chǎng)景來(lái)看:管理員還原用戶(hù)a的虛擬機(jī),發(fā)請(qǐng)求的是管理員,當(dāng)前context中記錄的是管理員的信息,這里的quotas理所當(dāng)然的就是管理員的,然后操作了用戶(hù)a的虛擬機(jī),更新的卻是管理員的quotas。嗯,真相大白!
三.修復(fù)Bug:
?Bug的原因是獲取的quotas并不屬于期望的用戶(hù),但是直接修改context顯然不合適(會(huì)影響后續(xù)的操作),先了解一下quotas對(duì)象自身吧:
class Quotas(base.NovaObject): # 部分代碼 def __init__(self, *args, **kwargs): super(Quotas, self).__init__(*args, **kwargs) # Set up defaults. self.reservations = [] self.project_id = None self.user_id = None self.obj_reset_changes() ... def reserve(self, context, expire=None, project_id=None, user_id=None, **deltas): reservations = quota.QUOTAS.reserve(context, expire=expire, project_id=project_id, user_id=user_id, **deltas) self.reservations = reservations self.project_id = project_id self.user_id = user_id self.obj_reset_changes() def commit(self, context=None): if not self.reservations: return if context is None: context = self._context quota.QUOTAS.commit(context, self.reservations, project_id=self.project_id, user_id=self.user_id) self.reservations = None self.obj_reset_changes()
?注意看reserve方法的參數(shù),默認(rèn)為None的project_id和user_id,這正是改變quotas屬主的方便入口!
?修改后的代碼這里就不貼了,感興趣的同學(xué)可以到這次提交中看:Code Review
四.代碼提交和Review:
?openstack社區(qū)有著整套項(xiàng)目管理流程,這里有一張圖能夠較詳細(xì)的描述工作流程:
?由圖可見(jiàn)bugfix是其中最簡(jiǎn)單的流程。
以上是“OpenStack如何處理BUG”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
標(biāo)題名稱(chēng):OpenStack如何處理BUG
URL分享:http://www.dlmjj.cn/article/pghjoo.html