Ceph与Kubernetes深度集成:生产级存储解决方案

Ceph与Kubernetes深度集成:生产级存储解决方案


前言

随着容器化技术的普及,Kubernetes已成为企业云原生架构的标准平台。Ceph与Kubernetes的深度集成为容器化应用提供了强大的持久化存储能力。通过Ceph CSI(Container Storage Interface)驱动,Kubernetes可以原生使用Ceph的块存储(RBD)、文件系统存储(CephFS)和对象存储(RGW)。本教程将深入讲解Ceph CSI架构设计、部署配置、StorageClass优化、快照管理以及与主流云原生应用的集成实践,帮助你构建生产级的容器化存储解决方案。


1. Ceph CSI架构解析

1.1 CSI组件概述

Ceph CSI Driver是Kubernetes与Ceph集群之间的桥梁,提供标准化的存储接口:

| 组件 | 功能 | 部署位置 | |-----|------|---------| | rbd-plugin | 块存储(RBD)provisioner | 每个Node节点 | | cephfs-plugin | 文件系统存储(CephFS)provisioner | 每个Node节点 | | csi-provisioner | StorageClass动态provisioner | Controller Pod | | csi-attacher | 处理VolumeAttachment | Controller Pod | | csi-resizer | 存储卷扩容 | Controller Pod | | csi-snapshotter | 快照管理 | Controller Pod |

1.2 工作原理


Kubernetes PVC → StorageClass → CSI Provisioner → Ceph Cluster
     ↓                                                      ↓
VolumeAttachment → Node Stage → Mount/Format → Pod使用

2. Ceph CSI部署

2.1 前置条件


# 检查Kubernetes版本
kubectl version --client

# 确认内核版本(推荐5.4+)
uname -r

# 安装必要工具
apt-get install -y linux-headers-$(uname -r)

2.2 部署RBD CSI


# 克隆Ceph CSI仓库
git clone https://github.com/ceph/ceph-csi.git
cd ceph-csi/deploy

# 创建RBAC资源
kubectl apply -f rbd/kubernetes/csi-provisioner-rbac.yaml
kubectl apply -f rbd/kubernetes/csi-nodeplugin-rbac.yaml

# 创建CSI Driver
kubectl apply -f rbd/kubernetes/csi-rbdplugin.yaml
kubectl apply -f rbd/kubernetes/csi-rbdplugin-provisioner.yaml

# 验证部署
kubectl -n ceph-csi-rbd get pods

2.3 部署CephFS CSI


# 创建CephFS RBAC
kubectl apply -f cephfs/kubernetes/csi-provisioner-rbac.yaml
kubectl apply -f cephfs/kubernetes/csi-nodeplugin-rbac.yaml

# 创建CephFS Driver
kubectl apply -f cephfs/kubernetes/csi-cephfsplugin.yaml
kubectl apply -f cephfs/kubernetes/csi-cephfsplugin-provisioner.yaml

# 验证部署
kubectl -n ceph-csi-cephfs get pods

2.4 配置Ceph CSI连接


# csi-config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ceph-csi-config
data:
  config.json: |
    [
      {
        "clusterID": "ceph-cluster-id",
        "monitors": [
          "10.0.10.11:6789",
          "10.0.10.12:6789",
          "10.0.10.13:6789"
        ]
      }
    ]

# 应用配置
kubectl apply -f csi-config-map.yaml -n ceph-csi-rbd
kubectl apply -f csi-config-map.yaml -n ceph-csi-cephfs

3. StorageClass配置

3.1 RBD StorageClass


# storageclass-ceph-rbd.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: "ceph-cluster-id"
  pool: rbd
  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
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true

3.2 CephFS StorageClass


# storageclass-cephfs.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: cephfs
provisioner: cephfs.csi.ceph.com
parameters:
  clusterID: "ceph-cluster-id"
  fsName: cephfs
  csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/provisioner-secret-namespace: default
  csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/node-stage-secret-namespace: default
reclaimPolicy: Delete
volumeBindingMode: Immediate

3.3 创建存储密钥


# 创建RBD密钥
ceph auth get-or-create client.k8s-rbd \
    mon 'allow r' \
    mds 'allow r' \
    osd 'allow class-read object_prefix rbd_children, allow * pool=rbd' \
    -o /etc/ceph/ceph.client.k8s-rbd.keyring

# Base64编码
KEY=$(ceph auth get-key client.k8s-rbd)
echo $KEY | base64 -w 0

# 创建Secret
cat > csi-rbd-secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
type: Opaque
data:
  userID: Y2VwaC1rOHMtcmJk
  userKey: $(echo $KEY | base64 -w 0)
EOF

kubectl apply -f csi-rbd-secret.yaml

4. PVC使用示例

4.1 创建PVC


# pvc-example.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ceph-rbd-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: ceph-rbd

# 创建PVC
kubectl apply -f pvc-example.yaml

# 查看PVC状态
kubectl get pvc ceph-rbd-pvc
kubectl describe pvc ceph-rbd-pvc

4.2 在Pod中使用PVC


# pod-with-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-storage
spec:
  containers:
  - name: app
    image: nginx:latest
    volumeMounts:
    - name: storage
      mountPath: /data
    ports:
    - containerPort: 80
  volumes:
  - name: storage
    persistentVolumeClaim:
      claimName: ceph-rbd-pvc

# 部署Pod
kubectl apply -f pod-with-pvc.yaml

# 验证挂载
kubectl exec app-with-storage -- df -h /data

5. 存储卷扩容

5.1 启用扩容功能


# StorageClass需要启用allowVolumeExpansion
allowVolumeExpansion: true

