RBD块设备与用户管理

RBD块设备与用户管理
[TOC]
基本操作
增删改查
1)创建专用存储池并声明为 RBD 类型root@Ceph-201 ~# ceph osd pool create kpyun 8 8 replicated --size 3 --autoscale_mode offpool 'kpyun' createdroot@Ceph-201 ~# ceph osd pool ls | grep kpyun | wc -l1root@Ceph-201 ~# ceph osd pool ls detail | grep kpyunpool 7 'kpyun' replicated size 3 min_size 2 crush_rule 0object_hash rjenkins pg_num 8 pgp_num 8 autoscale_mode off# 声明存储池为 rbd 类型(否则 ceph -s 会报 HEALTH_WARN)root@Ceph-201 ~# ceph osd pool application enable kpyun rbdenabled application 'rbd' on pool 'kpyun'root@Ceph-201 ~# ceph healthHEALTH_OK ✅️ 健康状态
2)创建块设备 rbd create -s <size> <pool>/<image>root@Ceph-201 ~# rbd create -s 2G kpyun/C413# 创建一个 2GB 的块设备# -s = --size 指定创建的 RBD 镜像大小
3)查看块设备列表 rbd -p <pool> ls -lroot@Ceph-201 ~# rbd help ls# help 可查看帮助信息usage: rbd ls [--long] [--pool <pool>] [--namespace <namespace>] ....Optional arguments -l [ --long ] long listing format -p [ --pool ] arg pool nameroot@Ceph-201 ~# rbd -p kpyun lsC413👆'有哪些块设备'# 更简便一点root@Ceph01 ~# rbd ls kpyunC413root@Ceph-201 ~# rbd ls -l kpyun✅️ 有详细信息NAME SIZE PARENT FMT PROT LOCKC413 2 GiB 2# FMT 2 表示使用 RBD v2 格式
4)查看块设备详细信息 rbd info <pool>/<image>root@Ceph-201 ~# rbd info kpyun/C413rbd image 'C413': size 2 GiB in 512 objects --> '2GB 被切分为 512 个 object' order 22 (4 MiB objects) --> '每个 object 4MB' # order 22 表示对象大小的对数基数(以2为底) # 即:2^22 = 4,194,304 字节 = 4 MiB ✅️ 512 个对象 × 4 MiB/对象 = 2,048 MiB ✅️ 2,048 MiB = 2 GiB snapshot_count: 0 id: 3451beb095673 block_name_prefix: rbd_data.3451beb095673 format: 2
5)扩容块设备 rbd resize -s <size> <pool>/<image>root@Ceph-201 ~# rbd resize -s 4G kpyun/C413Resizing image: 100% complete...done.root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKC413 4 GiB 2
6)缩容块设备(需要加 --allow-shrink) rbd resize -s <size> <pool>/<image> --allow-shrinkroot@Ceph-201 ~# rbd resize -s 1G kpyun/C413 --allow-shrinkResizing image: 100% complete...done.root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKC413 1 GiB 2
7)重命名块设备 rbd rename -p <pool> <old> <new>root@Ceph-201 ~# rbd rename -p kpyun C413 haharoot@Ceph-201 ~# rbd ls kpyunhaha
8)删除块设备 rbd rm <pool>/<image>root@Ceph-201 ~# rbd rm kpyun/hahaRemoving image: 100% complete...done.root@Ceph-201 ~# rbd ls kpyun | grep haha | wc -l0客户端挂载
- 格式化 xfs
1)创建RBD设备# 在我们原来的池子中 --> 新建RBD块设备root@Ceph-201 ~# rbd create -s 4G kpyun/serverroot@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 4 GiB 2root@Ceph-201 ~# rbd info kpyun/serverrbd image 'server': size 4 GiB in 1024 objects order 22 (4 MiB objects)
2)Ceph通用包# 另外两个节点也要保证安装 ceph-common'客户端'root@Ceph-202 ~# ceph versionceph version 20.2.1root@Ceph-203 ~# ceph versionceph version 20.2.1
3)拷贝 Ceph 认证文件'拷贝至客户端'root@Ceph-201 ~# ls /etc/ceph/ceph.client.admin.keyring ceph.conf'主要是这两个文件📃'# 我已经提前拷贝至其他两个件节点root@Ceph-202 ~# ls /etc/ceph/✅️ Ceph-202 和 Ceph-203 都有root@Ceph-203 ~# ceph healthHEALTH_OK✅️ 另外两个节点也可以查看集群状态
4)客户端添加rbd块设备root@Ceph-203 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 4 GiB 2'我在客户端也是可以查看到相应的块设备的' rbd map <pool>/<image> # 客户端映射为本地设备 ✅️ rbd unmap <pool>/<image> # 取消映射root@Ceph-203 ~# rbd map kpyun/server/dev/rbd0 rbd showmapped # 查看已映射设备root@Ceph-203 ~# rbd showmappedid pool namespace image snap device0 kpyun server - /dev/rbd0root@Ceph-203 ~# ls -lh /dev/rbd0brw-rw---- 1 root disk 251, 0 May 27 16:29 /dev/rbd0'它是一个块设备' --> 你可以理解为新加了一块磁盘 ✅️
5)客户端格式化 & 挂载root@Ceph-203 ~# mkfs -t xfs /dev/rbd0✅️ 正经格式化设备root@Ceph-203 ~# df -h | grep /mnt | wc -l0root@Ceph-203 ~# mount /dev/rbd0 /mntroot@Ceph-203 ~# df -h | grep /mnt/dev/rbd0 4.0G 110M 3.9G 3% /mnt
6)客户端写入数据root@Ceph-203 ~# ls /mntroot@Ceph-203 ~# echo Hello > /mnt/test.txtroot@Ceph-203 ~# cat /mnt/test.txtHello ✅️ 数据写入成功'上面格式化的是xfs' --> 下面格式化 ext4 ✅️
1)服务端创建块设备root@Ceph-201 ~# rbd create -s 10G kpyun/server02root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 4 GiB 2 exclserver02 10 GiB 2 # 已挂载👆的会有 excl 锁标记
2)客户端添加映射root@Ceph-203 ~# rbd ls kpyunserverserver02# 👆客户端这边也能刷新到新添加的设备root@Ceph-203 ~# rbd map kpyun/server02/dev/rbd1root@Ceph-203 ~# rbd showmappedid pool namespace image snap device0 kpyun server - /dev/rbd01 kpyun server02 - /dev/rbd1
3)格式化 & 挂载root@Ceph-203 ~# mkfs -t ext4 /dev/rbd1root@Ceph-203 ~# mkdir /testroot@Ceph-203 ~# mount /dev/rbd1 /testroot@Ceph-203 ~# df -hT | grep rbd-T --> 显示文件系统类型/dev/rbd0 xfs 4.0G 110M 3.9G 3% /mnt/dev/rbd1 ext4 9.8G 24K 9.3G 1% /test'一个xfs, 一个ext4'root@Ceph-203 ~# echo haha > /test/hh.txtroot@Ceph-203 ~# cat /test/hh.txthaha ✅️ 数据写入成功容量热更新
✅️ 两种文件类型'ext4 和 xfs'都适用# 服务端扩容后,客户端不需要卸载重新挂载📌 直接在线同步新容量root@Ceph-203 ~# df -hT | grep rbd-T --> 显示文件系统类型/dev/rbd0 xfs 4.0G 110M 3.9G 3% /mnt/dev/rbd1 ext4 9.8G 24K 9.3G 1% /test
1)服务端先进行扩容root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 4 GiB 2 exclserver02 10 GiB 2 exclroot@Ceph-201 ~# rbd resize -s 5G kpyun/serverResizing image: 100% complete...done.root@Ceph-201 ~# rbd resize -s 15G kpyun/server02Resizing image: 100% complete...done.root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver02 15 GiB 2 excl
2)客户端热更新root@Ceph-203 ~# df -hT | grep rbd/dev/rbd0 xfs 4.0G 110M 3.9G 3% /mnt/dev/rbd1 ext4 9.8G 28K 9.3G 1% /test'客户端再次查看, 容量并没有立马扩充过来'✅️ 不同的文件系统, 需要执行不同的热更新命令root@Ceph-203 ~# xfs_growfs /dev/rbd0'后跟块设备即可' 👆 --> 用于xfs文件系统root@Ceph-203 ~# resize2fs /dev/rbd1 👆 --> 用于ext4文件系统root@Ceph-203 ~# df -hT | grep rbd/dev/rbd0 xfs 5.0G 130M 4.9G 3% /mnt/dev/rbd1 ext4 15G 28K 14G 1% /test✅️ 容量发生改变 --> '在线扩容完成'📌 一句话总结:
- ext4 用
resize2fs| xfs 用xfs_growfs- 都不需要卸载,在线热更新
开启自动挂载
'重启集群后'root@Ceph-203 ~# rbd showmappedroot@Ceph-203 ~# rbd ls kpyunserverserver02# 虽然可以查看到块设备 --> 但'客户端找不到映射关系'root@Ceph-203 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 ❌️server02 15 GiB 2 ❌️'自然也没有锁定🔒' # 已挂载的会有 excl👆锁标记
✅️ 我们格式化过文件系统, 并且对应的块设备是有内容的--> 所以我们只需要挂载即可!'恢复数据' --> 只需要两步
1)映射块设备 ✅️root@Ceph-203 ~# rbd map kpyun/server/dev/rbd0root@Ceph-203 ~# ls /mnt🈚 连挂载目录也不需要进行创建 --> 里面没有内容'在脚本中也可以重复创建 --> mkdir -p /mnt'# 加上-p选项后,重复创建目录不报错root@Ceph-203 ~# df -h | grep /mnt | wc -l0
2)挂载 ✅️root@Ceph-203 ~# mount /dev/rbd0 /mntroot@Ceph-203 ~# df -h | grep /mnt | wc -l1root@Ceph-203 ~# cat /mnt/test.txtHello'原来的数据内容恢复了'rc.local
'开机自动执行里面的命令'root@Ceph-203 ~# ls /etc/rc.localls: cannot access '/etc/rc.local': No such file or directory# Ubuntu系统默认不存在 --> 需要手动创建===========================================root@Ceph-203 ~# cat > /etc/rc.local <<EOF#!/bin/bashrbd map kpyun/serverrbd map kpyun/server02mount /dev/rbd0 /mntmount /dev/rbd1 /testexit 0EOF'开头结尾不能省略'root@Ceph-203 ~# chmod +x /etc/rc.localroot@Ceph-203 ~# systemctl is-active rc-local.serviceinactiveroot@Ceph-203 ~# df -hT | grep rbd | wc -l0root@Ceph-203 ~# systemctl restart rc-local.service'重启服务 --> 即可触发脚本'# 开机自动触发root@Ceph-203 ~# journalctl -u rc-localMay 27 22:04:50 Ceph-203 systemd[1]: 'Starting' rc-local.service - /etc/rc.local Compatibility...May 27 22:04:50 Ceph-203 rc.local[6889]: /dev/rbd0May 27 22:04:50 Ceph-203 rc.local[6930]: /dev/rbd1May 27 22:04:50 Ceph-203 systemd[1]: 'Started' rc-local.service - /etc/rc.local Compatibility.root@Ceph-203 ~# df -hT | grep rbd/dev/rbd0 xfs 5.0G 130M 4.9G 3% /mnt/dev/rbd1 ext4 15G 28K 14G 1% /test===========================================root@Ceph-203 ~# reboot'重启验证'root@Ceph-203 ~# df -hT | grep rbd | wc -l2✅️ 开机自动挂载-
虽然
rc.local是一种传统且简单的方法 -
但在现代 Linux 系统中,官方==推荐==的做法是
-
==创建自定义==的
systemd服务单元文件来管理开机自启任务 -
因为它提供了更好的依赖管理、日志记录和控制选项
-
/etc/fstab
-
单独使用
/etc/fstab确实不行-
因为 挂载之前必须先
rbd map -
而 fstab 在开机时执行得太早,那时映射设备还不存在
-
-
但是可以借助 systemd 的
x-systemd.requires=选项,让 fstab 挂载依赖rc-local.service- 映射 →
rc.local(只做 map) - 挂载 →
/etc/fstab(开机自动挂载)
- 映射 →
'清理环境 --> 重启reboot'
1)rc.local 只负责映射root@Ceph-203 ~# cat > /etc/rc.local <<EOF#!/bin/bashrbd map kpyun/serverrbd map kpyun/server02exit 0EOFroot@Ceph-203 ~# chmod +x /etc/rc.local
2)/etc/fstab 依赖 rc-local 服务root@Ceph-203 ~# cat >> /etc/fstab <<EOF/dev/rbd0 /mnt xfs defaults,_netdev,x-systemd.requires=rc-local.service 0 0/dev/rbd1 /test ext4 defaults,_netdev,x-systemd.requires=rc-local.service 0 0EOF✅️ _netdev --> 标识这是网络块设备(依赖网络就绪)✅️ x-systemd.requires=rc-local.service --> 让该挂载单元依赖 rc-local# 开机时 systemd 会先等 rc-local 完成(映射好设备),再自动挂载
3)手动触发root@Ceph-203 ~# df -hT | grep rbd | wc -l0root@Ceph-203 ~# systemctl restart rc-local.service'触发映射'root@Ceph-203 ~# mount -a'使/etc/fstab生效'root@Ceph-203 ~# df -hT | grep rbd | wc -l2✅️ 成功挂载
3)重启验证root@Ceph-203 ~# rebootroot@Ceph-203 ~# df -hT | grep rbd | wc -l2✅️ 开机自动挂载成功systemd
-
==官方推荐方案==:自定义 systemd 服务单元
-
思路:写一个 shell 脚本 → 用 systemd service 管理 → 设置开机自启
'清理环境 --> 重启reboot'
1)编写映射+挂载脚本⚠️ 分隔符必须写成 <<'EOF',否则 ${} 会在写入文件前就被 bash 展开成空值root@Ceph-203 ~# cat > /usr/local/bin/rbd-auto-mount.sh <<'EOF'#!/bin/bash# RBD 自动映射 & 挂载脚本
POOL="kpyun"DEV1="/dev/rbd0"DEV2="/dev/rbd1"MNT1="/mnt"MNT2="/test"
# --- 映射 ---rbd map ${POOL}/serverrbd map ${POOL}/server02
# --- 挂载(已挂载则跳过)---if mountpoint -q "${MNT1}"; then echo "${MNT1} 已挂载,跳过"else mount "${DEV1}" "${MNT1}" echo "${DEV1} → ${MNT1} 挂载成功"fi
if mountpoint -q "${MNT2}"; then echo "${MNT2} 已挂载,跳过"else mount "${DEV2}" "${MNT2}" echo "${DEV2} → ${MNT2} 挂载成功"fiEOFroot@Ceph-203 ~# chmod +x /usr/local/bin/rbd-auto-mount.sh
2)编写 systemd 服务单元root@Ceph-203 ~# cat > /etc/systemd/system/rbd-mount.service <<EOF[Unit]Description=rbd-auto-mountAfter=network-online.target# After=network-online.target 确保网络已就绪后再执行# 因为 Ceph 集群通信依赖网络
[Service]Type=oneshot# Type=oneshot → 一次性任务,执行完即结束# 在开机状态只能执行一次 --> restart也不会再次运行ExecStart=/usr/local/bin/rbd-auto-mount.shRemainAfterExit=yes# RemainAfterExit → 执行完后仍视为 active,方便后续追踪状态
[Install]WantedBy=multi-user.target# 开机时自动启用EOF
3)开机自启服务root@Ceph-203 ~# systemctl daemon-reload# 重载 systemd 配置,让它识别新写的单元文件root@Ceph-203 ~# systemctl enable rbd-mount.serviceCreated symlink /etc/systemd/system/multi-user.target.wants/rbd-mount.service ...
4)重启验证root@Ceph-203 ~# rebootroot@Ceph-203 ~# df -hT | grep rbd/dev/rbd0 xfs 5.0G 130M 4.9G 3% /mnt/dev/rbd1 ext4 15G 28K 14G 1% /test✅️ 开机自动挂载成功
5)查看服务状态 & 日志root@Ceph-203 ~# systemctl status rbd-mount.service● rbd-mount.service - rbd-auto-mount Loaded: loaded (/etc/systemd/system/rbd-mount.service; enabled; preset: enabled) Active: active (exited)root@Ceph-203 ~# journalctl -u rbd-mount | tail -6May 28 08:59:52 Ceph-203 systemd[1]: Starting rbd-mount.service - rbd-auto-mount...May 28 08:59:54 Ceph-203 rbd-auto-mount.sh[863]: /dev/rbd0May 28 08:59:55 Ceph-203 rbd-auto-mount.sh[1212]: /dev/rbd1May 28 08:59:55 Ceph-203 rbd-auto-mount.sh[857]: /dev/rbd0 → /mnt 挂载成功May 28 08:59:55 Ceph-203 rbd-auto-mount.sh[857]: /dev/rbd1 → /test 挂载成功May 28 08:59:55 Ceph-203 systemd[1]: Finished rbd-mount.service - rbd-auto-mount.虽然 rc.local 也是一种 systemd 服务(同样有日志和状态追踪)
但自定义单元提供了
-
更好的依赖管理(精确到
network-online.target) -
更清晰的日志记录(独立单元,不会被其他 rc.local 任务干扰)
以及 更灵活的控制选项(Restart=on-failure、超时、启停等)
快照管理
备份与恢复
'对于客户端的选择 --> 我们依旧选择Ceph-203'# 因为有现成的服务,不需要额外拷贝文件
1)环境准备root@Ceph-203 ~# df -hT | grep rbd/dev/rbd0 xfs 5.0G 130M 4.9G 3% /mnt/dev/rbd1 ext4 15G 28K 14G 1% /test'我们往里面写点文件'# 以/mnt举例 --> 也就是/dev/rbd0root@Ceph-203 ~# touch /mnt/p1{a..d}.txtroot@Ceph-203 ~# ls /mntp1a.txt p1b.txt p1c.txt p1d.txt test.txt
2)服务端对块设备进行拍快照'切换至 Ceph-201'root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 excl❌️server02 15 GiB 2 excl❌️# 👆镜像名称 --> 而且都是被占用的状态root@Ceph-201 ~# rbd help snap create✅️ rbd help --> '有提示'✅️ snap --> '快照'-p [ --pool ] # 存储池名称--namespace # 命名空间--image # 镜像名--snap # 快照名root@Ceph-201 ~# rbd snap create -p kpyun --image server --snap p1Creating snap: 100% complete...done. '快照名称叫p1'# server 镜像对照客户端/dev/rbd0root@Ceph-201 ~# rbd snap ls -p kpyun --image serverSNAPID NAME SIZE PROTECTED TIMESTAMP 3 p1 5 GiB Thu May 28 10:34:34 2026# 查看指定池子中的镜像'但其实有更简单的方式进行查看'root@Ceph-201 ~# rbd snap ls kpyun/server✅️ -p 和 --image 可叠加在一起 就是👆这个样子
3)客户端再次进行修改数据root@Ceph-203 ~# touch /mnt/p2{e..g}.txtroot@Ceph-203 ~# ls /mntp1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txt
4)服务端再次创建快照root@Ceph-201 ~# rbd snap create kpyun/server@p2Creating snap: 100% complete...done. '这里的@p2就是指定了快照名称'root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 3 p1 5 GiB Thu May 28 10:34:34 2026 4 p2 5 GiB Thu May 28 10:54:19 2026 👆 快照名称
5)客户端篡改数据root@Ceph-203 ~# ls /mntp1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txtroot@Ceph-203 ~# rm -f /mnt/*'模拟误删除'root@Ceph-203 ~# ls /mnt | wc -l0⚠️ 现在什么都没有了
6)恢复数据(准备工作)✅️ 需要提前取消挂载 & 删除块设备映射'我们这里只演示 /dev/rbd0 'root@Ceph-203 ~# umount /dev/rbd0root@Ceph-203 ~# rbd unmap kpyun/serverroot@Ceph-203 ~# rbd showmappedid pool namespace image snap device1 kpyun server02 - /dev/rbd1'现在只剩下一个了'
7)服务端恢复数据root@Ceph-201 ~# rbd snap rollback kpyun/server@p2Rolling back to snapshot: 100% complete...done.⚠️ 使用快照进行'数据恢复'(回滚覆盖)的时候, 会将快照的数据拷贝到块设备中 📌 '如果数据量非常大的时候,会非常耗时!!!'
8)客户端重新映射 & 挂载验证root@Ceph-203 ~# rbd map kpyun/server/dev/rbd0root@Ceph-203 ~# mount /dev/rbd0 /mntroot@Ceph-203 ~# ls /mnt/p1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txt'数据全部都恢复过来了'删除
'服务端进行操作'root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 3 p1 5 GiB Thu May 28 10:34:34 2026 4 p2 5 GiB Thu May 28 10:54:19 2026
1)删除p1快照root@Ceph-201 ~# rbd snap rm kpyun/server@p1Removing snap: 100% complete...done.root@Ceph-201 ~# rbd snap ls kpyun/server'SNAPID' NAME SIZE PROTECTED TIMESTAMP 4 p2 5 GiB Thu May 28 10:54:19 2026 👆snap-id 只剩下一个快照 ✅️
2)查看镜像详细信息root@Ceph-201 ~# rbd info kpyun/server@p2rbd image 'server': <-- 📌 查看的是镜像 '快照也是从镜像来的' size 5 GiB in 1280 objects order 22 (4 MiB objects) snapshot_count: 1 id: 3453e71b8fd8 ✅️ 镜像IDroot@Ceph-203 ~# rbd info kpyun/serverrbd image 'server': 👆 '直接跟镜像也是可以的' size 5 GiB in 1280 objects order 22 (4 MiB objects)
3)另一种方式删除快照⚠️ 不推荐(苦涩) --> 使用IDroot@Ceph-201 ~# rbd snap rm -p kpyun --image-id 3453e71b8fd8 --snap-id 4'比较麻烦' --> 指定存储池, 镜像id, 快照idroot@Ceph-201 ~# rbd snap ls kpyun/server | wc -l0- 保护快照 —> 防止误删除
1)快照准备root@Ceph-201 ~# rbd snap create kpyun/server@v1Creating snap: 100% complete...done.root@Ceph-201 ~# rbd snap create kpyun/server@v2Creating snap: 100% complete...done.root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 5 v1 5 GiB ❌️ Thu May 28 12:53:03 2026 6 v2 5 GiB ❌️ Thu May 28 12:53:07 2026'现在删的时候, 随便删除' 👆没有被保护🛡️📌 如何保护快照❓️
2)保护快照root@Ceph-201 ~# rbd snap protect kpyun/server@v2root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 5 v1 5 GiB Thu May 28 12:53:03 2026 6 v2 5 GiB yes✅️ Thu May 28 12:53:07 2026root@Ceph-201 ~# rbd snap rm kpyun/server@v2Removing snap: 0% complete...failed.rbd: snapshot 'v2' is protected from removal.root@Ceph-201 ~# rbd snap rm kpyun/server@v1Removing snap: 100% complete...done.✅️ 可以轻松删除没有保护的快照root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 6 v2 5 GiB yes Thu May 28 12:53:07 2026
3)取消保护root@Ceph-201 ~# rbd snap unprotect kpyun/server@v2root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 6 v2 5 GiB ❌️ Thu May 28 12:53:07 2026
4)更改快照名称root@Ceph-201 ~# rbd snap rename kpyun/server@v2 kpyun/server@haharoot@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 6 haha 5 GiB Thu May 28 12:53:07 2026
5)删除所有未保护的快照root@Ceph-201 ~# rbd help snap purge'查看一下它的帮助信息'Delete all 'unprotected' snapshots.# 删除所有未保护的快照root@Ceph-201 ~# rbd snap purge kpyun/server'Removing all snapshots': 100% complete...done.克隆快照

