中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OpenStack如何處理BUG

發布時間:2021-12-29 16:25:37 來源:億速云 閱讀:136 作者:小新 欄目:云計算

這篇文章主要介紹OpenStack如何處理BUG,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

一.發現Bug:

?Nova中的虛擬機軟刪除(soft-delete)功能,是指在一段時間內,僅將數據庫中的某虛擬機記錄做一個標記(status='SOFT-DELETE'),然后將虛擬化平臺(kvm等)中對應的虛擬機實例置為關機狀態,當超過某一時間段后才將虛擬機實例真正刪除;該功能為云平臺用戶提供了“后悔時間”,可以在一定程度上挽回誤操作。默認情況下,軟刪除功能是關閉的,其開啟方式是在nova配置文件中添加"reclaim_instance_interval"選項,并將其值設置為"后悔時間"的毫秒數。

?在描述具體Bug前,需要對openstack中的用戶管理方面的基本概念簡單介紹一下。

OpenStack如何處理BUG

?上圖是openstack用戶模型的簡化版本,為了便于理解將不屬于keystone管理的quota也拿了過來。

?Bug就與軟刪除相關。具體場景是這樣的:假設OpenStack中有兩個項目和兩個用戶:普通項目A其用戶a,管理員項目Admin其用戶為admin(用戶管理相關概念可以查閱keystone文檔),用戶a不慎將自己的一臺虛擬機刪除了,這時求助系統管理員看看有沒有辦法恢復,好在系統開啟的軟刪除功能,而且被刪除的虛擬機還在可回收的時間范圍內,這時管理員便以admin的身份登錄系統,為用戶a恢復了虛擬機,但是細心的管理員卻發現了一些不對:其Admin項目下并沒有任何虛擬機,但是其配額卻被使用了,難道這和剛才的操作有關?再來重試一下:普通用戶刪除虛擬機,admin用戶來為其恢復,這時配額又發生了變化,果然如此:被恢復的虛擬機的配額錯誤的添加到了Admin項目下。該Bug在最新的kilo版本中仍然存在,感興趣的同學可以實驗一下。

二.定位Bug:

?發現了Bug的存在,那就更進一步,到代碼中找一下原因吧。

?如何確定問題代碼的位置呢?這需要對Nova的項目結構有大體的了解,我們來簡單了解一下:

OpenStack如何處理BUG

?上圖是nova架構的極簡版本,與本問題無關的組件都沒有畫上去,恢復虛擬機的操作過程大致是這樣:

  1. nova api接收到用戶請求,到數據庫中查詢虛擬機詳情,將該虛擬機所在的主機、名稱等數據發送到消息隊列中;

  2. nova compute服務在監聽到相關消息后,開始執行具體操作,將虛擬機在數據庫中的記錄做些調整,調用底層驅動恢復虛擬機。

?既然軟刪除的功能層面沒有任何問題,虛擬機的刪除和恢復過程都很順利,可見不會是驅動的問題,順著API層的代碼調用往下找,很快就可以定位了。直接看出問題的代碼片段:

def restore(self, context, instance):
    # 該代碼做了刪減
    flavor = instance.get_flavor()
    # 獲取quotas對象
    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層面上進行虛擬機回收的主要方法,可以看到其中有明顯的配額操作(quotas),在解讀這段代碼前有必要先對nova中"context"的概念做個簡介。不僅是nova,在openstack其他項目中都隨處可見這個"context",它是一個包裝了用戶請求信息的對象,包含用戶的項目和認證信息等,通過它可以簡便的進行各項目之間的API調用和用戶信息的查詢,API服務接收到用戶的每一次HTTP請求,都會創建一個新的context。

?回到這段代碼,我們重點關注對quotas所作的操作:在方法的第二行,通過了一個方法獲取了quotas,有在方法的結尾執行了quotas.commit(),能夠獲取到的信息不多,我們再看一下獲取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的過程:通過當前的context創建quotas對象,并且執行了reserve操作; 我們知道context是由HTTP請求而來,里面保存的是發請求的用戶的信息,所以這里的quotas對象的“所有者”也就是context中的用戶。

?結合Bug發生的場景來看:管理員還原用戶a的虛擬機,發請求的是管理員,當前context中記錄的是管理員的信息,這里的quotas理所當然的就是管理員的,然后操作了用戶a的虛擬機,更新的卻是管理員的quotas。嗯,真相大白!

三.修復Bug:

?Bug的原因是獲取的quotas并不屬于期望的用戶,但是直接修改context顯然不合適(會影響后續的操作),先了解一下quotas對象自身吧:

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方法的參數,默認為None的project_id和user_id,這正是改變quotas屬主的方便入口!

?修改后的代碼這里就不貼了,感興趣的同學可以到這次提交中看:Code Review

四.代碼提交和Review:

?openstack社區有著整套項目管理流程,這里有一張圖能夠較詳細的描述工作流程:OpenStack如何處理BUG

?由圖可見bugfix是其中最簡單的流程。

以上是“OpenStack如何處理BUG”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

浮梁县| 色达县| 钦州市| 蕉岭县| 黔西县| 伽师县| 东方市| 湖口县| 原阳县| 安吉县| 承德县| 巴彦淖尔市| 贵溪市| 大理市| 乐清市| 沿河| 鹤壁市| 巴林右旗| 镇原县| 日照市| 小金县| 宜兰市| 武安市| 通海县| 克拉玛依市| 利津县| 洪雅县| 米易县| 芒康县| 蕉岭县| 莱州市| 林州市| 安达市| 定远县| 常熟市| 马鞍山市| 丰镇市| 肃南| 武陟县| 濉溪县| 南和县|