RBD块设备与用户管理

9529 字
48 分钟
RBD块设备与用户管理
RBD块设备与用户管理

RBD块设备与用户管理#

[TOC]


基本操作#

增删改查#

Terminal window
1)创建专用存储池并声明为 RBD 类型
root@Ceph-201 ~# ceph osd pool create kpyun 8 8 replicated --size 3 --autoscale_mode off
pool 'kpyun' created
root@Ceph-201 ~# ceph osd pool ls | grep kpyun | wc -l
1
root@Ceph-201 ~# ceph osd pool ls detail | grep kpyun
pool 7 'kpyun' replicated size 3 min_size 2 crush_rule 0
object_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 rbd
enabled application 'rbd' on pool 'kpyun'
root@Ceph-201 ~# ceph health
HEALTH_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 -l
root@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 name
root@Ceph-201 ~# rbd -p kpyun ls
C413
👆'有哪些块设备'
# 更简便一点
root@Ceph01 ~# rbd ls kpyun
C413
root@Ceph-201 ~# rbd ls -l kpyun
✅️ 有详细信息
NAME SIZE PARENT FMT PROT LOCK
C413 2 GiB 2
# FMT 2 表示使用 RBD v2 格式
4)查看块设备详细信息
rbd info <pool>/<image>
root@Ceph-201 ~# rbd info kpyun/C413
rbd 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/C413
Resizing image: 100% complete...done.
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
C413 4 GiB 2
6)缩容块设备(需要加 --allow-shrink)
rbd resize -s <size> <pool>/<image> --allow-shrink
root@Ceph-201 ~# rbd resize -s 1G kpyun/C413 --allow-shrink
Resizing image: 100% complete...done.
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
C413 1 GiB 2
7)重命名块设备
rbd rename -p <pool> <old> <new>
root@Ceph-201 ~# rbd rename -p kpyun C413 haha
root@Ceph-201 ~# rbd ls kpyun
haha
8)删除块设备
rbd rm <pool>/<image>
root@Ceph-201 ~# rbd rm kpyun/haha
Removing image: 100% complete...done.
root@Ceph-201 ~# rbd ls kpyun | grep haha | wc -l
0

客户端挂载#

  • 格式化 xfs
Terminal window
1)创建RBD设备
# 在我们原来的池子中 --> 新建RBD块设备
root@Ceph-201 ~# rbd create -s 4G kpyun/server
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 4 GiB 2
root@Ceph-201 ~# rbd info kpyun/server
rbd image 'server':
size 4 GiB in 1024 objects
order 22 (4 MiB objects)
2)Ceph通用包
# 另外两个节点也要保证安装 ceph-common
'客户端'
root@Ceph-202 ~# ceph version
ceph version 20.2.1
root@Ceph-203 ~# ceph version
ceph 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 health
HEALTH_OK
✅️ 另外两个节点也可以查看集群状态
4)客户端添加rbd块设备
root@Ceph-203 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 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 showmapped
id pool namespace image snap device
0 kpyun server - /dev/rbd0
root@Ceph-203 ~# ls -lh /dev/rbd0
brw-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 -l
0
root@Ceph-203 ~# mount /dev/rbd0 /mnt
root@Ceph-203 ~# df -h | grep /mnt
/dev/rbd0 4.0G 110M 3.9G 3% /mnt
6)客户端写入数据
root@Ceph-203 ~# ls /mnt
root@Ceph-203 ~# echo Hello > /mnt/test.txt
root@Ceph-203 ~# cat /mnt/test.txt
Hello ✅️ 数据写入成功

Terminal window
'上面格式化的是xfs' --> 下面格式化 ext4 ✅️
1)服务端创建块设备
root@Ceph-201 ~# rbd create -s 10G kpyun/server02
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 4 GiB 2 excl
server02 10 GiB 2 # 已挂载👆的会有 excl 锁标记
2)客户端添加映射
root@Ceph-203 ~# rbd ls kpyun
server
server02
# 👆客户端这边也能刷新到新添加的设备
root@Ceph-203 ~# rbd map kpyun/server02
/dev/rbd1
root@Ceph-203 ~# rbd showmapped
id pool namespace image snap device
0 kpyun server - /dev/rbd0
1 kpyun server02 - /dev/rbd1
3)格式化 & 挂载
root@Ceph-203 ~# mkfs -t ext4 /dev/rbd1
root@Ceph-203 ~# mkdir /test
root@Ceph-203 ~# mount /dev/rbd1 /test
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
'一个xfs, 一个ext4'
root@Ceph-203 ~# echo haha > /test/hh.txt
root@Ceph-203 ~# cat /test/hh.txt
haha ✅️ 数据写入成功

