OpenStack-Nova組件理解

Nova是OpenStack雲中的計算組織控制器。支持OpenStack雲中實例(instances)生命週期的所有活動都由Nova處理。這樣使得Nova成爲一個負責管理計算資源、網絡、認證、所需可擴展性的平臺。但是,Nova自身並沒有提供任何虛擬化能力,相反它使用libvirt API來與被支持的Hypervisors交互。Nova 通過一個與Amazon Web Services(AWS)EC2 API兼容的web services API來對外提供服務。

功能和特點:

實例生命週期管理
管理計算資源
網絡和認證管理
REST風格的API
異步的一致性通信
Hypervisor透明:支持Xen,XenServer/XCP, KVM, UML, VMware vSphere and Hyper-V
OpenStack計算的組成:

Nova 雲架構包括以下主要組件:

  • API Server (nova-api)
  • Message Queue (rabbit-mq server)
  • Compute Workers (nova-compute)
  • Network Controller (nova-network)
  • Volume Worker (nova-volume)
  • Scheduler (nova-scheduler)
  • API Server(nova-api)


API Server

對外提供一個與雲基礎設施交互的接口,也是外部可用於管理基礎設施的唯一組件。管理使用EC2 API通過web services調用實現。然後API Server通過消息隊列(Message Queue)輪流與雲基礎設施的相關組件通信。作爲EC2 API的另外一種選擇,OpenStack也提供一個內部使用的“OpenStack API”。

Message Queue(Rabbit MQ Server)

OpenStack 節點之間通過消息隊列使用AMQP(Advanced Message Queue Protocol)完成通信。Nova 通過異步調用請求響應,使用回調函數在收到響應時觸發。因爲使用了異步通信,不會有用戶長時間卡在等待狀態。這是有效的,因爲許多API調用預期的行爲都非常耗時,例如加載一個實例,或者上傳一個鏡像。

Compute Worker(nova-compute)

Compute Worker處理管理實例生命週期。他們通過Message Queue接收實例生命週期管理的請求,並承擔操作工作。在一個典型生產環境的雲部署中有一些compute workers。一個實例部署在哪個可用的compute worker上取決於調度算法。

Network Controller(nova-network)

Network Controller 處理主機地網絡配置。它包括IP地址分配、爲項目配置VLAN、實現安全組、配置計算節點網絡。

Volume Workers(nova-volume)

Volume Workers用來管理基於LVM( Logical Volume Manager )的實例卷。Volume Workers有卷的相關功能,例如新建卷、刪除卷、爲實例附加捲,爲實例分離卷。卷爲實例提供一個持久化存儲,因爲根分區是非持久化的,當實例終止時對它所作的任何改變都會丟失。當一個卷從實例分離或者實例終止(這個卷附加在該終止的實例上)時,這個卷保留着存儲在其上的數據。當把這個卷重附加載相同實例或者附加到不同實例上時,這些數據依舊能被訪問。

一個實例的重要數據幾乎總是要寫在捲上,這樣可以確保能在以後訪問。這個對存儲的典型應用需要數據庫等服務的支持。

Scheduler(nova-scheduler)

調度器Scheduler把nova-API調用映射爲OpenStack組件。調度器作爲一個稱爲nova-schedule守護進程運行,通過恰當的調度算法從可用資源池獲得一個計算服務。Scheduler會根據諸如負載、內存、可用域的物理距離、CPU構架等作出調度決定。nova scheduler實現了一個可插入式的結構。

當前nova-scheduler實現了一些基本的調度算法:

隨機算法:計算主機在所有可用域內隨機選擇
可用域算法:跟隨機算法相仿,但是計算主機在指定的可用域內隨機選擇。
簡單算法:這種方法選擇負載最小的主機運行實例。負載信息可通過負載均衡器獲得。
---------------------------------------------------------------------------------------------------------------------------------------------------

對於Nova,我們先來看一張圖:


 



