跳转到内容

Ceph / Rook 面试题

30 道题
分类
存储
题目数
30 道
已阅读 0 / 30 题
1 Ceph 的核心架构组件

答案:

Ceph 是统一分布式存储系统,以 RADOS(Reliable Autonomic Distributed Object Store)为底层对象存储层,向上提供块存储、文件存储和对象存储三种接口。核心组件包括:

组件全称职责
MONMonitor维护集群 Map(Monitor Map / OSD Map / PG Map / CRUSH Map / MDS Map),通过 Paxos 协议保证强一致性
OSDObject Storage Daemon负责数据存储、复制、恢复、再平衡,直接与磁盘交互,一个磁盘对应一个 OSD 进程
MDSMetadata Server维护 CephFS 的目录树和文件元数据(inode / dentry),允许将元数据与数据分离以提升性能
RGWRADOS Gateway提供 S3 / Swift 兼容的对象存储 RESTful 接口,基于 librgw 将 HTTP 请求转换为 RADOS 操作
MGRManager收集集群运行时指标(PG 状态 / 磁盘利用率 / 性能计数器),提供 Dashboard / Prometheus / RESTful 管理接口

架构分层

应用层        RBD (块设备)   CephFS (文件系统)   RGW (对象存储)
              ──────────────────────────────────────────
内核/用户态   librbd          libcephfs         librgw
              ──────────────────────────────────────────
底层存储      RADOS (librados)
              ──────────────────────────────────────────
              MON 集群 (Paxos)  +  OSD 集群 (CRUSH)

集群 Map 的分发与 Epoch 机制

MON 集群维护全局一致的多份 Map 副本。每个 Map 带有递增 epoch 版本号。客户端携带自身 epoch 发起 I/O 时,OSD 若检测到 epoch 落后,拒绝写入并返回最新 Map,避免向已下线的 OSD 写入脏数据。整个过程无需全局锁。

2 Ceph 的 CRUSH 算法与数据分布

答案:

CRUSH(Controlled Replication Under Scalable Hashing)是 Ceph 的伪随机数据分布算法,取代传统中心化元数据查询,客户端可直接计算数据存储位置,实现去中心化 I/O。

核心机制

  • CRUSH Map:描述集群拓扑层级(Root -> Datacenter -> Room -> Row -> Rack -> Host -> OSD),每个节点附有权重。
  • CRUSH Rule:定义数据的故障域放置策略,如 replicated_rule 指定 3 副本分布在不同 Host 上。
  • Hash 计算:对象名 -> Hash -> PG -> CRUSH Rule -> OSD 集合,全程确定性计算,无需查询元数据表。
  • Bucket 类型:Uniform / List / Tree / Straw / Straw2,推荐 Straw2,OSD 增减时迁移量最小。

CRUSH Rule 示例

rule replicated_rule {
    id 0
    type replicated
    min_size 1
    max_size 10
    step take default
    step chooseleaf firstn 0 type host  // 选择不同 Host 上的 OSD
    step emit
}

与传统中心化方案的对比

维度CRUSH传统元数据服务器
扩展性无中心瓶颈,随 OSD 线性扩展元数据服务器成为瓶颈
故障域天然支持多层故障域隔离需额外规划
数据迁移增减 OSD 仅迁移必要数据依赖中心调度
I/O 路径客户端直连 OSD,无中间跳转需经元数据服务器
3 Ceph 的 PG(Placement Group)机制

答案:

PG 是 Ceph 数据管理的逻辑粒度单位,介于对象(Object)和 OSD 之间,用于聚合 OSD 故障检测、复制、恢复和再平衡等操作,避免以对象为最小单位导致元数据爆炸。

层级关系

Pool (逻辑存储池)
  └── PG (Placement Group)
        └── Object (实际存储对象)

关键概念

  • PG 数量公式Total PGs = (OSDs × 100) / Replica_Size,单 OSD 承载 100~200 PG 为推荐区间。
  • PG 状态active+clean(正常)、degraded(副本不全)、peering(PG 内 OSD 协商状态)、recovering(数据恢复中)、backfilling(数据回填)、stale(MON 超时未收到 OSD 上报)。
  • PGP(PG Placement):控制 PG 到 OSD 的映射,PGP 总数应与 PG 总数保持一致,否则数据分布不均。
  • Peering 过程:PG 内 OSD 通过互相交换日志(PG Log)协商权威副本,达成一致后开始恢复。

PG 分裂(Split)

当 Pool 的 pg_num 增大时,原有 PG 分裂为多个新 PG。分裂过程中会产生大量数据迁移,应在业务低峰操作,分多次小幅增加。

4 Ceph 的 BlueStore 存储引擎

答案:

BlueStore 从 Ceph Luminous(v12.x)起成为默认存储引擎,专为 SSD / NVMe 设计,废弃了传统 FileStore 的 POSIX 文件系统中间层,直接管理裸盘。

架构组成

组件存储内容存储介质
RocksDB对象元数据、PG 日志、WAL、Omap、分配器元数据高速介质(NVMe / SSD)
BlueFSRocksDB 的轻量文件系统同 RocksDB 介质
Block Device实际对象数据主存储设备(HDD / SSD / NVMe)

WAL 与 DB 设备分离策略

配置 (bluestore)                         rocksdb WAL     rocksdb DB     对象数据
────────────────────────────────────────────────────────────────────────────
仅主盘                                   主盘             主盘             主盘
主盘 + DB/WAL 分区                       主盘独立分区      主盘独立分区      主盘
主盘 + 独立 SSD                           独立 SSD         独立 SSD         主盘
主盘 + 独立 WAL (NVMe) + 独立 DB (SSD)     独立 NVMe        独立 SSD         主盘

性能对比

维度BlueStoreFileStore
写放大天然双写(WAL + Data),无文件系统日志开销文件系统日志 + OSD 日志,三重写入
元数据管理RocksDB 键值存储,高效文件系统 xattr 或 LevelDB,受限于 POSIX
校验端到端 checksum依赖文件系统
SSD 优化原生支持,直接管理裸设备受文件系统抽象层限制
GC / 压缩RocksDB 后台 Compaction依赖文件系统

BlueStore 延迟优化参数

[osd]
bluestore_cache_size_hdd = 4GB       # HDD OSD 缓存
bluestore_cache_size_ssd = 4GB       # SSD OSD 缓存
bluestore_cache_trim_interval = 0.05 # Trim 间隔
bluestore_throttle_cost_per_io = 1.5 # I/O 节流系数
5 Rook 的架构与核心 CRD

答案:

Rook 是 CNCF 毕业项目,将 Ceph 编排为 Kubernetes 原生存储解决方案。Rook Operator 自动处理部署、配置、扩展、升级和灾难恢复。

核心架构组件

graph TD
    subgraph RookOperator["Rook Operator"]
        CC["Cluster\nController"]
        BC["Block\nController"]
        FC["Filesys\nController"]
        OC["Object\nController"]
    end
    subgraph RookAgent["Rook Agent - DaemonSet"]
        Agent["每节点运行,管理 OSD / 设备发现 / 配置注入"]
    end
    subgraph CephPods["Ceph 守护进程 Pod"]
        MON["MON Pod"]
        OSD["OSD Pod"]
        MDS["MDS Pod"]
        RGW["RGW Pod"]
        MGR["MGR Pod"]
    end
    subgraph CSI["CSI 驱动 Pod"]
        RBD["RBD CSI Plugin"]
        CephFS["CephFS CSI Plugin"]
    end
    RookOperator --> RookAgent
    RookAgent --> CephPods
    CephPods --> CSI

核心 CRD

