欢迎光临
我们一直在努力

云原生实战:手把手教你用 Helm 在 K8s 上部署高可用 MinIO 集群

当你的业务已经全面拥抱 Kubernetes,存储层却还在裸机上手工维护,这本身就是一种架构割裂。MinIO 作为云原生时代对象存储的代表,对 K8s 有着近乎原生的支持——它本身就被设计为在容器化环境中运行。

这篇文章,我们不谈概念,只讲实操:如何在你的 K8s 集群里,用 Helm 一键部署一套高可用的 MinIO 分布式集群。整个过程大约 20 分钟,读完后你可以立即在环境里复现。


前置准备

开始之前,请确保你的环境满足以下条件:

项目要求
Kubernetes 集群 1.20+,至少 3 个 Worker 节点
Helm 3.8+
StorageClass 集群内已配置可用的 SC(如 NFS、Ceph RBD、云盘等)
内存 每个 Worker 节点建议 8GB+
磁盘 Worker 节点挂载 SSD 数据盘(用于 PV)

关于 StorageClass 的特别提醒:MinIO 在 K8s 中运行需要持久化存储。如果你使用云厂商托管 K8s(如阿里云 ACK、腾讯云 TKE、AWS EKS),通常默认就带有云盘 StorageClass。如果是自建集群,请提前部署好 NFS、Ceph 或 OpenEBS 等存储方案。

验证你的 StorageClass:

kubectl get sc

如果输出中有 (default) 标记的 StorageClass,说明存储就绪。


方案选择:Operator vs Helm Chart

MinIO 在 K8s 生态中提供两种部署方式:

对比维度MinIO OperatorHelm Chart
定位 企业级全功能管理平台 轻量级快速部署
功能 支持多租户、TLS自动配置、监控集成、升级管理 仅部署 MinIO 服务
复杂度 高,需要学习 Operator 概念 低,一条命令安装
适用场景 大规模生产环境、多团队共享 中小型集群、快速验证、DevOps 场景