容量热更新#

Terminal window
✅️ 两种文件类型'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 kpyun
NAME SIZE PARENT FMT PROT LOCK
server 4 GiB 2 excl
server02 10 GiB 2 excl
root@Ceph-201 ~# rbd resize -s 5G kpyun/server
Resizing image: 100% complete...done.
root@Ceph-201 ~# rbd resize -s 15G kpyun/server02
Resizing image: 100% complete...done.
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server02 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
✅️ 容量发生改变 --> '在线扩容完成'
Note

📌 一句话总结:

  • ext4 用 resize2fs | xfs 用 xfs_growfs
    • 都不需要卸载,在线热更新

开启自动挂载#

Terminal window
'重启集群后'
root@Ceph-203 ~# rbd showmapped
root@Ceph-203 ~# rbd ls kpyun
server
server02
# 虽然可以查看到块设备 --> 但'客户端找不到映射关系'
root@Ceph-203 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 ❌️
server02 15 GiB 2 ❌️
'自然也没有锁定🔒' # 已挂载的会有 excl👆锁标记
✅️ 我们格式化过文件系统, 并且对应的块设备是有内容的
--> 所以我们只需要挂载即可!
'恢复数据' --> 只需要两步
1)映射块设备 ✅️
root@Ceph-203 ~# rbd map kpyun/server
/dev/rbd0
root@Ceph-203 ~# ls /mnt
🈚 连挂载目录也不需要进行创建 --> 里面没有内容
'在脚本中也可以重复创建 --> mkdir -p /mnt'
# 加上-p选项后,重复创建目录不报错
root@Ceph-203 ~# df -h | grep /mnt | wc -l
0
2)挂载 ✅️
root@Ceph-203 ~# mount /dev/rbd0 /mnt
root@Ceph-203 ~# df -h | grep /mnt | wc -l
1
root@Ceph-203 ~# cat /mnt/test.txt
Hello
'原来的数据内容恢复了'

rc.local#

Terminal window
'开机自动执行里面的命令'
root@Ceph-203 ~# ls /etc/rc.local
ls: cannot access '/etc/rc.local': No such file or directory
# Ubuntu系统默认不存在 --> 需要手动创建
===========================================
root@Ceph-203 ~# cat > /etc/rc.local <<EOF
#!/bin/bash
rbd map kpyun/server
rbd map kpyun/server02
mount /dev/rbd0 /mnt
mount /dev/rbd1 /test
exit 0
EOF
'开头结尾不能省略'
root@Ceph-203 ~# chmod +x /etc/rc.local
root@Ceph-203 ~# systemctl is-active rc-local.service
inactive
root@Ceph-203 ~# df -hT | grep rbd | wc -l
0
root@Ceph-203 ~# systemctl restart rc-local.service
'重启服务 --> 即可触发脚本'
# 开机自动触发
root@Ceph-203 ~# journalctl -u rc-local
May 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/rbd0
May 27 22:04:50 Ceph-203 rc.local[6930]: /dev/rbd1
May 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 -l
2
✅️ 开机自动挂载
  • 虽然 rc.local 是一种传统且简单的方法

  • 但在现代 Linux 系统中,官方==推荐==的做法是

    • ==创建自定义==的 systemd 服务单元文件来管理开机自启任务

    • 因为它提供了更好的依赖管理、日志记录和控制选项

/etc/fstab#

  • 单独使用 /etc/fstab 确实不行

    • 因为 挂载之前必须先 rbd map

    • 而 fstab 在开机时执行得太早,那时映射设备还不存在

  • 但是可以借助 systemd 的 x-systemd.requires= 选项,让 fstab 挂载依赖 rc-local.service

    • 映射 → rc.local(只做 map)
    • 挂载 → /etc/fstab(开机自动挂载)
Terminal window
'清理环境 --> 重启reboot'
1)rc.local 只负责映射
root@Ceph-203 ~# cat > /etc/rc.local <<EOF
#!/bin/bash
rbd map kpyun/server
rbd map kpyun/server02
exit 0
EOF
root@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 0
EOF
✅️ _netdev --> 标识这是网络块设备(依赖网络就绪)
✅️ x-systemd.requires=rc-local.service --> 让该挂载单元依赖 rc-local
# 开机时 systemd 会先等 rc-local 完成(映射好设备),再自动挂载
3)手动触发
root@Ceph-203 ~# df -hT | grep rbd | wc -l
0
root@Ceph-203 ~# systemctl restart rc-local.service
'触发映射'
root@Ceph-203 ~# mount -a
'使/etc/fstab生效'
root@Ceph-203 ~# df -hT | grep rbd | wc -l
2
✅️ 成功挂载
3)重启验证
root@Ceph-203 ~# reboot
root@Ceph-203 ~# df -hT | grep rbd | wc -l
2
✅️ 开机自动挂载成功

