OpenStack Nova內部機制【譯】

本文經原作者同意後進行轉載和翻譯,原文鏈接

本人正在學習Openstack源碼,爲了自己學習和他人學習方便,故可能將一些國外優秀博客翻譯轉載。本人看英語文章基本順利,但是翻譯卻不太在行,也希望通過這個方式提升一下英語水平,如果您發現我翻譯後的文章問題太嚴重,儘管指出,謝謝!另外也希望志同道合的朋友一起探討有關Openstack的問題!

作爲 核心開發者 ,我已經爲 Openstack 的 Nova 項目工作了18個月多。開始的時候這個項目很小,所以你可以很容易的從代碼庫找到你想要的東西。你的代碼不必完全遵守 PEP8 即可提交。但是,對於任何一個項目來說,隨着項目的深入,更多瑣碎的問題將接踵而來。嚴格控制異常處理、併發、狀態管理、同步異步操作及數據分區變得至關重要。作爲核心開發者也越來越難以記住所有的規則,更不用說是一個新的貢獻者,所以新的貢獻者很難完成第一次提交。

出於這個原因,我想我會在我博客中寫一些深入介紹Openstack項目的文章,幫助一些人少走彎路。在這開始,我需要先介紹一下Openstack源碼佈局和基礎架構。

我將假設你懂得 Cloud IaaS (鏡像管理、虛擬機管理器、實例管理、網絡管理等概念), Python (如果你是經驗豐富的程序員,語言不是問題)還有基於事件驅動的框架(又叫做 Reactor pattern )。

源碼佈局

在你一拿到Nova的源碼後,你會很容易的瞭解它的主要佈局。

git clone https://github.com/openstack/nova.git 真正的Nova服務的代碼在 ./nova 下,相應的單元測試在 ./nova/tests 下。這是一個簡化的Nova源碼目錄結構:

├── etc
   └── nova
├── nova
   ├── api - the Nova HTTP service
      ├── ec2 - the Amazon EC2 API bindings
      ├── metadata
      └── openstack - the OpenStack API
   ├── auth - authentication libraries
   ├── common - shared Nova components
   ├── compute - the Nova Compute service
   ├── console - instance console library
   ├── db - database abstraction
      └── sqlalchemy
            └── migrate_repo
                  └── versions - Schema migrations for SqlAlchemy
   ├── network - the Nova Network service
   ├── notifier - event notification library
   ├── openstack - ongoing effort to reuse Nova parts with other OpenStack parts.
      └── common
   ├── rpc - Remote Procedure Call libraries for Nova Services
   ├── scheduler - Nova Scheduler service
   ├── testing
      └── fake - Fakes for testing
   ├── tests - Unit tests. Sub directories should mirror ./nova
   ├── virt - Hypervisor abstractions
   ├── vnc - VNC libraries for accessing Windows instances
   └── volume - the Volume service
├── plugins - hypervisor host plugins. Mostly for XenServer.

深入看代碼前,我們需要仔細瞭解Nova的架構。Openstack是多個服務的集合,一個服務意味着運行着的一個進程。根據部署Openstack的規模,決定了你是選擇將所有服務運行在同一個機器上還是多個機器上。

Openstack的核心服務爲: API、Compute、Scheduler和Network。你也可能需要管理主機鏡像(可存儲在 Swift Storage Service )的 Glance Image Service 。我們會在之後深入瞭解每一個服務,但是現在需要了解他們各自的任務是什麼。 API是進入Nova的HTTP接口。Compute和虛擬機管理器交互來運行虛擬機(經常是一個主機一個Compute服務)。Network通過和交換機、路由器、防火牆以及相關設備來管理Ip地址池。Scheduler從可用池中選擇最合適的計算節點來創建新的實例(它也可能用來選擇Volumes)。

數據庫本身不是Nova的服務之一。每一個Nova服務都可以直接訪問數據庫(儘管它不應該這樣訪問,我們正在修正這個問題)。如果一個計算節點被攻擊,我們要避免它來訪問數據庫。

你可能單獨的運行一個 Authentication 服務(像Kenstone) 或者負責管理硬盤的 Volume 服務,這都不是必須的。

Openstack Nova 使用 AMQP (特別是 RabbitMQ ) 作爲服務之間的交流總線。AMQP 信息寫入到專門的隊列中,然後由專門的服務從中去走進行處理。這個決定了Nova的性能。如果你發現一個單一的計算節點不能處理所有的請求,你可以增加另外一個計算節點,其他服務也可以這麼做。

