第 1/15 天

引言
当你的 Kubernetes 集群从测试环境走向生产,第一个要面对的问题就是:数据放哪儿?
Pod 是临时的,节点是会故障的,本地磁盘是跟着节点走的。你部署的 MySQL、Redis、Kafka、Elasticsearch……每一个中间件都要求持久化、高可用、跨节点数据恢复。EmptyDir 撑不住,HostPath 不安全,NFS 性能和可靠性都不够看。
这时候,Ceph + K8s 的组合就成了标准答案。Ceph 提供统一分布式存储后端(块、文件、对象三合一),K8s 通过 CSI 驱动动态对接,中间件用 Helm Chart 一键部署,PVC 自动对接 Ceph 存储池——这就是本系列 15 篇文章要讲透的完整链路。
今天先打地基:回顾 Ceph 架构、梳理 K8s 存储体系、讲清两者的对接方式,为后续 14 篇中间件实战做好知识储备。
一、Ceph 分布式存储架构回顾
1.1 Ceph 核心组件
Ceph 是一个统一的分布式存储系统,对外提供三种存储接口(块、文件、对象),底层使用同一套 RADOS(Reliable Autonomic Distributed Object Store)存储集群。核心组件如下:
| 组件 | 全称 | 职责 | 部署要求 |
|---|---|---|---|
| MON | Monitor | 维护集群拓扑地图(CRUSH map)、监控集群健康 | 奇数个(3 或 5),跨节点部署 |
| OSD | Object Storage Daemon | 实际存储数据,处理读写、复制、恢复 | 每块磁盘一个 OSD |
| MGR | Manager | 提供监控指标、Dashboard、Balancer 模块 | 至少 1 个,推荐 2 个高可用 |
| MDS | Metadata Server | 管理 CephFS 元数据(目录树、文件属性) | 仅使用 CephFS 时部署 |
| RGW | Rados Gateway | 提供 S3/Swift 兼容的对象存储接口 | 仅使用对象存储时部署 |
用一条命令查看集群整体状态:
# 查看 Ceph 集群健康状态
ceph -s
# 输出示例:
# cluster:
# id: a3f7b2c0-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# health: HEALTH_OK
# services:
# mon: 3 daemons, quorum mon01,mon02,mon03
# mgr: mgr01(active), standbys: mgr02
# osd: 12 osds: 12 up, 12 in
# data:
# pools: 4 pools, 64 pgs
# objects: 1.2M objects, 850 GB
# usage: 1.2 TB used, 8.8 TB / 10 TB avail
# pgs: 64 active+clean
# 查看 OSD 拓扑树(按 host → rack → row → root 分层)
ceph osd tree
# 输出示例:
# ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
# -1 10.00000 root default
# -3 3.00000 host node01
# 0 hdd 1.00000 osd.0 up 1.00000 1.00000
# 1 hdd 1.00000 osd.1 up 1.00000 1.00000
# 2 hdd 1.00000 osd.2 up 1.00000 1.00000
# -5 3.00000 host node02
# 3 hdd 1.00000 osd.3 up 1.00000 1.00000
# …
1.2 Ceph 三大存储接口
Ceph 的核心优势在于”一套存储三种接口”,上层应用可以按需选择:
| 接口类型 | 组件 | 适用场景 | K8s 对接方式 |
|---|---|---|---|
| RBD(块设备) | OSD | 数据库、消息队列等需要高性能随机 IO | ceph-csi RBD 驱动 + StorageClass |
| CephFS(文件系统) | OSD + MDS | 多 Pod 共享读写、配置文件、日志 | ceph-csi CephFS 驱动 + StorageClass |
| RGW(对象存储) | OSD + RGW | 备份归档、图片附件、S3 兼容应用 | S3 SDK 或 Rook COSI |
本系列的中间件主要使用 RBD 块存储(数据库类)和 CephFS 文件存储(共享配置类),RGW 在 MinIO 篇章会做对比讲解。
1.3 CRUSH 算法与数据分布
Ceph 不依赖中心化元数据服务器来定位数据,而是使用 CRUSH(Controlled Replication Under Scalable Hashing)算法,客户端直接计算对象存储位置。这带来两个关键优势:
- 无单点:数据定位不依赖任何中心节点
- 弹性扩缩:增减 OSD 时,CRUSH 重新计算只迁移最少数据
# 查看 PG(Placement Group)分布状态
ceph pg dump –format plain | head -20
# 查看特定 Pool 的副本策略
ceph osd pool get replicapool size
# 输出:size: 3 (三副本)
# 查看纠删码池配置(EC 模式,省空间)
ceph osd pool get ecpool erasure_code_profile
# 输出:erasure_code_profile: default-4+2
二、Kubernetes 存储体系全景
2.1 PV/PVC/StorageClass 三件套
K8s 的存储体系由三个核心对象构成,理解它们的协作关系是后续所有实战的基础:
| 对象 | 作用 | 生命周期 | 创建方式 |
|---|---|---|---|
| PV (PersistentVolume) | 集群中的存储资源(如一块 Ceph RBD image) | 集群级 | 静态供给或动态创建 |
| PVC (PersistentVolumeClaim) | 用户对存储的申请(申请多大、什么类型) | 命名空间级 | 开发者声明 |
| StorageClass | 存储”模板”,定义动态供给的参数(CSI 驱动、副本数等) | 集群级 | 管理员预定义 |
工作流程:开发者创建 PVC → StorageClass 匹配 → CSI 驱动自动在 Ceph 上创建 RBD image → 绑定 PV → Pod 挂载使用。
2.2 CSI 机制详解
CSI(Container Storage Interface)是 K8s 与存储系统之间的标准接口。Ceph 通过 ceph-csi 项目提供两个驱动:
- RBD CSI:
rbd.csi.ceph.com— 提供块存储,ReadWriteOnce(单 Pod 读写),适合数据库 - CephFS CSI:
cephfs.csi.ceph.com— 提供文件存储,ReadWriteMany(多 Pod 共享读写),适合配置共享
# 查看 K8s 集群中已安装的 CSI 驱动
kubectl get csidrivers
# 输出示例:
# NAME ATTACHREQUIRED STORAGECLASS
# rbd.csi.ceph.com true ceph-rbd-sc
#cephfs.csi.ceph.com true cephfs-sc
# 查看 CSI 驱动的运行 Pod(通常部署在 kube-system 命名空间)
kubectl get pods -n kube-system | grep ceph-csi
# 输出示例:
# csi-rbdplugin-xxxxx 3/3 Running 0 12h
# csi-rbdplugin-provisioner 4/4 Running 0 12h
# csi-cephfsplugin-xxxxx 3/3 Running 0 12h
2.3 静态 vs 动态供给
| 模式 | 流程 | 适用场景 |
|---|---|---|
| 静态供给 | 管理员手动创建 Ceph image → 创建 PV → PVC 绑定 | 已有数据迁移、精确控制 |
| 动态供给(推荐) | PVC 直接引用 StorageClass → CSI 自动创建 image 和 PV | 标准部署、Helm Chart 默认模式 |
本系列所有中间件部署统一使用动态供给模式。
三、Ceph 接入 K8s 的架构设计
3.1 整体架构拓扑
Ceph 集群与 K8s 集群的网络拓扑是关键设计点。生产环境推荐以下架构:
┌─────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Master-1 │ │ Master-2 │ │ Master-3 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Worker-1 │ │ Worker-2 │ │ Worker-3 │ │
│ │ (MySQL) │ │ (Redis) │ │ (Kafka) │ │
│ └─────┬────┘ └─────┬────┘ └─────┬────┘ │
│ │PVC │PVC │PVC │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ ceph-csi (RBD + CephFS 驱动) │ │
│ └──────────────────┬───────────────────┘ │
│ │ 网络平面 │
└─────────────────────┼─────────────────────────────┘
│
┌─────────────────────┼─────────────────────────────┐
│ Ceph 存储集群 │
│ │ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ MON x3 │ │ MGR x2 │ │ MDS x2 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ OSD 池 (12+ 块磁盘, 三副本) │ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │osd.0 │ │osd.1 │ │osd.2 │ … │ │
│ │ └──────┘ └──────┘ └──────┘ │ │
│ └──────────────────────────────────────┘ │
└───────────────────────────────────────────────────┘
3.2 网络规划
Ceph 和 K8s 之间的网络连通性是接入的前提。两种常见方案:
| 方案 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| Ceph 与 K8s 混部 | 同一组节点既跑 K8s 又跑 Ceph | 网络零延迟、硬件利用率高 | 存储和计算争抢资源 |
| Ceph 与 K8s 分离 | Ceph 独立节点,K8s 独立节点,网络互通 | 资源隔离、故障隔离好 | 需要额外网络规划 |
# 在 K8s 节点上测试与 Ceph MON 的网络连通性
# 假设 Ceph MON 运行在 10.0.1.10/11/12,端口 6789
for mon in 10.0.1.10 10.0.1.11 10.0.1.12; do
echo -n “MON $mon: “
nc -zv -w 2 $mon 6789 2>&1
done
# 测试 OSD 网络(端口 6800-7300 范围)
nc -zv -w 2 10.0.1.10 6800 2>&1
3.3 Ceph CSI 部署要点
ceph-csi 通常以 Helm Chart 或 DaemonSet + Deployment 形式部署在 K8s 集群中。关键配置项:
# ceph-csi-values.yaml — RBD CSI 关键配置
csiConfig:
– clusterID: “a3f7b2c0-xxxx-xxxx-xxxx-xxxxxxxxxxxx”
monitors:
– “10.0.1.10:6789”
– “10.0.1.11:6789”
– “10.0.1.12:6789”
# RBD StorageClass — 中间件部署的核心引用对象
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID: “a3f7b2c0-xxxx-xxxx-xxxx-xxxxxxxxxxxx”
pool: “rbdpool”
imageFeatures: “layering”
csi.storage.k8s.io/provisioner-secret-name: ceph-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: kube-system
csi.storage.k8s.io/node-stage-secret-name: ceph-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: kube-system
reclaimPolicy: Retain
allowVolumeExpansion: true
# CephFS StorageClass — 共享文件存储用
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID: “a3f7b2c0-xxxx-xxxx-xxxx-xxxxxxxxxxxx”
fsName: “cephfs”
pool: “cephfs_data”
csi.storage.k8s.io/provisioner-secret-name: cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: kube-system
csi.storage.k8s.io/node-stage-secret-name: cephfs-secret
csi.storage.k8s.io/node-stage-secret-namespace: kube-system
reclaimPolicy: Retain
allowVolumeExpansion: true
四、中间件存储选型策略
4.1 块存储 vs 文件存储 vs 对象存储
不同中间件对存储的 IO 模式不同,选对存储类型是性能和可靠性的前提:
| 存储类型 | IO 特性 | 访问模式 | 适合的中间件 |
|---|---|---|---|
| RBD 块存储 | 高 IOPS、低延迟、随机读写 | RWO(单 Pod 读写) | MySQL, Redis, Kafka, MongoDB, ClickHouse |
| CephFS 文件存储 | 多 Pod 共享、顺序读写为主 | RWX(多 Pod 读写) | Nacos 配置共享, GitLab 仓库共享, ES 快照 |
| RGW 对象存储 | 高吞吐、海量小文件 | HTTP/S3 API | MinIO 对比, 备份归档, 日志归档 |
4.2 本系列各篇存储选型一览
提前剧透——后面 14 篇每个中间件的存储方案:
| 天数 | 中间件 | 存储类型 | StorageClass | 理由 |
|---|---|---|---|---|
| 2 | Ceph RBD 接入 | — | — | 基础设施篇 |
| 3 | CephFS 接入 | — | — | 基础设施篇 |
| 4 | MySQL | RBD | ceph-rbd-sc | 数据库需要块设备,高 IOPS |
| 5 | Redis Cluster | RBD | ceph-rbd-sc | 持久化用块设备 |
| 6 | Redis Sentinel | RBD | ceph-rbd-sc | 同上,哨兵 + 单点 Redis |
| 7 | MinIO | RBD | ceph-rbd-sc | MinIO 自身管理纠删码,底层要块设备 |
| 8 | MongoDB | RBD | ceph-rbd-sc | WiredTiger 引擎需要块设备 |
| 9 | Nacos | CephFS | cephfs-sc | 集群配置共享,多 Pod RWX |
| 10 | Zookeeper | RBD | ceph-rbd-sc | 事务日志需要块设备 |
| 11 | Elasticsearch | RBD | ceph-rbd-sc | Lucene 段文件需要高 IOPS |
| 12 | Kafka | RBD | ceph-rbd-sc | 消息日志追加写,块设备 |
| 13 | GitLab | RBD + CephFS | 混合 | 仓库用块,共享用文件 |
| 14 | ClickHouse | RBD | ceph-rbd-sc | 列式存储需要块设备 |
| 15 | 监控巡检总结 | — | — | 运维总结篇 |
五、常用巡检命令速查
Ceph 和 K8s 存储的日常巡检基础命令,贯穿后续每一篇:
# === Ceph 集群巡检 ===
ceph -s # 集群整体健康
ceph health detail # 健康问题详情
ceph df # 存储池容量使用
ceph osd pool ls # 列出所有存储池
ceph osd stat # OSD 状态统计
ceph pg stat # PG 状态统计
# === K8s 存储巡检 ===
kubectl get sc # 列出所有 StorageClass
kubectl get pv # 列出所有 PV
kubectl get pvc -A # 全命名空间 PVC 状态
kubectl describe pvc <name> -n <ns> # PVC 事件详情
kubectl get volumeattachments # 卷挂载状态
kubectl logs -n kube-system <csi-pod> # CSI 驱动日志
常见问题
Q: Ceph 集群健康状态显示 HEALTH_WARN,还能给 K8s 用吗?
A: 可以,但需排查原因。常见告警:PG 数量超出推荐值(pg_num 过多)、OSD 容量接近满(>85%)、少量 PG 不活跃。HEALTH_ERR 状态才需要立即停止写入。建议先用 ceph health detail 查看具体告警项,修复后再对接 K8s。
Q: ceph-csi 部署在 K8s 集群还是 Ceph 集群?
A: 部署在 K8s 集群。ceph-csi 以 DaemonSet(每个 Worker 节点运行,负责卷挂载/卸载)+ Deployment(provisioner,负责动态创建/删除卷)的形式运行在 K8s 中。Ceph 集群只需提供 MON 地址和 CephX 认证凭据,不需要在 Ceph 侧安装任何 K8s 组件。
Q: 中间件 Helm Chart 默认的 storageClass 不支持 Ceph,怎么办?
A: 几乎所有 Bitnami 和官方 Chart 都支持通过 values.yaml 的 global.storageClass 或 persistence.storageClass 参数指定自定义 StorageClass。部署时传入 --set global.storageClass=ceph-rbd-sc 或在 values.yaml 中配置即可,无需修改 Chart 模板。
总结
今天梳理了 Ceph 分布式存储的架构体系和 K8s 存储体系的对接全景,核心要点:
- Ceph 通过 RADOS 统一后端提供 RBD/CephFS/RGW 三种接口,中间件主要用 RBD 块存储
- K8s 通过 PV/PVC/StorageClass + ceph-csi 实现动态供给,开发者只需声明 PVC
- 生产环境推荐 Ceph 与 K8s 网络互通但节点分离部署
- 每种中间件的存储选型需根据 IO 模式决定(块 vs 文件 vs 对象)
- 后续每篇中间件部署统一用开源 Helm Chart + Ceph StorageClass 动态供给
下期预告
第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战)
下一篇将手把手部署 ceph-csi RBD 驱动,配置 StorageClass,创建测试 PVC 验证动态供给全流程,为后续所有中间件部署打好存储基础。
系列目录
- 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述 ← 本篇
- 第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战) 🔜
- 第 3 天:K8s 接入 CephFS 共享文件存储(多读场景与性能调优) 🔜
- 第 4 天:K8s 部署 MySQL 高可用集群 🔜
- 第 5 天:K8s 部署 Redis Cluster 集群 🔜
- 第 6 天:K8s 部署 Redis Sentinel 哨兵模式 🔜
- 第 7 天:K8s 部署 MinIO 对象存储集群 🔜
- 第 8 天:K8s 部署 MongoDB 副本集集群 🔜
- 第 9 天:K8s 部署 Nacos 注册配置中心 🔜
- 第 10 天:K8s 部署 Zookeeper 集群 🔜
- 第 11 天:K8s 部署 Elasticsearch 集群 🔜
- 第 12 天:K8s 部署 Kafka 集群 🔜
- 第 13 天:K8s 部署 GitLab 代码托管平台 🔜
- 第 14 天:K8s 部署 ClickHouse 列式数据库集群 🔜
- 第 15 天:K8s 中间件统一监控与运维巡检总结 🔜
![图片[2] - Ceph+K8s 中间件实战 | 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述 - 恒星](https://www.stellardata.top/wp-content/uploads/2026/09/微信公众号二维码.jpg)


















暂无评论内容