systemd#

  • ==官方推荐方案==:自定义 systemd 服务单元

  • 思路:写一个 shell 脚本 → 用 systemd service 管理 → 设置开机自启

Terminal window
'清理环境 --> 重启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}/server
rbd 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} 挂载成功"
fi
EOF
root@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-mount
After=network-online.target
# After=network-online.target 确保网络已就绪后再执行
# 因为 Ceph 集群通信依赖网络
[Service]
Type=oneshot
# Type=oneshot → 一次性任务,执行完即结束
# 在开机状态只能执行一次 --> restart也不会再次运行
ExecStart=/usr/local/bin/rbd-auto-mount.sh
RemainAfterExit=yes
# RemainAfterExit → 执行完后仍视为 active,方便后续追踪状态
[Install]
WantedBy=multi-user.target
# 开机时自动启用
EOF
3)开机自启服务
root@Ceph-203 ~# systemctl daemon-reload
# 重载 systemd 配置,让它识别新写的单元文件
root@Ceph-203 ~# systemctl enable rbd-mount.service
Created symlink /etc/systemd/system/multi-user.target.wants/rbd-mount.service ...
4)重启验证
root@Ceph-203 ~# reboot
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
✅️ 开机自动挂载成功
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 -6
May 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/rbd0
May 28 08:59:55 Ceph-203 rbd-auto-mount.sh[1212]: /dev/rbd1
May 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.
Tip

虽然 rc.local 也是一种 systemd 服务(同样有日志和状态追踪)

但自定义单元提供了

  • 更好的依赖管理(精确到 network-online.target)

  • 更清晰的日志记录(独立单元,不会被其他 rc.local 任务干扰)

以及 更灵活的控制选项(Restart=on-failure、超时、启停等)

快照管理#

备份与恢复#

Terminal window
'对于客户端的选择 --> 我们依旧选择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/rbd0
root@Ceph-203 ~# touch /mnt/p1{a..d}.txt
root@Ceph-203 ~# ls /mnt
p1a.txt p1b.txt p1c.txt p1d.txt test.txt
2)服务端对块设备进行拍快照
'切换至 Ceph-201'
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 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 p1
Creating snap: 100% complete...done. '快照名称叫p1'
# server 镜像对照客户端/dev/rbd0
root@Ceph-201 ~# rbd snap ls -p kpyun --image server
SNAPID 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}.txt
root@Ceph-203 ~# ls /mnt
p1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txt
4)服务端再次创建快照
root@Ceph-201 ~# rbd snap create kpyun/server@p2
Creating snap: 100% complete...done. '这里的@p2就是指定了快照名称'
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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 /mnt
p1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txt
root@Ceph-203 ~# rm -f /mnt/*
'模拟误删除'
root@Ceph-203 ~# ls /mnt | wc -l
0
⚠️ 现在什么都没有了
6)恢复数据(准备工作)
✅️ 需要提前取消挂载 & 删除块设备映射
'我们这里只演示 /dev/rbd0 '
root@Ceph-203 ~# umount /dev/rbd0
root@Ceph-203 ~# rbd unmap kpyun/server
root@Ceph-203 ~# rbd showmapped
id pool namespace image snap device
1 kpyun server02 - /dev/rbd1
'现在只剩下一个了'
7)服务端恢复数据
root@Ceph-201 ~# rbd snap rollback kpyun/server@p2
Rolling back to snapshot: 100% complete...done.
⚠️ 使用快照进行'数据恢复'(回滚覆盖)的时候, 会将快照的数据拷贝到块设备中
📌 '如果数据量非常大的时候,会非常耗时!!!'
8)客户端重新映射 & 挂载验证
root@Ceph-203 ~# rbd map kpyun/server
/dev/rbd0
root@Ceph-203 ~# mount /dev/rbd0 /mnt
root@Ceph-203 ~# ls /mnt/
p1a.txt p1b.txt p1c.txt p1d.txt p2e.txt p2f.txt p2g.txt test.txt
'数据全部都恢复过来了'

