【openstack】【cinder】Offload rbd’s copy_volume_to_image function from host to ceph cluster

    目前,云硬盘创建镜像,调用cinder upload-to-image。处理流程:先缓存rbd image到本地(本地磁盘IO利用率高),再调用glance upload image 到glance(占用管理网络带宽),整体很耗时间。

官方的具体描述:https://specs.openstack.org/openstack/cinder-specs/specs/liberty/optimze-rbd-copy-volume-to-image.html

官方提供两种方案,具体描述如下:

前提:

  1. cinder和glance的存储后端在同一个ceph集群中
  2. 如果不是,仍然采用目前的方案,先将rbd image导入到cinder volume本地,然后再调用glance uoload api上传文件到glance 存储后端
  3. 如果是的话,可采用rbd.image.copy 方法,将volume  从一个volume pool 拷贝到image pool

方法1:采用copy

方法2:采用clone。具体如下:1. 创建一个volume 快照snap ,同时project 这个snap 2. 基于快照clone一个child image 3.Flatten 这个child image 4. unprotect 这个snap,然后删除它

根据测试:方法1耗时更短。(具体可查看官网描述)


具体的代码修改,可参考如下(Liberty):

cinder.volume.drivers.rbd.py

def copy_volume_to_image(self,context, volume, image_service, image_meta):

    #(offload rbd's copy_volume_to_imagefunction from host to ceph cluster)

   if self.configuration.rbd_copy_volume_to_glance://cinder.conf中可控制是否采用copy方法

       glance_rbd_ceph_fsid = self.configuration.glance_rbd_ceph_fsid

       if self._get_fsid() ==glance_rbd_ceph_fsid://判断glance和cinder是否在同一个ceph集群

           LOG.debug("Glance backend is in the same ceph cluster, "

                      "try to copy volume%s to glance.", volume['name'])

           image_id = image_meta['id']

           src_pool = self.configuration.rbd_pool

           src_img_name = volume['name']

           dst_pool = self.configuration.glance_rbd_pool

           dst_img_name = image_id

           self._copy(src_pool, src_img_name, dst_pool, dst_img_name)

 

           # 可根据需要是否创建一个snapshot

              """"""

              return

       else:

           LOG.debug("Glance backend is in a different ceph cluster.")

   # 'rbd_copy_volume_to_glance'is False or glance's ceph cluster is difference with cinder' ceph cluster

   LOG.debug("Try to upload volume %sto glance.", volume['name'])

   tmp_dir = self._image_conversion_dir()

   tmp_file = os.path.join(tmp_dir,

                            volume['name'] +'-' + image_meta['id'])

    withfileutils.remove_path_on_error(tmp_file):

       args = ['rbd', 'export',

                '--pool', self.configuration.rbd_pool,

                volume['name'],tmp_file]

       args.extend(self._ceph_args())

       self._try_execute(*args)

       image_utils.upload_volume(context, image_service,

                                  image_meta,tmp_file)

   os.unlink(tmp_file)

# 新增_cpye方法

 

def _copy(self, src_pool, src_img_name,dst_pool, dst_img_name):

       """

       :param src_pool:      source rbdimage's pool

               src_img_name:  source rbd image's name

               dst_pool:      dest rbd image's pool

               dst_img_name:  dest rbd image's name

       """

       LOG.debug('copying %(pool)s/%(img)s to %(dst_pool)s/%(dst_img)s',

                  dict(pool=src_pool,img=src_img_name, dst_pool=dst_pool, dst_img=dst_img_name))

       src_name = utils.convert_str(src_img_name)

       dest_name = utils.convert_str(dst_img_name)

       src_pool = utils.convert_str(src_pool)

       dest_pool = utils.convert_str(dst_pool)

       with RBDVolumeProxy(self, src_name, pool=src_pool, read_only=True) asvol:

           with RADOSClient(self, dest_pool) as dest_client:

                vol.copy(dest_client.ioctx,dest_name, features=vol.features())



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值