分布式存储系统Ceph:块存储 RBD(ok)
RBD(Rados Block Device)是 Ceph 提供的块设备,最常用作 VM 磁盘、K8s 持久化卷。本篇讲清创建、映射、快照、K8s 集成。
一、RBD 是什么?
RBD = RADOS Block Device
- • 一个网络块设备
- • 客户端用
librbd访问 RADOS - • 块设备上可以建任何文件系统(xfs / ext4 / btrfs)
- • 多个客户端共享时需要 CephFS 或 iSCSI 包装
核心优势:
- • 无限扩展(pool 容量即 RBD 容量)
- • 快照(秒级、几乎免费)
- • 克隆(写时复制)
- • 多副本(默认 3 份)
二、创建和使用 RBD
2.1 创建 pool
# 创建 rbd pool
$ ceph osd pool create rbd-pool 64
# ^^ pg_num
# 启用 rbd 应用
$ ceph osd pool application enable rbd-pool rbd
# 初始化 pool
$ rbd pool init -p rbd-pool
2.2 创建 image
# 基本
$ rbd create my-image --size 1G --pool rbd-pool
# 高级选项
$ rbd create my-image --size 1G \
--pool rbd-pool \
--image-feature layering,exclusive-lock,object-map,fast-diff,deep-flatten \
--data-pool rbd-pool \
--object-size 4M
# 看
$ rbd ls -p rbd-pool
my-image
# 详细信息
$ rbd info my-image -p rbd-pool
rbd image 'my-image':
size 1 GiB in 256 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: ...
block_name_prefix: rbd_data.XXX
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: ...
access_timestamp: ...
modify_timestamp: ...
2.3 调整大小
# 扩容
$ rbd resize my-image --size 2G -p rbd-pool
# 缩容(注意:先缩 FS 再缩 RBD)
$ rbd resize my-image --size 1G -p rbd-pool --allow-shrink
2.4 客户端映射
方法 1:内核模块(推荐 KVM 用)
# 1. 映射
$ sudo rbd map my-image -p rbd-pool
# 2. 看
$ lsblk /dev/rbd0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
rbd0 252:0 0 1G 0 disk
# 3. 格式化
$ sudo mkfs.xfs /dev/rbd0
# 4. 挂载
$ sudo mount /dev/rbd0 /mnt
# 5. 写数据
$ sudo echo "hello rbd" > /mnt/test.txt
# 6. 取消映射
$ sudo umount /mnt
$ sudo rbd unmap /dev/rbd0
方法 2:NBD(无需内核模块)
# 1. 装 nbd
$ sudo apt install -y nbd-client
# 2. 加载 nbd 模块
$ sudo modprobe nbd
# 3. 映射
$ sudo rbd-nbd map my-image -p rbd-pool
# 4. 看
$ lsblk /dev/nbd0
# 5. 格式化挂载(同上)
方法 3:FUSE
# 装 rbd-fuse
$ sudo apt install -y rbd-fuse
$ sudo rbd-fuse -p rbd-pool /mnt/rbd
2.5 持久化挂载
# /etc/fstab
# 内核模块方式
/dev/rbd/rbd-pool/my-image /mnt xfs _netdev,noauto,x-systemd.requires=ceph.target 0 0
三、RBD 快照
3.1 创建快照
# 拍快照
$ rbd snap create my-image@snap1 -p rbd-pool
# 看
$ rbd snap ls my-image -p rbd-pool
SNAPID NAME SIZE PROTECTED TIMESTAMP
1 snap1 1 GiB ...
3.2 回滚
# 警告:先卸载!
$ sudo umount /mnt
# 回滚
$ rbd snap rollback my-image@snap1 -p rbd-pool
# 重新挂载
$ sudo mount /dev/rbd0 /mnt
3.3 删快照
$ rbd snap rm my-image@snap1 -p rbd-pool
四、RBD 克隆
4.1 创建克隆
# 1. 保护快照
$ rbd snap protect my-image@snap1 -p rbd-pool
# 2. 克隆
$ rbd clone my-image@snap1 my-clone -p rbd-pool
# 3. 看
$ rbd ls -p rbd-pool
my-image
my-clone
克隆是写时复制的:
- • 没修改的 block 共享源 image
- • 修改时复制到新位置
4.2 flatten 克隆
# 把克隆从源解耦
$ rbd flatten my-clone -p rbd-pool
flatten 后克隆独立,但失去"与源共享"的好处。
五、KVM 集成
5.1 用 RBD 作为 VM 磁盘
# 用 librbd(推荐)
$ virt-install \
--name vm-001 \
--ram 4096 \
--vcpus 4 \
--disk vol=rbd-pool/vm-001,format=raw,bus=virtio,size=50 \
--cdrom /iso/ubuntu.iso \
--os-variant ubuntu22.04 \
--network bridge=br0
关键:
format=raw+rbd:路径 → 直接走 librbd,性能最好。
5.2 用 libvirt 管理
# 1. 定义 secret(一次性)
$ cat > secret.xml << EOF
<secret ephemeral='no' private='no'>
<usage type='ceph'>
<name>client.admin secret</name>
</usage>
</secret>
EOF
$ sudo virsh secret-define secret.xml
$ sudo virsh secret-set-value <secret-uuid> $(sudo cat /etc/ceph/ceph.client.admin.keyring | grep key | awk '{print $3}')
# 2. 启动 VM
$ sudo virsh start vm-001
5.3 性能调优
# KVM 内使用 virtio
<disk type='network' device='disk'>
<driver name='qemu' type='raw' cache='writeback' io='native'/>
<source protocol='rbd' name='rbd-pool/vm-001'>
<host name='node01' port='6789'/>
</source>
<target dev='vda' bus='virtio'/>
</disk>
六、K8s 集成
6.1 Rook 部署(推荐)
# 1. 装 Rook Operator
$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-1.13/deploy/examples/crds.yaml
$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-1.13/deploy/examples/common.yaml
$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-1.13/deploy/examples/operator.yaml
# 2. 部署 Ceph cluster
$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-1.13/deploy/examples/cluster.yaml
6.2 StorageClass
$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-1.13/deploy/examples/csi/rbd/storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/node-publish-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
reclaimPolicy: Delete
volumeBindingMode: Immediate
6.3 创建 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: rook-ceph-block
resources:
requests:
storage: 10Gi
$ kubectl apply -f pvc.yaml
$ kubectl get pvc rbd-pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
rbd-pvc Bound pvc-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 10Gi RWO
6.4 Pod 用 PVC
apiVersion: v1
kind: Pod
metadata:
name: rbd-pod
spec:
containers:
- name: app
image: ubuntu:22.04
volumeMounts:
- name: rbd-vol
mountPath: /data
command: ["sleep", "infinity"]
volumes:
- name: rbd-vol
persistentVolumeClaim:
claimName: rbd-pvc
七、rbd 高级特性
7.1 镜像格式
| 格式 | 特性 | 适用 |
|---|---|---|
| 1 | 旧 | 不推荐 |
| 2(默认) | 支持快照、克隆 | 推荐 |
7.2 Feature 标志
# 创建时指定
$ rbd create my-image \
--image-feature layering,exclusive-lock,object-map,fast-diff,deep-flatten \
-p rbd-pool
# 启用 deep-flatten(防止克隆层级过深)
$ rbd feature enable my-image deep-flatten -p rbd-pool
7.3 数据校验
RBD 写入时会计算 CRC32 校验和,读出时校验。
7.4 块大小
# 4M(默认)或自定义
$ rbd create my-image --object-size 8M -p rbd-pool
八、监控与维护
8.1 看 RBD 信息
# 所有 image
$ rbd ls -p rbd-pool
# 详情
$ rbd info my-image -p rbd-pool
# 看使用
$ rbd du my-image -p rbd-pool
NAME PROVISIONED USED
my-image 1 GiB 1 GiB
8.2 性能监控
# 在 OSD 节点看 IO
$ iostat -x 1
# 看 librbd 客户端
$ rbd perf image stats my-image -p rbd-pool
# 或
$ rbd perf image iostat my-image -p rbd-pool
九、常见问题
1. "rbd: image uses unsupported features"
# 错误:客户端 OSD 太旧不支持新 features
# 解决 1:升级客户端
$ sudo apt update && sudo apt install -y ceph-common
# 解决 2:创建时禁用新 features
$ rbd create my-image --image-feature layering -p rbd-pool
2. "rbd: map failed: (6) No such device or address"
# 检查
$ sudo rbd map my-image -p rbd-pool --debug
# 看具体错误
# 常见:网络不通
$ telnet mon-host 6789
3. "Input/output error"
# 看 OSD 状态
$ ceph -s
$ ceph osd tree
# 看 PG 状态
$ ceph pg stat
4. 客户端连接 RBD 但性能差
# 1. 用 rbd cache
$ rbd feature enable my-image exclusive-lock -p rbd-pool
# 2. /etc/ceph/ceph.conf
[client]
rbd cache = true
rbd cache writethrough until flush = true
rbd cache size = 33554432
rbd cache max dirty = 25165824
# 3. 网络优化
# - 客户端和 mon 在同一 AZ
# - 10G 网络
# - 分离 cluster/public 网络
十、本篇小结
| 操作 | 命令 |
|---|---|
| 创建 image | rbd create my-image --size 1G -p rbd-pool |
| 映射 | rbd map my-image -p rbd-pool |
| 取消映射 | rbd unmap /dev/rbd0 |
| 拍快照 | rbd snap create my-image@snap1 -p rbd-pool |
| 克隆 | rbd clone my-image@snap1 my-clone -p rbd-pool |
| 扩容 | rbd resize my-image --size 2G -p rbd-pool |
K8s 集成:
- • Rook 部署 Ceph
- •
StorageClass: rook-ceph-block - •
PVC→PV→Pod mount
性能优化:
- •
format=raw+librbd - •
cache writeback+io native - • virtio 驱动
- • 10G 网络

浙公网安备 33010602011771号