删除#

Terminal window
'服务端进行操作'
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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@p1
Removing 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@p2
rbd image 'server': <-- 📌 查看的是镜像 '快照也是从镜像来的'
size 5 GiB in 1280 objects
order 22 (4 MiB objects)
snapshot_count: 1
id: 3453e71b8fd8 ✅️ 镜像ID
root@Ceph-203 ~# rbd info kpyun/server
rbd image 'server': 👆 '直接跟镜像也是可以的'
size 5 GiB in 1280 objects
order 22 (4 MiB objects)
3)另一种方式删除快照
⚠️ 不推荐(苦涩) --> 使用ID
root@Ceph-201 ~# rbd snap rm -p kpyun --image-id 3453e71b8fd8 --snap-id 4
'比较麻烦' --> 指定存储池, 镜像id, 快照id
root@Ceph-201 ~# rbd snap ls kpyun/server | wc -l
0
  • 保护快照 —> 防止误删除
Terminal window
1)快照准备
root@Ceph-201 ~# rbd snap create kpyun/server@v1
Creating snap: 100% complete...done.
root@Ceph-201 ~# rbd snap create kpyun/server@v2
Creating snap: 100% complete...done.
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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@v2
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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 2026
root@Ceph-201 ~# rbd snap rm kpyun/server@v2
Removing snap: 0% complete...failed.
rbd: snapshot 'v2' is protected from removal.
root@Ceph-201 ~# rbd snap rm kpyun/server@v1
Removing snap: 100% complete...done.
✅️ 可以轻松删除没有保护的快照
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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@v2
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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@haha
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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.

克隆快照#

RBD块设备快照和克隆回滚图解
RBD块设备快照和克隆回滚图解

Tip
  • 看👆红字🔴tips —> 被克隆出来的快照本质是一个块设备 —> 也就是一个可挂载的镜像
Note

📌 传统回滚 vs 克隆快照

  • 传统回滚(rollback):快照 → 覆盖原块设备(全量拷贝,数据量大时非常慢)
  • 克隆快照(clone):快照 → “软链接”出一个新的==可读写==镜像(秒级完成,不拷贝数据)

核心概念

  1. 被 protect 的快照 = 父快照(只读,数据源)
  2. clone 出来的镜像 = 子快照(可读写,新的 RBD 块设备)
  3. 客户端映射 & 挂载的是==子快照==,写入的数据落在子快照中,不再接触父快照

COW 写时复制

  • 读:数据未修改时,直接从父快照读取
  • 写:先将原始数据块从父快照拷贝到子快照,再写入子快照
  • 只有被修改的块才会触发拷贝,未修改的仍然引用父快照

flatten 扁平化

  • 将父快照中所有剩余未修改的数据块拷贝到==子快照==
  • 之后子快照完全独立,不再依赖父快照,父快照可以被删除
Terminal window
1)数据准备
root@Ceph-201 ~# rbd snap create kpyun/server@c1
Creating snap: 100% complete...done.
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID NAME SIZE PROTECTED TIMESTAMP
7 c1 5 GiB Thu May 28 14:15:25 2026
root@Ceph-201 ~# rbd ls -p kpyun -l
NAME SIZE PARENT FMT PROT LOCK
server 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 /data
root@Ceph-203 ~# ls /data
root@Ceph-203 ~# mount /dev/rbd2 /data
mount: /data: 'wrong fs type, bad option, bad superblock' on /dev/rbd2
missing codepage or helper program, or other error.
dmesg(1) may have more information after failed mount system call.
# 错误的类型和选项
root@Ceph-203 ~# ll /dev/rbd2
brw-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 -l
0
'并没有挂载上!'
✅️ 这个快照是'只读'的不允许你挂载
# 快照设备无法直接挂载 --> 克隆的快照可以挂载
3)克隆快照
'快照必须被 protect 才能克隆'
root@Ceph-201 ~# rbd ls -p kpyun -l
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server@c1📌 5 GiB 2
👆有@标识符就是快照 --> 不能进行挂载 ❌️
root@Ceph-201 ~# rbd snap protect kpyun/server@c1
root@Ceph-201 ~# rbd snap ls kpyun/server
SNAPID 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 kpyun
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server@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-data
root@Ceph-203 ~# mount /dev/rbd2 /clone-data
mount: /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 -1
XFS (rbd2): Filesystem has duplicate UUID 7b5d93af-7816-4618-b617-4e702ade203b - can't mount
❌️ 克隆镜像与原镜像 UUID 完全相同,必须卸载原设备才能挂载
6)再次尝试挂载
'先卸载原设备 → 再取消映射 → 最后挂载克隆镜像'
root@Ceph-203 ~# umount /dev/rbd0
root@Ceph-203 ~# rbd unmap kpyun/server
root@Ceph-203 ~# rbd showmapped
id pool namespace image snap device
1 kpyun server02 - /dev/rbd1
2 kpyun server-clone - /dev/rbd2
'原设备 /dev/rbd0 已消失'
root@Ceph-203 ~# mount /dev/rbd2 /clone-data
root@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.txt
new data from clone
8)直接删除父快照
'服务端操作'
root@Ceph-201 ~# rbd snap rm kpyun/server@c1
Removing snap: 0% complete...failed.
rbd: snapshot 'c1' is protected from removal.
# 移除失败 --> 受保护
'那我们直接取消保护试试'
root@Ceph-201 ~# rbd snap unprotect kpyun/server@c1
unprotecting 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 -l
0
❌️ 无父镜像,已独立
10)解除父快照保护(可删除)
root@Ceph-201 ~# rbd snap unprotect kpyun/server@c1
root@Ceph-201 ~# rbd snap rm kpyun/server@c1
Removing snap: 100% complete...done.
✅️ 成功删除