總的來說,nova的各個組件是以數據庫和隊列爲中心進行通信的,下面對其中的幾個組件做一個簡單的介紹:
Queue,也就是消息隊列,它就像是網絡上的一個hub,nova各個組件之間的通信幾乎都是靠它進行的,當前的Queue是用RabbitMQ實現的,它和database一起爲各個守護進程之間傳遞消息。
database存儲雲基礎架構中的絕大多數狀態。這包括了可用的實例類型,在用的實例,可用的網絡和項目。當前廣泛使用的數據庫是sqlite3(僅適合測試和開發工作)、MySQL和PostgreSQL。
nova-compute負責決定創造虛擬機和撤銷虛擬機,通過運行一系列系統命令(例如發起一個KVM實例,)並把這些狀態更新到nova-database中去,其過程相當複雜,但是基本原理很簡單。
nova-schedule負責從queue裏取得虛擬機請求並決定把虛擬機分配到哪個服務器上去。schedule的算法可以自己定義,目前有Simple (最少加載主機),chancd(隨機主機分配) ,zone(可用區域內的隨機節點)等算法。
nova-volume負責記錄每一個計算實例,相當於一個計算請求吧,並負責創建,分配或撤銷持久層容器(Amazon的,iSCSI,AoE等等)給這些compute instances。
nova -netwok負責處理隊列裏的網絡任務。
nova-api守護進程是OpenStack Compute的中心。它爲所有API查詢提供一個入口, 並且同時支持OpenStack API 和 Amazon EC2 API。
爲了看看nova是如何工作的,我們可以以啓動一個實例爲例來進行說明,因爲啓動一個新的instance涉及到很多openstack nova裏面的組件共同協作。


 


其中:
API :處理客戶端的請求,並且轉發到 Queue和Database中。
Scheduler:選擇一個host去執行命令
nova-compute :啓動和停止實例,附加和刪除卷等操作
nova-network:管理網絡資源,分配固定IP。
接下來就是真正的過程了,先從API開始:
API
例如我們輸入一個命令:euca-run-instances -k test -t m1.tiny ami-tiny 它會執行以下操作:
查看這種類型的instance是否達到最大值
給scheduler發送一個消息(實際上是發送到Queue中)去運行這個實例。
Schedule
調度器接收到了消息隊列Queue中API發來的消息,然後根據事先設定好的調度規則,選擇好一個host,之後,這個instance會在這個host上創建。
Compute
真正去創建一個instance的操作是由Compute完成的,而這個過程中computer組件與Glance密不可分,如圖所示:


 




---------------------------------------------------------------------------------------------------------------------------------------------------

想了解雲計算可以做什麼,就意味着你必須掌握虛擬化概念。通過虛擬化,你可以在虛擬機上而不是物理計算機上運行操作系統和應用程序。要使用虛擬機,你必須提供一個鏡像文件,它包含了運行虛擬機所需的信息:包括要運行的操作系統、用戶的登錄名和密碼、儲存在系統上的文件等等。在 OpenStack 核心項目中,Nova 項目可謂是核心中的核心。正如 OpenStack 網站所介紹的,Nova 是 IaaS 系統的主要部分, 旨在爲大規模的配置和管理虛擬機實例提供一個框架。與 Amazon 的EC2 服務的功能類似,它允許用戶使用自己的鏡像文件,通過可編程 API 創建、管理和銷燬虛擬服務器。Nova 生產環境的配置模式
從功能上看, Nova 平臺中有兩類節點: 控制節點和計算節點,其角色由安裝的服務決定,控制節點包括網絡控制 Network、調度管理 Scheduler、api服務、存儲卷管理、數據庫管理、身份管理和鏡像管理等,計算節點主要提供 nova-compute 服務。節點之間使用 AMQP 作爲通訊總線,只要將 AMQP 消息被寫入特定的消息隊列中,相關的服務就可以獲取該消息進行處理。由於使用了消息總線,因此服務之間是位置透明的,你可以將所有服務可以部署在同一臺主機上,即 All-in-One(一般用於測試),也可以根據業務需要,將其分開部署在不同的主機上。用在生產環境 Nova 平臺配置一般有三種類型:最簡配置:需要至少兩個節點,除了 nova-compute 外所有服務都部署在一臺主機裏,這臺主機進行各種控制管理,即控制節點。  圖1-1 OpenStack 雙節點架構
標準配置:控制節點的服務可以分開在多個節點,標準的生產環境推薦使用至少 4 臺主機來進一步細化職責。控制器、網絡、卷和計算職責分別由一臺主機擔任。  

圖1-2 OpenStack 多節點架構
高級配置:很多情況下(比如爲了高可用性),需要把各種管理服務分別部署在不同主機,(比如分別提供數據庫集羣服務、消息隊列、鏡像管理、網絡控制等),形成更復雜的架構:
 

