[轉自 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操作。
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
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'])
注意:
2.2.5 使用snapshot clone rbd image
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名稱;
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/