openstack neutron軟件架構

綜述

衆所周知,OpenStack 是目前開源界第二大的項目,參與的廠商之多可謂少見,實屬發展的分佈式系統軟件大作,面對這麼一個項目,我用自己在網絡方面的經驗與大家分享以 Neutron 爲例的 OpenStack 軟件設計。

Neutron 簡介

Neutron 是 OpenStack 的虛擬網絡組件,用洋氣點的話說,就是一個 SDN 控制器。爲什麼我們需要虛擬網絡?過去我們只給客戶提供虛擬機,你花錢,我租你一臺,想連接上就再買個公網 IP,就像很多人在 DigitalOcean 做得一樣(當然 DigitalOcean 現在也有虛擬網絡)。那有了虛擬網絡可以幹什麼呢?我們來看一下 UnitedStack 控制面板裏的一張圖:

這是一個所見即所得網絡架構

這是一個所見即所得網絡架構!我們可以在上面隨意的增加、修改和刪除2、3層網絡、路由器和虛擬機。而且通過虛擬網絡,爲用戶提供自助式的安全組、VPN、負載均衡設備等高級服務也將方便許多。

此外,從軟件設計角度來看 Neutron,它做到了 Unified API、Small Core、Pluggable Open Architecture 和Extensible,可以說是一個設計精良的系統。

架構

Neutron 的組件設計

  • 需要藉助 Keystone 完成認證服務
  • 由 neutron-server 接受請求
  • 組件間用消息中間件完成交流
  • 消息會在 Server、Plugin 和 Agent 間傳遞
  • Agent 和 Plugin 與數據庫交互
  • Agent 需要調用 Provider 完成功能

下面我們微觀的看一下 Neutron:

微觀的看一下 Neutron

Neutron Server

在上面的圖裏我們可以看到,Neutron 的服務端是個很複雜的模塊,他的複雜之處主要體現在它在”微內核“的基礎上實現了 Plugin、Service Plugin、Extension 的插拔,及其與 DB 的交互。

先從請求的入口說起。簡單的說,Neutron Server 就是一個 WSGI Application,WSGI 的好處相信不必我多說,它可以方便的增加或者抽取 Middleware,就像一個洋蔥一樣,把最核心的東西放在裏面,別的各種類似 Filter 的東西一層一層疊在外面就好了。借用一個 Pylon 官方文檔的圖:

Pylon 官方文檔的圖

只說核心 App,APIRouter,顧名思義,它是用來路由 API 請求的,把 API 請求真正發往那些實現功能的函數,在這裏 Neutron 會加載 core plugin 和 plugin extension,擴展它的 Resource map,針對每一個資源集合(比如 networks、subnets、ports 等)建立 Controller,以後 API 將被路由到 Controller 去,Controller 再去調用對應的 create、get、update、delete 方法。同時在這裏還可以做一些通用的檢查,比如權限、數據有效性、自動轉化數據格式等等。

如何清晰的表達一個資源?首先要說明這是一個擴展的資源,而不是新的資源,然後它擴展的是 port,接着是否允許 post、put,需要怎麼轉換數據格式,用什麼做數據驗證,是否要做權限檢查,默認值多少,在 get 資源時是否顯示,就算不懂 Neutron 的人也能看懂這些語句的意思。這裏體現了 Neutron/OpenStack 的代碼框架設計的優雅高明的地方,節省了程序員寫 dirty code 的時間,減少了初學者的學習門檻。

Core Plugin and Extensions

爲什麼在Middleware裏要加 Extension 相關的 Filter?很簡單,因爲 Extension 擴展了 Resource Map,我們需要配置其相應的 URL,那麼基礎資源是哪些呢?在 Neutron 裏,經過一些考慮後,我們把三類資源定義爲核心資源,這三類資源分別是network、subnet、port。這三類資源的實現呢,對應的要求由 Core Plugin 來實現。