rbd杂谈#

  • 纠删码池(Erasure Coded Pool)虽然节省空间,但不适合 RBD 块设备使用

⚠️ 为什么?

哪怕你只写 4KB 数据,落在某个条带上,就会触发”读旧数据 + 重算校验块 + 写一批盘”的连锁反应

  • RBD 块设备的随机小块 IO 与纠删码的全条带读写模式天然冲突
  • 生产环境中 RBD 应使用多副本存储池(replicated pool)

多节点并发挂载问题#

RBD 块设备不支持多节点同时挂载写入,原因在于 exclusive-lock 排它锁机制

Tip

💡 类比:你不能把同一块物理磁盘同时插在服务器 A 和服务器 B 上,RBD 也是同样的道理

实验验证:两个客户端同时挂载同一镜像

Terminal window
root@Ceph-203 ~# rbd ls -p kpyun
server
server02
'上面都有数据' --> 不必格式化
1)客户端1:映射并挂载,写入测试数据
root@Ceph-203 ~# rbd map kpyun/server
/dev/rbd0
root@Ceph-203 ~# mount /dev/rbd0 /mnt
root@Ceph-203 ~# df -hT | grep mnt
/dev/rbd0 xfs 5.0G 130M 4.9G 3% /mnt
root@Ceph-203 ~# ls /mnt/
p1a.txt p1b.txt p1c.txt ......
root@Ceph-203 ~# echo hello > /mnt/test.txt
root@Ceph-203 ~# cat /mnt/test.txt
hello
'可以正常写入文件'
2)服务端查看:LOCK 字段出现 `excl` 标记
✅️ '客户端也可以查看'
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl❌️
server02 15 GiB 2
# excl 表示该设备已被独占锁定
Terminal window
3)客户端2:映射并挂载
'同一设备(镜像)'
root@Ceph-202 ~# rbd map kpyun/server
/dev/rbd0
root@Ceph-202 ~# mount /dev/rbd0 /mnt
root@Ceph-202 ~# ls /mnt/
test.txt p1a.txt p1b.txt ....
root@Ceph-202 ~# cat /mnt/hh.txt
hello
✅️ 查看到了我们刚才'客户端1'测试写入的文件
4)客户端2 '测试写入数据'
root@Ceph-202 ~# echo Client2... > /mnt/host2.txt
root@Ceph-202 ~# cat /mnt/host2.txt
Client2...
Terminal window
5)切回客户端1:数据没有任何变化
✅️ '不显示客户端2写入的数据'
root@Ceph-203 ~# ls /mnt | grep host2.txt | wc -l
0
# 数据不一致~ '此时数据已经开始冲突了'

⚠️ 结论

  • 生产环境中不要让 2 个主机同时使用同一个镜像
  • *如果确实有多节点共享存储的需求,应该用 CephFS 文件系统✅️,*而不是 RBD 块设备❌️

死锁处理:强制解除客户端锁定#

  • 当客户端无法正常解除映射时(如节点宕机),锁会残留在服务端,需要手动清除