圖1-3 OpenStack 高級架構
這種配置上的彈性得益於 Nova 選用 AMQP 作爲消息傳遞技術,更準確地說,Nova 服務使用遠程過程調用(RPC)彼此進行溝通。。AMQP 代理(可以是 RabbitMQ 或 Qpid)位於任兩個 Nova 服務之間,使它們以松耦合的方式進行通信。因此不單 API 服務器可以和服務進行通訊,服務之間也可以相互通訊,如計算服務和網絡服務、卷服務進行通訊以獲得必要的資源。每一個 Nova 服務(Compute、scheduler 等等)在初始化時會創建兩個消息隊列:其路由選擇關鍵字分別爲“NODE-TYPE.NODE-ID”(如:Compute.)和“NODE-TYPE”(如 Compute)。後者則接收一般性消息,而前者則只接收發給特定節點的命令,例如執行 “euca-terminate instance”, 很明顯,該命令只應發送給運行該實例的某個計算節點。無論是那一種生產配置模式,都允許用戶根據需添加更多的計算節點,由 N 臺服務器執行計算任務。

鳥瞰 OpenStack 
在一個經典部署的 OpenStack 中,Nova、Swift 和 Glance 這三大組件需要協同交互,這裏我們通過啓動實例這樣一個典型操作來看看它們之間的交互:
  • 1. 客戶端利用 API 發出請求,要求啓動一個實例。
  • 2. 該請求通過一系列檢查 (比如配額、權限等等)後,由 Nova API 服務器進行處理。
  • 3. Nova API 服務器通過隊列將啓動實例的任務交給了 Nova 調度器。
  • 4. 調度器根據調度規則決定在哪運行實例 — 即從 N 個計算節點中選取符合規則的節點
  • 5. 調度器通過隊列向指定的計算節點發出消息讓其開始創建實例
  • 6. 計算節點通知客戶端實例開始創建,現在客戶端可以繼續其它任務
  • 7. 在後臺,計算節點利用 Glance API 在 Glance 註冊表中查找所需的鏡像文件
  • 8-9. Glance API 向計算節點返回該鏡像文件的物理位置和元數據
  • 10. 得到了物理位置等信息,計算節點就可以 Swift Proxy 請求鏡像文件
  • 12-13. Swift Proxy 從 Swift 工作單元中獲得映象,並將其傳遞給計算節點
獲得了鏡像文件之後,計算節點就可以利用 libvirt API 來與被支持的Hypervisors交互:
  • 計算節點會在數據庫中更新實例的詳細信息,並調用 hypervisor 開始配置實例的塊設備
  • 計算節點向網絡節點的隊列發出消息以便爲實例配置網絡
  • 一旦收到返回的網絡信息,計算節點就開始最後的配置調整,並啓動實例
  • 創建實例完成之後,無論成功與否,結算節點都會更新數據庫,並在消息隊列中發出通知
各組件間的交互如圖 1-4 所示:
 

圖1-4 在 OpenStack 中啓動實例
接下來我們來看一下 Nova 各部件在執行啓動實例時的通訊過程。

Nova 部件間的通訊
最核心的 Nova 幾個服務包括:API,計算服務,調度器和網絡。API 是 Nova 的 HTTP 界面,計算服務則運行在每一臺主機上負責與 hypervisor 通訊(通常每臺主機有一個計算服務)。網絡服務管理 IP 地址池並且與交換機、路由器、防火牆等相關服務通訊。調度器則負責既有的池中選擇最適合的計算節點來負責運行新的實例(同時它也負責獲取卷)。Nova 本身是按分佈式應用程序進行架構的,在上一篇文章中,我們已經介紹了各個部件的功能,這裏我們簡單回憶一下:
  • API 服務器(nova-api): 處理用戶請求並將之路由給雲控制器
  • 雲控制器(Cloud Controller):nova-api的一個類,負責處理計算節點、網絡控制器、 API 服務器和調度器之間的通訊
  • 調度器:選擇某一主機來運行命令
  • 計算工作單元:管理計算實例:啓動或終止實例、掛載或卸載卷等等…
  • 網絡控制器:管理網絡資源:分配固定 IP 地址、配置 VLAN …
注意:雲控制器不是 Nova 7個部件之一,它只是 API 服務器的一個內部類而已。爲了方便敘述通訊過程,這裏我們單獨把它抽離出來。在 Nova 內部,啓動實例的流程是這樣的:首先 API服務器接收到來自用戶的 run_instances 命令。 API服務器將該消息轉發到雲控制器(1)。我們知道這裏需要進行驗證以確保用戶具有所需的權限。雲控制器將消息發送給調度器(2)。調度程序將消息轉換爲一個隨機的主機,並詢問他開始一個新的實例(3)。在主機上抓起的消息(4)的計算工作。計算工人需要一個固定的IP,所以將消息發送到網絡控制器(5,6,7,8)推出一個新的實例。