CRDAPI Group职责
CephClusterceph.rook.io/v1定义 Ceph 集群全局配置:版本、MON 数量、网络、存储、Dashboard、监控
CephBlockPoolceph.rook.io/v1定义 RBD 块存储池:副本数、故障域、PG 数量、QoS
CephBlockPoolRadosNamespaceceph.rook.io/v1定义 RBD 池下的 RADOS Namespace,实现多租户隔离
CephFilesystemceph.rook.io/v1定义 CephFS 文件系统:MDS 数量、池配置、保留策略
CephFilesystemSubVolumeGroupceph.rook.io/v1定义 CephFS SubVolumeGroup,NFS-Ganesha 导出单元
CephObjectStoreceph.rook.io/v1定义 RGW 对象存储:实例数、端口、TLS 证书、Multi-Site
CephObjectStoreUserceph.rook.io/v1定义 RGW 用户及 S3 凭据
CephClientceph.rook.io/v1为外部消费方生成 ceph.conf 和 keyring
CephNFSceph.rook.io/v1定义 NFS-Ganesha 导出,基于 RGW 或 CephFS 后端
CephRBDMirrorceph.rook.io/v1定义 RBD 异步镜像复制

Operator 协调循环

Rook Operator Watch CRD -> 读取期望状态 Spec -> 对比集群实际状态 -> 生成 Ceph 原生配置 -> 通过 Ceph 命令行工具或守护进程 API 执行变更 -> 更新 Status。

6 Rook CephCluster 的部署与配置

答案:

Rook CephCluster 的部署分为 Operator 安装和 CephCluster CR 创建两个阶段。

部署流程

# 1. 克隆 Rook 仓库,部署 Operator
git clone --single-branch --branch v1.14.0 https://github.com/rook/rook.git
kubectl create -f rook/deploy/examples/crds.yaml     # 创建 CRD
kubectl create -f rook/deploy/examples/common.yaml   # 创建 RBAC / ServiceAccount
kubectl create -f rook/deploy/examples/operator.yaml # 部署 Operator

# 2. 创建 CephCluster CR
kubectl apply -f cluster.yaml

CephCluster 核心配置

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: quay.io/ceph/ceph:v18.2.0
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3                        # MON 数量,建议奇数 ≥ 3
    allowMultiplePerNode: false     # 禁止同一节点多 MON
  mgr:
    count: 2
    modules:
      - name: pg_autoscaler
        enabled: true
  dashboard:
    enabled: true
    ssl: true
  network:
    provider: host                  # host 或 multus
    selectors:
      public: public-network
      cluster: cluster-network
  storage:
    useAllNodes: true               # 自动发现节点
    useAllDevices: true             # 自动发现空白设备
    deviceFilter: "^sd[b-d]"       # 设备名过滤
    config:
      osdsPerDevice: "1"            # 每设备 OSD 数(NVMe 可设为 > 1)
    nodes:
      - name: node-1
        devices:
          - name: /dev/nvme0n1
            config:
              osdsPerDevice: "4"
  resources:
    osd:
      limits:
        cpu: "4"
        memory: "16Gi"
      requests:
        cpu: "2"
        memory: "8Gi"

Ceph 网络隔离

网络类型用途配置字段
Public Network客户端 I/O 请求,MON 间通信network.selectors.public
Cluster NetworkOSD 间数据复制与恢复network.selectors.cluster

CephCluster 状态检查

kubectl -n rook-ceph get cephcluster
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph status
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd tree
7 Rook CephBlockPool(RBD)的创建与使用

答案:

CephBlockPool 定义 RBD 块存储池,通过 CSI 驱动为 Pod 提供 PersistentVolume。

CephBlockPool 创建

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
  namespace: rook-ceph
spec:
  failureDomain: host              # 故障域级别
  replicated:
    size: 3                         # 副本数
    requireSafeReplicaSize: true    # 要求可用副本才允许写入
  enableRBDStats: true              # 开启 RBD 性能统计
  parameters:
    pg_num: "128"
    pgp_num: "128"
    compression_mode: aggressive
    target_size_ratio: 0.3          # PG Autoscaler 权重

StorageClass 定义

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,exclusive-lock,object-map,fast-diff,deep-flatten
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
  csi.storage.k8s.io/fstype: ext4
allowVolumeExpansion: true
reclaimPolicy: Delete
mountOptions:
  - discard                     # 启用 TRIM / UNMAP

应用使用示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
apiVersion: v1
kind: Pod
metadata:
  name: mysql
spec:
  containers:
    - name: mysql
      image: mysql:8.0
      volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: mysql-data

Volume Expansion 在线扩容

kubectl patch pvc mysql-data -p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'

RBD Snapshot 快照与恢复

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-rbdplugin-snapclass
driver: rook-ceph.rbd.csi.ceph.com
deletionPolicy: Delete
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: mysql-snapshot
spec:
  volumeSnapshotClassName: csi-rbdplugin-snapclass
  source:
    persistentVolumeClaimName: mysql-data
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-restore
spec:
  storageClassName: rook-ceph-block
  dataSource:
    name: mysql-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
8 Rook CephFilesystem(CephFS)的创建与使用

答案:

CephFilesystem 定义 CephFS 分布式文件系统,支持 ReadWriteMany(RWX)访问模式,适用于共享存储场景。

CephFilesystem 创建

apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: myfs
  namespace: rook-ceph
spec:
  metadataPool:
    replicated:
      size: 3
    parameters:
      pg_num: "128"
      compression_mode: "none"      # 元数据池不建议压缩
  dataPools:
    - name: replicated
      failureDomain: host
      replicated:
        size: 3
      parameters:
        pg_num: "256"
        compression_mode: aggressive
    - name: ec-data                # 纠删码数据池
      failureDomain: host
      erasureCoded:
        dataChunks: 6
        codingChunks: 2            # 6+2 EC,1.33x 冗余率
  preserveFilesystemOnDelete: false
  metadataServer:
    activeCount: 1
    activeStandby: true             # 启用 standby MDS
    resources:
      limits:
        cpu: "4"
        memory: "8Gi"
      requests:
        cpu: "2"
        memory: "4Gi"

StorageClass 定义

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-cephfs
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
  clusterID: rook-ceph
  fsName: myfs
  pool: myfs-replicated
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
allowVolumeExpansion: true
reclaimPolicy: Delete

RWX 多 Pod 共享示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-data
spec:
  storageClassName: rook-cephfs
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 500Gi
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-shared
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-shared
  template:
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          volumeMounts:
            - name: data
              mountPath: /usr/share/nginx/html
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: shared-data

SubVolumeGroup 租户隔离

CephFS SubVolumeGroup 在多租户场景下提供命名空间隔离和配额控制。通过 CephFilesystemSubVolumeGroup CRD 创建子卷组,每个租户的应用 PVC 限定在其 SubVolumeGroup 内。

apiVersion: ceph.rook.io/v1
kind: CephFilesystemSubVolumeGroup
metadata:
  name: tenant-a-group
  namespace: rook-ceph
spec:
  filesystemName: myfs
# StorageClass 通过 subvolumegroup 参数指向租户组
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-cephfs-tenant-a
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
  clusterID: rook-ceph
  fsName: myfs
  subvolumegroup: tenant-a-group
9 Rook CephObjectStore(RGW / 对象存储)的创建与使用

答案:

CephObjectStore 定义 RADOS Gateway 对象存储服务,提供 S3 / Swift 兼容 API。

CephObjectStore 创建

apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: my-store
  namespace: rook-ceph
spec:
  metadataPool:
    replicated:
      size: 3
  dataPool:
    replicated:
      size: 3
    erasureCoded:
      dataChunks: 4
      codingChunks: 2
  preservePoolsOnDelete: true
  gateway:
    type: s3
    port: 80
    securePort: 443
    instances: 3
    sslCertificateRef: rgw-tls-cert   # TLS Secret 引用
    resources:
      limits:
        cpu: "4"
        memory: "8Gi"
      requests:
        cpu: "2"
        memory: "4Gi"
  healthCheck:
    bucket:
      disabled: false
      interval: 60s

用户与凭据创建

apiVersion: ceph.rook.io/v1
kind: CephObjectStoreUser
metadata:
  name: my-user
  namespace: rook-ceph
