天天看點

Glance源碼架構探秘(一)

Glance源碼架構探秘(一)

Glance源碼架構探秘(二)

Glance源碼架構探秘(三)

Glance源碼架構探秘(四)

前言

從本章開始,将會陸續為大家分享有關OpenStack各元件子產品代碼架構的探秘。首先從OpenStack的鏡像管理子產品Glance開始,原因是Glance隻負責鏡像的上傳,下載下傳等管理,功能對比Nova子產品來說相對比較少,便于代碼結構的分析。還是那句話,Stacker們,大家多交流,我看到留言會回複的~

Glance項目提供虛拟機鏡像的查找,注冊和重制,使用RESTful接口接受虛拟機鏡像管理的查詢請求。

2013-4-15新增

從F版開始使用的API V2,相對于V1版大大簡化了流程,将glance-api與glance-registry合并在了一起。

Glance源碼架構探秘(一)

glance-api V2

然而因為目前國内大多還停留在E版本的系統上,是以本文還是着重研究下E版本的代碼。目前暫時還不清楚此項更改對應的blue-print。

Glance源碼架構探秘(一)

程輝部落格中glance v1版架構圖

在程輝的一篇部落格中,有Glance的架構介紹,其中有上面的圖。作者将Glance-API和Glance-Registry解釋為調用關系是不正确的。這兩個服務是獨立運作的服務,在sbin目錄下,看過glance部署文章的同學知道,glance部署的最後一步就是啟動glance-api和glance-registry這兩個服務。這兩個服務作為WSGI,會分别響應來自使用者的RESTful請求,而不是圖上所暗示的glance-api響應請求,然後調用glance-registry進行image中繼資料在資料庫的注冊。(2013-4-15删除)

E版本代碼中,Glance-api和Glance-Registry兩個服務還沒有進行合并。檢視KeyStone的endpoint可知,系統和外界進行互動的接口是綁定了端口号9292的glance-api服務,而綁定端口号為9191的glance-registry隻在系統内部使用。

glance-api作為glance對外的服務入口,接受用戶端的所有指令,分發并響應,如果指令操作涉及到資料庫的增删改查等操作,glance會建立一個RegistryClient執行個體,往下向glance-registry轉發restful指令。

Glance對外服務的入口主要有2個(2013-4-15删除)

Glance有兩個WSGI服務子產品

1、Glance-API:主要負責接收響應鏡像管理指令的Restful請求,分析消息請求資訊并分發其所帶的指令(如新增,删除,更新等)。(2013/4/15新增)涉及到資料庫的操作會調用registry-clinet生成響應的http指令轉發給Glance-Registry服務。預設綁定端口是9292。

2、Glance-Registry:主要負責接收響應鏡像中繼資料指令的Restful請求。分析消息請求資訊并分發其所帶的指令(如擷取中繼資料,更新中繼資料等),進行資料庫相關的增删改查工作。預設綁定的端口是9191。

在/etc/glance目錄下有兩個檔案glance-api-paste.ini和glance-registry-paste.ini,兩個入口服務啟動後,會用配置檔案分析子產品讀取這兩個檔案,執行其檔案中标注的需要執行的WSGIapp和middleware。簡述paste檔案中的概念:

app:實際處理REST API請求的python類。

filter:一種裝飾器,為app提供一層封裝,在app處理請求之前會先調用filter的對象。

pipeline:所對應的對象是對filter和app的的封裝,他将多個filter和某個app綁在一起,在app處理請求之前要先通過pipline指定的在app之前的filter的處理。

在glance-registry中有

[app:registryapp]
paste.app_factory = glance.registry.api.v1:API.factory
           

證明這是一個獨立的服務程式

我們以glance-api為例,分析其服務入口程式

"""
Glance API Server
"""

import gettext
import os
import sys

# If ../glance/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
                                   os.pardir,
                                   os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')):
    sys.path.insert(0, possible_topdir)

gettext.install('glance', unicode=1)

from glance.common import config
from glance.common import wsgi
from glance.common import exception
from glance.openstack.common import log
import glance.store


def fail(returncode, e):
    sys.stderr.write("ERROR: %s\n" % e)
    sys.exit(returncode)


if __name__ == '__main__':
    try:
        config.parse_args()
        log.setup('glance')

        glance.store.create_stores()
        glance.store.verify_default_store()

        server = wsgi.Server()
        server.start(config.load_paste_app(), default_port=9292)
        server.wait()
    except exception.WorkerCreationFailure, e:
        fail(2, e)
    except RuntimeError, e:
        fail(1, e)
           

首先程式會調用glance.store.create_stores,注冊與後端存儲(swift、s3、filesystem等)相關的控制子產品,并校驗預設存儲方式。

緊接着啟動一個Http Server,openstack的WSGI SERVER用到了eventlet這個綠色線程(協程)的元件,這個我們後面一章會介紹到。

通過config.load_paste_app()方法,會從上面提到的glance-api-paste.ini配置檔案中讀取要啟動的WSGI app,并在server中啟動,并讓server線程等待接收http rest查詢響應。

下一章将為大家分析openstack所有服務共同用到的WSGI Server元件eventlet和Restful查詢請求的分發器Routes元件。

繼續閱讀