cinder本地卷设计与实现

阿凡达2018-08-14 10:32

如何在cinder添加新存储后端

在cinder中添加新的存储后端,也即实现一个新的volume driver,需要在新driver中提供如下的driver method:

  • 必须要提供的:
    • create_volume ,创建卷
    • delete_volume ,删除卷
    • extend_volume ,扩容卷
    • initialize_connection ,建立云主机所在物理机和卷间的连接,nova挂载接口中用到
    • terminate_connection ,断开云主机所在物理机和卷间的链接,nova卸载接口中用到
  • 可以选择提供的:
    • attach_volume ,云主机挂载卷成功后cinder中的回调方法
    • detach_volume ,云主机卸载卷成功后cinder中的回调方法
    • migrate_volume ,迁移卷
    • create_export ,创建卷后根据不同卷类型看是否需要做一些加工,比如lvmiscsidriver中,会将创建出的lvm卷配置成一个iscsi target提供出去
    • remote_export ,和create_export相反
  • 快照功能需提供的:
    • create_snapshot ,创建快照
    • delete_snapshot ,删除快照
    • create_volume_from_snapshot , 从快照创建卷


cinder本地卷存储后端设计

需求

  • 为实现高性能云硬盘,需要实现一种可按照云硬盘方式管理,但存储资源又落在计算节点上,不经过网络,直接读写本地SSD存储设备的存储后端,也即 本地卷存储后端。
  • 本地存储后端,负责将计算节点上规划好的高性能SSD存储设备,通过卷的管理方式创建并挂载给该计算节点上的云主机。和当前网易已提供的ceph卷和nbs卷的唯一区别是,本地卷的存储资源完全落在某个计算节点上,且不能跨计算节点挂载到云主机中使用;API调用方面,本地卷和ceph卷,nbs卷无任何区别。


关键点

  • 本地卷创建删除等资源管理逻辑
  • 本地卷挂卸载载逻辑


本地卷创删的资源管理逻辑

  • 本地存储资源的管理
  • 计划采用lvm的管理方式,先将硬盘组成多个raid盘,然后将raid盘格式化成physical volume(pv),再将多个pv组成一个大的volume group(vg)。最终以这个vg作为该节点的本地卷存储pool提供给本地卷存储后端管理使用。
  • 采用lvm的管理方式,可以很方便的实现资源pool的动态扩容:添加新盘,格式化成pv,然后添加到vg中。还可以利用lvm的快照功能。还有一个不可忽视的好处是,社区代码中已经支持lvm卷的创建删除等管理操作。详见(cinder/volume/drivers/lvm.py LVMVolumeDriver)


本地卷挂卸载管理逻辑

  • 卷挂载到云主机中的两步操作:
    • 卷连接到云主机所在物理机上。
    • 将连接到物理机上的卷通过libvirt挂载到云主机中。
  • 将卷连接到物理机
    • 在initialize_connection方法中实现,一般是将卷路径,连接协议等信息返回给调用者。比如ceph卷和nbs卷的返回信息如下:
        ceph卷返回:
        {                                                                                                                                                          
            'driver_volume_type': 'rbd',                                                                                                                                  
            'data': {                                                                                                                                                     
                'name': '%s/%s' % (self.configuration.rbd_pool,                                                                                                           
                                   volume['name']),                                                                                                                       
                'hosts': hosts,                                                                                                                                           
                'ports': ports,                                                                                                                                           
                'auth_enabled': (self.configuration.rbd_user is not None),                                                                                                
                'auth_username': self.configuration.rbd_user,                                                                                                             
                'secret_type': 'ceph',                                                                                                                                    
                'secret_uuid': self.configuration.rbd_secret_uuid,}
        }                                                                                                      
       nbs卷返回:
        {                                                                 
            "data": {                                                              
                "access_mode": "rw",                                               
                "device_path": device_path,                                        
                "volume_id": self._get_nbs_id_from_volume(volume)                  
            },                                                                     
            "driver_volume_type": "local",                                         
         }
      

    • 本地卷大致可以参考NBS卷的实现方式,但除了返回lvm卷的device_path,driver_volume_type配置为local等信息外,需要在返回中添加本地卷的存储host属性,nova挂载接口中加以检查。
    • nova挂载卷的逻辑中,增加云主机host和卷存储host信息匹配检查逻辑,只有云主机和存储卷的host一致时才允许挂载。


本地卷具体实现

新实现一个LVMLOCALVolumeDriver

  • cinder/volume/drivers/lvm.py 中实现一个LVMLOCALVolumeDriver,继承LVMVolumeDriver。
  • 新添加一种volume_type : lvm,对应LVMLOCALVolume存储后端。
  • 在LVMLOCALVolumeDriver中需要重构的方法包含:
    • create_volume 最后需要将卷的host信息作为provider_location返回(可参考nbsdriver),其他创建逻辑同父类函数。
    • initialize_connection()中,直接返回如下信息:
        {                                                                 
            "data": {                                                              
                "access_mode": "rw",                                            
                "device_path": device_path,                                     
                "volume_id": volume['id'],
                "host": volume['provider_location'], 
            },                                                                     
            "driver_volume_type": "local",                                         
        }
      
    • terminate_connection()啥都不做,直接pass返回。
  • nova挂载卷逻辑中对本地卷的host信息和云主机的host信息做比较判断。


服务部署要求

  • 由于本地卷要求计算节点上必须要配置有cinder-volume服务,并配上LVMLOCALVolume存储后端。加上之前的ceph或nbs存储后端。一个节点上的cinder-volume服务要部署两种以上的后端,这个要求改变当前的配置方式,具体变更可参考cinder with multi-backend storage

网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者管强授权发布。