Ceph 存储运维完全指南 / 05 - 块存储 RBD
05 - 块存储 RBD
5.1 RBD 概述
RBD(RADOS Block Device) 是 Ceph 提供的块存储接口,可将 Ceph 集群的存储能力以块设备的形式呈现给客户端。RBD 是 OpenStack Cinder、Kubernetes RBD CSI 等云平台的核心存储后端。
RBD 核心特性
| 特性 | 说明 |
|---|---|
| 精简配置(Thin Provisioning) | 按需分配空间,创建 100G 镜像不立即占用物理空间 |
| 快照(Snapshot) | 秒级创建快照,支持回滚 |
| 克隆(Clone) | 基于快照创建 Copy-on-Write 克隆 |
| 分层(Layering) | 支持多层快照和克隆链 |
| 动态调整 | 在线扩容镜像大小 |
| 条带化(Striping) | 数据分散到多个 OSD 提升性能 |
| KRBD | Linux 内核 RBD 驱动,直接映射为 /dev/rbd* |
| QEMU 集成 | QEMU/KVM 虚拟机直接使用 RBD 作为磁盘 |
RBD 与其他块存储对比
| 特性 | Ceph RBD | iSCSI SAN | 本地 LVM |
|---|---|---|---|
| 分布式 | ✅ | ✅(集中式) | ❌ |
| 精简配置 | ✅ | 部分 | ✅ |
| 快照/克隆 | ✅ 原生 | 厂商实现 | LVM 快照 |
| 在线迁移 | ✅ | ✅ | ❌ |
| 性能 | 高 | 中 | 极高 |
| 可靠性 | 高(多副本) | 高(RAID) | 低(单机) |
| 扩展性 | 线性扩展 | 受限 | 受限 |
5.2 RBD 镜像管理
前置准备
# 创建 RBD 专用存储池
ceph osd pool create rbd 256 256 replicated
ceph osd pool set rbd min_size 2
# 初始化 RBD 池(创建 RBD 头信息)
rbd pool init rbd
创建镜像
# 创建 10GB 镜像
rbd create rbd/myimage --size 10G
# 创建带特定对象大小的镜像(默认 4MB)
rbd create rbd/myimage --size 100G --object-size 4M
# 创建带条带化的镜像(提升大文件顺序读写性能)
rbd create rbd/fastimage --size 100G --stripe-unit 4096K --stripe-count 16
# 创建镜像并指定特性
rbd create rbd/myimage --size 50G --image-feature layering,exclusive-lock,object-map,fast-diff
# 查看镜像列表
rbd ls rbd
# 查看镜像详细信息
rbd info rbd/myimage
输出示例:
rbd image 'myimage':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 12345678-abcd-efgh-ijkl-123456789abc
block_name_prefix: rbd_data.12345678
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Mon May 10 10:00:00 2026
access_timestamp: Mon May 10 10:00:00 2026
modify_timestamp: Mon May 10 10:00:00 2026
RBD 镜像特性
| 特性 | 说明 | 推荐 |
|---|---|---|
| layering | 支持分层克隆 | ✅ 必选 |
| striping | 条带化写入 | 按需 |
| exclusive-lock | 独占锁,防止并发写入 | ✅ 推荐 |
| object-map | 对象映射,加速快照和克隆 | ✅ 推荐 |
| fast-diff | 快速计算差异 | ✅ 推荐 |
| deep-flatten | 克隆展平后无依赖 | ✅ 推荐 |
| journaling | 写入日志,支持 RBD Mirror | 按需 |
| data-pool | 数据存储到单独的 EC 池 | 按需 |
# 查看默认特性
rbd feature list
# 启用/禁用特性
rbd feature enable rbd/myimage exclusive-lock
rbd feature disable rbd/myimage journaling
镜像大小调整
# 在线扩容(只能扩大不能缩小)
rbd resize rbd/myimage --size 200G
# 确认调整后的大小
rbd info rbd/myimage | grep size
# 客户端侧需要通知文件系统
# Linux 客户端
sudo resize2fs /dev/rbd0 # ext4
sudo xfs_growfs /dev/rbd0 # xfs
删除镜像
# 删除镜像
rbd rm rbd/myimage
# 如果有快照,需要先删除快照,或使用 --force
rbd rm rbd/myimage --force # 删除所有快照和镜像
5.3 快照(Snapshot)管理
创建和管理快照
# 创建快照
rbd snap create rbd/myimage@snap1
rbd snap create rbd/myimage@snap2
# 列出快照
rbd snap ls rbd/myimage
# 回滚到快照(需要先 unmap)
rbd snap rollback rbd/myimage@snap1
# 删除单个快照
rbd snap rm rbd/myimage@snap1
# 删除所有快照
rbd snap purge rbd/myimage
# 保护快照(克隆前必须保护)
rbd snap protect rbd/myimage@snap1
# 取消保护
rbd snap unprotect rbd/myimage@snap1
快照原理
原始镜像 (10G)
┌─────────────────────────────────────────┐
│ Object 0 │ Object 1 │ ... │ Object 2559│
└─────────────────────────────────────────┘
创建快照 @snap1(瞬间完成,仅记录元数据)
┌─────────────────────────────────────────┐
│ snap1 → 指向当前所有对象的版本 │
└─────────────────────────────────────────┘
修改 Object 0(Copy-on-Write,原版本保留给 snap1)
┌─────────────────────────────────────────┐
│ Object 0'│ Object 1 │ ... │Object 2559 │ ← myimage(新版本)
│ Object 0 │ │ ← snap1 仍指向旧版本
└─────────────────────────────────────────┘
5.4 克隆(Clone)
创建克隆流程
# 步骤 1:创建源镜像
rbd create rbd/base-image --size 50G
# 步骤 2:写入一些数据(模拟已安装操作系统的镜像)
sudo rbd map rbd/base-image
sudo mkfs.ext4 /dev/rbd0
sudo mount /dev/rbd0 /mnt
echo "Base OS data" | sudo tee /mnt/important.txt
sudo umount /mnt
sudo rbd unmap /dev/rbd0
# 步骤 3:创建快照并保护
rbd snap create rbd/base-image@v1.0
rbd snap protect rbd/base-image@v1.0
# 步骤 4:基于快照创建克隆(Copy-on-Write,秒级完成)
rbd clone rbd/base-image@v1.0 rbd/vm001-disk
rbd clone rbd/base-image@v1.0 rbd/vm002-disk
rbd clone rbd/base-image@v1.0 rbd/vm003-disk
# 查看克隆关系
rbd children rbd/base-image@v1.0
# 输出:
# rbd/vm001-disk
# rbd/vm002-disk
# rbd/vm003-disk
# 查看克隆的 parent 信息
rbd info rbd/vm001-disk
克隆链与展平
base-image → @v1.0 (protected)
├── vm001-disk (clone)
├── vm002-disk (clone)
└── vm003-disk (clone)
vm001-disk 写入数据时:
1. 检查对象是否已存在于 vm001-disk
2. 不存在 → 从 base-image@v1.0 复制
3. 在 vm001-disk 中修改
4. 后续读写直接在 vm001-disk 中操作
# 展平克隆(断开与 parent 的依赖,独立存在)
rbd flatten rbd/vm001-disk
# 展平后 parent 关系消失
rbd info rbd/vm001-disk | grep parent
# 无输出
注意事项:
- 克隆镜像依赖 parent 快照,展平前不能删除 parent
- 生产环境建议展平后再使用,避免性能影响
- 展平操作会复制所有未修改的对象,可能产生大量 I/O
5.5 KRBD 内核映射
KRBD(Kernel RBD) 将 RBD 镜像映射为本地块设备。
# 映射 RBD 镜像到本地
sudo rbd map rbd/myimage
# 输出: /dev/rbd0
# 查看已映射的设备
rbd showmapped
# 输出:
# id pool namespace image snap device
# 0 rbd myimage - /dev/rbd0
# 使用映射的设备
sudo mkfs.ext4 /dev/rbd0
sudo mount /dev/rbd0 /mnt
echo "Hello from Ceph RBD" | sudo tee /mnt/test.txt
df -h /mnt
# 取消映射
sudo umount /mnt
sudo rbd unmap /dev/rbd0
指定 Ceph 集群连接信息
# 使用自定义配置
sudo rbd map rbd/myimage --conf /etc/ceph/ceph.conf --keyring /etc/ceph/ceph.client.admin.keyring
# 使用特定用户
sudo rbd map rbd/myimage --id myuser --keyring /etc/ceph/ceph.client.myuser.keyring
# 指定 monitor 地址(无配置文件时)
sudo rbd map rbd/myimage --mon-host 192.168.1.10,192.168.1.11,192.168.1.12
KRBD 性能调优
# 调整队列深度
echo 128 | sudo tee /sys/bus/rbd/devices/rbd0/queue_depth
# 调整读取预取
echo 8388608 | sudo tee /sys/bus/rbd/devices/rbd0/read_ahead_bytes # 8MB
# 内核模块参数
sudo modprobe rbd read_ahead_kb=4096
5.6 QEMU/KVM 虚拟机集成
QEMU 直接使用 RBD
# 创建虚拟机磁盘
qemu-img create -f rbd rbd/vm-disk 50G
# 查看 RBD 上的虚拟机磁盘
qemu-img info -f rbd rbd/vm-disk
# 启动虚拟机(直接使用 RBD)
qemu-system-x86_64 \
-m 4G \
-smp 4 \
-drive file=rbd:vms/vm-disk,id=drive0,if=none,cache=writeback \
-device virtio-blk-pci,drive=drive0 \
-cdrom /path/to/install.iso \
-boot d
Libvirt/QEMU 配置
<!-- /etc/libvirt/qemu.conf -->
# 使用 Ceph 认证
# ceph 用户名和密钥文件路径
# 创建 libvirt secret(用于存储 Ceph 密钥)
cat > /tmp/secret.xml <<EOF
<secret ephemeral='no' private='no'>
<usage type='ceph'>
<name>libvirt ceph secret</name>
</usage>
</secret>
EOF
virsh secret-define --file /tmp/secret.xml
# 输出: Secret xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx created
# 设置密钥值
CEPH_KEY=$(ceph auth get-key client.admin)
virsh secret-set-value --secret xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --base64 $CEPH_KEY
Libvirt 域 XML 示例
<disk type='network' device='disk'>
<driver name='qemu' type='raw' cache='writeback'/>
<auth username='admin'>
<secret type='ceph' uuid='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'/>
</auth>
<source protocol='rbd' name='vms/vm-disk'>
<host name='192.168.1.10' port='6789'/>
<host name='192.168.1.11' port='6789'/>
<host name='192.168.1.12' port='6789'/>
</source>
<target dev='vda' bus='virtio'/>
</disk>
5.7 RBD Mirror(异地复制)
RBD Mirror 支持在两个 Ceph 集群间异步复制镜像,用于灾备。
# === 主集群操作 ===
# 启用 journaling 特性
rbd feature enable rbd/myimage journaling
# 配置 peer 集群
rbd mirror pool peer add rbd client@backup-cluster
# 启用池级别的 mirror
rbd mirror pool enable rbd pool
# 启用镜像级别的 mirror
rbd mirror image enable rbd/myimage
# === 备份集群操作 ===
# 同样启用 mirror
rbd mirror pool enable rbd pool
# 启动 rbd-mirror 守护进程
systemctl enable --now ceph-rbd-mirror@backup
# 查看 mirror 状态
rbd mirror pool status rbd
5.8 业务场景:OpenStack 集成
# 为 OpenStack 创建专用池
ceph osd pool create volumes 256 256 replicated
ceph osd pool create images 128 128 replicated
ceph osd pool create backups 128 128 replicated
ceph osd pool create vms 256 256 replicated
# 初始化 RBD
rbd pool init volumes
rbd pool init images
rbd pool init backups
rbd pool init vms
# 创建 OpenStack 专用用户
ceph auth get-or-create client.openstack \
mon 'profile rbd' \
osd 'profile rbd pool=volumes, profile rbd pool=images, profile rbd pool=backups, profile rbd pool=vms' \
mgr 'profile rbd pool=volumes, profile rbd pool=images, profile rbd pool=backups, profile rbd pool=vms'
# 输出密钥文件
ceph auth get-key client.openstack
扩展阅读
下一章:06 - 文件存储 CephFS — 学习 CephFS 文件系统的部署、挂载、子卷、快照和多活 MDS 配置。