第 7/15 天 · Ceph+K8s 中间件实战系列
引言
在云原生体系中,对象存储是海量非结构化数据的首选落地方案。无论是应用日志归档、ML 训练数据集、容器镜像仓库后端,还是备份与灾备场景,对象存储凭借扁平命名空间、无限扩展能力和 HTTP 原生协议,成为分布式存储栈中不可或缺的一环。
当 Ceph 已为 K8s 提供了 RBD 块存储和 CephFS 文件存储后,我们完全可以复用同一套 Ceph 后端,在 K8s 上部署 MinIO 对象存储集群。MinIO 是高性能、S3 兼容的开源对象存储,官方提供完善的 Helm Chart,天然适配 K8s 的 StatefulSet + PVC 模型。本篇将基于官方 minio/minio Helm Chart,在 Ceph RBD StorageClass 之上部署一套 4 节点分布式 MinIO 集群,完整覆盖架构设计、部署实战、登录验证与日常巡检。

设计架构
组件拓扑
MinIO 分布式集群在 K8s 上的部署形态如下:
| 组件 | 说明 |
|---|---|
| MinIO Server Pod | 通过 StatefulSet 部署 4 个副本,每个 Pod 运行一个 MinIO Server 实例 |
| PVC(持久卷) | 每个 Pod 绑定一个 Ceph RBD PVC,用于存储对象数据 |
| Service | Headless Service 供 Pod 间互相发现;ClusterIP Service 供集群内访问 |
| MinIO Console | 内置 Web 管理界面,独立 Service 暴露 |
| Ingress / NodePort | 对外暴露 S3 API 和 Console 端口 |
数据流向
Client (mc / SDK / 浏览器)
│
▼
Service (minio-svc:9000) ──→ 负载分发到 4 个 Pod
│
├── Pod-0 (minio-0) ──→ PVC-0 (Ceph RBD pv-0)
├── Pod-1 (minio-1) ──→ PVC-1 (Ceph RBD pv-1)
├── Pod-2 (minio-2) ──→ PVC-2 (Ceph RBD pv-2)
└── Pod-3 (minio-3) ──→ PVC-3 (Ceph RBD pv-3)
│
▼
Ceph RBD 集群
│
▼
Ceph OSD 磁盘池
高可用机制
MinIO 分布式模式采用 纠删码(Erasure Coding) 实现数据冗余与自愈:
- 4 节点起步:分布式模式最少需要 4 个节点(Pod),数据与奇偶校验分片分布在不同节点的独立卷上。
- 纠删码集:默认 EC:4(4 数据 + 4 奇偶),在 4×4=16 磁盘配置下可容忍 8 块磁盘故障而数据不丢失。对于 4 节点单盘配置,采用 EC 模式后最多容忍 2 节点宕机仍可读、1 节点宕机可写。
- 自动自愈:当故障节点恢复后,MinIO 自动从其他分片恢复数据,无需人工干预。
- Pod 级容错:StatefulSet 保证 Pod 身份稳定(minio-0/1/2/3),Pod 重建后自动重新挂载原 PVC,数据不丢失。
存储规划
| 资源 | 配置 | 说明 |
|---|---|---|
| StorageClass | ceph-rbd-sc |
第 2 天创建的 Ceph RBD StorageClass |
| 每节点 PVC | 50Gi | 生产环境建议根据数据量调整 |
| 访问模式 | ReadWriteOnce |
RBD 块存储为块设备,每 PVC 单 Pod 独占挂载 |
| 可用容量 | 约 50% | 纠删码模式下,4 节点 50Gi×4 = 200Gi 原始空间,可用约 100Gi |
注意:MinIO 在分布式模式下,可用容量取决于纠删码配置。4 节点默认配置下可用空间约为总容量的一半。
部署实战
前置条件确认
确保 Ceph RBD StorageClass 已就绪:
# 确认 StorageClass 存在
kubectl get storageclass ceph-rbd-sc
# 确认 Ceph CSI 驱动正常运行
kubectl get pods -n ceph-csi-rbd -l app=ceph-csi-rbd
# 预期输出
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ceph-rbd-sc rbd.csi.ceph.com Delete Immediate true 3d
添加 MinIO 官方 Helm 仓库
# 添加 MinIO 官方 Helm Chart 仓库
helm repo add minio https://charts.min.io/
# 更新仓库索引
helm repo update
# 查看 MinIO Chart 版本
helm search repo minio/minio –versions | head -5
# 预期输出
# NAME CHART VERSION APP VERSION DESCRIPTION
# minio/minio 5.x.x RELEASE.xxxx High Performance, Kubernetes Native S3 …
编写 values.yaml 自定义配置
创建 minio-values.yaml,核心配置指向 Ceph RBD StorageClass 并启用分布式模式:
# minio-values.yaml — Ceph RBD + 分布式 MinIO 集群配置
# Chart: minio/minio
# — 副本数:分布式模式最少 4 —
replicaCount: 4
# — 镜像配置 —
image:
repository: quay.io/minio/minio
tag: RELEASE.2024-01-01T00-00-00Z
pullPolicy: IfNotPresent
# — 存储配置(核心:指向 Ceph RBD) —
persistence:
enabled: true
storageClass: "ceph-rbd-sc"
accessMode: ReadWriteOnce
size: 50Gi
annotations: { }
# — 纠删码分布模式 —
# 当 replicaCount >= 4 时,MinIO 自动启用分布式纠删码模式
mode: distributed
# — 凭证配置 —
rootUser: "minioadmin"
rootPassword: "MinI0Adm1n#2026"
# — 资源限制 —
resources:
requests:
memory: 1Gi
cpu: 1000m
limits:
memory: 4Gi
cpu: 4000m
# — Service 配置 —
service:
type: ClusterIP
port: 9000
consolePort: 9001
# — MinIO Console Web 管理 —
consoleService:
type: NodePort
port: 9001
nodePort: 30901
# — 环境变量 —
env:
– name: MINIO_BROWSER
value: "on"
# — 亲和性与反亲和性(保证 Pod 分散) —
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
– labelSelector:
matchExpressions:
– key: app.kubernetes.io/name
operator: In
values:
– minio
topologyKey: kubernetes.io/hostname
# — 生命周期管理 —
# 启用 Prometheus 指标暴露
prometheus:
serviceMonitors:
– interval: 30s
scrapeTimeout: 10s
Helm 部署命令
# 创建专用命名空间
kubectl create namespace middleware
# 执行 Helm 部署
helm install minio minio/minio
–namespace middleware
–values minio-values.yaml
# 预期输出
# NAME: minio
# LAST DEPLOYED: Tue Sep 29 00:30:00 2026
# NAMESPACE: middleware
# STATUS: deployed
# REVISION: 1
# TEST SUITE: None
验证部署状态
部署完成后,逐项验证 Pod、Service 和 PVC:
# 1. 查看 StatefulSet Pod 状态(4 个 Pod 均需 Running 且 Ready)
kubectl get pods -n middleware -l app.kubernetes.io/name=minio -o wide
# 预期输出:
# NAME READY STATUS RESTARTS AGE
# minio-0 1/1 Running 0 2m
# minio-1 1/1 Running 0 2m
# minio-2 1/1 Running 0 2m
# minio-3 1/1 Running 0 2m
# 2. 查看 Service
kubectl get svc -n middleware -l app.kubernetes.io/name=minio
# 预期输出:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# minio ClusterIP 10.96.200.1 <none> 9000/TCP 2m
# minio-console NodePort 10.96.200.2 <none> 9001:30901/TCP 2m
# minio-headless ClusterIP None <none> 9000/TCP 2m
# 3. 查看 PVC(4 个 PVC 均需 Bound)
kubectl get pvc -n middleware -l app.kubernetes.io/name=minio
# 预期输出:
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# export-minio-0 Bound pvc-xxxx-xxxx 50Gi RWO ceph-rbd-sc 2m
# export-minio-1 Bound pvc-yyyy-yyyy 50Gi RWO ceph-rbd-sc 2m
# export-minio-2 Bound pvc-zzzz-zzzz 50Gi RWO ceph-rbd-sc 2m
# export-minio-3 Bound pvc-wwww-wwww 50Gi RWO ceph-rbd-sc 2m
# 4. 检查 Ceph 后端实际创建的 RBD 镜像
kubectl exec -n ceph-csi-rbd <csi-plugin-pod> — rbd ls -p k8s-pool 2>/dev/null || echo "在 Ceph 节点执行 rbd ls -p k8s-pool 确认"

