分布式存储系统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 网络
posted @ 2026-09-17 12:00  技术颜良  阅读(25)  评论(0)    收藏  举报