Terminal window
1)查看被锁定的设备
root@Ceph-201 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl❌️
# server 设备被独占锁定
2)查看锁的详细信息
root@Ceph-201 ~# rbd lock ls kpyun/server
There is 1 exclusive lock on this image.
Locker ID Address
client.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.txt
root@Ceph-203 ~# cat /mnt/host1.txt
Client1...
# 锁落在 `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 -l
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 ✅️
✅️ LOCK 字段已无 excl 标记

存储池资源配额#

Ceph 支持对存储池设置对象数量和存储大小两种配额限制

Note

📌 注意:这里的”对象数量”指的是 RADOS ✅️对象个数,不是 4MB 那个 RBD❌️ object

Terminal window
1)创建测试存储池 & 声明类型
root@Ceph01 ~# ceph osd pool create oldboy 32 32 --size 3 --autoscale_mode off
pool 'oldboy' created
root@Ceph01 ~# ceph osd pool application enable oldboy rbd
enabled application 'rbd' on pool 'oldboy'
2)查看当前配额(默认无限制)
'专门查存储池的配额上限和当前用量'
root@Ceph01 ~# ceph osd pool get-quota oldboy
quotas 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, value
set-quota max_objects = 3 for pool oldboy
root@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 oldboy
root@Ceph01 ~# rados put file02 /etc/fstab -p oldboy
root@Ceph01 ~# rados put file03 /etc/shadow -p oldboy
root@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 0
set-quota max_objects = 0 for pool oldboy
'设为 0 即清除限制 ✅️'
root@Ceph01 ~# rados put file04 /etc/group -p oldboy
root@Ceph01 ~# ceph osd pool get-quota oldboy | grep objects
max objects: N/A
Terminal window
1)限制最大存储为 10 MiB
root@Ceph01 ~# echo 10*1024*1024 | bc
10485760
单位全称说明
MBMegabyte(兆字节)通常指 1024 KB
KBKilobyte(千字节)通常指 1024 B
BByte(字节)就是 byte,同一个东西
bit比特(位)1 Byte = 8 bit

所以 10 MB → byte 的正确计算是:

10 MB = 10 × 1024 KB = 10 × 1024 × 1024 B = 10,485,760 Byte

Terminal window
root@Ceph01 ~# ceph osd pool set-quota oldboy max_bytes 10485760
set-quota max_bytes = 10485760 for pool oldboy
root@Ceph01 ~# ceph osd pool get-quota oldboy
quotas for pool 'oldboy':
max objects: N/A
max bytes : 10 MiB (current num bytes: 2733 bytes)
root@Ceph01 ~# echo 2733/1024 | bc
2 # 2KB(两千字节)
# 换算成MB可以忽略不计
2)生成测试文件
root@Ceph01 ~# dd if=/dev/zero of=bigfile.1 bs=1M count=5
root@Ceph01 ~# dd if=/dev/zero of=bigfile.2 bs=1M count=5
root@Ceph01 ~# dd if=/dev/zero of=bigfile.3 bs=1M count=5
3)验证存储大小限制
root@Ceph01 ~# rados put file05 bigfile.1 -p oldboy
root@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 0
set-quota max_bytes = 0 for pool oldboy
root@Ceph01 ~# ceph osd pool get-quota oldboy
quotas for pool 'oldboy':
max objects: N/A
max bytes : N/A

回收站机制#

Ceph RBD 支持类似”回收站”的 trash 功能,删除镜像时先移入回收站而非直接销毁

📌 推荐在生产环境中启用此机制,防止误删导致的灾难性数据丢失

Terminal window
root@Ceph01 ~# rbd create -s 10G oldboy/xixi
root@Ceph01 ~# rbd ls -l oldboy
NAME SIZE PARENT FMT PROT LOCK
xixi 10 GiB 2
root@Ceph01 ~# rbd trash ls oldboy | wc -l
0 '回收站为空'
1)将块设备移入回收站
root@Ceph01 ~# rbd trash move oldboy/xixi
'移入回收站'
root@Ceph01 ~# rbd trash ls oldboy
1e5dfb2f6964b xixi
oot@Ceph01 ~# rbd trash ls -l oldboy
ID NAME SOURCE DELETED_AT STATUS
1e5dfb2f6964b 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 oldboy
NAME SIZE PARENT FMT PROT LOCK
xixi 10 GiB 2
# xixi 已恢复 ✅️

快照数量限制#

可以给单个 RBD 镜像设置最大快照数量,超过限制后无法再创建新快照