spec:
  store: my-store
  displayName: "S3 ReadWrite User"
  quotas:
    maxBuckets: 100
    maxSize: 1024Gi
    maxObjects: 1000000
  capabilities:
    - user: "*"
    - bucket: "*"
    - usage: read
    - metadata: read

获取 S3 凭据与 Endpoint

# 获取 Access Key
kubectl -n rook-ceph get secret rook-ceph-object-user-my-store-my-user \
  -o jsonpath='{.data.AccessKey}' | base64 --decode

# 获取 Secret Key
kubectl -n rook-ceph get secret rook-ceph-object-user-my-store-my-user \
  -o jsonpath='{.data.SecretKey}' | base64 --decode

# 获取 RGW Service Endpoint
kubectl -n rook-ceph get svc rook-ceph-rgw-my-store -o jsonpath='{.spec.clusterIP}'

S3 客户端验证

s3cmd --access_key=<AccessKey> --secret_key=<SecretKey> \
  --host=<RGW-Endpoint> --host-bucket="" \
  --no-ssl mb s3://my-bucket

RGW 负载均衡与 Ingress 暴露

apiVersion: v1
kind: Service
metadata:
  name: rgw-external-lb
  namespace: rook-ceph
spec:
  type: LoadBalancer
  selector:
    app: rook-ceph-rgw
    rgw: my-store
  ports:
    - name: http
      port: 80
      targetPort: 8080
    - name: https
      port: 443
      targetPort: 8443
10 Rook 的 CephBlockPoolRadosNamespace 与 RBD 镜像

答案:

CephBlockPoolRadosNamespace 在已有 RBD Pool 内创建 RADOS Namespace 逻辑分区,实现存储层多租户隔离。每个 Namespace 拥有独立的 RBD 镜像集合,不同 Namespace 中的同名镜像互不影响。

RADOS Namespace 创建

apiVersion: ceph.rook.io/v1
kind: CephBlockPoolRadosNamespace
metadata:
  name: tenant-x-ns
  namespace: rook-ceph
spec:
  blockPoolName: replicapool
# StorageClass 指向特定 Namespace
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block-tenant-x
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  clusterID: rook-ceph
  pool: replicapool
  radosNamespace: tenant-x-ns

RBD Mirroring 异步镜像复制

apiVersion: ceph.rook.io/v1
kind: CephRBDMirror
metadata:
  name: rbd-mirror
  namespace: rook-ceph
spec:
  count: 1
  resources:
    limits:
      cpu: "2"
      memory: "4Gi"
  peers:
    secretNames:
      - cluster-b-peer-secret
  pool: replicapool
  mode: pool                  # pool 或 image 级别
  snapshotSchedules:
    - interval: 15m
      startTime: "00:00:00"

RBD 镜像的 Snapshot 与 Trash 管理

RBD 镜像支持分层快照和延迟删除(Trash)。删除镜像时先进 Trash,在延迟期(默认 7 天)内可恢复。

# 查看 Trash 中的镜像
rbd trash ls -p replicapool
# 恢复已删除镜像
rbd trash restore -p replicapool <image-id>
11 Rook 的 CSI 驱动(RBD CSI / CephFS CSI)

答案:

Rook 集成 CSI(Container Storage Interface)规范,通过 RBD CSI 和 CephFS CSI 驱动实现 Kubernetes 原生卷的生命周期管理。

CSI 组件架构

graph TD
    subgraph K8sMaster["Kubernetes Master"]
        Prov["CSI Provisioner"]
        Snap["CSI Snapshotter / Resizer"]
        Prov --> Ctrl
        Snap --> Ctrl
        Ctrl["CSI Controller Plugin\nrook-ceph.rbd.csi.ceph.com /\nrook-ceph.cephfs.csi.ceph.com"]
    end
    subgraph K8sNode["Kubernetes Node"]
        Node["CSI Node Plugin\nDaemonSet: csi-rbdplugin /\ncsi-cephfsplugin"]
        Stage["NodeStage\nVolume"]
        Publish["NodePublish\nVolume"]
    end
    Ctrl --> Node

RBD CSI 卷生命周期

阶段方法操作
CreateVolumeController调用 rbd create 创建 RBD 镜像
DeleteVolumeController调用 rbd rm 删除 RBD 镜像
ControllerPublishVolumeControllerrbd map + 将设备路径返回给 kubelet
NodeStageVolumeNode格式化为文件系统 + mount 到 global mount 路径
NodePublishVolumeNodebind mount 到 Pod 的 volumeMount 路径
NodeUnpublishVolumeNodeunmount Pod 路径
NodeUnstageVolumeNodeunmount global mount 路径
ControllerUnpublishVolumeControllerrbd unmap

CSI 侧车容器(Sidecar)

侧车功能
csi-provisioner监听 PVC 事件,调用 CSI CreateVolume / DeleteVolume
csi-snapshotter监听 VolumeSnapshot 事件,管理快照生命周期
csi-resizer监听 PVC 扩容事件,调用 ControllerExpandVolume
csi-attacher监听 VolumeAttachment 事件,完成 Attach / Detach
livenessprobeCSI 驱动健康检查

多集群 Ceph 访问

通过 clusterID 映射,在多个 Kubernetes 集群中配置相同 clusterID 和对应 Secret,实现多个集群共享同一 Ceph 集群。

# 外部 K8s 集群 StorageClass
parameters:
  clusterID: rook-ceph-external
  pool: replicapool
  csi.storage.k8s.io/provisioner-secret-namespace: external-ns
12 Rook 的存储分类(DeviceClass / CrushDeviceClass)

答案:

CrushDeviceClass 将 OSD 按设备类型分类(HDD / SSD / NVMe),允许不同性能等级的存储设备归属于不同的 CRUSH 规则,实现存储分层。

设备自动分类

Rook 根据设备属性自动设置 crushDeviceClass

设备属性crushDeviceClass
旋转磁盘(HDD)hdd
固态磁盘(SSD / SATA)ssd
NVMe 设备nvme

基于 DeviceClass 的 CephBlockPool 创建

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: nvme-fast-pool
  namespace: rook-ceph
spec:
  failureDomain: host
  deviceClass: nvme
  replicated:
    size: 3
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: hdd-archive-pool
  namespace: rook-ceph
spec:
  failureDomain: host
  deviceClass: hdd
  replicated:
    size: 2

自定义 CRUSH Rule 与 DeviceClass

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: ssd-primary-pool
  namespace: rook-ceph
spec:
  failureDomain: rack
  deviceClass: ssd
  replicated:
    size: 3
  crushRoot: ssd-root          # 限定 CRUSH tree 根节点

不同 DeviceClass 的 StorageClass 映射

# NVMe 高性能 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-nvme-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  pool: nvme-fast-pool

# HDD 归档 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-hdd-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  pool: hdd-archive-pool
13 Rook 的 Placement Group 自动扩缩(PG Autoscaler)

答案:

PG Autoscaler 根据 Pool 的实际使用量或预期使用量自动调整 pg_num,避免人工估算不准确导致的 PG 过多或不足。

PG Autoscaler 模式

模式行为适用场景
off完全禁用自动调整静态环境 / 精确控制
warn提示建议调整值,不自动执行生产环境过渡期
on自动执行 PG 数量调整动态变化环境

PG Autoscaler 参数

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
  namespace: rook-ceph
spec:
  parameters:
    pg_autoscale_mode: "on"
    target_size_ratio: 0.3     # Pool 占集群总容量比例,用于计算 PG

原理与计算

PG Autoscaler 基于两个关键输入计算 PG 数量:

  • target_size_ratio:Pool 容量占集群总容量的比值(如 0.3 表示 30%)。
  • target_size_bytes:Pool 的绝对容量目标(与 ratio 互斥)。
  • 最终 PG 数 = (OSD 数 × Mon PG Per OSD) / Replica Size,结合 target_size_ratio 加权分配。

手动触发调优

# 查看 Pool 的 PG Autoscaler 状态
ceph osd pool autoscale-status