5.2 在线扩容PVC


# 修改PVC大小
kubectl patch pvc ceph-rbd-pvc -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'

# 查看扩容状态
kubectl get pvc ceph-rbd-pvc -w

# 验证文件系统
kubectl exec app-with-storage -- df -h /data

6. 快照与恢复

6.1 VolumeSnapshotClass


# snapshotclass.yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: ceph-snapshot
driver: rbd.csi.ceph.com
parameters:
  clusterID: "ceph-cluster-id"
deletionPolicy: Delete

# 创建SnapshotClass
kubectl apply -f snapshotclass.yaml

6.2 创建快照


# volume-snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: ceph-rbd-snapshot
spec:
  volumeSnapshotClassName: ceph-snapshot
  source:
    persistentVolumeClaimName: ceph-rbd-pvc

# 创建快照
kubectl apply -f volume-snapshot.yaml

# 查看快照状态
kubectl get volumesnapshot ceph-rbd-snapshot

6.3 从快照恢复


# restore-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ceph-rbd-restored
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  dataSource:
    kind: VolumeSnapshot
    name: ceph-rbd-snapshot
  storageClassName: ceph-rbd

# 从快照创建PVC
kubectl apply -f restore-pvc.yaml

7. 高级配置

7.1 拓扑感知配置


# topology-aware.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd-topology
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: "ceph-cluster-id"
  pool: rbd
  topologyConstrainedTopology: |
    [
      {
        "kubernetes.io/hostname": "ceph-node01"
      }
    ]
volumeBindingMode: WaitForFirstConsumer

7.2 加密PVC


# encrypted-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd-encrypted
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: "ceph-cluster-id"
  pool: rbd
  encrypted: "true"
  encryptionKMS: "vault"
reclaimPolicy: Delete

7.3 QoS配置


# qos-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd-ssd
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: "ceph-cluster-id"
  pool: ssd-pool
  csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
  csi.storage.k8s.io/provisioner-secret-namespace: default
reclaimPolicy: Delete
volumeBindingMode: Immediate

8. 多租户隔离

8.1 Namespace隔离


# 为每个租户创建独立的Pool和Secret
ceph osd pool create tenant1-data 64 64
rbd pool init tenant1-data

# 创建租户密钥
ceph auth get-or-create client.tenant1 \
    mon 'allow r' \
    osd 'allow class-read object_prefix rbd_children, allow * pool=tenant1-data' \
    -o /etc/ceph/ceph.client.tenant1.keyring

# 为每个租户创建独立的StorageClass
kubectl create namespace tenant1

8.2 Quota管理


# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-storage-quota
  namespace: tenant1
spec:
  hard:
    persistentvolumeclaims: "10"
    requests.storage: "100Gi"

9. 监控与故障排查

9.1 CSI日志查看


# RBD CSI日志
kubectl -n ceph-csi-rbd logs -f csi-rbdplugin-provisioner-xxxxx
kubectl -n ceph-csi-rbd logs -f csi-rbdplugin-xxxxx -c driver-registrar

# CephFS CSI日志
kubectl -n ceph-csi-cephfs logs -f csi-cephfsplugin-provisioner-xxxxx

9.2 常见问题


# 问题1:PVC Pending
# 排查步骤
kubectl describe pvc 
kubectl get events --sort-by='.lastTimestamp'

# 问题2:Mount失败
# 排查步骤
kubectl describe pod 
kubectl logs  -c 

# 问题3:权限错误
# 检查Secret配置
kubectl get secret csi-rbd-secret -o yaml
ceph auth get client.k8s-rbd

9.3 健康检查


# CSI Driver健康检查
kubectl -n ceph-csi-rbd get pods
kubectl -n ceph-csi-cephfs get pods

# 存储类状态
kubectl get storageclass

# PVC状态汇总
kubectl get pvc --all-namespaces

10. 最佳实践

10.1 部署建议

| 配置项 | 建议值 | 说明 | |-------|-------|------| | RBD Pool | 独立专用 | 避免与其他工作负载混用 | | Pool Size | 3副本 | 保证数据可靠性 | | StorageClass数量 | 按需精简 | 避免过多配置 | | 快照保留 | 合理设置 | 控制存储空间 |

10.2 性能优化


# 1. 使用SSD Pool作为元数据
ceph osd pool create ssd-metadata 64 64
ceph osd tier add rbd-pool ssd-metadata --cache-mode writeback

# 2. 配置IO限流
ceph osd pool set rbd rbd_qos_iops_limit 5000

# 3. 调整CSI线程数
kubectl -n ceph-csi-rbd set env deployment/csi-rbdplugin-provisioner CSI_WORKER_THREADS=16

10.3 运维要点

1. 定期快照:设置自动快照策略保护数据 2. 容量监控:监控PVC使用量,设置告警 3. 密钥轮换:定期轮换CSI密钥 4. 版本兼容:保持CSI与Kubernetes版本兼容 5. 日志保留:配置CSI日志保留策略


总结

Ceph与Kubernetes的深度集成为云原生应用提供了企业级的持久化存储能力。通过Ceph CSI驱动,可以实现RBD块存储和CephFS文件存储的动态供应、快照恢复、在线扩容等高级功能。正确配置StorageClass、建立完善的监控告警体系、制定合理的快照策略,是构建生产级容器存储解决方案的关键。

关键要点: 1. 使用Ceph CSI原生驱动实现Kubernetes集成 2. 为不同工作负载配置专用的StorageClass 3. 启用快照功能保护关键数据 4. 持续监控CSI性能和存储使用情况 5. 保持CSI版本与Kubernetes版本匹配

发表回复

后才能评论