这段时间捣鼓了一下Glance源代码,还是有收获的,修改了部分代码实现了支持多个ceph存储后端的功能。这个功能是不是个伪需求都还待定,反正也就当磨练了。
关于支持多个ceph存储后端的功能,稍微说一下
需要实现的功能就是在命令中行上传镜像,通过指定集群将镜像上传到不同ceph集群中。在通过nova创建虚拟机的时候肯定也需要能够使用这些创建虚拟机,当然这在计算节点的nova配置中就能实现。
整体结构图
Glance架构是一个典型的CS架构,提供的也是标准的Rest接口,各个layer分层也是很清楚的。
Following components are present in the Glance architecture:
A client - any application that makes use of a Glance server.
REST API - Glance functionalities are exposed via REST.
Database Abstraction Layer (DAL) - an application programming interface
(API) that unifies the communication between Glance and databases.
Glance Domain Controller - middleware that implements the main
Glance functionalities such as authorization, notifications, policies, database connections.
Glance Store - used to organize interactions between Glance and various
data stores.
Registry Layer - optional layer that is used to organise secure
communication between the domain and the DAL by using a separate service.
这都是直接从官网弄下来的。稍微解释一下
名字 解释
glance-api 服务端,负责处理各个请求
glance-store 与底层存储打交道,做适应性驱动等
glance-client 客户端,处理用户命令并发送请求到服务端
glance-registry 处理元数据相关,跟数据库有关
Gateway and basic layers
The domain model contains the following layers:
Authorization
Property protection
Notifier
Policy
Quota
Location
Database
这次主要关注的还是Location这一层,database主要是由glance-registry来进行数据库的交互,顺带了解了很多。
请求处理的大致过程如下:
Client端发送请求,api端router.py中将请求下发,选择相应的方法处理请求,目前我们测试环境中使用的api是v1版本
经过中间auth, notifier, policy, quota到location,会调用到glance_store进行底端存储,并返回存储的位置信息,需要写到数据库中
在跟数据库的交互中需要用到glance_registry,将镜像的相关信息写到数据库中,值得注意的是会将上面镜像存储的位置信息location_uri写入到数据库中,在进行删除等操作会直接从数据库中读取这个uri,进行删除
这里只是分析了一些主要的请求处理流程,对于一些复杂的过程暂时不考虑
重要流程分析
1. Glance服务启动过程
在/cmd/api.py中可以看到启动服务时进行操作:
def main():
try:
config.parse_args()
log.setup('glance')
glance.store.create_stores()
#将所有支持的存储store_cls及其location_cls信息加载
glance.store.verify_default_store()
#验证默认存储,这两步会调用到rbd.py中生成store对象测试
server = wsgi.Server()
#启动wsgi服务
server.start(config.load_paste_app('glance-api'), default_port=9292)
server.wait()
这时会启动wsgi的服务来接收请求。在router.py中,会将请求与方法绑定:
class API(wsgi.Router):
"""WSGI router for Glance v1 API requests."""
def __init__(self, mapper):
images_resource = images.create_resource() #controller
mapper.connect("/",
controller=images_resource,
action="index")
mapper.connect("/images",
controller=images_resource,
action='index',
conditions={'method': ['GET']})
mapper.connect("/images/detail",
controller=images_resource,
action='detail',
conditions={'method': ['GET']})
mapper.connect("/images",
controller=images_resource,
action='create',
conditions={'method': ['POST']})
在create_resource中会生成两个wsgi需要的序列化和还原序列化的控制器
def create_resource():
"""Images resource factory method"""
deserializer = ImageDeserializer()
"""Handles deserialization of specific controller method requests."""
serializer = ImageSerializer()
"""Handles serialization of specific controller method responses."""
return wsgi.Resource(Controller(), deserializer, serializer)
2.列表过程image-list
在使用glance image-list时候调用的就是这个过程,用于检索可用的image列表。
glance-client会发送一个get请求到 http://glance.openstack.example.org/v1/images/detail 给api端
glance-api收到请求后,按照前面的router.py中的map将请求映射到detail方法。
def detail(self, req):
self._enforce(req, 'get_images')
params = self._get_query_params(req)
try:
images = registry.get_images_detail(req.context, **params) #从registery中读取元数据
# Strip out the Location attribute. Temporary fix for
# LP Bug #755916. This information is still coming back
# from the registry, since the API server still needs access
# to it, however we do not return this potential security
# information to the API end user...
for image in images:
redact_loc(image, copy_dict=False) #清除系统不小心存留的位置信息
self._enforce_read_protected_props(image, req)
except exception.Invalid as e:
raise HTTPBadRequest(explanation="%s" % e)
return dict(images=images)
数据将会已下面格式的JSON返回
{'images': [
{'uri': 'http://glance.openstack.example.org/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9',
'name': 'Ubuntu 10.04 Plain 5GB',
'disk_format': 'vhd',
'container_format': 'ovf',
'size': '5368709120',
'checksum': 'c2e5db72bd7fd153f53ede5da5a06de3',
'created_at': '2010-02-03 09:34:01',
'updated_at': '2010-02-03 09:34:01',
'deleted_at': '',
'status': 'active',
'is_public': true,
'min_ram': 256,
'min_disk': 5,
'owner': null,
'properties': {'distro': 'Ubuntu 10.04 LTS'}},
...]}
3.镜像创建过程
4.镜像删除过程