1. 程式人生 > >OpenStack Nova虛擬機創建流程解析

OpenStack Nova虛擬機創建流程解析

我想 content mage 計算節點 問題 -c accep server 用戶

https://yikun.github.io/2017/09/27/OpenStack-Nova%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%88%9B%E5%BB%BA%E6%B5%81%E7%A8%8B%E8%A7%A3%E6%9E%90/

1. 概述

Nova是OpenStack中處理計算業務(虛擬機、裸機、容器)的組件,整體的虛擬機創建流程自然是學習和熟悉Nova組件的第一步。本篇文章主要基於OpenStack Pike版本,基於最新的Cell v2架構部署為例,來介紹虛擬機的創建流程,並分析了Pike等最近幾個版本中,虛擬機創建流程的關鍵變化。

2. 虛擬機創建流程

技術分享圖片

上圖是虛擬機創建流程的整體流程,可以看到整體虛擬機創建流程一次經過了API、Conductor、Scheduler、Placement、Compute等主要服務,下面我們逐步介紹下虛擬機創建時,這些服務做的一些事情以及在Pike版本新引入的部分:

2.1 Nova-API

在OpenStack的組件中,基本每個組件都會有一個API服務,對於Nova來說API服務主要的作用就是接收由用戶通過Client或者一些其他REST請求工具(比如 curl、postman)發送的請求。一般來說會包含一些虛擬機創建的參數,比如虛擬機的規格、可用域之類的信息。

在虛擬機創建的流程中,API就是Nova的入口,當API接收到請求後,主要會處理一些關於參數校驗、配額檢測等事務。

1. 參數校驗

例如,我們指定鏡像和規格來創建一個虛擬機時,通常會使用:

1 nova --debug boot --image 81e58b1a-4732-4255-b4f8-c844430485d2 --flavor 1 yikun

我們通過--debug來開啟debug模式,來看看命令行究竟做了什麽事,可以從回顯中,看到一個關鍵的信息:

curl -g -i -X POST http://xxx.xxx.xxx.xxx/compute/v2.1/servers -H “Accept: application/json” -H “User-Agent: python-novaclient” -H “OpenStack-API-Version: compute 2.53” -H “X-OpenStack-Nova-API-Version: 2.53” -H “X-Auth-Token: $token” -H “Content-Type: application/json” -d ‘{“server”: {“name”: “yikun”, “imageRef”: “81e58b1a-4732-4255-b4f8-c844430485d2”, “flavorRef”: “1”, “max_count”: 1, “min_count”: 1, “networks”: “auto”}}’

我們可以看到虛擬機創建時,傳入了一些諸如虛擬機名稱、鏡像、規格、個數、網絡等基本信息。在API中,首先就會對這些參數進行校驗,比如鏡像ID是否合法、網絡是否正確等。

2. 配額檢測

值得一提的是,在Pike版本的虛擬機創建開始時,對配額檢測進行了優化。

我先看看之前的實現,在之前版本的Nova中,Quota檢測過程相對來說比較復雜,首先會進行reserve操作,對資源進行預占,然後預占成功,並且創建成功後,最終會進行commit操作。然而,為了保證在並發的場景下,不會對超過用戶配額(這都是錢啊!),因此在reserve和commit進行資源更新的時候都會quota相關的數據表的用戶相關行加把鎖,也就是說更新quota記錄的時候,一個用戶去更新時,其他用戶再想刷新只能等著,直到前一個用戶完成數據庫記錄刷新為止,這樣就大大降低的效率,並發的性能也就不是很客觀了。

另外,由於需要對cell v2進行支持,目前所有的quota表均已移動到API的數據庫了可以參考BPCellsV2 - Move quota tables to API database。Cell V2的設計思想是,由API、Super Conductor去訪問上層的全局數據庫(nova_api數據庫),而底下的cell中的組件,只需要關心cell中的邏輯即可。因此,為了徹底的解耦,讓cell中的compute無需再訪問api數據庫進行諸如commit操作,在Pike版本,社區對quota機制進行了優化,詳情可以參考Count resources to check quota in API for cells這個BP。

因此Pike版本之後,配額檢測變成了這樣:

  1. 首先,api中進行第一次Quota檢測,主要方法就是收集地下各個cell數據庫中的資源信息,然後和api數據庫中的quota上限進行對比。例如,一個用戶可以創建10個虛擬機,在cell1中有2個,cell2中有7個,再創建一個虛擬機時,會搜集cell1和cell2中的虛擬機個數之和(9個),然後加上變化(新增一個),與總配額進行比較。
  2. 二次檢測(cell v2在super conductor裏做)。由於在並發場景下,可能出現同時檢測發現滿足,之後進行創建,就會造成配額的超分,針對這個問題,社區目前給出的方案是,在創建虛擬機記錄之後,再進行recheck,如果發現超額了,會將超額分配的虛擬機標記為ERROR,不再繼續往下走了。

每次檢測的邏輯都調用相同的函數,具體邏輯如下圖所示:
技術分享圖片

2.2 Nova Super Conductor