本文选择 Helm Chart 方案,原因是:

  • 大多数团队的 K8s 存储需求并不复杂,不需要引入 Operator 的认知负担
  • Helm 部署更快,15 分钟就能看到成果
  • 理解 Helm 部署后,再迁移到 Operator 也会更顺畅

  • 第一步:添加 MinIO Helm 仓库

    # 添加官方仓库
    helm repo add minio https://charts.min.io/

    # 更新索引
    helm repo update

    # 查看可用的 Chart 版本
    helm search repo minio/minio –versions | head -5

    你会看到类似输出:

    NAME CHART VERSIONAPP VERSIONDESCRIPTION
    minio/minio 5.2.0 RELEASE.2024-… Multi-Cloud Object Storage

    版本选择建议:生产环境不要追最新版,选择一个已发布 1~2 个月的稳定版本。本文以 5.2.0 为例。


    第二步:定制 values.yaml

    Helm Chart 的强大之处在于可配置。MinIO 官方 Chart 有上百个参数,但我们只需要关注生产环境最核心的那些。

    创建一个 minio-values.yaml:

    # ========================================
    # 基础配置
    # ========================================

    # 集群模式:true = 分布式,false = 单机
    mode: distributed

    # 分布式模式的节点数(必须是 4 的倍数,推荐 4)
    replicas: 4

    # 每个节点的磁盘数(总磁盘数 = replicas × drivesPerNode)
    drivesPerNode: 1

    # Root 凭证(生产环境请务必修改!)
    rootUser: "minioadmin"
    rootPassword: "minioadmin"

    # ========================================
    # 持久化存储配置
    # ========================================

    persistence:
    enabled: true
    storageClass: "" # 留空则使用集群 default SC;也可指定如 "nfs-client"
    accessMode: ReadWriteOnce
    size: 100Gi # 每个节点的存储配额

    # ========================================
    # 服务暴露方式
    # ========================================

    service:
    type: ClusterIP # 集群内访问,配合 Ingress 暴露
    port: 9000

    consoleService:
    type: ClusterIP
    port: 9001

    # Ingress 配置(推荐生产环境使用)
    ingress:
    enabled: true
    ingressClassName: nginx # 根据你的 Ingress Controller 调整
    hostname: minioapi.yourdomain.com
    path: /
    pathType: Prefix
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "900"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "900"

    # Console 的独立 Ingress
    consoleIngress:
    enabled: true
    ingressClassName: nginx
    hostname: minioconsole.yourdomain.com
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"

    # ========================================
    # 资源限制(生产环境必须配置)
    # ========================================

    resources:
    requests:
    memory: "4Gi"
    cpu: "2000m"
    limits:
    memory: "8Gi"
    cpu: "4000m"

    # ========================================
    # 节点调度策略
    # ========================================

    # 反亲和性:确保每个 Pod 分布在不同节点,避免单节点故障导致数据丢失
    affinity:
    podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    labelSelector:
    matchLabels:
    app: minio
    topologyKey: kubernetes.io/hostname

    # 容忍与污点(可选,如果 Worker 节点打了专用污点)
    tolerations: []

    # ========================================
    # 监控与日志
    # ========================================

    # 启用 Prometheus 监控指标
    metrics:
    enabled: true
    serviceMonitor:
    enabled: true
    namespace: monitoring

    # 启用 Pod 安全上下文
    securityContext:
    enabled: true
    runAsUser: 1000
    runAsGroup: 1000

    # 启用 TLS(推荐生产环境)
    tls:
    enabled: false
    certSecret: ""
    publicCrt: ""
    privateKey: ""

    关键参数解读:

  • mode: distributed + replicas: 4:开启分布式模式,4 个 Pod 组成一个高可用集群。为什么是 4?因为这是 MinIO 纠删码(EC:2)的最小规模。

  • persistence.storageClass:留空表示使用集群默认的 StorageClass。如果你有多个存储后端(如 SSD 和 SATA),建议显式指定性能更好的那个。

  • podAntiAffinity:这是生产环境的硬性要求。它确保 4 个 MinIO Pod 分布在不同的 Worker 节点上。如果某台物理机宕机,只会影响 1 个 Pod,集群仍然可用。

  • resources:MinIO 对内存和 CPU 有一定要求,尤其是纠删码编解码会消耗计算资源。给每个 Pod 预留 4GB 内存和 2 核 CPU 是比较稳妥的起步配置。


  • 第三步:部署 MinIO

    配置文件准备就绪后,一条命令完成部署:

    # 创建命名空间(推荐隔离部署)
    kubectl create namespace minio-system

    # Helm 安装
    helm install minio minio/minio \\
    –namespace minio-system \\
    –version 5.2.0 \\
    -f minio-values.yaml \\
    –wait \\
    –timeout 600s

    参数说明:

    • –wait:等待所有 Pod 就绪后才返回,便于脚本化部署
    • –timeout 600s:分布式模式初始化可能需要几分钟,给足时间

    当看到以下输出时,说明安装成功:

    NAME: minio
    LAST DEPLOYED: Mon Jan 15 09:30:00 2026
    NAMESPACE: minio-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    1. Get the MinIO URL by running these commands:


    第四步:验证集群状态

    4.1 查看 Pod 分布

    kubectl get pods -n minio-system -o wide

    理想状态应该是 4 个 Pod,每个都 Running,并且分布在不同的节点上:

    NAME READY STATUS RESTARTS AGE IP NODE
    minio-0 1/1 Running 0 2m 10.244.1.10 k8s-node-01
    minio-1 1/1 Running 0 2m 10.244.2.15 k8s-node-02
    minio-2 1/1 Running 0 2m 10.244.3.20 k8s-node-03
    minio-3 1/1 Running 0 2m 10.244.4.25 k8s-node-04

    4.2 查看 PVC 绑定

    kubectl get pvc -n minio-system

    每个 Pod 会对应一个 PVC,状态应为 Bound:

    NAME STATUS VOLUME CAPACITY
    data-minio-0 Bound pvc-abc123-… 100Gi
    data-minio-1 Bound pvc-def456-… 100Gi
    data-minio-2 Bound pvc-ghi789-… 100Gi
    data-minio-3 Bound pvc-jkl012-… 100Gi

    4.3 查看持久化卷详情

    kubectl get pv | grep minio

    确认每个 PV 的容量、访问模式和回收策略都符合预期。


    第五步:访问 MinIO

    5.1 方式一:通过 Ingress(生产环境推荐)

    如果你配置了 Ingress,直接通过域名访问:

    • API 端点:http://minio-api.yourdomain.com
    • Console 控制台:http://minio-console.yourdomain.com

    用 values.yaml 中配置的 rootUser 和 rootPassword 登录。

    5.2 方式二:通过 kubectl port-forward(本地调试)

    # 端口转发 API
    kubectl port-forward svc/minio 9000:9000 -n minio-system &

    # 端口转发 Console
    kubectl port-forward svc/minio-console 9001:9001 -n minio-system &

    然后本地访问 http://localhost:9001。

    5.3 方式三:通过 NodePort(无 Ingress 环境)

    修改 values.yaml 中的 service.type 为 NodePort,重新执行 helm upgrade:

    helm upgrade minio minio/minio \\
    –namespace minio-system \\
    –set service.type=NodePort \\
    –set consoleService.type=NodePort

    查看分配的 NodePort:

    kubectl get svc -n minio-system


    第六步:使用 mc 连接 K8s 中的 MinIO

    在 K8s 内运行 MinIO 只是第一步,你的业务应用还需要连接它。在集群外的一台机器上配置 mc:

    # 下载 mc 客户端
    wget https://dl.min.io/client/mc/release/linux-amd64/mc
    chmod +x mc
    mv mc /usr/local/bin/

    # 添加 K8s MinIO 别名
    mc alias set k8s-minio http://minio-api.yourdomain.com minioadmin minioadmin

    # 查看集群信息
    mc admin info k8s-minio

    # 创建 bucket
    mc mb k8s-minio/mybucket

    # 上传测试文件
    mc cp ./test.txt k8s-minio/mybucket/

    # 验证文件
    mc ls k8s-minio/mybucket/

    如果一切正常,你会看到 Network 和 Drives 都显示 4/4 OK,说明分布式集群健康运行。


    第七步:生产环境必做的 3 件事

    7.1 修改默认密码

    在 values.yaml 中修改 rootPassword,然后执行:

    helm upgrade minio minio/minio \\
    –namespace minio-system \\
    -f minio-values.yaml

    注意:Helm upgrade 会触发 RollingUpdate,MinIO Pod 会逐个重启,但服务不会中断(因为有 4 个节点,可以同时容忍 2 个节点离线)。

    7.2 启用 TLS

    生产环境必须启用 HTTPS。推荐方案是:Ingress 层终止 TLS,MinIO 本身跑 HTTP。

    如果你已经配置了 cert-manager,只需修改 Ingress 注解:

    ingress:
    enabled: true
    annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod" # 或你的 CA Issuer
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    tls:
    secretName: minioapitls
    hosts:
    minioapi.yourdomain.com

    重新 apply 后,cert-manager 会自动签发并挂载证书。

    7.3 配置监控告警

    values.yaml 中已经启用了 metrics.enabled: true 和 serviceMonitor.enabled: true。接下来在 Prometheus 中导入 MinIO Dashboard(Grafana ID: 13502),并配置以下告警规则:

    groups:
    name: minioalerts
    rules:
    alert: MinioNodeOffline
    expr: minio_cluster_nodes_offline_total > 0
    for: 2m
    annotations:
    summary: "MinIO 节点离线"

    alert: MinioDiskOffline
    expr: minio_cluster_drive_offline_total > 0
    for: 1m
    annotations:
    summary: "MinIO 磁盘离线"

    alert: MinioHighDiskUsage
    expr: (minio_cluster_capacity_usable_free_bytes / minio_cluster_capacity_usable_total_bytes) < 0.2
    for: 5m
    annotations:
    summary: "MinIO 可用空间不足 20%"


    常见问题与排查

    Q1:Pod 一直处于 Pending 状态

    kubectl describe pod minio-0 -n minio-system

    最常见的原因:

    • PVC 无法绑定 → 检查 StorageClass 和底层存储 provisioner 是否正常
    • 资源不足 → 检查节点是否有足够的 CPU/内存
    • 节点亲和性冲突 → 如果配置了 podAntiAffinity,确保有足够的节点(至少 replicas 数量)

    Q2:Helm 安装超时

    分布式 MinIO 初始化时需要格式化磁盘和建立纠删码组,这个过程在慢速存储上可能需要 5~10 分钟。增加 timeout:

    helm install ... –timeout 1200s

    Q3:mc 连接报 “Server not initialized, please try again”

    说明集群还在初始化中,等 2~3 分钟后重试。如果持续报错,检查 Pod 日志:

    kubectl logs minio-0 -n minio-system

    Q4:如何扩容?

    Helm Chart 的分布式模式不支持在线扩容 replicas。如果需要扩容,必须:

  • 导出数据
  • 卸载 Helm release:helm uninstall minio -n minio-system
  • 修改 values.yaml 中的 replicas(如从 4 改到 8)
  • 重新安装
  • 注意:这会导致服务中断。生产环境建议使用 MinIO Operator,它支持 Server Pool 在线扩容。


    总结

    通过这篇文章,我们在 Kubernetes 集群中完成了以下工作:

  • 选型决策:对比了 Operator 与 Helm Chart,选择了更适合快速落地的 Helm 方案
  • 环境准备:验证了 K8s 集群和 StorageClass 就绪
  • 配置定制:编写了生产级 values.yaml,重点配置了持久化、反亲和性、资源限制和 Ingress
  • 一键部署:使用 Helm 安装了 4 节点分布式 MinIO
  • 验证访问:通过 mc 客户端确认集群健康,并完成了 Bucket 创建和文件上传
  • 生产加固:修改密码、启用 TLS、接入 Prometheus 监控告警
  • MinIO 在 K8s 上的部署,核心优势在于基础设施即代码(IaC):整个存储集群的配置都收敛在一个 values.yaml 中,版本管理、回滚、重建都变得极其简单。当你的应用已经容器化,存储层没有理由还停留在手工运维时代。

    如果你在部署过程中遇到问题,欢迎在评论区交流。

    赞(0)
    未经允许不得转载:171主机测评 » 云原生实战:手把手教你用 Helm 在 K8s 上部署高可用 MinIO 集群
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址