Ceph的客户端是系统对外提供的功能接口,上层应用通过它访问ceph存储系统。

RADOS的客户端API

上述接口几乎包括了对Ceph集群和其中数据的所有访问功能。其中所谓集群的整体访问包括连接集群、创建存储池、删除存储池和获取集群状态等等。所谓对象访问是之对存储池中对象的访问,包括创建删除对象、向对象写数据或者追加数据和读对象数据等接口。上述功能通过Rados和IoCtx两个类实现,两个类的主要函数如图2所示(这里仅是示例,实际接口数量要多很多,具体参考源代码)。

图2 访问接口类图

https://www.freesion.com/article/9714523649/

Librados 架构图
Librados 架构图

 

1. librbd  &  librados介绍

Librbd模块实现了RBD接口,其基于Librados实现了对RBD的基本操作。

1.1 架构概述

 上层应用层访问RBD块设备有两种途径:librbd和krbd。其中librbd是一个属于librados的用户态接口库,而krbd是继承在GNU/Linux内核中的一个内核模块,通过用户态的rbd命令行工具,可以将RBD块设备映射为本地的一个块设备文件。

从RBD的架构图中可以看到,RBD块设备由于元数据信息少且访问不频繁,故RBD在ceph集群中不需要daemon守护进程将元数据加载到内存进行元数据访问加速,所有的元数据和数据操作直接与集群中的MON服务和OSD服务交互。其架构图如下:

 最上层是librbd层,模块cls_rbd是一个Cls扩展模块,实现了RBD的元数据相关的操作。RBD的数访问直接通过librados来访问。在最底层是OSDC层完成数据的发送。

1.2 源码结构

1.2.1 librbd

在src/librbd下为librbd的源码,其中分为.cc文件和.h文件和子目录,文件的大致内容为:

1. .cc和.h 文件:对应组件的源码;

2.子目录: 子目录中文件为针对每个模块的请求,如针对librbd/operation.cc组件,存在路径为operation,路径中文件为:

可见相应目录中为对应组件的请求的实现,这些请求发送到rados,进而实现对osd的操作。

1.2.2 librados

 src/librados中为librados的源码,内容如下:

与librbd目录下源码相比,librados中的源码内容相对较少,librados.cc中负责接口的封装,具体的实现细节在IoCtxImpl.cc中。

2  librados & librbd API介绍

2.1 源码概览

ceph封装的接口源码位于src/pybind路径下,其中子目录下的.pyx文件为api接口源码,文件结构如图:

2.2 主要操作介绍

 对于librbd和librados提供的python api接口,本文重点关注以下操作:

1 1.  pool的创建和删除;
2 2.  image的创建和删除;
3 3.  snapshot的创建、利用snapshot进行clone操作、snapshot的删除;
4 4.  image flatten操作。

 下文将按照{create pool} -> {create image} -> {create snapshot} -> {image clone} -> {image flatten} -> {delete snapshot} -> {delete image} -> {delete pool}的顺序来依次介绍上述操作的api接口调用。

2.2.1 准备工作:创建链接

在所有操作之前,首先需要创建对集群的连接,才能进行进一步的操作:

1 import rados
2 import rbd
3 # connect to cluster
4 cluster = rados.Rados(conffile='/etc/ceph/ceph.conf')
5 cluster.connect()

2.2.2 创建存储池,并获取ioctx

创建了对集群的connection之后,就可以创建存储池,并获取ioctx。

