2021SC@SDUSC
cinder 是OpenStack 块存储的服务,为Nova虚拟机,容器等提供volume。
cinder的目的:
块存储:
- 操作系统获得存储空间的方式一般有两种:
1. 通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘,然后分区、格式化、创建文件系统;或者直接使用裸硬盘存储数据(数据库)。
2. 通过 NFS、CIFS 等 协议,mount 远程的文件系统。
2. 第一种裸硬盘的方式叫做 Block Storage(块存储),每个裸硬盘通常也称作 Volume(卷) 第二种叫做文件系统存储。NAS 和 NFS 服务器,以及各种分布式文件系统提供的都是这种存储。
块存储服务提供对 volume 从创建到删除整个生命周期的管理。从 instance 的角度看,挂载的每一个 Volume 都是一块硬盘。OpenStack 提供 Block Storage Service 的是 Cinder,其具体功能是:
1. 提供 REST API 使用户能够查询和管理 volume、volume snapshot 以及 volume type。
2. 提供 scheduler 调度 volume 创建请求,合理优化存储资源的分配
3. 通过 driver 架构支持多种 back-end(后端)存储方式,包括 LVM,NFS,Ceph 和其他诸如 EMC、IBM 等商业存储产品和方案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jPD394sG-1635174897985)(C:\Users\Jeremiah\AppData\Roaming\Typora\typora-user-images\image-20211025213146992.png)]
cinder-api :
控制卷的创建,删除,保存(从卷,镜像和快照中创建)
2. 快照的创建,删除和保存
3. volume attach and detach (call by nova)
4. 管理卷的种类,配额和备份
cinder-volume:
主要组件:
API:cinder-api与cinder-volume的交互
manager:真正实现api的组件
driver:manager 组件调用,包含与多种存储类型交流的后端专用代码。
注:
cinder - scheduler:
选择哪个后端用于放置新的volume
设置scheduler的插件 (Filter scheduler has plugins for filters and weights)
filter scheduler
流程:
volume-provider:
数据的存储设备,为volume提供存储空间,每个provider通过自己的driver与cinder-volume相协作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XJN2nQyw-1635174897988)(C:\Users\Jeremiah\AppData\Roaming\Typora\typora-user-images\image-20211025214907243.png)]
一 cinder api
调用cinder 提供api (api有v2和v3两个版本,v2已经被移除,现在默认使用v3版本,v3会进行更多的检查)即:v3/volume
api对请求做了name,description,image_id,type,metadata,snapshot等做了检查
之后调用volume_api的create方法
try:
new_volume = self.volume_api.create(
context, size, volume.get('display_name'),
volume.get('display_description'), **kwargs)
*except* exception.VolumeTypeDefaultMisconfiguredError *as* err:
*raise* exc.HTTPInternalServerError(*explanation*=err.msg)
检查volume_type和snapshot,并check metadata的属性,安装创建属性列表调用flows\api\create_volume.py的get_flow方法
create_what = {
'context': context,
'raw_size': size,
'name': name,
'description': description,
'snapshot': snapshot,
'image_id': image_id,
'raw_volume_type': volume_type,
'metadata': metadata or {},
'raw_availability_zone': availability_zone,
'source_volume': source_volume,
'scheduler_hints': scheduler_hints,
'key_manager': self.key_manager,
'optional_args': {'is_quota_committed': False},
'consistencygroup': consistencygroup,
'cgsnapshot': cgsnapshot,
'raw_multiattach': multiattach,
'group': group,
'group_snapshot': group_snapshot,
'source_group': source_group,
'backup': backup,
}
try:
sched_rpcapi = (self.scheduler_rpcapi if (
not cgsnapshot and not source_cg and
not group_snapshot and not source_group)
else None)
volume_rpcapi = (self.volume_rpcapi if (
not cgsnapshot and not source_cg and
not group_snapshot and not source_group)
else None)
flow_engine = create_volume.get_flow(self.db,
self.image_service,
availability_zones,
create_what,
sched_rpcapi,
volume_rpcapi)
volume\flows\api\create_volume.py
创建并返回api 的入口流:为独立任务注入键值对;解压并验证键值对;保存分配的额度,创建数据库入口;提交额度;将任务交给scheduler或者manager
flow_name = ACTION.replace(":", "_") + "_api"
api_flow = linear_flow.Flow(flow_name)
api_flow.add(ExtractVolumeRequestTask(
image_service_api,
availability_zones,
rebind={'size': 'raw_size',
'availability_zone': 'raw_availability_zone',
'volume_type': 'raw_volume_type',
'multiattach': 'raw_multiattach'}))
api_flow.add(QuotaReserveTask(),
EntryCreateTask(),
QuotaCommitTask())
if scheduler_rpcapi and volume_rpcapi:
# This will cast it out to either the scheduler or volume manager via
# the rpc apis provided.
api_flow.add(VolumeCastTask(scheduler_rpcapi, volume_rpcapi, db_api))
# Now load (but do not run) the flow using the provided initial data.
return taskflow.engines.load(api_flow, store=create_what)
cinder\scheduler\rpcapi.py
调用scheduler manager.py的SchedulerManager.create_volume方法
二 scheduler
cinder\scheduler\manager.py
调用 flows 的create_volume方法
flow_engine = create_volume.get_flow(context,
self.driver,
request_spec,
filter_properties,
volume,
snapshot_id,
image_id,
backup_id)
cinder\scheduler\flows\create_volume.py
创建ScheduleCreateVolumeTask
ScheduleCreateVolumeTask.execute函数,会调用driver_api.schedule_create_volume
create_what = {
'context': context,
'raw_request_spec': request_spec,
'filter_properties': filter_properties,
'volume': volume,
'snapshot_id': snapshot_id,
'image_id': image_id,
'backup_id': backup_id,
}
flow_name = ACTION.replace(":", "_") + "_scheduler"
scheduler_flow = linear_flow.Flow(flow_name)
# This will extract and clean the spec from the starting values.
scheduler_flow.add(ExtractSchedulerSpecTask(
rebind={'request_spec': 'raw_request_spec'}))
# This will activate the desired scheduler driver (and handle any
# driver related failures appropriately).
scheduler_flow.add(ScheduleCreateVolumeTask(driver_api))
# Now load (but do not run) the flow using the provided initial data.
return taskflow.engines.load(scheduler_flow, store=create_what)
cinder\scheduler\filter_scheduler.py
FilterScheduler. schedule_create_volume函数,更新数据库,最后通过消息队列请求调用volume_rpcapi.create_volume。
/cinder/volume/rpcapi.py
从消息队列中获得,调用VolumeManager.create_volume
三 cinder volume
/cinder/volume/manager.py
同样使用flow来创建volume,执行CreateVolumeFromSpecTask这个任务
/cinder/volume/flows/manager/create_volume.py
按照不同类别和driver创建卷,更新数据库,使卷可用
if model_update:
with volume.obj_as_admin():
volume.update(model_update)
volume.save()
cinder与nova组件的架构方式相似,执行顺序有一定规律,scheduler与os的调度机制相似,可类比创建线程过程
按照不同类别和driver创建卷,更新数据库,使卷可用
if model_update:
with volume.obj_as_admin():
volume.update(model_update)
volume.save()
cinder与nova组件的架构方式相似,执行顺序有一定规律,scheduler与os的调度机制相似,可类比创建线程过程
卷的创建 经过了 api – scheduler –volume的过程,api负责检查参数 ;scheduler负责调度;volume负责创建的执行和数据库和卷的管理。