Ceph+K8s 中间件实战 | 第 7 天:K8s 部署 MinIO 对象存储集群(分布式架构 + 运维巡检)

第 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 集群,完整覆盖架构设计、部署实战、登录验证与日常巡检。

K8s Logo

设计架构

组件拓扑

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 确认"

K8s Logo

登录验证

安装 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 对象存储集群。关键要点回顾:

  1. 架构设计:StatefulSet 4 副本 + Headless Service + 每节点独立 Ceph RBD PVC,实现 Pod 身份稳定与数据持久化。
  2. 纠删码高可用:4 节点分布式模式自动启用纠删码,容忍节点级故障且数据自愈,无需额外开销。
  3. Helm 部署:官方 Chart 配合 values.yaml 中 storageClass: ceph-rbd-sc 即可无缝接入 Ceph 后端。
  4. 运维闭环:mc 客户端 + kubectl + Prometheus 指标构成完整的登录验证与日常巡检工具链。

MinIO 部署完成后,后续章节中部署的 GitLab(代码仓库 LFS)、ClickHouse(备份)等中间件均可使用 MinIO 作为对象存储后端,形成完整的存储栈。

下期预告

第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录) — 将使用 Bitnami 官方 Helm Chart 部署 MongoDB 副本集,配合 Ceph RBD 持久化,实现文档数据库在 K8s 上的高可用运行。敬请期待。

系列目录

微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 恒星
欢迎您留下宝贵的见解!
提交
头像 - 恒星

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容