Terminal window
1)查看当前快照数量(无限制)
root@Ceph01 ~# rbd info oldboy/xixi | egrep "snapshot_count|snapshot_limit"
snapshot_count: 0 # 这个镜像当前有多少个快照,现在是 0
# snapshot_limit 这个镜像最多允许创建多少个快照,没显示就是无上限
2)设置快照上限为 2
root@Ceph01 ~# rbd snap limit set oldboy/xixi --limit 2
root@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-001
Creating snap: 100% complete...done.
root@Ceph01 ~# rbd snap create oldboy/xixi@oldboy-002
Creating snap: 100% complete...done.
root@Ceph01 ~# rbd snap create oldboy/xixi@oldboy-003
rbd: failed to create snapshot: (122) Disk quota exceeded
'达到上限,无法再创建 ❌️'
4)清除快照数量限制
root@Ceph01 ~# rbd snap limit clear oldboy/xixi
root@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/xixi
root@Ceph01 ~# rbd snap ls oldboy/xixi | wc -l
0 '所有快照已清除 ✅️'

📌 小结: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-writex 的子集,读写类方法
profile osd以 OSD 身份连接集群、获取状态
profile mds以 MDS 身份连接集群

以 admin 为例:

Terminal window
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 *"

基础操作#

Terminal window
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'
Tip

注意:get-or-create 如果用户已存在但 caps 不同会报错,不会覆盖;get-or-create-key 同理

Terminal window
# test1
root@Ceph01 ~# ceph auth add client.test mon 'allow r' osd 'allow rwx pool=kpyun'
added key for client.test
root@Ceph01 ~# ceph auth get client.test
[client.test]
key = AQD9MmRqaEQKHBAAoWW481bcfc5nRoF0x5ckzA==
caps mon = "allow r"
caps osd = "allow rwx pool=kpyun"
# test2
root@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"
# test3
root@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重定向,同上
Terminal window
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.keyring
root@Ceph01 ~# cat ceph.client.backup1.keyring
[client.backup1]
key = AQACOWRqREFiAhAA+vcJpyJq7cjjB263ORxy9w==
caps mon = "allow r"
caps osd = "allow rwx pool=kpyun"

导入恢复#

Terminal window
root@Ceph01 ~# ceph auth del client.backup1 # 模拟误删
root@Ceph01 ~# ceph auth get client.backup1 # 确认已删除
Error ENOENT: failed to find client.backup1 in keyring
root@Ceph01 ~# ceph auth import -i ceph.client.backup1.keyring # 从备份文件恢复
root@Ceph01 ~# ceph auth get client.backup1 # 验证恢复成功

实操#

Terminal window
root@Ceph01 ~# ceph osd pool create oldboy 32 32 replicated --size 3 --autoscale_mode off
pool 'oldboy' created
root@Ceph01 ~# ceph osd pool application enable oldboy rbd
enabled application 'rbd' on pool 'oldboy'
root@Ceph01 ~# rbd create -s 2G oldboy/haha
root@Ceph01 ~# rbd create -s 4G oldboy/xixi
root@Ceph01 ~# rbd ls -l oldboy
NAME SIZE PARENT FMT PROT LOCK
haha 2 GiB 2
xixi 4 GiB 2
root@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.keyring
creating ceph.client.jiu.keyring
root@Ceph01 ~# ls -lh
total 0
-rw------- 1 root root 0 Jul 25 13:53 ceph.client.jiu.keyring
root@Ceph01 ~# ceph auth get client.jiu -o ceph.client.jiu.keyring
root@Ceph01 ~# cat ceph.client.jiu.keyring
[client.jiu]
key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA==
caps mon = "allow r"
caps osd = "allow rwx pool=oldboy"
# 切换另一个机器 Ceph03
root@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 rbdmap
root@Ceph03 ~# rm -rf /etc/ceph/ceph.client.admin.keyring
root@Ceph03 ~# ceph -s
2026-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 拷到 Ceph03
root@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.bin
Note

keyring 文件命名规范——--id <user> 会去找 /etc/ceph/ceph.client.<user>.keyring,不按此命名则找不到

Terminal window
# Ceph01操作
root@Ceph01 ~# rbd ls -l kpyun --id admin
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server02 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 jiu
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server02 15 GiB 2 excl
root@Ceph03 ~# cat /etc/ceph/ceph.client.jiu.keyring
[client.jiu]
key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA==
caps mon = "allow r"
caps osd = "allow rwx pool=oldboy"
# 你会发现配置文件还是只有oldboy池子的权限
Note

caps 只在服务端生效——客户端认证只看 key 值,文件里 caps 字段可以被删掉,不影响连接