# 手动为 Pool 设置 target ratio
ceph osd pool set replicapool target_size_ratio 0.5
14 Rook 的 OSD 管理(添加 / 移除 / 替换磁盘)

答案:

Rook 通过 OSD 守护进程管理底层磁盘的生命周期,支持添加新盘、移除故障盘和替换失效盘。

OSD 添加流程

  1. 节点上新插入磁盘后,Rook Agent(DaemonSet)自动检测。
  2. Agent 调用 ceph-volume 创建 OSD(分区 / 格式化 BlueStore / 注册到集群)。
  3. OSD Pod 启动,Ceph 集群自动触发数据再平衡(CRUSH rebalance)。
  4. 观察 PG 状态:ceph -s / ceph pg stat
# 查看 OSD 树
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd tree

# 查看 OSD 状态
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd df

OSD 移除流程

# 1. 标记 OSD 为 out(集群自动迁移数据)
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd out osd.<N>

# 2. 等待数据迁移完成
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph -w

# 3. 停止 OSD 进程
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd down osd.<N>

# 4. 删除 OSD(从 CRUSH Map 和 Auth 中移除)
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd purge osd.<N>

# 5. 清理节点上的设备
# 如使用 Rook 管理的 OSD,通过删除对应 deployment 触发清理 Job
kubectl -n rook-ceph delete deployment rook-ceph-osd-<N>

# 6. 物理移除磁盘

OSD 替换流程

替换场景下优先执行逐出再移除,避免多盘同时故障导致数据丢失。

# 1. 执行逐出(evict),替换 out
ceph osd destroy osd.<N> --force
# 2. 物理更换磁盘
# 3. Rook Agent 检测到新盘,自动创建新 OSD
# 4. 集群自动再平衡

OSD 权重调节

# 调整 OSD 权重(根据容量差异微调)
ceph osd crush reweight osd.<N> <weight>

# 批量平衡(upmap 优化器)
ceph balancer mode upmap
ceph balancer on
15 Rook 的 MON 高可用与仲裁机制

答案:

Ceph MON 集群使用 Paxos 协议维护集群 Map 的强一致性,要求多数 MON 在线才能形成法定人数(quorum)。

MON 数量的选择

MON 数量可容忍故障数推荐场景
10开发 / 测试环境
31生产环境(最小推荐)
52大型集群(> 100 OSD)
73超大规模集群

CephCluster MON 配置

apiVersion: ceph.rook.io/v1
kind: CephCluster
spec:
  mon:
    count: 3
    allowMultiplePerNode: false
    volumeClaimTemplate:
      spec:
        storageClassName: local-storage    # MON 数据使用本地 PV
        resources:
          requests:
            storage: 20Gi

MON 高可用设计要点

策略说明
反亲和性调度MON Pod 通过 PodAntiAffinity 分布在不同 Node 上
独立存储每个 MON 绑定独立持久化卷,不可共享
网络隔离MON 通信使用独立 cluster network
时钟同步所有 MON 节点必须配置 NTP,时钟偏差不可超过 50ms(默认 mon_clock_drift_allowed)

仲裁故障恢复

当 MON 数量降至 quorum 以下时集群不可用。恢复方式:

# 1. 检查 MON 状态
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph mon stat

# 2. 如 MON 数据完整,重启失败 MON Pod
kubectl -n rook-ceph delete pod rook-ceph-mon-a-xxxx

# 3. 如 MON 数据损坏,从健康 MON 提取 monmap 注入新 MON
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph-monstore-tool \
  /var/lib/rook/mon-a get monmap -- --out /tmp/monmap

# 4. 将 MON 从集群中移除并重建
ceph mon remove a
16 Rook 的 MDS(Metadata Server)与 CephFS 性能

答案:

MDS 负责管理 CephFS 文件系统的元数据(目录树、文件 inode、权限),与数据 I/O 分离,是可水平扩展的无状态服务。

MDS 部署模式

配置行为
activeCount: 1单 Active MDS,可配合 standby
activeCount: 2+多 Active MDS,以子树分区方式负载均衡
activeStandby: true启用 Standby-Replay MDS,Active MDS 故障时快速接管

多 Active MDS 配置

apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: myfs
  namespace: rook-ceph
spec:
  metadataServer:
    activeCount: 2
    activeStandby: true
    resources:
      limits:
        cpu: "8"
        memory: "16Gi"
      requests:
        cpu: "4"
        memory: "8Gi"

MDS 性能调优

[mds]
mds_cache_memory_limit = 16GB          # MDS 内存缓存上限
mds_cache_reservation = 0.05           # 缓存保留比例
mds_recall_state_timeout = 60          # 客户端状态回收超时
mds_session_timeout = 60               # 客户端会话超时
mds_bal_interval = 10                  # MDS 负载均衡间隔(秒)
mds_log_max_segments = 128             # MDS 日志段数量
mds_max_file_recover = 32              # 恢复期间最大打开文件数

MDS 性能监控

# MDS 性能计数器
ceph daemon mds.myfs-a perf dump

# 客户端会话
ceph tell mds.myfs:a client ls

# 查看子树分区分布
ceph fs status myfs

CephFS 内核客户端 vs FUSE 客户端

维度Kernel Client (kcephfs)FUSE Client (ceph-fuse)
性能高,零拷贝较低,需用户态-内核态切换
部署需内核模块支持用户态部署,不依赖内核
配额部分版本不支持完整支持
安全需 root 挂载普通用户可挂载
Snapshot支持支持
17 Rook 的 RGW(RADOS Gateway)S3 兼容 API

答案:

RADOS Gateway 将 S3 / Swift RESTful API 请求转换为 RADOS 对象操作,提供云原生对象存储能力。

RGW 架构

graph TD
    Req["HTTP/HTTPS Request"]
    LB["LoadBalancer\nEnvoy / HAProxy / Nginx"]
    RGW1["RGW Pod"]
    RGW2["RGW Pod"]
    RGW3["RGW Pod"]
    RADOS["RADOS"]
    Req --> LB
    LB --> RGW1
    LB --> RGW2
    LB --> RGW3
    RGW1 --> RADOS
    RGW2 --> RADOS
    RGW3 --> RADOS

RGW 多项配置

apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: cluster-a-store
  namespace: rook-ceph
spec:
  gateway:
    instances: 5
    port: 80
    securePort: 443
  zone:
    name: zone-a
  healthCheck:
    bucket:
      interval: 30s

S3 API 兼容性

功能支持情况
Bucket CRUD完整支持
Object CRUD完整支持
Multipart Upload支持
Versioning支持(Bucket Versioning)
Lifecycle Policy支持(过期 / 转换)
Cross-Origin (CORS)支持
Server-Side Encryption (SSE-S3)支持
Object Lock / Legal Hold支持
Bucket Policy / ACL支持
Static Website Hosting支持
S3 Select不支持
Object Lambda不支持

RGW 性能参数

[client.rgw]
rgw_frontends = "beast port=80"
rgw_thread_pool_size = 512
rgw_max_concurrent_requests = 1024
rgw_cache_enabled = true
rgw_cache_lru_size = 100000
rgw_gc_max_objs = 32
rgw_gc_processor_period = 3600

Beast HTTP 引擎优化

RGW 默认使用 Beast 作为 HTTP 前端,相比 Civetweb 性能和稳定性均有提升。

# Beast 绑核(减少上下文切换)
rgw_frontends = "beast port=80 num_threads=4"

# 限制请求体大小
rgw_max_put_size = 5GiB
rgw_max_get_size = 10GiB
18 Rook 的 Dashboard 管理界面

答案:

Ceph Dashboard 提供 Web 图形化管理界面,集成集群状态、性能指标、配置管理和容量可视化。

Dashboard 启用

apiVersion: ceph.rook.io/v1
kind: CephCluster
spec:
  dashboard:
    enabled: true
    ssl: true
    urlPrefix: /
    port: 8443
    sslCertificateSecretName: dashboard-cert  # 自定义 TLS

