Ceph 中块设备 RBD 的基本用法
块设备 (block device) 是一系列的数据块序列。基于数据块的存储接口是最常用的用来存储 硬盘
, CD
, 软盘
, 磁盘
等数据的方式。正因为这种普适性,虚拟块设备成了与大容量数据存储系统交互的非常理想的选择。
目录
块设备概述
Ceph 中的 块设备, 即可靠的、自治的、分布式的对象存储(RBDs) 块设备(RBDs), 是稀疏预分配的,可调大小的,将数据条状存储在 Ceph 存储集群上。 Ceph 块设备 使用了 RADOS
的一些功能:
- 创建快照
- 副本
- 一致性
Ceph 块设备使用 librbd
库与 OSDs
交互,其在 KVMs 如 QEMU, 和云计算系统如 OpenStack,CloudStack 等依赖于 libvirt
和 QEMU
功能与之交互的应用中有很高的性能。

块设备基本命令
要使用块设备相关命令, 你需要能够访问正在运行的 Ceph 存储集群,并且安装了 Ceph Block 客户端。 rbd
命令能够创建、列出、自检、移除块设备,还可以对块设备进行克隆、建立快照、回滚快照、查看快照等。
显示帮助
因为 rbd
的命令和子命令非常多, 要记住所有的比较困难, 可以 通过 help
命令查寻相应命令的使用方法.
### Usage
[ceph@ceph0 ~]$ rbd help []
### e.g.
[ceph@ceph0 ~]$ rbd help snap llist
创建一个块设备池
在使用块设备客户端前, 必须有一个 rbd
类型的池存在并且被初始化了. 创建一个 rbd
Pool, 可以使用如下命令:
[ceph@ceph0 ~]$ ceph osd pool create {pool-name} {pg-num} {pgp-num}
### set rbd property for pool
[ceph@ceph0 ~]$ ceph osd pool application enable {pool-name} rbd
[ceph@ceph0 ~]$ rbd pool init -p {pool-name}
创建块设备镜像
使用如下命令 创建一个块设备镜像:
### Usage:
[ceph@ceph0 ~]$ rbd create --pool {pool-name} {image-name} --size {megabytes}
### e.g. create a rbd image named data of size 1GB stored in a pool named volumes
[ceph@ceph0 ~]$ rbd create -p volumes data --size 1024
创建的时候有一些选项:
--order n
, 创建的 RBD 的条带大小为2^n bytes, 如
–order 24` 为 16M--iamge-format
, 默认格式是 1, 原始格式, 不支持 RBD 分层, format 2 支持 RBD 分层, 可以 COW, 可写快照。
罗列块设备镜像
要列出 Pool 内所有的镜像, 可用如下命令
### Usage: list rbd pool if pool name is absent
[ceph@ceph0 ~]$ rbd ls [{pool-name}]
### e.g. list images of pool volumes
[ceph@ceph0 ~]$ rbd ls volumes
获取镜像信息
列出 Pool 内的镜像后, 我们可能对某一个镜像感兴趣, 可通过如下命令获取其信息:
### Usage: image-name in rbd if pool-name is absent
[ceph@ceph0 ~]$ rbd [{pool-name}] info --image {image-name}
### e.g. retriving information of image data in pool rbd
[ceph@ceph0 ~]$ rbd info --image data
### e.g. retriving information of image data in pool volumes
[ceph@ceph0 ~]$ rbd info -p volumes --image data
### or simply
[ceph@ceph0 ~]$ rbd info volumes/data
调整块设备镜像大小
Ceph 的块设备镜像是稀疏分配的, 直到你开始往其中存入数据, 它们才会使用物理空间. 它们有一个最大可用容量, 由 --size
选项指定, 但你可以通过 resize
命令来更改其大小.
### Usage: resize image-name in rbd pool if pool-name is absent
[ceph@ceph0 ~]$ rbd resize --image --size [--pool ]
### e.g. cresize data in volumes pool from original to 60G
[ceph@ceph0 ~]$ rbd resize volumes/data --size 60G
rbd
大小一般只能扩大, 不能减小, 否则很可能会损坏数据. 若非要减小其大小, 可加上 --allow-shrink
选项
移除块设备镜像
当一个镜像完成了使命, 我们便可以将其删除掉,
### Usage: remove image image-name in pool rbd if pool-name is absent
[ceph@ceph0 ~]$ rbd rm [--pool {pool-name}] rm {image-name}
### e.g. remove an image bar from pool volumes
[ceph@ceph0 ~]$ rbd rm volumes/bar
### or
[ceph@ceph0 ~]$ rbd rm -p volumes bar
将镜像移到回收站
相比于 rm
命令, 我们可以使用 trash
命令将镜像移到回收站里, 过后再将其删除, 防止意外删除镜像. trash
命令提供了比 rm
更多的选项.
- 移动镜像到回收站
### Usage
[ceph@ceph0 ~]$ rbd trash move [--pool {pool-name}] image-name
### e.g.
[ceph@ceph0 ~]$ rbd trash move -p volumes data
- 从回收站彻底删除镜像. 利用镜像的
image-id
:
### Usage
[ceph@ceph0 ~]$ rbd trash remove [--pool {pool-name}] {image-id}
### e.g.
[ceph@ceph0 ~]$ rbd trash remove volumes/data-image-id
- 延时回收镜像. 通过
--delay {time-in-second}
选项来指定一定时间内镜像不可从回收站删除.
### Usage
[ceph@ceph0 ~]$ rbd trash move [--delay {time-in-second}] [--pool {pool-name}] {image-name}
### e.g.
[ceph@ceph0 ~]$ rbd trash move --delay 360 -p volumes data
- 从回收站恢复镜像. 只要一个镜像还在回收站中未被删除, 且没有指定
--delay
选项, 就可以回收站中恢复.
### Usage
[ceph@ceph0 ~]$ rbd trash restore [--pool {pool-name}/]{image-id}
### e.g.
[ceph@ceph0 ~]$ rbd trash restore {pool-name}/data-image-id
启用 / 禁用镜像特性
我们可以启用或禁用镜像的某些特性, 比如 fast-diff
, exclusive-lock
, object-map
或者 journaling
等等.
- 启用特性
### Usage
[ceph@ceph0 ~]$ rbd feature enable {pool-name}/{image-name} {feature-name}
### e.g. enable journaling on volumes/data
[ceph@ceph0 ~]$ rbd feature enable volumes/data journaling
- 禁用特性
### Usage
[ceph@ceph0 ~]$ rbd feature disable {pool-name}/{image-name} {feature-name}
### e.g. disable journaling on volumes/data
[ceph@ceph0 ~]$ rbd feature disable volumes/data journaling
- 在启用
fast-diff
和object-map
特性后, 要重新建立object map
:
[ceph@ceph0 ~]$ rbd object-map rebuild {pool-name}/{image-name}ss
deep flatten
特性只能在 镜像建立时 启用, 不能在 已经建立而没有启用 的镜像上启用.
使用镜像元数据
Ceph 支持向镜像添加 key-value
对形式的元数据. key-value
对没有什么严格的形式. 使用 rbd image-meta
命令可以添加删除元数据.
- 设置镜像元数据
### Usage
[ceph@ceph0 ~]$ rbd image-meta set {pool-name}/{image-name} {key} {value}
### e.g.
[ceph@ceph0 ~]$ rbd image-meta set volumes/data last-update 2018-09-19:10:51
- 获取一个键的值
### Usage
[ceph@ceph0 ~]$ rbd image-meta get {pool-name}/{image-name}
### e.g.
[ceph@ceph0 ~]$ rbd image-meta get volumes/data last-update
- 移除镜像元数据
### Usage
[ceph@ceph0 ~]$ rbd image-meta remove {pool-name}/{image-name} {key}
### e.g.
[ceph@ceph0 ~]$ rbd image-meta remove volumes/data last-update
- 列出镜像的元数据
### Usage
[ceph@ceph0 ~]$ rbd image-meta list {pool-name}/{image-name}
### e.g.
[ceph@ceph0 ~]$ rbd image-meta list volumes/data
- 重设镜像默认配置
### Usage
[ceph@ceph0 ~]$ rbd image-meta set {pool-name}/{image-name} conf_{parameter} {value}
### e.g.
[ceph@ceph0 ~]$ rbd image-meta set volumes/data conf_rbd_cache false
RBD 块设备镜像功能
RBD 的镜像功能是一种在两个及以上 Ceph 集群间异步副本功能。 镜像功能保证了对一个 iamge 做的更改在所有副本上保持时间点的一致性, 包括读写、块设备大小调整、快照、克隆和扁平化等等。 具体可参考 Ceph RBD 镜像功能与异地备份
内核模块操作
要使用 内核模块操作, 必须有一个正在运行的 Ceph 集群。
列出镜像
Ceph 块设备的一大应用就是可挂载到虚拟机,我们也可以挂载到本地使用。要挂载一个镜像,需要先知道镜像名字,先将所有镜像列出:
[ceph@ceph-client ~]$ rbd list
映射 RBD 到本地使用
需要指定 pool 名字, 镜像名字,用户名字, 若使用 CephX
进行认证,则还要加上相应的 密钥文件(keyring)
.
### Usage
[ceph@ceph-client ~]$ rbd map [--pool {pool-name}] image-name --id {user-name} [--keyring /path/to/keyring]
### e.g.
[ceph@ceph-client ~]$ rbd map volumes/data --id admin --keyring /etc/ceph/ceph.client.admin.keyring
显示已映射的设备
要显示已映射的设备,可以使用 rbd
的 showmapped
选项:
## Usage
[ceph@ceph-client ~]$ rbd showmapped
一般会映射到 /dev/rbd/xxx/xxx
之类的地方, 比如 /dev/rbd/rbd/rbd1
, 然后就就像一般硬盘一样可以对其格式化,挂载使用
[ceph@ceph-client ~]$ sudo mkfs.ext4 /dev//dev/rbd/volumes/data
[ceph@ceph-client ~]$ sudo mount -t ext4 /dev/rbd/volumes/data /mnt/volumes/data
[ceph@ceph-client ~]$ df -Th
取消设备映射
## Usage
[ceph@ceph-client ~]$ rbd unmap /dev/rbd/{pool-name}/{image-name}
## e.g.
[ceph@ceph-client ~]$ rbd unmap /dev/rbd/volumes/data
使用 Python 处理 RBD
Python 中的 rbd
模块提供了像处理文件一样处理 RBD 镜像的功能, 核心接口由 librbd
提供。
使用这些功能之前,要先导入 rados
和 rbd
模块
### in python
>>> import rados
>>> import rbd
创建和写入镜像
- 连接到
RADOS
(Ceph 集群), 打开一个 IO 上下文 (IO context)
>>> cluster = rados.Rados(conffile = 'my_ceph.conf')
>>> cluster.connect()
>>> ioctx = cluster.open_ioctx('my_pool')
- 实例化一个 class:rbd.RBD 对象,可以用来创建镜像:
>>> rbd_inst = rbd.RBD()
>>> size = 4*1024**3 # 4 GiB
>>> rbd_inst.create(ioctx, 'my_image', size)
- 实例化一个 class:rbd.RBD 对象,对镜像进行读写:
>>> image = rbd.Image(ioctx, 'my_image')
>>> data = 'foo' * 200
>>> image.write(data, 0)
- 关闭镜像, I/O 上下文,和与 RADOS 的连接:
>>> image.close()
>>> ioctx.close()
>>> cluster.shutdown()
- 为了安全,可以使用
finally:
或with
语句:
### with
with rados.Rados(conffile='my_ceph.conf') as cluster:
with cluster.open_ioctx('my_pool') as ioctx:
rbd_inst = rbd.RBD()
size = 4*1024**3 # 4 GiB
rbd_inst.create(ioctx, 'my_image', size)
with rbd.Image(ioctx, 'my_image') as image:
data = 'foo' * 200
image.write(data, 0)
### try and finally
cluster = rados.Rados(conffile = 'my_ceph.conf')
try:
ioctx = cluster.open_ioctx('my_pool')
try:
rbd_inst = rbd.RBD()
size = 4*1024**3 # 4 GiB
rbd_inst.create(ioctx, 'my_image', size)
image = rbd.Image(ioctx, 'my_iamge')
try:
data = 'foo' * 200
image.write(data, 0)
finally:
image.close()
finally:
ioctx.close()
finally:
cluster.shutdown()