Terminal window
root@Ceph03 ~# vim /etc/ceph/ceph.client.jiu.keyring
root@Ceph03 ~# cat /etc/ceph/ceph.client.jiu.keyring
[client.jiu]
key = AQAST2RqKakzFxAAi4lSGsAonopRXm8QKUOaMA==
# 其他的都删除了,只剩key值
root@Ceph03 ~# ceph health --id jiu
HEALTH_OK
root@Ceph03 ~# rbd ls -l kpyun --id jiu
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server02 15 GiB 2 excl

课后练习#

Terminal window
# 环境准备
# 客户端安装 ceph-common
jiuzhao@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
Terminal window
# 服务端
root@Ceph01 ~# rbd create -s 20G kpyun/wordpress
root@Ceph01 ~# rbd ls -l kpyun
NAME SIZE PARENT FMT PROT LOCK
server 5 GiB 2 excl
server02 15 GiB 2 excl
wordpress 20 GiB 2
# 客户端
root@Ubuntu ~# rbd map kpyun/wordpress
/dev/rbd0
root@Ubuntu ~# rbd showmapped
id pool namespace image snap device
0 kpyun wordpress - /dev/rbd0
root@Ubuntu ~# mkfs.xfs /dev/rbd0
root@Ubuntu ~# mkdir /home/jiuzhao/test
root@Ubuntu ~# mount /dev/rbd0 /home/jiuzhao/test
root@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 3306
LISTEN 0 4096 0.0.0.0:3306 0.0.0.0:*
root@Ubuntu ~# docker exec -it mysql-server /bin/bash
bash-4.4# mysql
Welcome 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-init
Creating snap: 100% complete...done.
root@Ceph01 ~# rbd snap ls kpyun/wordpress
SNAPID 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-server
mysql-server
root@Ubuntu ~# umount /home/jiuzhao/test
root@Ubuntu ~# rbd unmap kpyun/wordpress
root@Ubuntu ~# rbd showmapped | wc -l
0
# 回滚数据库块设备(服务端Ceph01)
root@Ceph01 ~# rbd snap rollback kpyun/wordpress@backup-init
Rolling back to snapshot: 100% complete...done.
# 客户端挂载,启动MySQL容器验证数据是否找回(客户端)
root@Ubuntu ~# rbd map kpyun/wordpress
/dev/rbd0
root@Ubuntu ~# mount /dev/rbd0 /home/jiuzhao/test
docker 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">
# 数据恢复

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

相关文章智能推荐
1
K8s故障排查 & 控制器与Service实战
Kubernetes故障排查三板斧describe/logs/exec与command&args,容器三种状态与pause基础架构容器,env环境变量部署WordPress,Deployment副本控制与滚动更新回滚,Service四类型ClusterIP/NodePort/LoadBalancer/ExternalName,kube-proxy+iptables底层实现,名称空间,CoreDNS服务发现与跨ns解析,deploy+svc部署WordPress及跨名称空间连库实战
2
K8s开篇 & kubeadm集群部署实战
KubernetesK8s核心概念与架构详解,基于kubeadm从零部署高可用集群,Flannel网络配置,Pod基础使用与YAML声明式管理
3
Prometheus 告警 && etcd 集群实战
Prometheus监控Alertmanager 告警路由/模板/静默/抑制 + 钉钉插件,etcd 3.7 TLS 高可用集群部署/备份恢复/Prometheus 监控,复用既有 kpyun CA 体系
4
Prometheus存储实战 && HTTPS认证 && 黑盒监控
Prometheus监控VictoriaMetrics单机部署+remote_write远端存储,Prometheus启用HTTPS+Basic Auth认证,node-exporter黑白名单,标签管理(relabel/metric_relabel),blackbox-exporter HTTP/ICMP/TCP黑盒探测,Grafana存储迁移到MySQL
5
Prometheus自定义监控 && 服务发现 && 联邦模式
Prometheus监控部署 pushgateway 实现短期任务/自定义指标的推送式监控(API 推送删除、honor_labels、TCP 12 状态、丢包率脚本),用 Go + client_golang 开发自定义 exporter(静态编译零依赖),落地 file_sd 与 consul 服务发现(consul 2.0.3 集群 + consul_exporter),最后用 3 台 Prometheus server 搭建联邦模式实现分布式采集汇总
Profile Image of the Author
久棹
不是先学好了再干,而是先干起来再学习,干中学!
分类
站点统计
文章
115
分类
15
标签
272
总字数
306,562
运行时长
0 天
最后活动
0 天前
文章目录