Dashboard 初始密码

# 首次部署后获取 admin 密码
kubectl -n rook-ceph get secret rook-ceph-dashboard-password \
  -o jsonpath="{['data']['password']}" | base64 --decode

Dashboard 功能模块

模块功能
Cluster集群健康状态、PG 状态、OSD 状态
Block (RBD)镜像列表、I/O 性能、快照管理
NFSNFS-Ganesha 导出管理
Filesystem (CephFS)MDS 状态、客户端会话
Object Gateway (RGW)用户、Bucket、用量统计
Pools池列表、PG 状态、配额管理
Hosts主机列表、OSD 分布、守护进程状态

通过 Ingress 暴露 Dashboard

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rook-ceph-dashboard
  namespace: rook-ceph
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  rules:
    - host: ceph-dashboard.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: rook-ceph-mgr-dashboard
                port:
                  number: 8443
  tls:
    - hosts:
        - ceph-dashboard.example.com
      secretName: dashboard-tls

Dashboard 用户管理

# 创建只读用户
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- \
  ceph dashboard ac-user-create readonly-user <password> read-only

# 授予特定权限
ceph dashboard ac-user-set-roles admin-user administrator
19 Rook 的备份与灾难恢复(RBD Mirroring / RGW Multi-Site)

答案:

Rook 支持两大灾备机制:RBD Mirroring 实现块存储异步镜像复制,RGW Multi-Site 实现对象存储跨集群同步。

RBD Mirroring 架构

graph LR
    subgraph ClusterA["集群 A"]
        RBD1["RBD Image<br/>(Primary)<br/>Snapshot Schedule"]
        Mirror1["CephRBD Mirror Daemon"]
        RBD1 --> Mirror1
    end
    subgraph ClusterB["集群 B"]
        RBD2["RBD Image<br/>(Secondary)<br/>Snapshot Schedule"]
        Mirror2["CephRBD Mirror Daemon"]
        RBD2 --> Mirror2
    end
    RBD1 -->|"Journal 同步"| RBD2

RBD Mirroring 配置

apiVersion: ceph.rook.io/v1
kind: CephRBDMirror
metadata:
  name: rbd-mirror
  namespace: rook-ceph
spec:
  count: 2
  pool: replicapool
  mode: image
  peers:
    secretNames:
      - cluster-b-peer-secret

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
  namespace: rook-ceph
spec:
  mirroring:
    enabled: true
    mode: image
    snapshotSchedules:
      - interval: 5m
        startTime: "00:00:00"
    maxSnapshots: 5

RGW Multi-Site 架构

graph TD
    Realm["Realm: global"]
    ZoneA["Zone A<br/>(Primary)<br/>Site: beijing"]
    ZoneB["Zone B<br/>(Secondary)<br/>Site: shanghai"]
    Realm --> ZoneA
    Realm --> ZoneB
    ZoneA <-->|"Sync"| ZoneB

RGW Multi-Site CR 配置

apiVersion: ceph.rook.io/v1
kind: CephObjectRealm
metadata:
  name: global-realm
  namespace: rook-ceph

apiVersion: ceph.rook.io/v1
kind: CephObjectZoneGroup
metadata:
  name: default-group
  namespace: rook-ceph
spec:
  realm: global-realm

apiVersion: ceph.rook.io/v1
kind: CephObjectZone
metadata:
  name: zone-a
  namespace: rook-ceph
spec:
  zoneGroup: default-group
  metadataPool:
    replicated:
      size: 3
  dataPool:
    replicated:
      size: 3

灾难恢复 RPO / RTO 对比

方案RPORTO复杂度
RBD Mirroring (Journal)秒级(异步)分钟级
RBD Mirroring (Snapshot)分钟级分钟级
RGW Multi-Site秒级(异步)分钟级
20 Rook 的 Ceph 版本升级(滚动升级 / 跨大版本升级)

答案:

Rook Operator 支持通过修改 CephCluster CR 中的 cephVersion.image 实现 Ceph 滚动升级。Rook 会按依赖顺序逐个更新守护进程,确保升级期间集群可用。

升级流程

# 1. 检查当前集群状态
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph versions
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph status

# 2. 更新 CephCluster 镜像
kubectl -n rook-ceph patch cephcluster rook-ceph --type merge \
  -p '{"spec":{"cephVersion":{"image":"quay.io/ceph/ceph:v18.2.1","allowUnsupported":false}}}'

# 3. 观察升级进度
kubectl -n rook-ceph logs -f deploy/rook-ceph-operator
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph versions

升级顺序

Rook Operator 按照以下顺序逐步升级 Ceph 守护进程:

  1. MGR(Manager)
  2. MON(Monitor)
  3. MDS(Metadata Server)
  4. RGW(RADOS Gateway)
  5. OSD(Object Storage Daemon)
  6. RBD Mirror / NFS-Ganesha 等其他组件

升级安全策略

策略说明
健康检查前置升级前要求集群 HEALTH_OK,任意 PG 非 active+clean 状态阻止升级
canary 升级可以逐 OSD 灰度,观察单个 OSD 升级后的行为
禁止跨大版本小版本(v16.2.x -> v16.2.y)直接升级;大版本(v16 -> v17)需逐个跃迁
自动回滚OSD 单例升级失败不影响服务,Operator 保持旧版本 OSD 运行

跨大版本升级路径

v15.2.x (Octopus) → v16.2.x (Pacific) → v17.2.x (Quincy) → v18.2.x (Reef)
21 Rook 的多集群 Ceph(CephCluster Federation)

答案:

Rook 支持在多个 Kubernetes 集群中运行独立的 CephCluster,通过 CSI 的 clusterID 映射和外部集群连接实现跨集群存储共享。

多集群部署模型

模型架构适用场景
独立集群每个 K8s 集群独立的 CephCluster,互不感知完全隔离的多环境
外部连接一个 CephCluster 作为存储后端,多个 K8s 集群通过 CSI 外部模式消费共享存储后端
RBD Mirroring多个 CephCluster 通过 RBD 镜像异步复制灾备 / 多活

外部集群连接配置

# 1. 从 Ceph 集群导出连接信息
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- \
  python3 /etc/ceph/create-external-cluster-resources.py \
  --rbd-data-pool-name replicapool \
  --cephfs-filesystem-name myfs \
  --namespace rook-ceph-external

# 2. 在外部 K8s 集群上创建连接 Secret
kubectl create -f external-cluster-secret.yaml

# 3. 外部 K8s 集群 StorageClass 指向外部 Ceph
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block-external
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  clusterID: rook-ceph-external
  pool: replicapool

CephCluster Federation 关键点

维度注意事项
网络互通外部 K8s 集群节点必须能访问 Ceph 集群的 MON/OSD 网络
认证隔离通过 Ceph Auth 为每个外部集群创建独立 keyring,限制 Pool 访问权限
性能影响跨集群 I/O 路径增加网络延迟,建议同数据中心部署
CSI 版本外部集群的 CSI 驱动版本应与 Ceph 版本兼容
22 Rook 的性能调优(Network / BlueStore / PG 数量 / OSD 内存)

答案:

Ceph 集群性能受网络、存储引擎、PG 数量和 OSD 资源等因素共同影响,需从多个维度系统调优。

网络层调优

[global]
ms_type = async+posix                   # 异步消息层
ms_async_op_threads = 4                 # OSD 工作线程
ms_bind_port_min = 6800
ms_bind_port_max = 7300

[osd]
osd_op_num_threads_per_shard = 2        # SSD 建议 2~4,HDD 建议 1
osd_op_num_shards = 8                   # OSD 分片数

内核网络参数

# /etc/sysctl.d/90-ceph.conf
net.core.rmem_max = 134217728           # 128MB 接收缓冲区
net.core.wmem_max = 134217728           # 128MB 发送缓冲区
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.core.netdev_max_backlog = 300000

