ceph提供rbd存储
RBD详解
-
rbd就是rados block device,是ceph集群中常用的存储类型
-
rbd是通过linux内核模块或者librbd库与osd之间完成交互
-
一般只有在为物理主机提供设备的时候才会使用内核rbd模块,虚拟机一般使用librbd库,当rbd使用基于内核模块驱动时,可以使用linux自带的页缓存来提高性能,当使用librbd库时,使用rbd缓存来提高性能
1、rbd特点和工作流程
-
支持完整和增量快照,完整的快照
-
自动精简置备,用多少分多少的空间
-
写时复制
-
动态调整大小,支持在线扩容rbd块的大小
-
内存内缓存,多层缓存机制提升性能
-
rbd工作流程
-
创建一个pool(副本池),在池子里面创建rbd设备,客户端映射挂载(在客户端上面表现形式为一个磁盘)
-
用户写入数据,ceph进行对数据切块,每个块的大小默认为4M,每个块名字是object+序号;
-
将每个object通过哈希算法分配给对应的pg;
-
pg根据crush算法会寻找3个osd(假设副本数为3),把这object分别保存在这3个osd上存储,这一组osd就是pgp的概念;
-
osd实际把硬盘格式化为xfs文件系统,object存储在这个文件系统就相当于存储了一个文件rbd0.object1.file
-