----------------------------------------------------------------------------------------------------------------------------------------------------

OpenStack Nova Service啓動分析

Nova project下面具有多個service,api,compute,sceduler等等,他們的啓動過程都幾乎類似,這一篇博客就詳細記錄nova-sceduler的啓動過程。文章中貼出的源碼都是從OpenStack Folsom版截取過來的。
下面就開始分析nova-sceduler的啓動過程了,後面還有涉及到啓動之後,做的一些週期性工作,這部分可能與sceduler無關,是在compute中的,一次帖上來。




首先是解析啓動腳本的參數,包括配置文件,設置日誌,utils.monkey_patch現在不明白(爲了能夠使用高效的eventlet模塊, 需要打些補丁),然後創建服務,最後啓動服務,等待請求。 Service.Service.create(binary=’nova-scheduler)過程如下:




過程爲獲取host name,topic即爲用來與rabbit通信的標識,爲scheduler,manager爲scheduler_manager,在flags中搜 索其對應的類名,其值在nova.conf中指定,默認值爲nova.scheduler.manager.SchedulerManager ,report_interval爲節點將狀態報告給數據庫的時間間隔,默認爲10秒。Periodic_interval,執行週期性任務的週期。再開 始初始化service。




其中關鍵的manager,其中self.manager_class_name 爲nova.scheduler.manager.SchedulerManager,通過importutils.import_class動態的導入 該對象,故manager_class是這 麼一個對象。(記住,在python中,一切都是對象,有類型對象,實例對象,譬如int爲一個類型對象,5則爲一個實例對象,其類型是int,而int 的類型則爲type。)然後,調用SchedulerManager的__init__函數完成初始化,注意SchedulerManager的 __init__函數的參數列表,有args和kwargs,所以host=self.host就成了kwargs的一項。
創建完service類之後,開始啓動service。




其中workers爲none,執行else語句,lanuch_server如下:




使用eventlet.spawn啓動一個green thread,run_server如下:




開始啓動server,其中start的關鍵代碼如下:




首先獲取一個到rabbitmq server的連接,然後再註冊一個rpc_dispatcher,該對象與回調函數相關,接收到rabbitmq的消息後,再由它來處理,接着創建多個 consumer來接收特定topic的消息隊列的消息,並設置好消息監聽。 這樣一個服務就啓動來了,在後面還有設置週期性的task。
在初始化service的過程中,會調用importutils動態導入具體的manager,對於nova-compute,導入的則是 ComputeManager,該類的繼承關係 是,ComputeManager,Manager.SchedulerDependentManager,Manager,nova.db.Base. 其中Manager包含ManagerMeta元類。可以參考RabbitMQ(三)中 的manager類關係圖。 對Manager與ManagerMeta的分析如下,這塊代碼涉及到一個資源刷新的問題。對於metaclass的分析可以參考後面的python高級 中的metaclass最後一個例子分析。Manager具有一個類屬性_periodic_tasks,是一個列表類型的屬性,元素是各個需要週期執行 的task。在manager類創建時,因爲使用到了metaclass,會首先檢查每個具有_periodic_task屬性的函數,該屬性由裝飾器 periodic_task裝飾上的。




這部分的代碼就是啓動週期性的task。
LoopingCall初始化最關鍵的參數是f,即傳遞進一個函數。430行,就將service的report_state函數傳遞進去,然後調用start函數,下面是start函數的實現。


可以知道,start函數內部有一個閉包函數,然後啓動一個greenthread的來執行這個內部函數,內部函數根據傳遞的參數,決定是否要推遲啓動,然後開始週期性的執行傳遞進來的函數,即self.report_state和self.periodic_task.
查看report_state的代碼,關鍵的如下:



主要的作用是週期性的更新數據庫中的nova庫service表的report_count字段,目前不知道該字段有什麼作用!

再查看periodic_task函數,service.periodic_tasks函數最後會調用 self.manager.periodic_tasks,該函數在nova.manager.py中,該函數會去調用被periodic_task裝飾 的函數,在nova-compute服務中,被periodic_task裝飾的有_publish_service_capabilities函 數,_report_driver_status函數等等,report_driver_status讀取host的相關信息,然後更新 capabilities,最後通過scheduler_rpcapi發送到scheduler服務去。

原地址:http://www.aboutyun.com/thread-6733-1-1.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章