BlueStore 缓存调优

[osd]
# HDD 优化
bluestore_cache_size_hdd = 4GB
bluestore_cache_size_ssd = 4GB
bluestore_cache_kv_ratio = 0.6          # 60% 给 RocksDB 缓存,40% 给 onode 缓存
bluestore_cache_meta_ratio = 0.6        # 元数据缓存占比

# RocksDB 调优
bluestore_rocksdb_options = "compression=kLZ4Compression,max_write_buffer_number=8,min_write_buffer_number_to_merge=2,write_buffer_size=256MB,max_bytes_for_level_base=4GB,max_background_jobs=8"

PG 数量调优

每 OSD PG 数影响建议
< 50数据分布可能不均增加 PG
50 ~ 100资源消耗低,Variance 略高可接受
100 ~ 200平衡数据分布与资源消耗推荐区间
> 300OSD 内存和 CPU 压力大,Peering 时间长减少 PG 或增加 OSD

OSD 内存配置

[osd]
osd_memory_target = 8GB                 # Ceph 自动管理 OSD 内存上限
osd_memory_cache_min = 512MB            # 保留缓冲
bluestore_cache_autotune = true         # 自动调整 BlueStore 缓存

Rook 集群资源配置

apiVersion: ceph.rook.io/v1
kind: CephCluster
spec:
  resources:
    osd:
      limits:
        cpu: "8"
        memory: "16Gi"
      requests:
        cpu: "2"
        memory: "4Gi"
    mon:
      limits:
        cpu: "2"
        memory: "4Gi"
    mgr:
      limits:
        cpu: "1"
        memory: "2Gi"

网络延迟要求

存储类型推荐延迟最低要求
HDD 集群< 5ms< 15ms
SSD 集群< 2ms< 5ms
NVMe 集群< 500us< 2ms
23 Rook 的监控与 Prometheus 集成

答案:

Ceph 通过 MGR Prometheus 模块暴露集群级别指标,Rook 集成 Ceph Mixin 提供预配置的 Prometheus 告警规则和 Grafana Dashboard。

Prometheus 指标暴露

apiVersion: ceph.rook.io/v1
kind: CephCluster
spec:
  monitoring:
    enabled: true
    rulesNamespace: rook-ceph
  mgr:
    modules:
      - name: prometheus
        enabled: true

ServiceMonitor 自动创建

Rook 检测到集群中运行 Prometheus Operator 后自动创建 ServiceMonitor:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: rook-ceph-mgr
  namespace: rook-ceph
spec:
  endpoints:
    - port: http-metrics
      interval: 15s
  selector:
    matchLabels:
      app: rook-ceph-mgr

核心监控指标

指标类型Prometheus Metric关注点
集群健康ceph_health_status0=OK / 1=WARN / 2=ERR
OSD 状态ceph_osd_up / ceph_osd_inUP=在线 / IN=参与数据分布
PG 状态ceph_pg_total / ceph_pg_active / ceph_pg_cleanactive+clean 比例
容量ceph_cluster_total_bytes / ceph_cluster_total_used_bytes使用率与剩余容量
OSD I/Oceph_osd_op_r / ceph_osd_op_w / ceph_osd_op_latency读写 I/O 延迟
RGWceph_rgw_req / ceph_rgw_get / ceph_rgw_putRGW 吞吐量
网络ceph_osd_network_send_bytes / ceph_osd_network_recv_bytesOSD 间复制流量

关键告警规则

groups:
  - name: ceph.rules
    rules:
      - alert: CephClusterDown
        expr: ceph_health_status > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Ceph 集群不健康"

      - alert: CephOsdDown
        expr: ceph_osd_up == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Ceph OSD XQOPEN $labels.ceph_daemon XQCLOSE 已下线"

      - alert: CephPGsInactive
        expr: ceph_pg_inactive > 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "XQOPEN $value XQCLOSE 个 PG 处于 inactive 状态"

      - alert: CephPGsStuck
        expr: ceph_pg_stuck_inactive / ceph_pg_total > 0.01 or
              ceph_pg_stuck_unclean / ceph_pg_total > 0.01
        for: 10m
        labels:
          severity: critical

      - alert: CephClusterNearFull
        expr: ceph_cluster_total_used_bytes / ceph_cluster_total_bytes > 0.85
        labels:
          severity: critical

Grafana Dashboard

通过 Ceph Mixin 导入 JSON Dashboard 文件,内置以下面板组:

  • OSD 概览(延迟 / 吞吐量 / 容量)
  • Pool 概览(I/O / 容量 / PG 状态)
  • RGW 概览(请求量 / 延迟 / 错误数)
  • Host 概览(CPU / 内存 / 磁盘 / 网络)
24 Ceph 的纠删码(Erasure Coding)与多副本对比

答案:

纠删码将数据分片为 k 个数据块和 m 个校验块,通过计算校验块实现冗余保护。相比多副本,纠删码以更低的存储开销获得同等容错能力。

EC 配置示例

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: ec-pool
  namespace: rook-ceph
spec:
  failureDomain: host
  erasureCoded:
    dataChunks: 4
    codingChunks: 2
  parameters:
    crush-failure-domain: host

EC 冗余率对照

EC 策略数据块数 (k)校验块数 (m)允许故障数存储效率
4+141180%
4+242267%
6+262275%
8+282280%
8+383373%
16+4164480%

EC vs Replication 对比

维度Erasure CodingReplication
存储效率高(6+2 = 1.33x)低(3 副本 = 3x)
小 I/O 性能差(需 stripe 对齐)好(单副本读)
大 I/O 性能好(多盘并发读)
写入延迟较高(编码计算)较低
恢复速度慢(需解码计算)快(直接复制)
CPU 开销较高
适用场景对象存储 / 冷数据 / 大规模归档块存储 / 数据库 / 热数据

EC 适用约束

约束说明
仅全写RBD EC 池需要 imageFeatures: layering,不支持部分写入
故障域要求EC 中的 m 个校验块必须分布在 m 个故障域,因此 host 故障域要求节点数 >= k+m
不适合小 I/O每次写入需要重新计算 stripe,小于 stripe 宽度的写入触发 RMW(Read-Modify-Write)
仅 RGW 天然支持EC 对 RGW 对象存储是透明支持的;RBD 从 Luminous 开始支持
25 Ceph 的 CRUSH Map 手动调优与故障域隔离

答案:

CRUSH Map 定义集群的物理拓扑和故障域层次,精细调优 CRUSH Map 可以有效提升故障容错能力和数据分布均衡性。

CRUSH Map 层次结构示例

# buckets
host node-1 {
    id -3
    alg straw2
    hash 0
    item osd.0 weight 7.275
    item osd.1 weight 7.275
}
host node-2 {
    id -4
    alg straw2
    hash 0
    item osd.2 weight 7.275
    item osd.3 weight 7.275
}
rack rack-a {
    id -10
    alg straw2
    hash 0
    item node-1 weight 14.550
    item node-2 weight 14.550
}
rack rack-b {
    id -11
    alg straw2
    hash 0
    item node-3 weight 14.550
    item node-4 weight 14.550
}
root default {
    id -1
    alg straw2
    hash 0
    item rack-a weight 29.100
    item rack-b weight 29.100
}

CRUSH Rule 示例

// 在不同 Rack 上放置 3 副本
rule replicated_rack {
    id 1
    type replicated
    min_size 1
    max_size 10
    step take default
    step chooseleaf firstn 0 type rack
    step emit
}

// 在不同 Host 上放置 EC 6+2
rule ec_host {
    id 2
    type erasure
    min_size 6
    max_size 8
    step set_chooseleaf_tries 5
    step set_choose_tries 100
    step take default
    step choose indep 0 type host
    step choose indep 8 type osd
    step emit
}

CRUSH Map 注入与验证

# 导出当前 CRUSH Map
ceph osd getcrushmap -o /tmp/crushmap.bin
crushtool -d /tmp/crushmap.bin -o /tmp/crushmap.txt