Super Conductor在創建虛擬機的流程其實和之前差不多,選個合適的節點(調度),然後,寫入虛擬機相關的記錄,然後,投遞消息到選定的Compute節點進行虛擬機的創建。

在Cell v2場景,虛擬機的創建記錄已經需要寫入的子cell中,因此,conductor需要做的事,包括一下幾個步驟:

  1. 進行調度,選出host。
  2. 根據host,通過host_mappings找到對應的cell
  3. 在對應的cell db中創建虛擬機記錄,並且記錄instances_mappings信息
  4. 通過cell_mappings來查找對應的cell的mq,然後投遞到對應的cell中的compute

完成這些操作時,需要牽扯到3個關鍵的數據結構,我們來簡單的看一下:

  • host_mappings:記錄了host和cell的映射信息
  • instances_mappings:記錄了虛擬機和cell的映射信息
  • cell_mappings:記錄了cell和cell對應的mq的映射信息

與Cell v1不太相同,在目前的設計中,認為scheduler能看到的應該是底下能夠提供資源的具體的所有的Resource Provider(對於計算資源來說,就是所有的計算節點),而不是整個cell,也就是說所有cell中的資源scheduler都可以看到,而子cell就負責創建就好了。因此,在super conductor中,需要做一些transfer的事情,這樣也就不必在像cell v1那樣,在子cell裏還得搞個scheduler去做調度。

2.3 Nova-Scheduler

剛才我們在conductor中,已經介紹了,在選擇具體哪個節點來創建虛擬機時,調用了Scheduler的select_destination方法,在之前的版本的調度中,就是OpenStack最經典的Filter&Weight的調度,已經有大量的資料介紹過具體的實現和用法。可以參考官方文檔Filter Scheduler。

在Pike版本中,在調度這部分還是做了比較大的調度,主要就是2個相關變動。

  1. 通過Placement獲取可用的備選資源,參考Placement Allocation Requests的實現。
    在Ocata版本時,Resource Providers - Scheduler Filters in DB這個BP就已經在調度前加了一步,獲取備選節點。從BP的標題就可以看出,設計者想通過Placement服務提供的新的一套機制,來做過濾。原因是之前的調度需要在scheduler維護每一個compute節點的hoststate信息,然後調度的時候,再一個個去查,這太低效了,尤其是在計算節點數目比較多的時候。因此,增加了一個“預過濾”的流程,通過向Placement查詢,Placement服務直接通過SQL去查一把,把滿足條件(比如CPU充足、RAM充足等)先獲取到。
    而原來獲取備選節點的時候,只支持獲取單一的Resource Provider,這個BP增強了獲取備選資源的能力,用於後續支持更復雜的請求,比如共享資源、嵌套資源的Provider查詢。後面,Placement還會陸續支持更多的請求,比如對一些非存量不可計數的資源的支持。這樣留給後面Filter&Weight的壓力就小一些了,再往後,會不會完全取代Filter呢?我想,現有的各種過濾都可以通過Placement支持後,完全有可能的。

  2. Scheduler通過Placement來claim資源。參考Scheduler claiming resources to the Placement API的實現。
    在最早的時候,claim資源是由compute來做的,現在相當於提前到scheduler去搞了。有什麽好處呢?我們先看看原來的問題:
    調度時刻和真正的去compute節點去claim資源的時刻之間是由一段時間的,在資源不是那麽充足的環境,就會造成在scheduler調度的時候,資源還沒刷新,所以調度時候成功了,但是真正下來的時候,才發現compute實際已經沒有資源了,然後又“跨越半個地球”去做重調度,無形地增加了系統的負載。
    而且增加了創建的時長(哦,哪怕創建失敗呢?),你想想,用戶創了那麽久的虛擬機,最後你告訴我調度失敗了,用戶不太能忍。
    所以這個BP就把Claim資源放在調度處了,我上一個調度請求處理完,馬上就告訴placement,這資源老子用了,其他人不要動了。OK,世界終於清凈了,能拿到資源的拿到了,拿不到資源的馬上也知道自己拿不到了,大大增強了調度的用戶體驗。

2.4 Placement

恩,在調度的時候,已經介紹過這個服務了,在虛擬機創建的流程中,比較常用的接口就是獲取備選資源和claim資源。
Placement目標很宏偉,大致的作用就是:資源我來管,要資源問我要,用了資源告訴我。後面準備用一篇文章整體介紹一下Placement。(yep,這個Flag我立下了,會寫的)

2.5 Nova-Compute

好吧,到最後一個服務了,Compute。這個裏面依舊還是做那麽幾件事,掛卷,掛網卡,調driver的接口啟動一下虛擬機。至此,我們可愛的虛擬機就起來了。

3. 結語

整體的看一下,其實在Pike版本,Nova還是有很多的變動。真的是一個版本過去了,創建虛擬機的流程已經面目全非了。

從P版本的虛擬機創建流程來看,主要的優化集中在基於Cell V2架構下的多cell支持、調度的優化、Quota的優化,而後續的發展,目前也是集中在Placement各種資源的支持以及在Cell v2場景的諸如基本流程、調度等的優化。

OpenStack Nova虛擬機創建流程解析