如果AMQP是服務之間唯一的交互方式,那麼用戶如何執行指令?答案是API服務,它是一個HTTP服務(一個Python中的 WSGI 應用)。API服務監聽HTTP上的 REST 命令並且將他們轉換成相應服務的AMQP消息。同樣的,來自服務的相應也通過 AMQP和API服務轉換成HTTP相應返回給請求者。 OpenStack當前可以使用 EC2 (亞馬遜API) 和 OpenStack (是 Rackspace API 的變種)。我們將在後面的文章中詳細介紹API服務。

但是不僅僅是API可以和服務交互。服務之間也可以交互。Compute可能需要和Network和Volume交互來獲得必須的資源。如果我們不關心怎麼組織源碼,這些功能會是代碼有一點點凌亂。現在,我們開始深入瞭解服務和RPC機制。

註釋

我將使用Python的單元測試模塊,方法以及函數。特別的,nova.compute.api:API.runinstance 等同與 ./nova/compute/api.py文件中的runinstance方法。同樣的,nova.compute.api.dosomething指的是./nova/compute/api.py文件中的dosomething函數。

和一個服務交互

除了API服務,每一個Nova服務必須有一個相應的Python模塊來處理RPC命令的封裝處理。例如:

Network服務 ./nova/network/api.py Compute服務 ./nova/compute/api.py Scheduler服務 ./nova/scheduler/api.py … 這些模塊通過集合大量函數來使服務正常工作。但是有的時候他們包含一些類來工作。這都依賴與我們是否需要截斷一些服務對函數的調用。我們會在接下來接觸這些用例。

Scheduler服務nova.scheduler.api可能有着最多的簡單接口,包含最難的函數。

Network是一個有着唯一API類的服務,儘管它可以通過簡單的函數被實現。

Compute有一個有趣的類層封裝,如:

BaseAPI->API->AggregateAPI BaseAPI->HostAPI nova.compute.api.API 是類中的主力,我們將在以後做別的派生。

如果我想要暫停一個運行中的實例,我需要導入nova.compute.api,實例化API類並且調用pause()方法。這個過程將封裝參數並且將它傳送給Compute服務,由Compute通過相應的AMQP隊列來管理那個實例。尋找相應的compute服務的AMQP是通過一個數據庫的快速掃描實現的,這個方法在nova.compute.api:BaseAPI.castorcallcompute_message。對與其他服務也是這樣,通過調用相應的api模塊然後調用函數。

Cast和Call

AMQP不是完全的 RPC 機制,但是我們可以從它那裏獲得類RPC特性。在nova.rpc.init中有兩個調用來操作cast()和call()。cast()在一個服務上執行異步的調用,而call()是一個同步的操作所以它需要一個返回值。call()真正做的是從服務動態創建一個短暫的AMQP來返回消息。它會一直等待一個 eventlet greenthread 直到接收到響應。

如果異常是源於nova.exception:NovaException的,那麼它也可以通過這個響應傳遞以及在調用者方重生成/重拋出。否則,一個nova.rpc.common:RemoteError會被拋出。

理論上,我們將僅僅執行異步cast()來和服務通信,而call()很明耗費更大的代價。認真選擇你需要的,如果可能,儘量不要依賴返回值。同時,儘量使你的函數是冪等的,因爲它們可能會在未來一直執行。

如果你對rpc-over-amqp的工作原理感興趣,多看看nova.rpc.impl_kombu

Fail-Fast 系統架構

Openstack使用的是“快速失敗”的系統架構。如果一個請求不成功,則馬上返回一個一場丟給其調用者。但是,當一個Nova服務是eventlet中的一個操作時,它一般不會以我們希望的狀態終止任何進程或離開系統。一個新的請求可以通過AMQP或HTTP非常容易的被處理。除非我們正在做的一件事情需要顯示的進行清理。如果你期望字典中一個確定的值,一個關鍵錯誤彈出是正確的。對於不同的錯誤情況,你不需要常常派生一個獨立的異常,甚至在最壞的情況下,WSGI中間件將把它轉化成客戶端可以處理的。對於事件驅動的編程這是很不錯的方式,我們會在後續的文章中講解nova的錯誤處理。

好了,這是一些Nova源碼的佈局和服務間如何通訊。下一此我們將探究服務管理器和驅動,來了解服務如何在被調用方實現。


轉自:http://yansu.org/2012/11/08/openstack-nova-internal.html

發佈了5 篇原創文章 · 獲贊 25 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章