# 编辑 /tmp/crushmap.txt 后的注入
crushtool -c /tmp/crushmap.txt -o /tmp/crushmap_new.bin
ceph osd setcrushmap -i /tmp/crushmap_new.bin

# 验证 PG 分布
ceph osd df tree | sort -nk4

CRUSH 权重调整技巧

场景操作
OSD 容量差异大通过 reweight-by-utilization 按使用率动态调整权重
新节点加入后数据不均调高新节点 OSD 权重,运行 balancer
临时下线 OSDreweight 0 轻柔逐出,而非直接 out
长期容量规划统一 OSD 磁盘容量,避免同集群混合不同大小 OSD
26 Ceph 的 QoS 与 Scrub / Deep-Scrub 机制

答案:

Ceph 通过 mClock QoS 调度器和 Scrub / Deep-Scrub 机制分别实现 I/O 优先级控制和数据完整性校验。

mClock QoS 调度器

mClock 将 OSD 操作分为三类,以 Reservation / Weight / Limit 三维控制:

操作类型说明优先级
Client Ops用户 I/O(读写请求)
Recovery Ops数据恢复(degraded PG)
Scrub / Snaptrim数据校验与快照清理

mClock 配置参数

[osd]
osd_mclock_profile = high_client_ops       # 生产推荐
# 可选: high_recovery_ops / balanced / high_client_ops
osd_mclock_profile_custom_parameters = "reservation,weight,limit"
osd_mclock_max_capacity_iops_hdd = 315     # HDD 默认 IOPS 容量
osd_mclock_max_capacity_iops_ssd = 21500   # NVMe 默认 IOPS 容量

Scrub 与 Deep-Scrub 对比

维度Scrub (Light)Deep-Scrub
校验内容对象元数据(大小、属性)与 checksum对象完整数据字节级比对
频率每天(默认)每周(默认)
I/O 开销高(读取全量数据)
目的检测元数据不一致检测静默数据损坏(bit rot)
调度控制osd_scrub_begin_hour / osd_scrub_end_hour

Scrub 调度配置

[osd]
osd_scrub_begin_hour = 0              # Scrub 允许开始时间(0 点)
osd_scrub_end_hour = 6                # Scrub 允许结束时间(凌晨 6 点)
osd_scrub_sleep = 0.1                 # Scrub 间隔休眠(秒),降低对业务影响
osd_deep_scrub_interval = 604800      # Deep-Scrub 间隔(7 天,秒)
osd_scrub_max_interval = 2592000      # 最大 Scrub 间隔(30 天)
osd_deep_scrub_stride = 524288        # Deep-Scrub 一次读取块大小(字节)
osd_max_scrubs = 1                    # 单 OSD 同时进行的 Scrub 数
osd_scrub_auto_repair = false         # 是否自动修复 Scrub 错误(默认仅告警)

Scrub 冲突处理

Scrub 与 Client I/O 冲突时,mClock 自动降低 Scrub 操作优先级,保障用户 I/O 响应。

监控 Scrub 状态

# 查看 Scrub 错误
ceph pg dump | grep -E "scrub|inconsistent"

# 查看 PG 的 Deep Scrub 时间戳
ceph pg dump pgs | awk '{print $1, $20, $21}'

# 手动触发 Scrub
ceph pg scrub <pgid>
ceph pg deep-scrub <pgid>
27 Rook 的节点故障恢复流程

答案:

当 Kubernetes 节点发生故障(宕机 / 网络分区 / 内核崩溃),其上运行的 Ceph 守护进程(OSD / MON 等)随之不可用,集群按以下流程自动恢复:

节点故障检测与响应时序

时间线事件Ceph 行为K8s 行为
T+0s节点不可达与故障节点上 OSD 的 heartbeat 中断Node NotReady
T+30s对端 OSD 报告故障ceph osd down开始等待 Pod 驱逐超时
T+5minMON 标记 OSD 为 down开始等待 mon_osd_down_out_intervalPod 可能被驱逐到其他节点
T+10minMON 标记 OSD 为 out (默认600s)触发数据恢复(backfill / recovery)替换节点或修复后重新加入
T+N数据恢复完成PG 重新变为 active+clean

关键超时参数

[mon]
mon_osd_down_out_interval = 600        # OSD down 后标记 out 的延迟(秒)
mon_osd_report_timeout = 900           # MON 等待 OSD 上报的超时

[global]
osd_heartbeat_grace = 20               # OSD 心跳宽限时间(秒)
osd_heartbeat_interval = 6             # OSD 心跳间隔(秒)

Rook 层面节点故障处理

# 1. 检查 OSD 部署情况
kubectl -n rook-ceph get pods -l app=rook-ceph-osd -o wide

# 2. 如节点彻底故障,清理该节点 OSD 以提高恢复速度
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- \
  ceph osd crush remove <node-name>

# 3. 如节点预计长时间不可用,提前手动标记 OSD out
ceph osd out osd.<N>    # 手动 out,不等待 mon_osd_down_out_interval

# 4. 节点恢复后重新加入
#    Rook Agent 自动检测设备并重建 OSD

节点故障恢复时间优化

优化手段效果
降低 mon_osd_down_out_interval减少等待恢复启动的时间
增加 osd_max_backfills加速 backfill 并发
启用 osd_recovery_sleep = 0取消恢复节流
部署更多 OSD分散恢复 I/O 压力
使用独立 cluster network隔离恢复流量与客户端流量

Rook 生产建议

  • 设置 allowMultiplePerNode: false 避免 MON 单节点多实例。
  • 通过 topologySpreadConstraintspodAntiAffinity 将 MON / MGR 分散到不同节点和可用区。
  • OSD 使用节点本地 PV(hostPath 或 local-storage StorageClass),避免依赖网络存储。
28 Rook 与 Longhorn 对比

答案:

Rook(Ceph)和 Longhorn 均为 CNCF 项目中的 Kubernetes 原生存储方案,但在架构、性能、复杂度和适用场景上存在显著差异。

架构对比

维度Rook / CephLonghorn
存储后端分布式对象存储(RADOS),数据分布由 CRUSH 算法决定每个卷独立副本链,Engine 实例为每个卷创建独立控制器
元数据管理MON 集群独立管理,Paxos 强一致直接存储于 Kubernetes CRD
组件数量MON / OSD / MDS / RGW / MGR / CSI(多组件)Manager / Engine / CSI / UI(轻量)
部署复杂度高(需规划 OSD / MON 数量和拓扑)低(Helm 一键部署,自动发现节点磁盘)
最小节点数3 节点(生产推荐)2 节点

性能对比

维度Rook / CephLonghorn
IOPS (4K Random RW)高(NVMe 集群可达 100万+)中等(受副本 Engine 网络延迟约束)
延迟NVMe 集群 < 500us,SSD 集群 < 2ms通常 > 1ms(取决于网络和存储介质)
副本开销3 副本 = 3x,EC 模式 6+2 = 1.33x3 副本 = 3x,无 EC 选型
快照RBD 原生快照,轻量级基于 QCOW2 层的差分快照
写放大BlueStore 双写(WAL + Data)三重写(Volume Head + Snapshot + Replica 同步)

功能对比

功能Rook / CephLonghorn
块存储 (RWO)支持支持
共享文件存储 (RWX)原生 CephFSNFS-Ganesha(v1.4+)
对象存储 (S3)原生 RGW不支持
纠删码支持不支持
多站点 DRRBD Mirroring + RGW Multi-SiteVolume Backup + Restore
备份到 S3/NFS需额外配置内置 Backup Target 支持
UI 管理Ceph Dashboard内置简洁 UI
Prometheus 集成原生支持原生支持
灾备自动切换手动手动

适用场景