- 看👆红字🔴tips —> 被克隆出来的快照本质是一个块设备 —> 也就是一个可挂载的镜像
📌 传统回滚 vs 克隆快照
- 传统回滚(rollback):快照 → 覆盖原块设备(全量拷贝,数据量大时非常慢)
- 克隆快照(clone):快照 → “软链接”出一个新的==可读写==镜像(秒级完成,不拷贝数据)
核心概念
- 被 protect 的快照 = 父快照(只读,数据源)
- clone 出来的镜像 = 子快照(可读写,新的 RBD 块设备)
- 客户端映射 & 挂载的是==子快照==,写入的数据落在子快照中,不再接触父快照
COW 写时复制
- 读:数据未修改时,直接从父快照读取
- 写:先将原始数据块从父快照拷贝到子快照,再写入子快照
- 只有被修改的块才会触发拷贝,未修改的仍然引用父快照
flatten 扁平化
- 将父快照中所有剩余未修改的数据块拷贝到==子快照==
- 之后子快照完全独立,不再依赖父快照,父快照可以被删除
1)数据准备root@Ceph-201 ~# rbd snap create kpyun/server@c1Creating snap: 100% complete...done.root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 7 c1 5 GiB Thu May 28 14:15:25 2026root@Ceph-201 ~# rbd ls -p kpyun -lNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 excl'server@c1' 5 GiB 2 <-- 这个快照也显示出来了server02 15 GiB 2 excl
2)我们客户端映射快照 & 并挂载root@Ceph-203 ~# rbd map kpyun/server@c1/dev/rbd2 '这次映射的是快照👆某个块设备(镜像)的快照'root@Ceph-203 ~# mkdir /dataroot@Ceph-203 ~# ls /dataroot@Ceph-203 ~# mount /dev/rbd2 /datamount: /data: 'wrong fs type, bad option, bad superblock' on /dev/rbd2missing codepage or helper program, or other error. dmesg(1) may have more information after failed mount system call.# 错误的类型和选项root@Ceph-203 ~# ll /dev/rbd2brw-rw---- 1 root disk 251, 32 May 28 14:21 /dev/rbd2# 明明也映射成功了呀!root@Ceph-203 ~# blkid /dev/rbd2/dev/rbd2: UUID="7b5d93af-7816-4618-b617-4e702ade203b" BLOCK_SIZE="512" TYPE="xfs"# 查看 UUID & TYPE(文件类型)'看着好像也没有什么毛病呀'root@Ceph-203 ~# dmesg | tail -2[19335.011102] XFS (rbd2): Filesystem has duplicate UUID 7b5d93af-7816-4618-b617-4e702ade203b - can't mount❌️ 文件系统具有重复的UUID'因为挂载的是某个块设备的快照!' --> ✅️ 而且这个块设备依旧挂载在上面root@Ceph-203 ~# umount /dev/rbd0'把原来的块设备卸载了'root@Ceph-203 ~# mount /dev/rbd2 /data'挂载这个块设备的快照'mount: /data: ❌️ 'cannot mount' /dev/rbd2 read-only. --> '只读没办法挂载'===============================[root@R199 ~]# mount /images/Rocky-10.1-x86_64-dvd1.iso /var/ftp/rocky10/mount: /var/ftp/rocky10: WARNING: source write-protected, mounted read-only.'ISO 是只读的,正常现象' ✅️ 📌 写保护===============================root@Ceph-203 ~# df -h | grep rbd2 | wc -l0'并没有挂载上!'✅️ 这个快照是'只读'的不允许你挂载# 快照设备无法直接挂载 --> 克隆的快照可以挂载
3)克隆快照'快照必须被 protect 才能克隆'root@Ceph-201 ~# rbd ls -p kpyun -lNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver@c1📌 5 GiB 2👆有@标识符就是快照 --> 不能进行挂载 ❌️root@Ceph-201 ~# rbd snap protect kpyun/server@c1root@Ceph-201 ~# rbd snap ls kpyun/serverSNAPID NAME SIZE PROTECTED TIMESTAMP 7 c1 5 GiB yes ✅️ Thu May 28 14:15:25 2026
4)基于快照克隆出新镜像root@Ceph-201 ~# rbd clone kpyun/server@c1 kpyun/server-clone'父快照 @c1 → 子镜像 server-clone(秒级完成,不拷贝数据)'✅️ 本质是一个块设备 --> 可以直接挂载root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver@c1 5 GiB 2 ❌️server-clone 5 GiB kpyun/server@c1 2👆没有@标识符->是块设备(镜像)->可以挂载✅️👆'PARENT 指向父快照'root@Ceph-201 ~# rbd info kpyun/server-clone | grep parent parent: kpyun/server@c1 ✅️ 父子关系已建立root@Ceph-201 ~# rbd children kpyun/server@c1'查看父快照的孩子'kpyun/server-clone
5)客户端映射克隆镜像 & 挂载root@Ceph-203 ~# rbd map kpyun/server-clone/dev/rbd2 '这次映射的是克隆出来的可读写镜像'root@Ceph-203 ~# mkdir /clone-dataroot@Ceph-203 ~# mount /dev/rbd2 /clone-datamount: /clone-data: wrong fs type, bad option, bad superblock on /dev/rbd2⚠️ 直接尝试挂载失败❌️root@Ceph-203 ~# blkid /dev/rbd2/dev/rbd2: UUID="7b5d93af-7816-4618-b617-4e702ade203b" BLOCK_SIZE="512" TYPE="xfs"root@Ceph-203 ~# blkid /dev/rbd0/dev/rbd0: UUID="7b5d93af-7816-4618-b617-4e702ade203b" BLOCK_SIZE="512" TYPE="xfs"root@Ceph-203 ~# dmesg | tail -1XFS (rbd2): Filesystem has duplicate UUID 7b5d93af-7816-4618-b617-4e702ade203b - can't mount❌️ 克隆镜像与原镜像 UUID 完全相同,必须卸载原设备才能挂载
6)再次尝试挂载'先卸载原设备 → 再取消映射 → 最后挂载克隆镜像'root@Ceph-203 ~# umount /dev/rbd0root@Ceph-203 ~# rbd unmap kpyun/serverroot@Ceph-203 ~# rbd showmappedid pool namespace image snap device1 kpyun server02 - /dev/rbd12 kpyun server-clone - /dev/rbd2'原设备 /dev/rbd0 已消失'root@Ceph-203 ~# mount /dev/rbd2 /clone-dataroot@Ceph-203 ~# df -hT | grep rbd2/dev/rbd2 xfs 5.0G 130M 4.9G 3% /clone-data✅️ 克隆镜像挂载成功
7)客户端写入数据 → COW 触发root@Ceph-203 ~# ls /clone-data/p1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txt# 这些数据是从 server@c1 快照中读取的root@Ceph-203 ~# echo "new data from clone" > /clone-data/new.txt'写入时:原数据块从父快照@c1 拷贝至 server-clone → 新数据写入 server-clone'root@Ceph-203 ~# cat /clone-data/new.txtnew data from clone
8)直接删除父快照'服务端操作'root@Ceph-201 ~# rbd snap rm kpyun/server@c1Removing snap: 0% complete...failed.rbd: snapshot 'c1' is protected from removal.# 移除失败 --> 受保护'那我们直接取消保护试试'root@Ceph-201 ~# rbd snap unprotect kpyun/server@c1unprotecting snap failed: (16) Device or resource busy✅️ 依旧失败 --> 设备繁忙# 那么如何才能正确的删除父快照呢❓️
9)flatten 扁平化 → 脱离父快照依赖root@Ceph-201 ~# rbd flatten kpyun/server-clone# 操作对象是克隆出来的子快照(镜像/块设备)Image flatten: 100% complete...done.'父快照所有 剩余未修改的数据 全部拷贝至 server-clone' --> 子镜像完全独立✅️root@Ceph-201 ~# rbd info kpyun/server-clone | grep parent | wc -l0❌️ 无父镜像,已独立
10)解除父快照保护(可删除)root@Ceph-201 ~# rbd snap unprotect kpyun/server@c1root@Ceph-201 ~# rbd snap rm kpyun/server@c1Removing snap: 100% complete...done.✅️ 成功删除rbd杂谈
- 纠删码池(Erasure Coded Pool)虽然节省空间,但不适合 RBD 块设备使用
⚠️ 为什么?
哪怕你只写 4KB 数据,落在某个条带上,就会触发”读旧数据 + 重算校验块 + 写一批盘”的连锁反应
- RBD 块设备的随机小块 IO 与纠删码的全条带读写模式天然冲突
- 生产环境中 RBD 应使用多副本存储池(replicated pool)
多节点并发挂载问题
RBD 块设备不支持多节点同时挂载写入,原因在于 exclusive-lock 排它锁机制
💡 类比:你不能把同一块物理磁盘同时插在服务器 A 和服务器 B 上,RBD 也是同样的道理
实验验证:两个客户端同时挂载同一镜像
root@Ceph-203 ~# rbd ls -p kpyunserverserver02'上面都有数据' --> 不必格式化
1)客户端1:映射并挂载,写入测试数据root@Ceph-203 ~# rbd map kpyun/server/dev/rbd0root@Ceph-203 ~# mount /dev/rbd0 /mntroot@Ceph-203 ~# df -hT | grep mnt/dev/rbd0 xfs 5.0G 130M 4.9G 3% /mntroot@Ceph-203 ~# ls /mnt/p1a.txt p1b.txt p1c.txt ......root@Ceph-203 ~# echo hello > /mnt/test.txtroot@Ceph-203 ~# cat /mnt/test.txthello'可以正常写入文件'
2)服务端查看:LOCK 字段出现 `excl` 标记✅️ '客户端也可以查看'root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 excl❌️server02 15 GiB 2# excl 表示该设备已被独占锁定3)客户端2:映射并挂载'同一设备(镜像)'root@Ceph-202 ~# rbd map kpyun/server/dev/rbd0root@Ceph-202 ~# mount /dev/rbd0 /mntroot@Ceph-202 ~# ls /mnt/test.txt p1a.txt p1b.txt ....root@Ceph-202 ~# cat /mnt/hh.txthello✅️ 查看到了我们刚才'客户端1'测试写入的文件
4)客户端2 '测试写入数据'root@Ceph-202 ~# echo Client2... > /mnt/host2.txtroot@Ceph-202 ~# cat /mnt/host2.txtClient2...5)切回客户端1:数据没有任何变化✅️ '不显示客户端2写入的数据'root@Ceph-203 ~# ls /mnt | grep host2.txt | wc -l0# 数据不一致~ '此时数据已经开始冲突了'⚠️ 结论
- 生产环境中不要让 2 个主机同时使用同一个镜像
- *如果确实有多节点共享存储的需求,应该用 CephFS 文件系统✅️,*而不是 RBD 块设备❌️
死锁处理:强制解除客户端锁定
- 当客户端无法正常解除映射时(如节点宕机),锁会残留在服务端,需要手动清除
1)查看被锁定的设备root@Ceph-201 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 excl❌️# server 设备被独占锁定
2)查看锁的详细信息root@Ceph-201 ~# rbd lock ls kpyun/serverThere is 1 exclusive lock on this image.Locker ID Addressclient.344117 auto 18446462598732840961 10.0.0.202:0/1460535844'记录下 Locker、ID 和 Address 信息' 👆 就是Ceph202==================================================# 多节点并发挂载——最后 map 的为准'谁最后 rbd map,排他锁就在谁身上' # 但此前已映射的客户端并不会被"踢掉"# 另一个节点的旧映射虽然设备还在 /dev/rbdX,但锁已丢,静默损坏 ⚠️'静默损坏——你以为是写入成功了,实际数据丢了'==================================================root@Ceph-203 ~# echo Client1... > /mnt/host1.txtroot@Ceph-203 ~# cat /mnt/host1.txtClient1...# 锁落在 `10.0.0.202`(Ceph-202)身上,但 Ceph-203 仍然能读写 `/mnt/host1.txt`⚠️ 并没有真正落到 Ceph OSD 上,而是写进了 XFS 的 page cache(内存)'静默损坏——你以为是写入成功了,实际数据丢了'
3)回到服务端:强制移除锁root@Ceph-201 ~# rbd lock rm kpyun/server "auto 18446462598732840961" client.344117'使用步骤(2)中记录的 ID 和 Locker 进行强制解除'
4)验证锁已清除root@Ceph-201 ~# rbd lock ls kpyun/server'无输出,说明锁已清除 ✅️'root@Ceph-201 ~# rbd ls -p kpyun -lNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 ✅️✅️ LOCK 字段已无 excl 标记存储池资源配额
Ceph 支持对存储池设置对象数量和存储大小两种配额限制
📌 注意:这里的”对象数量”指的是 RADOS ✅️对象个数,不是 4MB 那个 RBD❌️ object
1)创建测试存储池 & 声明类型root@Ceph01 ~# ceph osd pool create oldboy 32 32 --size 3 --autoscale_mode offpool 'oldboy' createdroot@Ceph01 ~# ceph osd pool application enable oldboy rbdenabled application 'rbd' on pool 'oldboy'
2)查看当前配额(默认无限制)'专门查存储池的配额上限和当前用量'root@Ceph01 ~# ceph osd pool get-quota oldboyquotas for pool 'oldboy': max objects: N/A max bytes : N/A
3)限制最大对象数为 3 个root@Ceph-201 ~# ceph osd pool set-quota oldboy max_objects 3'前面都一样' --> 把 get-quota 换为 set-quota --> 设置✅️ 接着跟存储池名称, key, valueset-quota max_objects = 3 for pool oldboyroot@Ceph-201 ~# ceph osd pool get-quota oldboy | grep objects max objects: 3 objects (current num objects: 0 objects)
4)验证对象数量限制# 他是个数的限制rados put <对象名> <本地文件> -p <池名># file01 /etc/hosts oldboy# 意思是:把本地文件 /etc/hosts 上传为对象 file01,存到 pool oldboy 中rados put file01 /etc/hosts -p oldboy ↓ 单个对象 file01(< 4MB,不切) ↓ CRUSH 哈希 → 命中某个 PG ↓ PG → size 份副本 → 落到不同 OSD=================================================================root@Ceph01 ~# rados put file01 /etc/hosts -p oldboyroot@Ceph01 ~# rados put file02 /etc/fstab -p oldboyroot@Ceph01 ~# rados put file03 /etc/shadow -p oldboyroot@Ceph01 ~# ceph osd pool get-quota oldboy | grep objects max objects: 3 objects (current num objects: 3 objects)root@Ceph01 ~# rados put file04 /etc/group -p oldboy'卡住了,无法上传成功!已达到 3 个对象的限制 ❌️'
5)清除对象数量限制root@Ceph01 ~# ceph osd pool set-quota oldboy max_objects 0set-quota max_objects = 0 for pool oldboy'设为 0 即清除限制 ✅️'root@Ceph01 ~# rados put file04 /etc/group -p oldboyroot@Ceph01 ~# ceph osd pool get-quota oldboy | grep objects max objects: N/A1)限制最大存储为 10 MiBroot@Ceph01 ~# echo 10*1024*1024 | bc10485760| 单位 | 全称 | 说明 |
|---|---|---|
| MB | Megabyte(兆字节) | 通常指 1024 KB |
| KB | Kilobyte(千字节) | 通常指 1024 B |
| B | Byte(字节) | 就是 byte,同一个东西 |
| bit | 比特(位) | 1 Byte = 8 bit |
所以 10 MB → byte 的正确计算是:
10 MB = 10 × 1024 KB = 10 × 1024 × 1024 B = 10,485,760 Byte
root@Ceph01 ~# ceph osd pool set-quota oldboy max_bytes 10485760set-quota max_bytes = 10485760 for pool oldboyroot@Ceph01 ~# ceph osd pool get-quota oldboyquotas for pool 'oldboy': max objects: N/A max bytes : 10 MiB (current num bytes: 2733 bytes)root@Ceph01 ~# echo 2733/1024 | bc2 # 2KB(两千字节)# 换算成MB可以忽略不计
2)生成测试文件root@Ceph01 ~# dd if=/dev/zero of=bigfile.1 bs=1M count=5root@Ceph01 ~# dd if=/dev/zero of=bigfile.2 bs=1M count=5root@Ceph01 ~# dd if=/dev/zero of=bigfile.3 bs=1M count=5
3)验证存储大小限制root@Ceph01 ~# rados put file05 bigfile.1 -p oldboyroot@Ceph01 ~# rados put file06 bigfile.2 -p oldboy# 5MB + 5MB'目前已用约 10MB'root@Ceph01 ~# rados put file08 bigfile.3 -p oldboy^C # 卡住'卡住了!已超过 10 MiB 配额限制 ❌️'
4)清除配额限制root@Ceph01 ~# ceph osd pool set-quota oldboy max_bytes 0set-quota max_bytes = 0 for pool oldboyroot@Ceph01 ~# ceph osd pool get-quota oldboyquotas for pool 'oldboy': max objects: N/A max bytes : N/A回收站机制
Ceph RBD 支持类似”回收站”的 trash 功能,删除镜像时先移入回收站而非直接销毁
📌 推荐在生产环境中启用此机制,防止误删导致的灾难性数据丢失
root@Ceph01 ~# rbd create -s 10G oldboy/xixiroot@Ceph01 ~# rbd ls -l oldboyNAME SIZE PARENT FMT PROT LOCKxixi 10 GiB 2root@Ceph01 ~# rbd trash ls oldboy | wc -l0 '回收站为空'
1)将块设备移入回收站root@Ceph01 ~# rbd trash move oldboy/xixi'移入回收站'root@Ceph01 ~# rbd trash ls oldboy1e5dfb2f6964b xixioot@Ceph01 ~# rbd trash ls -l oldboyID NAME SOURCE DELETED_AT STATUS1e5dfb2f6964b xixi USER ... 2026 expired at ....⚠️ 注意:trash 中的镜像有'过期时间',过期后会被自动清理,需要及时恢复
2)移入回收站后,镜像列表不再显示root@Ceph01 ~# rbd ls -l oldboy# xixi 已消失 ❌️
3)从回收站恢复root@Ceph01 ~# rbd trash restore -p oldboy --image xixi --image-id 1e5dfb2f6964b'恢复时需要指定镜像名和 ID'root@Ceph01 ~# rbd trash ls -l oldboy'回收站已清空 ✅️'root@Ceph01 ~# rbd ls -l oldboyNAME SIZE PARENT FMT PROT LOCKxixi 10 GiB 2# xixi 已恢复 ✅️快照数量限制
可以给单个 RBD 镜像设置最大快照数量,超过限制后无法再创建新快照
1)查看当前快照数量(无限制)root@Ceph01 ~# rbd info oldboy/xixi | egrep "snapshot_count|snapshot_limit" snapshot_count: 0 # 这个镜像当前有多少个快照,现在是 0# snapshot_limit 这个镜像最多允许创建多少个快照,没显示就是无上限
2)设置快照上限为 2root@Ceph01 ~# rbd snap limit set oldboy/xixi --limit 2root@Ceph01 ~# rbd info oldboy/xixi | egrep "snapshot_count|snapshot_limit" snapshot_count: 0 snapshot_limit: 2
3)验证限制生效root@Ceph01 ~# rbd snap create oldboy/xixi@oldboy-001Creating snap: 100% complete...done.root@Ceph01 ~# rbd snap create oldboy/xixi@oldboy-002Creating snap: 100% complete...done.root@Ceph01 ~# rbd snap create oldboy/xixi@oldboy-003rbd: failed to create snapshot: (122) Disk quota exceeded'达到上限,无法再创建 ❌️'
4)清除快照数量限制root@Ceph01 ~# rbd snap limit clear oldboy/xixiroot@Ceph01 ~# rbd info oldboy/xixi | egrep "snapshot_count|snapshot_limit" snapshot_count: 2 '当前只有两个快照'# snapshot_limit 已清除 ✅️'解除限制后可以正常创建 ✅️'
5)批量删除快照# 逐个删除root@Ceph01 ~# rbd snap rm oldboy/xixi@oldboy-002# 一键清除所有未保护快照root@Ceph01 ~# rbd snap purge oldboy/xixiroot@Ceph01 ~# rbd snap ls oldboy/xixi | wc -l0 '所有快照已清除 ✅️'📌 小结:
rbd snap limit配合rbd snap protect,可以形成快照的双重保护 —— 数量不被撑爆 + 关键快照不被误删
用户管理
Ceph 用户命名:TYPEID.USERID
| 部分 | 含义 | 示例 |
|---|---|---|
| TYPEID | 用户类型 | client(普通用户)、内置组件用户:osd、mon、mgr、mds |
| USERID | 自定义名称 | client.admin、client.jiu、osd.0 |
每个用户通过 caps 字段授权,格式 allow <权限> [pool=<池名>]:
| 权限 | 说明 |
|---|---|
r | 读 |
w | 写 |
x | 执行(调用方法,包含 mon auth 等命令) |
* | r + w + x,全能 |
class-read / class-write | x 的子集,读写类方法 |
profile osd | 以 OSD 身份连接集群、获取状态 |
profile mds | 以 MDS 身份连接集群 |
以 admin 为例:
root@Ceph01 ~# cat /etc/ceph/ceph.client.admin.keyring[client.admin] key = AQBrGWBqxS8lORAAERATceWqk30FGg8gRefXKg== caps mds = "allow *" caps mgr = "allow *" caps mon = "allow *" caps osd = "allow *"基础操作
1)查看用户ceph auth ls # 所有用户ceph auth get client.admin # 指定用户
root@Ceph01 ~# ceph auth get client.admin# 和上面查看的配置文件一模一样[client.admin] key = AQBrGWBqxS8lORAAERATceWqk30FGg8gRefXKg== caps mds = "allow *" caps mgr = "allow *" caps mon = "allow *" caps osd = "allow *"
2)创建用户(三种方式)| 命令 | 特点 | 示例 |
|---|---|---|
ceph auth add | 创建并静默返回 | ceph auth add client.test mon 'allow r' osd 'allow rwx pool=kpyun' |
ceph auth get-or-create | 不存在则创建,存在则返回现有信息 | ceph auth get-or-create client.test2 mon 'allow r' osd 'allow rwx pool=kpyun' |
ceph auth get-or-create-key | 创建并只返回 key(适合脚本) | ceph auth get-or-create-key client.test3 mon 'allow r' osd 'allow rwx' |
注意:get-or-create 如果用户已存在但 caps 不同会报错,不会覆盖;get-or-create-key 同理
# test1root@Ceph01 ~# ceph auth add client.test mon 'allow r' osd 'allow rwx pool=kpyun'added key for client.testroot@Ceph01 ~# ceph auth get client.test[client.test] key = AQD9MmRqaEQKHBAAoWW481bcfc5nRoF0x5ckzA== caps mon = "allow r" caps osd = "allow rwx pool=kpyun"
# test2root@Ceph01 ~# ceph auth get-or-create client.test2 mon 'allow r' osd 'allow rwx pool=kpyun'[client.test2] key = AQDbNGRqgy1JBhAAaVK95bfvcOse+IJxY6P24A==root@Ceph01 ~# ceph auth get client.test2[client.test2] key = AQDbNGRqgy1JBhAAaVK95bfvcOse+IJxY6P24A== caps mon = "allow r" caps osd = "allow rwx pool=kpyun"
# test3root@Ceph01 ~# ceph auth get-or-create-key client.test3 mon 'allow r' osd 'allow rwx'AQCtNWRqpHGSKxAAN6642aSbjUVLuaz6I0hUVQ==root@Ceph01 ~# ceph auth get client.test3[client.test3] key = AQCtNWRqpHGSKxAAN6642aSbjUVLuaz6I0hUVQ== caps mon = "allow r" caps osd = "allow rwx"
3)获取用户 key'每个用户的key都是不一样的'ceph auth print-key client.test ;echo # 只输出 key# 加了一个换行符ceph auth get client.test | awk 'NR==2{print $3}' # awk 取值ceph auth get-or-create-key client.test # 也可以获取key值
4)修改权限# key 不变,caps 全量替换ceph auth caps client.test mon 'allow rx' osd 'allow r pool=kpyun'
5)删除用户ceph auth del client.test用户的备份和恢复
导出用户(三种方式)
| 方式 | 命令 | 文件权限 | 说明 |
|---|---|---|---|
| 推荐 | ceph-authtool --create-keyring <file>ceph auth get <user> -o <file> | 600 | 先创建空文件(自动600权限),再填入内容 |
| 简单 | ceph auth export <user> -o <file> | 644 | 一行搞定,但权限不安全 |
| 脚本 | ceph auth get <user> > <file> | 644 | 重定向,同上 |
root@Ceph01 ~# ceph auth add client.backup1 mon 'allow r' osd 'allow rwx pool=kpyun'root@Ceph01 ~# ceph-authtool --create-keyring ceph.client.backup1.keyring`命名规范:ceph.client.<用户>.keyring`root@Ceph01 ~# ceph auth get client.backup1 -o ceph.client.backup1.keyringroot@Ceph01 ~# cat ceph.client.backup1.keyring[client.backup1] key = AQACOWRqREFiAhAA+vcJpyJq7cjjB263ORxy9w== caps mon = "allow r" caps osd = "allow rwx pool=kpyun"导入恢复
root@Ceph01 ~# ceph auth del client.backup1 # 模拟误删root@Ceph01 ~# ceph auth get client.backup1 # 确认已删除Error ENOENT: failed to find client.backup1 in keyringroot@Ceph01 ~# ceph auth import -i ceph.client.backup1.keyring # 从备份文件恢复root@Ceph01 ~# ceph auth get client.backup1 # 验证恢复成功实操
root@Ceph01 ~# ceph osd pool create oldboy 32 32 replicated --size 3 --autoscale_mode offpool 'oldboy' createdroot@Ceph01 ~# ceph osd pool application enable oldboy rbdenabled application 'rbd' on pool 'oldboy'root@Ceph01 ~# rbd create -s 2G oldboy/haharoot@Ceph01 ~# rbd create -s 4G oldboy/xixiroot@Ceph01 ~# rbd ls -l oldboyNAME SIZE PARENT FMT PROT LOCKhaha 2 GiB 2xixi 4 GiB 2root@Ceph01 ~# ceph auth get-or-create client.jiu mon 'allow r' osd 'allow rwx pool=oldboy'[client.jiu] key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA==root@Ceph01 ~# ceph-authtool --create-keyring ceph.client.jiu.keyringcreating ceph.client.jiu.keyringroot@Ceph01 ~# ls -lhtotal 0-rw------- 1 root root 0 Jul 25 13:53 ceph.client.jiu.keyringroot@Ceph01 ~# ceph auth get client.jiu -o ceph.client.jiu.keyringroot@Ceph01 ~# cat ceph.client.jiu.keyring[client.jiu] key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA== caps mon = "allow r" caps osd = "allow rwx pool=oldboy"
# 切换另一个机器 Ceph03root@Ceph03 ~# ls -lh /etc/ceph/total 12K-rw------- 1 root root 151 Jul 22 12:42 ceph.client.admin.keyring-rw-r--r-- 1 root root 247 Jul 22 12:42 ceph.conf-rw-r--r-- 1 root root 92 Feb 9 04:52 rbdmaproot@Ceph03 ~# rm -rf /etc/ceph/ceph.client.admin.keyringroot@Ceph03 ~# ceph -s2026-07-25T14:03:08.084+0800 7a01048a16c0 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin: (2) No such file or directory===============================================不指定 --id 时,默认 --id admin: /etc/ceph/ceph.client.admin.keyring /etc/ceph/ceph.keyring /etc/ceph/keyring /etc/ceph/keyring.bin
# 把 keyring 拷到 Ceph03root@Ceph01 ~# scp ceph.client.jiu.keyring root@10.0.0.5:/etc/ceph/'客户端使用 keyring 验证权限'
# Ceph03 上用 jiu 身份操作root@Ceph03 ~# ceph -s --id jiu cluster: id: a9b741cd-856a-11f1-b216-525400c6b9fa health: HEALTH_OK .............root@Ceph03 ~# rbd ls -l oldboy --id jiu # ✅ 有 rwx pool=kpyun 权限root@Ceph03 ~# rbd ls -l kpyun --id jiu # ❌ Operation not permitted===============================================--id jiu 指定用户时,依次查找: /etc/ceph/ceph.client.jiu.keyring ← #✅ 命名规范:ceph.client.<用户>.keyring /etc/ceph/ceph.keyring /etc/ceph/keyring /etc/ceph/keyring.binkeyring 文件命名规范——--id <user> 会去找 /etc/ceph/ceph.client.<user>.keyring,不按此命名则找不到
# Ceph01操作root@Ceph01 ~# rbd ls -l kpyun --id adminNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver02 15 GiB 2 excl
# 修改权限至用户jiu也可以访问kpyun池root@Ceph01 ~# ceph auth caps client.jiu mon 'allow r' osd 'allow rwx pool=oldboy, allow rwx pool=kpyun'[client.jiu] key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA== caps mon = "allow r" caps osd = "allow rwx pool=oldboy, allow rwx pool=kpyun"updated caps for client.jiu
# 切换Ceph03验证root@Ceph03 ~# rbd ls -l kpyun --id jiuNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver02 15 GiB 2 exclroot@Ceph03 ~# cat /etc/ceph/ceph.client.jiu.keyring[client.jiu] key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA== caps mon = "allow r" caps osd = "allow rwx pool=oldboy"# 你会发现配置文件还是只有oldboy池子的权限caps 只在服务端生效——客户端认证只看 key 值,文件里 caps 字段可以被删掉,不影响连接
root@Ceph03 ~# vim /etc/ceph/ceph.client.jiu.keyringroot@Ceph03 ~# cat /etc/ceph/ceph.client.jiu.keyring[client.jiu] key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA==# 其他的都删除了,只剩key值root@Ceph03 ~# ceph health --id jiuHEALTH_OKroot@Ceph03 ~# rbd ls -l kpyun --id jiuNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver02 15 GiB 2 excl课后练习
# 环境准备
# 客户端安装 ceph-commonjiuzhao@Ubuntu ~$ sudo apt install -y ceph-common'宿主机只是客户端,能跑 ceph / rbd 命令就够了'jiuzhao@Ubuntu ~$ ls -lh /etc/ceph/total 4.0K-rw-r--r-- 1 root root 92 Mar 14 01:24 rbdmap# 默认客户端只有这个文件
# 拷贝配置文件sudo scp root@10.0.0.3:/etc/ceph/ceph.conf /etc/ceph/sudo scp root@10.0.0.3:/etc/ceph/ceph.client.admin.keyring /etc/ceph/
# 验证jiuzhao@Ubuntu ~$ sudo ceph -s cluster: id: a9b741cd-856a-11f1-b216-525400c6b9fa health: HEALTH_OK# 我直接切换root用户了jiuzhao@Ubuntu ~$ sudo su -root@Ubuntu ~#- 基于 docker 部署 WordPress 和 mysql 并关联 ceph
# 服务端root@Ceph01 ~# rbd create -s 20G kpyun/wordpressroot@Ceph01 ~# rbd ls -l kpyunNAME SIZE PARENT FMT PROT LOCKserver 5 GiB 2 exclserver02 15 GiB 2 exclwordpress 20 GiB 2
# 客户端root@Ubuntu ~# rbd map kpyun/wordpress/dev/rbd0root@Ubuntu ~# rbd showmappedid pool namespace image snap device0 kpyun wordpress - /dev/rbd0root@Ubuntu ~# mkfs.xfs /dev/rbd0root@Ubuntu ~# mkdir /home/jiuzhao/testroot@Ubuntu ~# mount /dev/rbd0 /home/jiuzhao/testroot@Ubuntu ~# df -hT | grep rbd/dev/rbd0 xfs 20G 424M 20G 3% /home/jiuzhao/test
# 启动mysql服务docker run -d --name mysql-server \ -e MYSQL_ALLOW_EMPTY_PASSWORD="yes" \ -e MYSQL_DATABASE=wordpress \ -e MYSQL_USER=jiuzhao \ -e MYSQL_PASSWORD=passwd \ -p 3306:3306 \ -v /home/jiuzhao/test:/var/lib/mysql \ --restart unless-stopped \ -e TZ=Asia/Shanghai \ mysql:8.0.36 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci \ --default-authentication-plugin=mysql_native_password \ --default-time-zone='+8:00'root@Ubuntu ~# ss -ntl | grep 3306LISTEN 0 4096 0.0.0.0:3306 0.0.0.0:*root@Ubuntu ~# docker exec -it mysql-server /bin/bashbash-4.4# mysqlWelcome to the MySQL monitor.mysql> SHOW DATABASES;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys || wordpress |+--------------------+5 rows in set (0.01 sec)
mysql> SELECT user,host FROM mysql.user;+------------------+-----------+| user | host |+------------------+-----------+| jiuzhao | % || root | % || mysql.infoschema | localhost || mysql.session | localhost || mysql.sys | localhost || root | localhost |+------------------+-----------+6 rows in set (0.00 sec)
mysql> SHOW GRANTS FOR jiuzhao;+--------------------------------------------------------+| Grants for jiuzhao@% |+--------------------------------------------------------+| GRANT USAGE ON *.* TO `jiuzhao`@`%` || GRANT ALL PRIVILEGES ON `wordpress`.* TO `jiuzhao`@`%` |+--------------------------------------------------------+2 rows in set (0.00 sec)
# 运行WordPress服务docker run -e WORDPRESS_DB_HOST=172.17.0.2 \ -e WORDPRESS_DB_USER=jiuzhao \ -e WORDPRESS_DB_PASSWORD=passwd \ -e WORDPRESS_DB_NAME=wordpress \ --name wordpress-server \ --restart unless-stopped \ -p 18080:80 \ -d wordpress:latest
http://localhost:18080/# 随便写个文章
# 对MySQL块设备拍快照(服务端Ceph01)root@Ceph01 ~# rbd snap create kpyun/wordpress@backup-initCreating snap: 100% complete...done.root@Ceph01 ~# rbd snap ls kpyun/wordpressSNAPID NAME SIZE PROTECTED TIMESTAMP 8 backup-init 20 GiB Sat Jul 25 16:13:10 2026
# MySQL搞破坏(客户端)root@Ubuntu ~# docker exec mysql-server mysql -e "DROP DATABASE wordpress;"
# 业务故障(客户端)root@Ubuntu ~# curl -SskL http://localhost:18080/ | grep '<h1>' <div class="wp-die-message"><h1>Error establishing a database connection</h1></div></body>
# 客户端卸载 & 取消映射(客户端)root@Ubuntu ~# docker rm -f mysql-servermysql-serverroot@Ubuntu ~# umount /home/jiuzhao/testroot@Ubuntu ~# rbd unmap kpyun/wordpressroot@Ubuntu ~# rbd showmapped | wc -l0
# 回滚数据库块设备(服务端Ceph01)root@Ceph01 ~# rbd snap rollback kpyun/wordpress@backup-initRolling back to snapshot: 100% complete...done.
# 客户端挂载,启动MySQL容器验证数据是否找回(客户端)root@Ubuntu ~# rbd map kpyun/wordpress/dev/rbd0root@Ubuntu ~# mount /dev/rbd0 /home/jiuzhao/testdocker run -d --name mysql-server \ -e MYSQL_ALLOW_EMPTY_PASSWORD="yes" \ ..........(同上)root@Ubuntu ~# curl -SskL http://localhost:18080/ | grep blog<body class="home blog wp-embed-responsive wp-theme-twentytwentyfive"># 数据恢复文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!