登录验证
安装 mc 客户端并连接集群
# 下载 MinIO Client (mc)
curl -O https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
mv mc /usr/local/bin/
# 配置别名连接集群(集群内访问用 Service 名)
mc alias set minio http://minio.middleware.svc.cluster.local:9000 minioadmin 'MinI0Adm1n#2026'
# 验证连接
mc admin info minio
# 预期输出:
# ● minio-0.minio-headless.middleware.svc.cluster.local:9000
# Uptime: 2 minutes
# Version: 2024-01-01T00:00:00Z
# ● minio-1.minio-headless.middleware.svc.cluster.local:9000
# Uptime: 2 minutes
# ● minio-2.minio-headless.middleware.svc.cluster.local:9000
# Uptime: 2 minutes
# ● minio-3.minio-headless.middleware.svc.cluster.local:9000
# Uptime: 2 minutes
#
# Disk usage:
# Total: 200 GiB
# Usage: 0 B
验证纠删码集群状态
# 查看集群健康详情
mc admin info minio –json | python3 -m json.tool
# 创建测试 Bucket 验证读写
mc mb minio/test-bucket
echo "Hello Ceph+K8s MinIO" > /tmp/hello.txt
mc cp /tmp/hello.txt minio/test-bucket/
mc cat minio/test-bucket/hello.txt
# 预期输出: Hello Ceph+K8s MinIO
# 列出所有 Bucket
mc ls minio
# 预期输出: [2026-09-29 00:35:00 CST] 0B test-bucket/
# 清理测试数据
mc rm minio/test-bucket/hello.txt
mc rb minio/test-bucket
Web Console 登录验证
MinIO Console 通过 NodePort 30901 暴露,可从集群节点直接访问:
浏览器访问: http://<任意Node-IP>:30901
用户名: minioadmin
密码: MinI0Adm1n#2026
登录后可在 Console 中查看:集群节点拓扑、磁盘使用率、Bucket 管理、用户与策略管理。
日常巡检
健康检查
# 1. Pod 健康状态巡检
kubectl get pods -n middleware -l app.kubernetes.io/name=minio
# 2. 查看集群健康状态
mc admin info minio
# 3. 检查 PVC 绑定状态与容量
kubectl get pvc -n middleware -l app.kubernetes.io/name=minio
# 4. 检查 Helm Release 状态
helm status minio -n middleware
日志查看
# 查看某个 Pod 的日志(如 minio-0)
kubectl logs -n middleware minio-0 –tail=100
# 实时跟踪所有 Pod 日志
kubectl logs -n middleware -l app.kubernetes.io/name=minio -f –max-log-requests=4
# 查看启动日志(排查启动问题)
kubectl logs -n middleware minio-0 –since=30m
# 查看事件(排查 PVC 绑定失败等问题)
kubectl get events -n middleware –sort-by='.lastTimestamp' | grep -i minio
性能监控
# 1. 查看集群磁盘使用率
mc admin info minio | grep -A 10 "Disk"
# 2. 查看各节点性能指标
mc admin info minio –json | python3 -c "
import sys, json
data = json.load(sys.stdin)
for srv in data.get('servers', []):
print(f" {srv['endpoint']} | CPU: {srv.get('cpu','N/A')} | Mem: {srv.get('mem','N/A')}")"
# 3. Prometheus 抓取 MinIO 指标(如果已配置 ServiceMonitor)
# MinIO 暴露 :9000/metrics 端点
curl -s http://minio.middleware.svc.cluster.local:9000/metrics | grep minio_
# 4. 查看对象写入带宽
mc admin trace minio –call s3.PutObject –verbose
容量巡检
# 查看每个 Bucket 的容量使用
mc du minio –depth 1
# 预期输出:
# 1.2Gi minio/app-logs/
# 5.0Gi minio/ml-datasets/
# 500Mi minio/backup/
# 6.7Gi TOTAL
# 查看 PVC 实际使用(在 Ceph 端)
# 在 Ceph 节点执行:
# rbd du -p k8s-pool | grep minio
# 设置 Bucket 容量配额
mc quota set minio/app-logs –size 10Gi
mc quota info minio/app-logs
版本升级巡检
# 查看当前 MinIO 版本
mc admin info minio | grep Version
# 检查 Helm Chart 可升级版本
helm search repo minio/minio –versions | head -10
# 执行滚动升级(StatefulSet 逐 Pod 滚动)
helm upgrade minio minio/minio
–namespace middleware
–values minio-values.yaml
–set image.tag=RELEASE.2024-06-01T00-00-00Z
# 升级后验证集群一致性
mc admin heal minio –recursive
常见问题
Q1: Pod 一直处于 Pending 状态,PVC 绑定失败?
常见原因:StorageClass 名称不匹配或 Ceph CSI Provisioner 未正常工作。排查步骤:
# 查看事件
kubectl describe pod -n middleware minio-0 | tail -20
# 检查 StorageClass
kubectl get storageclass ceph-rbd-sc
# 检查 CSI Provisioner Pod
kubectl get pods -n ceph-csi-rbd | grep provisioner
若 StorageClass 名称不同,修改 minio-values.yaml 中 persistence.storageClass 为实际名称后执行 helm upgrade。
Q2: 分布式模式下 Pod 数量不足 4 个会怎样?
MinIO 分布式模式要求最少 4 个节点。如果 replicaCount 设为 2 或 3,MinIO 启动时会报错并进入循环重启状态。生产环境建议至少 4 节点,扩容时以 4 的倍数增加(如 8、16 节点)。
Q3: 纠删码模式下可用空间只有一半,是否浪费?
纠删码的奇偶校验分片换来了数据冗余与容错能力,这是有意的权衡。若容量是首要关切而非容错,可考虑:①增加节点数(从 4 扩到 8,可用比例提升);②将 MinIO 直接对接 Ceph RGW(Ceph 原生对象网关),利用 Ceph 自身的副本/纠删码池,MinIO 仅作 S3 兼容层。
总结
本篇在 Ceph RBD 块存储基础上,使用官方 minio/minio Helm Chart 部署了 4 节点分布式 MinIO 对象存储集群。关键要点回顾:
- 架构设计:StatefulSet 4 副本 + Headless Service + 每节点独立 Ceph RBD PVC,实现 Pod 身份稳定与数据持久化。
- 纠删码高可用:4 节点分布式模式自动启用纠删码,容忍节点级故障且数据自愈,无需额外开销。
- Helm 部署:官方 Chart 配合
values.yaml中storageClass: ceph-rbd-sc即可无缝接入 Ceph 后端。 - 运维闭环:mc 客户端 + kubectl + Prometheus 指标构成完整的登录验证与日常巡检工具链。
MinIO 部署完成后,后续章节中部署的 GitLab(代码仓库 LFS)、ClickHouse(备份)等中间件均可使用 MinIO 作为对象存储后端,形成完整的存储栈。
下期预告
第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录) — 将使用 Bitnami 官方 Helm Chart 部署 MongoDB 副本集,配合 Ceph RBD 持久化,实现文档数据库在 K8s 上的高可用运行。敬请期待。
系列目录
- ✅ 第 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 全景)

















暂无评论内容