用戶將可以在配置文件裏自由的設置 Plugin,然後再由NeutronManager加載。其結構也很清晰,CommonDbMixin完成基礎的 DB 操作,比如在查詢時增加 hook,設置 filter 等,NeutronDbPluginV2做與 Core Plugin 相關的數據庫操作,最後 Core Plugin 繼承NeutronDbPluginV2以及擴展的類。那麼_supported_extension_aliases是做什麼的呢,我們前邊說 Server 有一層 Filter 去加載 Extension 的 Resource Map,它在查找 Extension 時呢,是先根據目錄進行查找的,查找 extensions 目錄下的所有Python 文件,然後每個 extension 都會有一個 alias 名字,extension manager 再去查我們當前加載的 Core Plugin 是否支持這個 Extension,如果支持則加載,否則在日誌裏記錄一下這個"extension not supported by plugin"。

Service Plugin

剛纔只提到了加載 Core Plugin 和 Extensions,其實加載 Core Plugin 之後就加載 Service Plugin 了,而且因爲 Core Plugin 和 Service Plugin 有很多相似的地方,所以 Core Plugin 很多地方也都按照 Service Plugin 去處理,就比如說 Resource Map,我們核心資源是寫在RESOURCE_ATTRIBUTE_MAP裏的,Plugin Extension 由 Extension Manager 加載,那 Service Plugin 呢?剛纔我們說 Extension Manager,並沒有區分什麼 Plugin Extension Manager 或者 Service Extension Manager,就是因爲這兩個確實是不做區分的,而且很重要的一點是我們統一的只由 Extension 去擴展資源,就如前面 Filter 只有 Extension 但沒有別的,所以如果你需要擴展 Resource Map,那麼寫一個擴展,然後把它加在你的 Service Plugin 的 supported_extension 裏,Server 就可以接受相應的請求並路由了。

Agent

把服務端做得優雅,微內核之後,我們就要將調用發到 Agent 端去幹活了,首先我們要解決的是 RPC 遠程調用的問題。爲了簡化設計,多應用已成熟的東西,Neutron 或者別的 OpenStack 組件都是使用現有的 MessageQueue 服務完成的,而且 MessageQqueue 的調用有單獨抽象出來一個模塊叫做 Oslo.Messaging,於是對於 Neutron、Nova 這些服務它們也就不需要去考慮底層的 MQ 支持哪些,該如何調用這些問題了。目前 Oslo.Messaging 支持的 MQ 組件有 RabbitMQ、ZeroMQ 和 Qpid。我們平時用的比較多的 MQ Backend 主要是 RabbitMQ,其對 Topic 類型消息的處理過程大概如圖所示:

對 Topic 類型消息的處理過程大概如圖所示

OK,現在消息能發能收了,但可以通訊還不夠,我們需要實現遠程過程調用,俗稱 RPC,在 Neutron 裏這主要涉及到兩個類:

Neutron 裏這主要涉及到兩個類

右邊的Rpcroxy是服務端聯繫 Agent 用的,而RpcCallback是 Agent 聯繫服務端用的。在無論消息段還是服務端,都會運行來自oslo.messaging的MessageHandlingServer或類似的類,也就是一個個用綠色線程啓的Rpcorker,當RpcWoker收到任務時會去執行相應的調用,在一些 Agent (比如 L3 Agent)裏還實現了優先隊列,以保證高優先級的任務被首先執行。

總結

將分散在全世界的數百名來自不同廠家,專注不同業務的工程師集合起來,完成一個目前沒有成熟標準和現成學習者的軟件,不得不說開源社區的力量很強大,它既要保證代碼的優秀、自然,還要兼顧不同廠商的利益與差異,能在 3 年多的時間完成一個現在我們已經敢把它部署在 UnitedStack 線上,同時運營着共有云和託管雲,支撐數千名客戶的穩定高效使用的虛擬網絡組件已經表現不俗。在此希望所有對網絡虛擬化感興趣的同學加入進UnitedStack,我們並肩打造一個更加優秀的雲計算平臺!
 
 
 

轉載自:http://mp.weixin.qq.com/s?__biz=MjM5NjUxNDIwNw==&mid=201853844&idx=1&sn=4567bf6952dc8dd37c25f3afe64810bf&scene=2&from=timeline&isappinstalled=0#rd,作者UnitedStack王爲。

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