Kubernetes 中使用 Ceph RBD(RADOS Block Device)作为动态存储后端,通过 StorageClass 实现 PersistentVolumeClaim (PVC) 的动态创建 PV(PersistentVolume),这是最常见的生产级块存储方案。重要提示(2025 年现状):

  • Kubernetes in-tree(内置)RBD 驱动(kubernetes.io/rbd)已废弃,不再维护。
  • 官方推荐使用 Ceph CSI 驱动(rbd.csi.ceph.com),支持动态 provisioning、扩展、快照、克隆等高级功能。
  • 如果使用 Rook-Ceph,CSI 驱动会自动部署并集成。

下面是完整配置步骤(以 Ceph CSI 驱动为例):1. 前置条件

  • Ceph 集群已运行(至少 3 个 Monitor 和 OSD)。
  • Kubernetes 集群版本 ≥ 1.21(推荐 ≥ 1.25)。
  • 所有 Worker 节点已安装 Ceph 客户端(ceph-common 包)。
  • 创建 Ceph 专用 Pool 并初始化:bashceph osd pool create kubernetes 128 128 replicated rbd pool init kubernetes ceph osd pool application enable kubernetes rbd

2. 创建 Ceph 用户权限(推荐使用独立用户)

bash

ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes' -o /etc/ceph/client.kubernetes.keyring

3. 创建 Kubernetes Secret(CSI 认证用)

yaml

apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: default   # 或 kube-system,根据你的 CSI 部署命名空间
stringData:
  userID: kubernetes
  userKey: AQ...==   # 从 client.kubernetes.keyring 中提取 base64 编码后的 key
type: kubernetes.io/rbd

bash

kubectl apply -f csi-rbd-secret.yaml

4. 创建 Ceph CSI ConfigMap(连接 Ceph 集群)

yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: ceph-csi-config
  namespace: default
data:
  config.json: |-
    [
      {
        "clusterID": "your-ceph-cluster-fsid",   # ceph fsid
        "monitors": [
          "mon1:6789",
          "mon2:6789",
          "mon3:6789"
        ]
      }
    ]

bash

kubectl apply -f ceph-csi-config.yaml

5. 创建 StorageClass(动态生成 PV 的核心)

yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"   # 可选:设为默认 SC
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: your-ceph-cluster-fsid                 # 与 ConfigMap 中的一致
  pool: kubernetes                                  # 你的 Ceph Pool 名称
  imageFeatures: layering                           # 必须包含 layering 支持克隆
  csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
  csi.storage.k8s.io/provisioner-secret-namespace: default
  csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
  csi.storage.k8s.io/node-stage-secret-namespace: default
  csi.storage.k8s.io/fstype: ext4                   # 或 xfs
reclaimPolicy: Delete                               # 或 Retain
allowVolumeExpansion: true                          # 启用在线扩展 PVC
mountOptions:
  - discard                                         # 可选:TRIM 支持
volumeBindingMode: Immediate                        # 或 WaitForFirstConsumer(拓扑感知)

bash

kubectl apply -f ceph-rbd-sc.yaml

6. 创建 PVC(自动触发动态 PV 创建)

yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ceph-rbd-pvc
spec:
  accessModes:
    - ReadWriteOnce   # RBD 只支持 RWO
  resources:
    requests:
      storage: 10Gi
  storageClassName: ceph-rbd

bash

kubectl apply -f ceph-rbd-pvc.yaml

7. 使用 PVC 创建 Pod

yaml

apiVersion: v1
kind: Pod
metadata:
  name: ceph-rbd-pod
spec:
  containers:
  - name: test-container
    image: busybox
    command: ["/bin/sh", "-c", "sleep 3600"]
    volumeMounts:
    - mountPath: /data
      name: rbd-volume
  volumes:
  - name: rbd-volume
    persistentVolumeClaim:
      claimName: ceph-rbd-pvc

bash

kubectl apply -f ceph-rbd-pod.yaml

8. 验证

bash

kubectl get pv,pvc,sc
kubectl get pod ceph-rbd-pod
kubectl exec -it ceph-rbd-pod -- df -h /data

常见问题排查

问题可能原因解决方法
PVC 卡在 PendingProvisioner 未就绪、Secret 错误、Pool 不存在检查 kubectl get pod -n <csi-ns> 日志
扩展失败未设置 allowVolumeExpansion: true修改 SC 并重启 CSI Pod
节点无法 mount缺少 ceph-common 或内核模块确保节点安装 ceph-common 和 rbd 模块
权限问题userKey 错误或权限不足检查 Ceph 用户权限(ceph auth get client.kubernetes)

推荐:使用 Rook-Ceph 简化部署如果你的 Ceph 是用 Rook 部署的,只需创建 CephBlockPool CRD,Rook 会自动创建 StorageClass: “`yaml apiVersion: ceph.rook.io/v1 kind: CephBlockPool metadata: name: kubernetes-pool namespace: rook-ceph spec: failureDomain: host replicated: size: 3Rook 会自动生成 StorageClass: rook-ceph-block


然后直接在 PVC 中引用 `storageClassName: rook-ceph-block` 即可。

这样就完成了基于 StorageClass 的 Ceph RBD 动态 PV 生成!如果有具体的 Ceph 版本、Rook 版本或报错信息,贴出来我可以帮你进一步调试。