[轉]ceph librbd和librados 代碼概述


[轉自 https://www.jianshu.com/p/4669a4ebda01]

ceph RBD接口和工具  https://www.cnblogs.com/sammyliu/p/4838139.html

 

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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM