第 3/15 天 · Ceph+K8s 中间件实战系列
在 Day 2 中我们完成了 Ceph RBD 块存储接入 K8s 的全部流程,RBD 提供 ReadWriteOnce(RWO)模式,适合 MySQL、Redis 等单 Pod 独占挂载场景。然而许多中间件(如 Nacos 集群配置共享、Elasticsearch 多节点数据目录、GitLab 共享仓库)需要多个 Pod 同时读写同一份存储——这就是 CephFS 共享文件存储的核心价值。本篇将深入讲解 CephFS 架构原理,并实战部署 CephFS CSI Driver、配置 StorageClass、验证 RWX 多读场景及性能调优。

一、设计架构:CephFS 共享文件存储体系
1.1 组件拓扑
CephFS 是 Ceph 提供的 POSIX 兼容分布式文件系统,其核心组件如下表所示:
| 组件 | 角色说明 | 部署要求 |
|---|---|---|
| MDS(Metadata Server) | 管理文件系统元数据(inode、目录树),是 CephFS 的核心 | 至少 2 个(active + standby) |
| Mon(Monitor) | 维护集群拓扑映射(OSD Map、MDS Map、PG Map) | 3 或 5 个节点(奇数) |
| OSD(Object Storage Daemon) | 存储实际数据对象 | 每块磁盘一个 OSD |
| Metadata Pool | 存放文件元数据(文件名、权限、目录结构) | 建议使用 SSD,副本数 3 |
| Data Pool | 存放文件实际数据内容 | 可使用 HDD,副本数 2-3 或 EC 纠删码 |
1.2 数据流向
K8s Pod (RWX PVC)
↓ mount.cifs / ceph-fuse / kernel cephfs
CephFS CSI Driver (Node Plugin)
↓ librados / cephfs 内核驱动
MDS(元数据服务器)─────→ Metadata Pool (SSD)
↓ 返回数据对象位置
OSD 集群 ─────→ Data Pool (HDD/SSD)
数据流向的关键点在于:元数据请求与数据请求分离。Pod 发起文件操作时,先通过 MDS 获取元数据(文件在哪个 OSD 上),再直接与 OSD 通信读写数据。这种分离设计使元数据操作(如 ls、stat)极快,同时数据读写可线性扩展。
1.3 高可用机制
CephFS 的高可用通过以下机制保障:
- MDS active/standby 模式:多个 MDS 实例运行,同一时刻只有一个 active 状态处理元数据请求,其余为 standby。当 active 故障,standby 在秒级自动接管。
- MDS 多 active(multimds):大型集群可启用多个 active MDS,将目录树分片(subtree partitioning)到不同 MDS,实现元数据水平扩展。
- Mon 集群仲裁:Mon 节点采用 Paxos 协议,3 节点容忍 1 故障,5 节点容忍 2 故障。
- OSD 副本/EC:数据池副本数 ≥ 2 或启用纠删码,自动修复故障 OSD 上的数据。
1.4 存储规划
| 存储类型 | K8s AccessMode | 典型场景 | 对应中间件 |
|---|---|---|---|
| Ceph RBD | RWO | 单 Pod 独占读写 | MySQL、Redis、MongoDB |
| CephFS | RWX | 多 Pod 同时读写共享目录 | Nacos 配置共享、ES 数据目录、GitLab 仓库 |