复制代码

 1 #list pool
 2 before_create = cluster.list_pools()
 3 print("before create pools:{0}.format(before_create))
 4 
 5 #create pool
 6 cluster.create_pool(POOL)
 7 
 8 #list pool
 9 after_create = cluster.list_pools()
10 print("after create pools:{0}.format(after_create))
11 
12 #get_ioctx
13 ioctx = cluster.open_ioctx(POOL)

复制代码

注意:

这里create_pool()接口的输入不包括pg和pgp,因为pgp和pg的数量在api中是根据ceph.conf中参数设置。

1 # /etc/ceph/ceph.conf
2 osd_pool_default_pg_num = {int}
3 osd_pool_default_pgp_num = {int}

2.2.3 创建image

创建存储池并获取ioctx,就可以开始创建rbd image了

复制代码

1 rbd_inst = rbd.RBD()
2 size = 4* 1024 * 3
3 
4 rbd_inst.create(ioctx, "myimage", size)
5 img_list = rbd_inst.list( ioctx)
6 print("after create images {0}".format(img_list))

复制代码

注意:

1.在哪个pool中创建image,ioctx就从哪个pool中获取;

2.image创建必须显示指定大小,size计算值为bytes。

2.2.4 创建snapshot

rbd image创建之后,就可以根据image创建snapshot了。

复制代码

1 # create snapshot
2 print("start to create snapshot")
3 rbd_img = rbd.Image(ioctx, name=IMG)
4 rbd_img.create_snap(SNP)
5 # list snapshot
6 print("list snapshot")
7 snap_list = rbd_img.list_snaps()
8 for item in snap_list:
9     print(item['name'])

复制代码

注意:

1.使用的是img.Image()类,与2.2.2区分;

2.snap_list的类型为rbd.SnapIterator(Image image),使用for循环迭代的元素为dict,其中有三个key: id(int:numeric identifier of the snapshot), size(int, size of the image at the time of snapshot (in bytes)); name ( str: name of the snapshot).

2.2.5 使用snapshot clone rbd image

如果需要使用snapshot克隆image,需要首先对snapshot进行保护,之后才能进行clone操作。

复制代码

1 # protect snapshot
2 rbd_img.protect_snap(SNP)
3 is_protect = rbd_img.is_protected_snap(SNP)
4 print("{0} protected status:{1}".format(SNP, is_protect))
5 # image clone
6 print("clone image")
7 # parent_ioctx, parent_image_name,parent_snap_name, child_ioctx, child_image_name
8 rbd_inst.clone(ioctx, “myimage”,“mysnapshot”, ioctx, “clnimg”)
9 img_list = rbd_inst.list(ioctx)

复制代码

注意:

1.rbd_image() 需要与保护的snapshot一致(即在初始化时需要提供该snapshot隶属的pool的ioctx和image的name):

2.clone() 函数必须传入的五个变量

 

(1) parent_ioctx: snapshot 父类的ioctx;

(2) parent_image_name: 父image的名称;

(3) parent_snap_name: 父snapshot的名称;

(4) child_ioctx: 子image的ioctx;

(5) child_image_name: 子image名称;

如果clone之后的image和原来的image位于同一个pool,则两者的ioctx相同,反之需要从子image所属的pool获取子ioctx。

 

2.2.6 image flatten

image flatten操作使clone生成的rbd image摆脱对snapshot的依赖

1 # image flatten
2 print("flatten image")
3 clone_img = rbd.Image(ioctx, name=”clnimg”)
4 clone_img.flatten()

注意:

因为需要访问的是clone生成的薪image,故需要新初始化一个rbd.Image()访问。

 

2.2.7 删除 snapshot / image / pool

复制代码

 1 # unprotect image
 2 print("unprotect snapshot")
 3 rbd_img.unprotect_snap(SNP)
 4 is_protect = rbd_img.is_protected_snap(SNP)
 5 print("{0} protected status:{1}".format(SNP, is_protect))
 6  
 7 # purge snapshot
 8 print("remove snapshot")
 9 rbd_img.remove_snap(SNP)
10  
11 # close image connection
12 rbd_img.clone()
13 clone_img.close()
14  
15 # remove rbd image
16 print("remove rbd image")
17 rbd_inst.remove(ioctx, IMG)
18 rbd_inst.remove(ioctx, CLN)

复制代码

注意:

1.只有在snapshot下的所有image都进行flatten操作之后,才能够unprotect该snapshot;

2.需要先关闭rbd.Image()对image的访问之后,才能移除rbd image。

2.2.8 关闭链接,终止对集群的访问

复制代码

 1 # close ioctx
 2 print("close ioctx")
 3 ioctx.close()
 4  
 5 # delete pool
 6 print("delete pool")
 7 cluster.delete_pool(POOL)
 8 after_delete = cluster.list_pools()
 9 print("after delete pools:  {0}".format(after_delete))
10  
11 # close connection
12 print("close connection")
13 cluster.shutdown()

复制代码

注意:

顺序:

{关闭ioctx} -> {删除pool}-> {关闭cluster链接}

2.4 参考资料

1. librbd(python)

http://docs.ceph.com/docs/master/rbd/api/librbdpy/

2. librados(python)

http://docs.ceph.com/docs/master/rados/api/python/

 

https://www.cnblogs.com/yi-mu-xi/p/10368990.html

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