场景推荐方案原因
大规模生产(100+ 节点,PB 级)Rook / Ceph成熟稳定,EC 低冗余,性能优秀
中小规模(10~50 节点)Longhorn 或 Rook根据团队能力选择
边缘 / 轻量部署(3~10 节点)Longhorn部署简单,维护成本低
数据库(MySQL / PostgreSQL)Rook / Ceph(RBD)低延迟,高 IOPS,Snapshots 支持
共享存储(Nginx 静态内容 / AI 训练数据)Rook / Ceph(CephFS)原生 RWX
对象存储需求Rook / CephRGW 原生 S3 API
29 Rook 的常见故障排查(OSD Flapping / PG Stuck / Slow Request)

答案:

Ceph 集群稳定运行期间可能遇到 OSD Flapping、PG 卡住、慢请求等故障,需系统排查定位。

OSD Flapping

OSD 频繁 up/down 切换,导致持续 Peering 和恢复。

排查步骤

# 1. 确认 OSD 震荡模式
ceph osd tree | grep -E "up|down"
ceph -w | grep -i osd

# 2. 查看 OSD 日志
kubectl -n rook-ceph logs rook-ceph-osd-<N> --tail=200 | grep -iE "heartbeat|timeout"

# 3. 检查节点资源
kubectl top node <node-name>

# 4. 检查网络延迟
ping -c 100 <osd-node-ip> | grep avg

常见原因与解决方案

原因症状解决方案
OSD 内存不足OOM Kill增加 osd_memory_target 或节点内存
磁盘 I/O 超时slow request 日志更换磁盘或增加 bluestore_cache_size
网络丢包 / 高延迟Heartbeat timeout检查网络设备、MTU、交换机
磁盘满osd full清理或扩容
时钟不同步MON 拒绝心跳配置 NTP

PG Stuck(PG 卡住)

PG 长期处于非 active+clean 状态。

# 1. 查看 stuck PG
ceph pg dump_stuck inactive
ceph pg dump_stuck unclean
ceph pg dump_stuck stale

# 2. 查询特定 PG 的详细信息
ceph pg <pgid> query | jq '.state, .blocked_by, .peering_blocked_by'

# 3. 检查 OSD 是否 up 且 in
ceph osd tree

# 4. 检查 MON 是否形成 quorum
ceph mon stat

PG 卡住常见原因

PG 状态原因解决方案
staleMON 长时间未收到 OSD 心跳检查 OSD 进程是否运行,网络是否可达
inactivePeering 未完成,OSD 间无法达成一致检查故障 OSD 是否过多,网络连通性
degraded副本数不足等待恢复完成或 manual repair
incompletePG 日志不完整,数据可能丢失检查 osd_find_best_info_ignore_history_les 高级修复
remappedOSD out 后 PG 重新映射等待 backfill 完成

Slow Request(慢请求)

# 1. 查看慢请求
ceph daemon osd.<N> ops | jq '.slow_ops'

# 2. 查看 OSD 延迟
ceph osd perf

# 3. 查看实时 I/O
ceph -w | grep -i slow

# 4. 分析具体阻塞原因
ceph daemon osd.<N> dump_historic_ops | jq '.ops[] | select(.description | contains("blocked"))'

慢请求排查清单

检查项命令阈值参考
磁盘利用率ceph osd df> 85% 触发 nearfull
磁盘延迟iostat -x 1HDD await > 20ms / SSD await > 5ms
CPU / 内存kubectl top podCPU > 80% / Memory > 90%
网络丢包ping / iperf3丢包 > 0.1%
PG 恢复进度ceph -s大量 degraded / misplaced objects
30 Rook Ceph on Kubernetes 生产环境最佳实践

答案:

生产环境部署 Rook Ceph 需从集群规划、资源配置、安全隔离、监控告警、备份恢复和运维流程等多个维度系统设计。

集群规划

维度推荐配置说明
最小节点数5 节点(3 MON + OSD)满足 MON quorum 并为 OSD 提供足够节点
MON 数量3(奇数)允许 1 个 MON 故障
OSD 磁盘类型同质化(统一 HDD 或 SSD)避免容量和性能差异导致数据倾斜
网络10Gbps+ 双网分离(Public + Cluster)OSD 间恢复流量与客户端 I/O 隔离
Kubernetes 版本与 Rook 兼容版本(参考 Rook 官方兼容矩阵)避免 API 弃用

资源配置

apiVersion: ceph.rook.io/v1
kind: CephCluster
spec:
  # 版本锁定
  cephVersion:
    image: quay.io/ceph/ceph:v18.2.1
    allowUnsupported: false

  # 节点亲和性:MON 跨 AZ
  placement:
    mon:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: rook-ceph-mon
            topologyKey: kubernetes.io/hostname
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule

  # PG Autoscaler
  mgr:
    modules:
      - name: pg_autoscaler
        enabled: true

  # 存储:使用 local-storage PV
  storage:
    useAllNodes: false        # 关闭自动发现
    nodes:
      - name: node-1
        devices:
          - name: /dev/nvme0n1
            config:
              osdsPerDevice: "1"
              deviceClass: nvme

  # 健康检查
  healthCheck:
    daemonHealth:
      mon:
        interval: 45s
      osd:
        interval: 60s
    livenessProbe:
      mon:
        periodSeconds: 10
      mgr:
        periodSeconds: 10
      osd:
        periodSeconds: 10

  # 日志保留
  logCollector:
    enabled: true
    periodicity: daily
    maxLogSize: 500M

  # 监控集成
  monitoring:
    enabled: true

安全加固

策略配置
TLS 通信启用 Dashboard SSL,RGW HTTPS
Secret 加密CephCluster 配置 security.kms 集成外部 KMS
网络策略通过 NetworkPolicy 限制 MON / OSD 间通信仅允许必要端口
RBAC 最小权限Rook Operator 使用专用 ServiceAccount,Role 限定 rook-ceph Namespace
禁用不安全访问Dashboard 密码使用 Secret 管理,定期轮换
Ceph Auth 最小权限CSI 驱动使用独立的 client keyring,仅授权特定 Pool 和 MDS 访问

存储池设计

# 热数据池:SSD / NVMe,3 副本,高性能
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: fast-pool
spec:
  deviceClass: ssd
  failureDomain: host
  replicated:
    size: 3
    requireSafeReplicaSize: true

# 温数据池:HDD,EC 6+2,大容量低成本
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: archive-pool
spec:
  deviceClass: hdd
  failureDomain: rack
  erasureCoded:
    dataChunks: 6
    codingChunks: 2

运维检查清单

频率检查项命令 / 指标
每日集群健康状态ceph -s / ceph health detail
每日OSD 容量均衡ceph osd df tree 关注 Variance
每周Deep-Scrub 进度`ceph pg dump
每周Rook Operator 日志kubectl -n rook-ceph logs deploy/rook-ceph-operator --tail=500
每月Ceph 版本更新评估对比 Rook Release Notes 与当前版本
每月备份验证测试 RBD Snapshot 恢复和 S3 备份可读性
每季度容灾演练模拟节点故障、MON 故障恢复流程
每季度容量规划根据趋势预测 6 个月后容量需求

升级建议

  1. Rook Operator 先升级,再升级 Ceph 版本。
  2. 升级前执行 ceph osd set noout 防止短暂的 OSD 震荡触发不必要的数据迁移。
  3. 逐节点或逐 OSD 灰度升级,观察 PG 状态和 I/O 延迟。
  4. 升级完成后执行 ceph osd unset noout
  5. 大版本升级(如 Pacific -> Quincy)前创建 MON 数据备份(ceph-monstore-tool)。

节点故障恢复 SOP

  1. 确认节点故障范围和影响面(哪些 OSD / MON 受影响)。
  2. 若为 MON 故障且 quorum 已丢失,优先恢复 MON。
  3. 若为 OSD 故障,评估是否需手动 ceph osd out 以加速恢复。
  4. 监控 PG 恢复进度,关注恢复 I/O 是否挤占客户端 I/O(必要时调整 mClock)。
  5. 节点恢复后验证 OSD 重新加入集群。
  6. 复盘故障原因,更新监控告警阈值。