二、部署实战:CephFS CSI Driver + StorageClass
2.1 前置条件确认
在开始前,确认 Ceph 集群已创建 CephFS 文件系统,并获取连接信息:
# 在 Ceph 管理节点执行
# 1. 查看 CephFS 是否已创建
ceph fs ls
# 输出示例: name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data]
# 2. 创建专用客户端密钥(供 K8s CSI 使用)
ceph fs authorize cephfs client.k8s-cephfs / rw
# 输出: [client.k8s-cephfs]
# key = AQAaTtZkAAAAARAAfZkxxxxxxxxxxxxxxxxx==
# 3. 获取 Mon 节点地址
ceph mon dump
# 输出示例: 192.168.10.11:6789, 192.168.10.12:6789, 192.168.10.13:6789
2.2 安装 CephFS CSI Driver
通过 Helm 安装官方 CephFS CSI Driver(ceph-csi/ceph-csi-cephfs),这是社区维护的标准 Chart:
# 添加 Ceph CSI 官方 Helm 仓库
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm repo update
# 安装 CephFS CSI Driver 到 kube-system 命名空间
helm install ceph-csi-cephfs ceph-csi/ceph-csi-cephfs
–namespace kube-system
–set provisionerReplicaCount=2
–set nodeplugin.updateStrategy=RollingUpdate
# 验证 CSI Driver Pod 运行状态
kubectl get pods -n kube-system | grep cephfs
# 期望输出:
# ceph-csi-cephfs-provisioner-xxxxx 2/2 Running
# ceph-csi-cephfs-nodeplugin-xxxxx 3/3 Running (每个节点一个)
2.3 创建 Ceph 认证 Secret
CSI Driver 需要通过 Secret 获取 Ceph 集群的连接凭据:
# cephfs-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: cephfs-secret
namespace: kube-system
type: Opaque
stringData:
userID: "k8s-cephfs"
userKey: "AQAaTtZkAAAAARAAfZkxxxxxxxxxxxxxxxxx==" # 替换为实际密钥
# 可选:admin 凭据(用于 RBD+FS 统一管理)
adminID: "admin"
adminKey: "AQAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=="
kubectl apply -f cephfs-secret.yaml
# 验证 Secret 已创建
kubectl get secret cephfs-secret -n kube-system
2.4 创建 CephFS StorageClass
这是本篇核心配置——CephFS StorageClass 实现 RWX 模式的动态 PVC 供给:
# cephfs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
# 集群 ID(ceph fsid 获取)或 Mon 地址列表
clusterID: "a3f4e7b2-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# CephFS 文件系统名称
fsName: "cephfs"
# 数据池名称(指定写入哪个 pool)
pool: "cephfs_data"
# 认证 Secret 引用
csi.storage.k8s.io/provisioner-secret-name: "cephfs-secret"
csi.storage.k8s.io/provisioner-secret-namespace: "kube-system"
csi.storage.k8s.io/controller-expand-secret-name: "cephfs-secret"
csi.storage.k8s.io/controller-expand-secret-namespace: "kube-system"
csi.storage.k8s.io/node-stage-secret-name: "cephfs-secret"
csi.storage.k8s.io/node-stage-secret-namespace: "kube-system"
# 子目录挂载(每个 PVC 在 CephFS 中创建独立子目录)
rootPath: "/k8s-volumes"
# 允许卷扩容
allowVolumeExpansion: true
# 绑定模式:立即绑定
volumeBindingMode: Immediate
reclaimPolicy: Delete
mountOptions:
– "noatime" # 不更新文件访问时间,减少元数据写入,提升性能
– "nodiratime" # 不更新目录访问时间
kubectl apply -f cephfs-storageclass.yaml
# 验证 StorageClass 已注册
kubectl get sc cephfs-sc
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE
# cephfs-sc cephfs.csi.ceph.com Delete Immediate
2.5 验证 RWX 多读场景
创建一个使用 CephFS 的 RWX PVC,并部署两个 Pod 同时挂载,验证共享读写:
# cephfs-rwx-demo.yaml
—
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cephfs-shared-pvc
namespace: default
spec:
accessModes:
– ReadWriteMany # RWX:多个 Pod 可同时挂载读写
storageClassName: cephfs-sc
resources:
requests:
storage: 10Gi
—
apiVersion: apps/v1
kind: Deployment
metadata:
name: cephfs-writer
namespace: default
spec:
replicas: 1
selector:
matchLabels: { app: cephfs-writer }
template:
metadata:
labels: { app: cephfs-writer }
spec:
containers:
– name: writer
image: busybox:latest
command: ["/bin/sh", "-c", "while true; do echo $(date) >> /shared/log.txt; sleep 5; done"]
volumeMounts:
– name: shared
mountPath: /shared
volumes:
– name: shared
persistentVolumeClaim:
claimName: cephfs-shared-pvc
—
apiVersion: v1
kind: Pod
metadata:
name: cephfs-reader
namespace: default
spec:
containers:
– name: reader
image: busybox:latest
command: ["tail", "-f", "/shared/log.txt"]
volumeMounts:
– name: shared
mountPath: /shared
volumes:
– name: shared
persistentVolumeClaim:
claimName: cephfs-shared-pvc # 同一个 PVC,RWX 模式
kubectl apply -f cephfs-rwx-demo.yaml
# 验证 PVC 状态
kubectl get pvc cephfs-shared-pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS
# cephfs-shared-pvc Bound pvc-xxx 10Gi RWX cephfs-sc
# 验证 Pod 状态
kubectl get pods -l app=cephfs-writer
kubectl get pod cephfs-reader
# 在 reader Pod 中观察 writer 写入的数据
kubectl exec cephfs-reader — cat /shared/log.txt
# 应看到持续追加的时间戳行,证明 RWX 共享读写成功
2.6 性能调优要点
CephFS 性能调优涉及多个层面:
| 调优项 | 配置方法 | 效果 |
|---|---|---|
| MDS 数量 | ceph fs set cephfs max_mds 2 |
多 active MDS 分摊元数据负载 |
| 元数据池介质 | 元数据池使用 SSD/NVMe OSD | 目录遍历、stat 操作提速 5-10x |
| 挂载选项 | noatime、nodiratime |
减少元数据写入 I/O |
| 内核 CephFS vs FUSE | 优先使用内核驱动(kernel client) | 内核态性能优于用户态 FUSE |
| PG 数量 | 数据池 pg_num 按每 OSD 100-200 PG 规划 |
分布均匀,避免热点 |
| 读缓存 | MDS 启用 mds_cache_memory_limit(默认 1GB) |
热点文件元数据缓存命中 |
# 调整 MDS 缓存大小(在 Ceph 管理节点执行)
ceph tell mds.cephfs-0 config set mds_cache_memory_limit 4294967296 # 4GB
# 启用多 active MDS
ceph fs set cephfs max_mds 2
ceph fs status # 查看当前 MDS active/standby 分布
三、登录验证
部署完成后,通过以下命令验证 CephFS 在 K8s 中的工作状态:
# 1. 验证 CSI Driver 运行状态
kubectl get csidriver | grep cephfs
# NAME ATTACHREQUIRED PODINFOONMOUNT STORAGECAPACITY
# cephfs.csi.ceph.com false true false
# 2. 验证 StorageClass 已注册
kubectl get sc cephfs-sc -o wide
# 3. 查看动态创建的 PV
kubectl get pv | grep cephfs
# pvc-xxxx 10Gi RWX cephfs-sc Bound default/cephfs-shared-pvc
# 4. 验证 Pod 内挂载点
kubectl exec cephfs-reader — df -h /shared
# Filesystem Size Used Avail Use% Mounted on
# 192.168.10.11:6789,192.168.10.12:6789,192.168.10.13:6789:/k8s-volumes/xxx
# 10G 20M 10G 1% /shared
# 5. 验证 CephFS 写入性能(简单基准测试)
kubectl exec cephfs-writer — sh -c 'dd if=/dev/zero of=/shared/testfile bs=1M count=100 oflag=direct 2>&1'
# 关注输出中的写入速度,CephFS 典型顺序写性能 50-200 MB/s(取决于 OSD 数量和网络)
四、日常巡检命令
4.1 存储健康巡检
# 在 Ceph 管理节点巡检 CephFS 状态
ceph fs status
# 输出包含: active MDS、standby MDS、数据池使用量、客户端连接数
ceph health detail | grep -i mds
# 查看 MDS 相关告警(如 MDS laggy、slow requests)
# 巡检元数据池和数据池使用率
ceph df | grep cephfs
# POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
# cephfs_metadata 3 64 120M 5000 360M 0.12 …
# cephfs_data 4 256 8.5G 12000 25G 2.50 …
4.2 K8s 侧 PVC 巡检
# 检查所有 CephFS PVC 状态
kubectl get pvc –all-namespaces -o wide | grep cephfs-sc
# 检查是否有 PVC 处于 Pending 状态(常见于 CSI Driver 故障)
kubectl get pvc –all-namespaces –field-selector=status.phase=Pending
# 查看 CSI Driver 日志(排障关键)
kubectl logs -n kube-system -l app=ceph-csi-cephfs-provisioner –tail=50
# 检查 Pod 挂载异常
kubectl describe pod <pod-name> | grep -A5 -i "events|mount|volume"
4.3 性能监控巡检
# MDS 性能指标查看
ceph tell mds.cephfs-0 perf dump | python3 -m json.tool | grep -E '"reqs"|"inodes"|"caps"'
# 查看 MDS 会话数(客户端连接数)
ceph tell mds.cephfs-0 session ls | python3 -m json.tool
# CephFS 客户端 I/O 统计
ceph fs top # 实时显示各客户端读写速率(Ceph 16+ 支持)
# K8s 侧监控 Pod 的 PVC I/O(需安装 node-exporter + ceph_exporter)
kubectl top pod -l app=cephfs-writer
五、常见问题 FAQ
Q1:PVC 一直处于 Pending 状态,如何排查?
A:常见原因有三:① CSI Driver Pod 未正常运行(kubectl get pods -n kube-system | grep cephfs);② StorageClass 中的 clusterID 或 Secret 配置错误;③ Ceph 集群状态不健康(ceph health 不为 HEALTH_OK)。排查命令:kubectl describe pvc <pvc-name> 查看 Events,再查看 kubectl logs provisioner Pod 日志。
Q2:CephFS 挂载后 Pod 内写入速度很慢?
A:① 确认使用的是内核 CephFS 客户端而非 FUSE(CSI Driver 默认使用内核驱动);② 检查 mountOptions 是否已添加 noatime;③ 确认元数据池位于 SSD 上;④ 检查 Ceph 集群 OSD 负载是否均衡(ceph osd df),不均衡会导致 PG 热点。
Q3:RWX 模式下多 Pod 同时写同一文件会冲突吗?
A:CephFS 提供 POSIX 语义,多 Pod 可同时写同一文件,但结果取决于应用层面的并发控制。多个 Pod 各自 append 写同一文件是安全的(内核保证原子追加),但如果多个 Pod 同时用 O_TRUNC 打开同一文件覆盖写,则后写入的会覆盖前一个。建议共享写场景使用文件锁(flock)或每 Pod 写独立文件。
六、总结
本篇完成了 CephFS 共享文件存储接入 K8s 的全部实战:从 MDS 架构原理、CephFS CSI Driver 的 Helm 部署,到 StorageClass 配置(指定 Ceph 数据池、认证 Secret),再到 RWX 多读场景验证和性能调优要点。CephFS 的 RWX 能力是后续多篇中间件部署的基础——Nacos 集群共享配置、Elasticsearch 多节点数据目录共享等场景都将直接复用 cephfs-sc 这个 StorageClass。
七、下期预告
第 4 天:K8s 部署 MySQL 高可用集群(Ceph RBD 持久化 + 架构设计 + 登录巡检)
从下一篇开始,我们将进入中间件部署阶段。MySQL 作为最核心的关系型数据库,将使用 Bitnami 官方 Helm Chart bitnami/mysql 部署高可用集群,配合 Ceph RBD StorageClass 实现数据持久化,敬请期待。
系列目录
- ✅ 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述
- ✅ 第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战)
- 📌 第 3 天:K8s 接入 CephFS 共享文件存储(多读场景与性能调优)(本文)
- ⏳ 第 4 天:K8s 部署 MySQL 高可用集群(Ceph RBD 持久化 + 架构设计 + 登录巡检)
- ⏳ 第 5 天:K8s 部署 Redis Cluster 集群(Ceph RBD + 架构设计 + 巡检命令)
- ⏳ 第 6 天:K8s 部署 Redis Sentinel 哨兵模式(高可用架构 + 登录验证)
- ⏳ 第 7 天:K8s 部署 MinIO 对象存储集群(分布式架构 + 运维巡检)
- ⏳ 第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录)
- ⏳ 第 9 天:K8s 部署 Nacos 注册配置中心(集群架构 + 登录巡检)
- ⏳ 第 10 天:K8s 部署 Zookeeper 集群(分布式协调架构 + 运维命令)
- ⏳ 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检)
- ⏳ 第 12 天:K8s 部署 Kafka 集群(Ceph RBD + 消息队列架构 + 运维)
- ⏳ 第 13 天:K8s 部署 GitLab 代码托管平台(Ceph RBD 持久化 + 架构 + 巡检)
- ⏳ 第 14 天:K8s 部署 ClickHouse 列式数据库集群(Ceph RBD + 架构设计)
- ⏳ 第 15 天:K8s 中间件统一监控与运维巡检总结(Prometheus + Grafana 全景)

















暂无评论内容