2、创建rbd池并使用
1、创建rbd
[root@ceph01 ~]# ceph osd pool create rbd
pool 'rbd' created
# 打上标签,表示这个存储池是干什么的
[root@ceph01 ~]# ceph osd pool application enable rbd rbd
enabled application 'rbd' on pool 'rbd'
# 初始化rbd池
[root@ceph01 ~]# rbd pool init rbd
[root@ceph01 ~]# rados -p rbd ls
rbd_info
2、创建用户和分发密钥
# 创建rbd用户
# profile rbd 表示这个用户只对rbd进行操作,所有的rbd都能进行操作,指定特定的话,就需要加上pool
ceph auth get-or-create client.rbd mon "profile rbd" osd "profile rbd"
# 保存密钥文件
ceph auth get client.rbd > ceph.client.rbd.keyring
# 分发密钥给客户端
scp ceph.client.rbd.keyring root@192.168.50.22:/etc/ceph
3、客户端查看pool
[root@ceph03 ceph]# ceph osd pool ls --name client.rbd --keyring /etc/ceph/ceph.client.rbd.keyring
device_health_metrics
rbd
4、创建rbd块
- 客户端上面可以创建,在存储池里面创建rbd块
[root@ceph03 ceph]# rbd create rbd/test --name client.rbd --size 1G --image-format 2 --image-feature layering
# 查看rbd块
[root@ceph03 ceph]# rados -p rbd ls --name client.rbd
rbd_id.test
rbd_directory
rbd_info
rbd_header.20cc0ce985d7b # 这个就是这个test的rbd号,之后写入的数据都是20c开头的
5、客户端映射rbd并挂载
# 客户端加载rbd模块,并永久生效
[root@ceph03 ceph]# modprobe rbd
[root@ceph03 ceph]# echo "rbd" >> /etc/modules-load.d/rbd.conf
[root@ceph03 ceph]# lsmod | grep rbd
rbd 135168 0
libceph 413696 1 rbd
- 查看客户端块设备
[root@ceph03 ceph]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 600M 0 part /boot
└─sda2 8:2 0 49.4G 0 part
└─openeuler_template-root 253:0 0 49.4G 0 lvm /var/lib/containers/storage/overlay
/
sdb 8:16 0 10G 0 disk
└─ceph--09540d06--52ca--42e5--a666--f1d7afb986b7-osd--block--2460d39f--92fd--4359--860e--b727f73e3491
253:2 0 10G 0 lvm
sdc 8:32 0 10G 0 disk
└─ceph--fc9bce64--6878--46b5--b373--c11e96081bc0-osd--block--0a1dde98--b1af--4d42--9acd--05f88e537b49
253:3 0 10G 0 lvm
sdd 8:48 0 10G 0 disk
└─ceph--2de132d5--e5a5--4066--9adb--d6e538712e45-osd--block--5eee5469--5fb4--4965--9c58--27392a1ac278
253:1 0 10G 0 lvm
sr0 11:0 1 3.5G 0 rom
- 客户端映射rbd
[root@ceph03 ceph]# rbd map --name client.rbd rbd/test
/dev/rbd0 # 这个rbd映射到客户端,表现形式为/dev/rbd0
# 大小为1G
[root@ceph03 ceph]# lsblk |grep rbd
rbd0 252:0 0 1G 0 disk
# 格式化磁盘
[root@ceph03 ceph]# mkfs -t xfs /dev/rbd0
[root@ceph03 ceph]# mkdir /rbd
[root@ceph03 ceph]# mount /dev/rbd0 /rbd/
# 写入数据
[root@ceph03 /]# echo 123 > /rbd/123.txt
# 查看存储池里面的对象,非常的多,因为数据写进来的时候,会被切片为多个对象
# 名称都是以rbd_data.20.cc开头的
[root@ceph01 ~]# rados -p rbd ls
rbd_data.20cc0ce985d7b.00000000000000a0
rbd_data.20cc0ce985d7b.00000000000000ff
rbd_id.test
rbd_data.20cc0ce985d7b.0000000000000060
rbd_directory
rbd_data.20cc0ce985d7b.00000000000000e0
rbd_data.20cc0ce985d7b.0000000000000000
rbd_info
rbd_data.20cc0ce985d7b.0000000000000020
rbd_data.20cc0ce985d7b.0000000000000080
rbd_data.20cc0ce985d7b.00000000000000c0
rbd_data.20cc0ce985d7b.0000000000000040
rbd_header.20cc0ce985d7b
6、开机自动映射和挂载
-
重启客户端的话,这个映射到客户端的磁盘就消失了
-
需要开启自动映射,有一个映射的服务,和开机映射的配置文件
[root@ceph01 ceph]# cat rbdmap
# RbdDevice Parameters
#poolname/imagename id=client,keyring=/etc/ceph/ceph.client.keyring
rbd/test id=rbd # 客户端id
# 开机自动映射磁盘到客户端上
[root@ceph03 ceph]# systemctl enable rbdmap --now
Created symlink /etc/systemd/system/multi-user.target.wants/rbdmap.service → /usr/lib/systemd/system/rbdmap.service.
# 开启自动将磁盘挂载
[root@ceph03 ceph]# tail -1 /etc/fstab
/dev/rbd0 /rbd xfs defaults,_netdev 0 0
7、rbd create 参数
-
poolname:指定映像文件创建在哪个池中,如不指定,则默认为rbd池
-
--size:指定映像文件大小
-
-m:指定monitor的地址
-
-k:指定认证密钥环的路径
-
--image-format:指定映像文件格式,可选为1和2,1已经废弃
-
--image-feature: 指定映像文件需要开启的特性
-
--stripe-unit: 指定rbd存储中最小文件块的大小,不得小于4k,不得大于32M,默认为4M,即一个对象的大小
-
--stripe-count: 如果指定了--stripe-unit,则--stripe-count也需要配置,其表示一个数据可以并行写入多少个数据块中,默认为1
关于rbd的特性说明:
| Name | Description | id |
|---|---|---|
| layering | Layering support to enable cloning支持镜像分层快照特性,用于快照及写时复制,可以对image创建快照并保护,然后从快照克隆出新的image出来,父子image之间采用COW技术,共享对象数据 | 1 |
| striping | 支持条带化v2,类似raid 0,只不过在ceph环境中的数据被分散到不同的对象中,可改善顺序读写场景较多情况下的性能 | 2 |
| exclusive-lock | 支持独占锁,限制一个镜像只能被一个客户端使用 | 4 |
| object-map | 支持对象映射(依赖 exclusive-lock),加速数据导入导出及已用空间统计等,此特性开启的时候,会记录image所有对象的一个位图,用以标记对象是否真的存在,在一些场景下可以加速 io | 8 |
| fast-diff | 快速计算镜像与快照数据差异对比(依赖 object-map) | 16 |
| deep-flatten | 支持快照扁平化操作, 用于快照管理时解决快照依赖关系等 | 32 |
| journaling | 修改数据是否记录日志, 该特性可以通过记录日志并通过日志恢复数据(依赖独占锁),开启此特性会增加系统磁盘 IO 使用 | 64 |
| data-pool | EC data pool support | 128 |
- 在创建的时候,指定多个rbd特性
[root@ceph01 ~]# rbd create rbd/test1 --size 2G --image-format 2 --image-feature layering,exclusive-lock,object-map
[root@ceph01 ~]# rbd info rbd/test1
rbd image 'test1':
size 2 GiB in 512 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 20d2c1e2e84ac
block_name_prefix: rbd_data.20d2c1e2e84ac
format: 2
features: layering, exclusive-lock, object-map, fast-diff
-
还可以直接修改默认的rbd特性,可以直接使用id
-
列如 layering+deep-flatten id = 1+32 = 33
# 修改默认rbd属性
[root@ceph01 ~]# ceph config set client rbd_default_features 33
[root@ceph01 ~]# rbd create rbd/test2 --size 1G
# 查看rbd/test2块设备
[root@ceph01 ~]# rbd info rbd/test2
rbd image 'test2':
size 1 GiB in 256 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 20d3f16be0a33
block_name_prefix: rbd_data.20d3f16be0a33
format: 2
features: layering, deep-flatten
op_features:
flags:
create_timestamp: Tue Mar 17 19:44:45 2026
access_timestamp: Tue Mar 17 19:44:45 2026
modify_timestamp: Tue Mar 17 19:44:45 2026
8、rbd映射基本操作
# 查看已经映射设备
# 挂载的一方上面执行
[root@ceph03 ceph]# rbd showmapped
id pool namespace image snap device
0 rbd test - /dev/rbd0
# 取消映射,必须先要取消挂载
[root@ceph03 ceph]# umount /rbd
[root@ceph03 ceph]# rbd unmap rbd/test
3、块设备的操作
1、rbd基本操作
# 查看rbd
[root@ceph01 ~]# rbd ls -p rbd
test
# 查看详细信息
[root@ceph01 ~]# rbd -p rbd info test
rbd image 'test':
size 1 GiB in 256 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 25aeb3e9f72b7
block_name_prefix: rbd_data.25aeb3e9f72b7
format: 2
features: layering
op_features:
flags:
create_timestamp: Wed Mar 18 20:52:52 2026
access_timestamp: Wed Mar 18 20:52:52 2026
modify_timestamp: Wed Mar 18 20:52:52 2026
2、调整rbd大小
# 将1G调整为3G
[root@ceph01 ~]# rbd resize rbd/test --size 3G
Resizing image: 100% complete...done.
# 挂载到客户端时,刷新文件系统
[root@ceph03 ceph]# xfs_growfs /dev/rbd0
[root@ceph03 ceph]# df -hT /rbd/
Filesystem Type Size Used Avail Use% Mounted on
/dev/rbd0 xfs 3.0G 56M 3.0G 2% /rbd
# 调小,慎重的操作,不建议使用,xfs大多数不允许使用缩容,会出现问题的
[root@ceph01 ~]# rbd resize rbd/test --size 2G --allow-shrink
Resizing image: 100% complete...done.
3、复制块设备
- 就是将复制一个块设备
[root@ceph01 ~]# rbd cp rbd/test rbd/copy1
Image copy: 100% complete...done.
# 默认是复制到一个池子里面去
[root@ceph01 ~]# rbd ls
copy1
test
test1
test2
4、移动到其他的pool
# 创建一个mv_rbd存储池
[root@ceph01 ~]# ceph osd pool create mv_rbd
pool 'mv_rbd' created
[root@ceph01 ~]# ceph osd pool application enable mv_rbd rbd
enabled application 'rbd' on pool 'mv_rbd'
# 初始化rbd存储池,因为是复制块设备到这个设备的
[root@ceph01 ~]# rbd pool init mv_rbd
# 移动块设备到mv_rbd里面
[root@ceph01 ~]# rbd cp rbd/copy1 mv_rbd/mv_copy
Image copy: 100% complete...done.
# 查看mv_rbd存储池里面有多少个块设备
[root@ceph01 ~]# rbd -p mv_rbd ls
mv_copy
当客户端挂载了一个rbd(已经格式化完成的),并且想挂载这个rbd复制过来的另一个rbd时,这时候系统是会报错的,原因是因为这两个rbd是完全一样的,系统识别是有点问题的,想要挂载的话必须取消之前的rbd映射,也就是说同一时间只能挂载一个,不管你是挂载的复制的还是被复制的,这俩只能有一个存在于系统上
- 复制后,这个信息都是一样的,所以不能再同一个时间点,挂载2个相同的设备
4、快照管理
- 快照,就是对这个块设备打上一个快照,然后当这个块设备文件丢失的时候,从这个快照恢复到块设备上即可
1、创建快照
# 对rbd/test打上一个快照
[root@ceph03 rbd]# rbd snap create rbd/test@snapshot01 --id rbd
Creating snap: 100% complete...done.
# 查看存储池里面的快照
[root@ceph03 rbd]# rbd snap ls rbd/test --id rbd
SNAPID NAME SIZE PROTECTED TIMESTAMP
4 snapshot01 2 GiB Tue Mar 17 20:12:05 2026
2、回滚快照
# 将客户端上面挂载的文件删除掉
[root@ceph03 rbd]# ls
123.txt
[root@ceph03 rbd]# rm -rf 123.txt
# 卸载rbd
[root@ceph03 ~]# umount /rbd
# 回滚
[root@ceph01 ~]# rbd snap rollback rbd/test@snapshot01
Rolling back to snapshot: 100% complete...done.
# 重新挂载,查看文件
[root@ceph03 ~]# mount -a
[root@ceph03 ~]# ls /rbd/
123.txt
3、保护快照
- 为什么用保护了,怕被误删除了
[root@ceph01 ~]# rbd snap protect rbd/test@snapshot01
[root@ceph01 ~]# rbd info rbd/test@snapshot01
rbd image 'test':
size 2 GiB in 512 objects
order 22 (4 MiB objects)
snapshot_count: 1
id: 20cc0ce985d7b
block_name_prefix: rbd_data.20cc0ce985d7b
format: 2
features: layering
op_features:
flags:
create_timestamp: Tue Mar 17 19:15:31 2026
access_timestamp: Tue Mar 17 20:01:53 2026
modify_timestamp: Tue Mar 17 19:15:31 2026
protected: True # 处于保护的状态
4、删除快照
# 发现删除不了,取消对快照的保护
[root@ceph01 ~]# rbd snap rm rbd/test@snapshot01
Removing snap: 0% complete...failed.
rbd: snapshot 'snapshot01' is protected from removal.
2026-03-17T20:28:20.871+0800 7f4081fe81c0 -1 librbd::Operations: snapshot is protected
# 取消保护快照
[root@ceph01 ~]# rbd snap unprotect rbd/test@snapshot01
# 删除快照
[root@ceph01 ~]# rbd snap rm rbd/test@snapshot01
Removing snap: 100% complete...done.
5、克隆快照
-
克隆之前需要对被克隆的快照进行保护,强制性的操作
-
因为原先的快照被删除的话,这个克隆的快照也没有用,是依赖这个原先的快照
-
当然,也有办法不依赖了,后面有操作的
# 创建快照,对rbd/test1块设备打上一个快照
[root@ceph01 ~]# rbd snap create rbd/test1@s1
Creating snap: 100% complete...done.
# 对快照进行备份
[root@ceph01 ~]# rbd snap protect rbd/test1@s1
# 克隆这个快照,就是在这个存储池里面创建了一个新的块设备
[root@ceph01 ~]# rbd clone rbd/test1@s1 rbd/clone_s1
# 查看rbd存储池里面的块设备
[root@ceph01 ~]# rbd ls -p rbd
clone_s1
copy1
test
test1
test2
- 查看克隆快照的信息
[root@ceph01 ~]# rbd info rbd/clone_s1
rbd image 'clone_s1':
size 2 GiB in 512 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 20e265b854f02
block_name_prefix: rbd_data.20e265b854f02
format: 2
features: layering, exclusive-lock, object-map, fast-diff
op_features:
flags:
create_timestamp: Tue Mar 17 20:33:52 2026
access_timestamp: Tue Mar 17 20:33:52 2026
modify_timestamp: Tue Mar 17 20:33:52 2026
parent: rbd/test1@s1 # 依赖这个父快照
overlap: 2 GiB
注意对比这个克隆出来的与其他的差异,这个rbd他有一个
parent: rbd/test1@s1,也就是说他是基于这个的,如果这个快照被删除那么这个克隆出来的也将无法使用,前面提到了
如果说我我就要让他独立存在呢?不受其他快照的影响,可以做到吗?是可以的
# 拉平克隆快照,使这个克隆快照独立起来,不依赖父快照
[root@ceph01 ~]# rbd flatten rbd/clone_s1
Image flatten: 100% complete...done.
[root@ceph01 ~]# rbd info rbd/clone_s1
rbd image 'clone_s1':
size 2 GiB in 512 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 20e265b854f02
block_name_prefix: rbd_data.20e265b854f02
format: 2
features: layering, exclusive-lock, object-map, fast-diff
op_features:
flags:
create_timestamp: Tue Mar 17 20:33:52 2026
access_timestamp: Tue Mar 17 20:33:52 2026
modify_timestamp: Tue Mar 17 20:33:52 2026
# 没有父快照的条目了
- 这个克隆的快照独立的话,就能映射到客户端上面,挂载了,常用的
5、客户端配置rbd缓存
[root@client rbd]# vim /etc/ceph/ceph.conf
# 加入下列这些配置
[clienti.rbd]
rbd_cache = true # 启用rbd缓存
rbd_cache_size = 33554432 # 32M
rbd_cache_max_dirty = 25165824
rbd_cache_target_dirty = 16777216
rbd_cache_max_dirty_age = 1
rbd_cache_writethrough_until_flush = true
rbd缓存:开启之后想往磁盘写数据会先内存,然后再从内存里写入到磁盘,加速写入速度,开启之后也会面临风险,因为数据是先到内存,万一断电那么就会丢失32M数据,因为缓存大小是32M
- 写写到缓存,然后在异步到osd中,性能比较的高,但是数据安全一般

浙公网安备 33010602011771号