在 Kubernetes 上部署 MinIO 对象存储:基于 examples 仓库的 Standalone 与 Distributed 完整实战指南

📅 发布时间:2026/10/7 21:04:05
在 Kubernetes 上部署 MinIO 对象存储:基于 examples 仓库的 Standalone 与 Distributed 完整实战指南
示例工程【免费下载链接】examplesKubernetes application example tutorials项目地址https://gitcode.com/gh_mirrors/examp/examples点击查看免费下载本指南以 examples 仓库中归档的 MinIO 示例文档_archived/storage/minio/README.md为骨架完整讲解如何在 Kubernetes 上以云原生方式部署 MinIOAWS S3 兼容的对象存储服务一套是使用 Deployment PVC LoadBalancer 的单机Standalone方案另一套是使用 Headless Service StatefulSet 的四节点分布式Distributed方案。读完本文你将掌握两类部署的完整 YAML 清单、kubectl 操作命令、DNS 命名原理与资源清理方法并能直接在本仓库的清单文件基础上落地运行。MinIO 是什么S3 兼容的云原生对象存储MinIO 是一个面向云应用与 DevOps 场景的、与 AWS S3 兼容的对象存储服务器。它的关键特性是“云原生cloud native”MinIO 能够感知自身运行在集群管理器之中并直接利用集群管理基础设施来分配计算与存储资源而不是把自己当成一个需要手工绑定主机节点的传统存储进程。正是这种设计让它与 Kubernetes 天然契合存储资源的分配交给 Kubernetes 的 PersistentVolumeClaim / PersistentVolume 体系完成数据不随 Pod 生命周期丢失计算资源的编排交给 Deployment、StatefulSet 等控制器完成Pod 故障后会自动重建网络访问的暴露交给 ServiceClusterIP / NodePort / LoadBalancer体系完成集群内外均可按需访问。前置条件本示例假定你满足以下环境要求已安装并运行Kubernetes 版本 1.4的集群示例清单使用apps/v1API 版本适用于 1.9 及以后的版本更早版本需按清单内注释回退到apps/v1beta2或extensions/v1beta1详见下文已安装kubectl命令行工具并加入系统 PATH集群具备可动态供给的存储类示例中storageClassName: standard在 GKE 等云平台通常开箱即用。仓库中六个清单文件与本文各步骤一一对应位于_archived/storage/minio/目录下可直接以本地相对路径配合kubectl使用。一、单机Standalone部署单机方案把 MinIO 以单副本 Deployment 的方式运行数据挂载到持久卷上适用于开发测试或数据量有限的场景。该小节使用以下 Kubernetes 核心组件组件用途本示例对应资源Pod承载 MinIO 容器的运行单元Deployment 模板中生成Service提供稳定的网络访问入口minio-serviceLoadBalancerDeployment管理副本集与 Pod 生命周期故障自动恢复minio-deploymentPersistentVolumeClaim向集群申请持久化存储minio-pv-claim10Gi1.1 快速开始Quickstart如果只想快速跑起来按顺序执行下面三条命令即可本仓库中请将 URL 替换为本地清单路径如kubectl apply -f _archived/storage/minio/minio-standalone-pvc.yamlkubectl create -f minio-standalone-pvc.yaml kubectl create -f minio-standalone-deployment.yaml kubectl create -f minio-standalone-service.yaml1.2 Step 1创建持久化卷声明PVCMinIO 必须拥有持久化存储来保存对象数据。如果缺少持久化存储数据会被写入容器文件系统一旦容器重启数据即被清空——这显然是对象存储不可接受的。创建 PersistentVolumeClaim 即向集群“申请”存储Kubernetes 会自动在集群中寻找与 PVC 请求匹配的 PV 并完成绑定。本示例的 PVC 清单如下完整文件见 minio-standalone-pvc.yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: # This name uniquely identifies the PVC. Will be used in deployment below. name: minio-pv-claim labels: app: minio-storage-claim spec: accessModes: - ReadWriteOnce storageClassName: standard resources: # This is the request for storage. Should be available in the cluster. requests: storage: 10Gi执行创建kubectl create -f minio-standalone-pvc.yaml persistentvolumeclaim minio-pv-claim created对关键字段的说明accessModes: ReadWriteOnce表示该卷同一时刻只能被一个节点以读写方式挂载。对单机 MinIO 而言完全够用多副本共享读写需要 ReadWriteMany分布式方案正是通过“每个副本一块独立卷”绕开了这一限制storageClassName: standard指定存储类。在支持动态供给的云环境如 GKE 的 standard 存储类下PVC 创建后会由控制器自动创建底层 PV无需手工预置requests.storage: 10Gi申请 10GiB 容量需确保集群中有足够的可供给配额。1.3 Step 2创建 MinIO DeploymentDeployment 封装了副本集ReplicaSet与 Pod一旦某个 Pod 异常退出控制器会立刻拉起一个新 Pod 顶上因此你无需操心单点故障就能获得一个稳定可用的 MinIO 服务。本示例的 Deployment 清单如下完整文件见 minio-standalone-deployment.yamlapiVersion: apps/v1 # for k8s versions before 1.9.0 use apps/v1beta2 and before 1.8.0 use extensions/v1beta1 kind: Deployment metadata: # This name uniquely identifies the Deployment name: minio-deployment spec: selector: matchLabels: app: minio strategy: type: Recreate template: metadata: labels: # Label is used as selector in the service. app: minio spec: # Refer to the PVC created earlier volumes: - name: storage persistentVolumeClaim: # Name of the PVC created earlier claimName: minio-pv-claim containers: - name: minio # Pulls the default Minio image from Docker Hub image: minio/minio:latest args: - server - /storage env: # Minio access key and secret key - name: MINIO_ACCESS_KEY value: minio - name: MINIO_SECRET_KEY value: minio123 ports: - containerPort: 9000 hostPort: 9000 # Mount the volume into the pod volumeMounts: - name: storage # must match the volume name, above mountPath: /storage执行创建kubectl create -f minio-standalone-deployment.yaml deployment minio-deployment created逐段解读这个清单strategy.type: Recreate更新策略为“先删旧、再建新”。因为示例在 Pod 上声明了hostPort: 9000同一节点上同一端口只能被一个 Pod 占用Recreate 策略可以避免新旧 Pod 同时竞争端口volumespersistentVolumeClaim.claimName把第 1 步创建的minio-pv-claim挂进 PodvolumeMounts.mountPath: /storage将其挂载到容器内/storage目录同时args里的server /storage告诉 MinIO 把该目录作为数据盘环境变量通过MINIO_ACCESS_KEY/MINIO_SECRET_KEY设置访问密钥是客户端如 S3 SDK、mc 客户端访问该实例的凭证环境变量值说明MINIO_ACCESS_KEYminio访问密钥Access Key客户端登录/认证使用MINIO_SECRET_KEYminio123秘密密钥Secret Key需妥善保管portscontainerPort: 9000声明容器监听端口hostPort: 9000额外把端口绑定到宿主机。注意示例清单将密钥明文写入 YAML仅适合演示生产环境应改为从 Kubernetes Secret 注入见文末“生产化建议”。1.4 Step 3创建 MinIO ServiceDeployment 就绪后访问方式取决于你的使用场景是集群内部访问还是暴露到集群外部公网。这由 Service 类型决定——默认类型ClusterIP只对集群内部连接可见NodePort与LoadBalancer则会把服务暴露给外部流量。本示例通过创建LoadBalancer类型的 Service 把 MinIO 暴露到外部完整文件见 minio-standalone-service.yamlapiVersion: v1 kind: Service metadata: name: minio-service spec: type: LoadBalancer ports: - port: 9000 targetPort: 9000 protocol: TCP selector: app: minio执行创建kubectl create -f minio-standalone-service.yaml service minio-service created关键点说明selector.app: minioService 通过标签选择器路由到带有app: minio标签的 Pod这与 Deployment 模板中的labels: app: minio一一对应是流量正确转发的核心纽带port: 9000 / targetPort: 9000Service 对外端口与容器实际监听端口均为 9000protocol: TCP指定传输协议LoadBalancer 类型的 Service 通常需要云厂商GCP、AWS、Azure 等的负载均衡器支持分配外部 IP 一般需要几分钟。创建后可用以下命令确认是否成功kubectl get svc minio-service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE minio-service 10.55.248.23 104.199.249.165 9000:31852/TCP 1mEXTERNAL-IP出现后即可通过http://104.199.249.165:9000访问 MinIO 的 S3 API 与 Web 控制台登录凭据即上一步设置的环境变量。PORT(S)中的9000:31852/TCP表示集群内 Service 端口 9000 同时映射到了各节点的 31852 端口NodePort本地开发时也可通过kubectl port-forward svc/minio-service 9000:9000转发访问。1.5 Step 4资源清理使用完毕后按依赖顺序清理 Deployment、PVC 与 Servicekubectl delete deployment minio-deployment \ kubectl delete pvc minio-pv-claim \ kubectl delete svc minio-service1.6 单机模式要点小结数据持久化依赖 PVC缺了它容器重启即丢数据Deployment 提供自动恢复能力但hostPort: 9000与Recreate策略意味着同一节点只能运行一个实例横向扩容受限因此单机方案适合开发测试与轻量场景三种 Service 类型中ClusterIP 仅集群内可访问NodePort / LoadBalancer 面向外部流量按需选用。二、分布式Distributed部署分布式方案把 MinIO 以 4 副本 StatefulSet 的方式部署每个 Pod 挂载独立持久卷、通过内网 DNS 相互发现并组成一个分布式存储集群。该小节使用以下核心组件组件用途本示例对应资源Pod承载 MinIO 容器的运行单元StatefulSet 模板中生成ServiceHeadless Service 提供稳定 DNS 域minioclusterIP: NoneStatefulSet提供确定性命名与唯一身份管理有状态副本minioreplicas: 42.1 快速开始Quickstart按顺序执行三条命令本仓库中请使用本地路径如kubectl apply -f _archived/storage/minio/minio-distributed-headless-service.yamlkubectl create -f minio-distributed-headless-service.yaml kubectl create -f minio-distributed-statefulset.yaml kubectl create -f minio-distributed-service.yaml2.2 Step 1创建 MinIO Headless ServiceHeadless ServiceclusterIP: None控制了 StatefulSet 内部 Pod 所处的 DNS 域。该 Service 管理的域形如$(service name).$(namespace).svc.cluster.local其中cluster.local是集群域名域内 Pod 的完整域名形如$(pod-name-{i}).$(service name).$(namespace).svc.cluster.local。这是让 StatefulSet 中每个 Pod 都能获得可解析 DNS 地址的前提——分布式 MinIO 正是依靠这些域名互相通信。本示例的 Headless Service 清单如下完整文件见 minio-distributed-headless-service.yamlapiVersion: v1 kind: Service metadata: name: minio labels: app: minio spec: clusterIP: None ports: - port: 9000 name: minio selector: app: minio执行创建kubectl create -f minio-distributed-headless-service.yaml service minio created注意它与普通 Service 的两个区别一是clusterIP: None不分配集群 IP改为直接暴露每个 Pod 的 DNS 记录二是命名必须与 StatefulSet 的serviceName字段一致本例均为minio否则 Pod 无法进入该 DNS 域。2.3 Step 2创建 MinIO StatefulSetStatefulSet 为每个 Pod 提供确定性的名称与唯一身份非常适合部署有状态的分布式应用。要启动分布式 MinIO需要把各参与节点的数据盘地址作为参数传给minio server命令并且所有参与的 Pod 必须执行相同的命令——StatefulSet 恰好能完美满足这一要求。本示例的 StatefulSet 清单如下完整文件见 minio-distributed-statefulset.yaml# for k8s versions before 1.9.0 use apps/v1beta2 and before 1.8.0 use extensions/v1beta1 apiVersion: apps/v1 kind: StatefulSet metadata: name: minio labels: app: minio spec: serviceName: minio replicas: 4 selector: matchLabels: app: minio template: metadata: labels: app: minio spec: containers: - name: minio env: - name: MINIO_ACCESS_KEY value: minio - name: MINIO_SECRET_KEY value: minio123 image: minio/minio:latest args: - server - http://minio-0.minio.default.svc.cluster.local/data - http://minio-1.minio.default.svc.cluster.local/data - http://minio-2.minio.default.svc.cluster.local/data - http://minio-3.minio.default.svc.cluster.local/data ports: - containerPort: 9000 hostPort: 9000 # These volume mounts are persistent. Each pod in the Statefulset # gets a volume mounted based on this field. volumeMounts: - name: data mountPath: /data # These are converted to volume claims by the controller # and mounted at the paths mentioned above. volumeClaimTemplates: - metadata: name: data spec: accessModes: - ReadWriteOnce storageClassName: standard resources: requests: storage: 10Gi执行创建kubectl create -f minio-distributed-statefulset.yaml statefulset minio created关键字段解读serviceName: minio绑定第 1 步创建的 Headless Service使 Pod 获得可解析的稳定 DNS 域名replicas: 4创建 4 个副本。StatefulSet 按序创建并保证命名确定性Pod 名称依次为minio-0、minio-1、minio-2、minio-3args中的 4 个 URL把 4 个 Pod 的固定 DNS 地址http://minio-{i}.minio.default.svc.cluster.local/data其中default是命名空间一次性传给server命令四节点用完全相同的命令组成一个分布式实例。分布式 MinIO 采用纠删码Erasure Coding机制在多个节点间分散冗余数据这也正是它比单机方案具备更高数据可靠性、可横向扩展的根本原因该行为由 MinIO 服务端实现本仓库仅负责以正确方式把节点地址编排进参数volumeClaimTemplatesStatefulSet 专属字段。控制器会依据模板为每一个Pod 自动生成并绑定一块独立 PVC命名形如data-minio-0、data-minio-1……随后挂载到mountPath: /data。这正是分布式 MinIO 中“每个节点一块独立持久盘”的实现来源无需像单机方案那样手工预创建 PVC。2.4 Step 3创建 MinIO Service分布式 StatefulSet 就绪后同样通过 Service 决定访问方式。本示例继续使用 LoadBalancer 类型把整个集群暴露出去完整文件见 minio-distributed-service.yamlapiVersion: v1 kind: Service metadata: name: minio-service spec: type: LoadBalancer ports: - port: 9000 targetPort: 9000 protocol: TCP selector: app: minio执行创建kubectl create -f minio-distributed-service.yaml service minio-service created该 Service 的selector.app: minio会命中 StatefulSet 创建的全部 4 个 PodLoadBalancer 会把外部流量负载均衡到整个分布式集群的任意节点。创建后确认外部 IPkubectl get svc minio-service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE minio-service 10.55.248.23 104.199.249.165 9000:31852/TCP 1m2.5 Step 4资源清理分布式方案需要清理的对象比单机多一个 Headless Servicekubectl delete statefulset minio \ kubectl delete svc minio \ kubectl delete svc minio-service2.6 分布式模式原理DNS 命名与自动供给卷从源码与清单结构可以归纳出分布式部署的两个关键机制确定性 DNS 身份$(pod-name-{i}).$(service name).$(namespace).svc.cluster.local这一命名规则让 MinIO 各节点在启动时即可通过固定域名互连。即使某节点 Pod 被删除重建其名称与域名保持不变分布式集群的成员关系得以稳定维系按副本自动供给存储volumeClaimTemplates是 StatefulSet 与 Deployment 的核心差异之一。控制器为每个有序副本生成独立 PVC 与卷配合ReadWriteOnce访问模式天然满足“每节点独享数据盘”的分布式存储需求避免了单机方案中共享卷与Recreate策略的限制。三、仓库中的资源清单与本地实操路径本仓库将上述文档与清单统一归档在 _archived/storage/minio/ 目录下六个文件与部署步骤的对应关系如下文件对应步骤用途minio-standalone-pvc.yaml单机 Step 1申请 10Gi 持久卷minio-standalone-deployment.yaml单机 Step 2单副本 MinIO Deploymentminio-standalone-service.yaml单机 Step 3LoadBalancer 对外暴露minio-distributed-headless-service.yaml分布式 Step 1Headless Service 提供 DNS 域minio-distributed-statefulset.yaml分布式 Step 24 副本分布式 StatefulSetminio-distributed-service.yaml分布式 Step 3LoadBalancer 对外暴露本地实操时可将文中示例的kubectl create -f命令替换为仓库相对路径kubectl create与kubectl apply均可后者更适合反复调整清单的迭代场景例如kubectl apply -f _archived/storage/minio/minio-standalone-pvc.yaml kubectl apply -f _archived/storage/minio/minio-standalone-deployment.yaml kubectl apply -f _archived/storage/minio/minio-standalone-service.yaml排障时建议配合kubectl get pods、kubectl describe pod pod-name、kubectl logs pod-name查看运行状态与日志若集群无云负载均衡器如 minikube、Kind可将 Service 的type临时改为NodePort或使用kubectl port-forward访问。四、版本兼容与生产化建议API 版本适配两套清单头部注释均提示——Kubernetes 1.9.0 及以上使用apps/v11.8.01.9.0 之前使用apps/v1beta21.8.0 之前使用extensions/v1beta1。请依据集群实际版本选择这也是为什么本示例要求集群版本不低于 1.4凭据安全示例把MINIO_ACCESS_KEY/MINIO_SECRET_KEY明文写入 YAML仅适合演示。生产环境建议将密钥放入 Kubernetes Secret再以env.valueFrom.secretKeyRef方式注入容器避免凭据随清单泄露镜像版本示例使用minio/minio:latest便于复现。生产环境建议固定到明确的稳定版本标签tag保证集群内各节点镜像一致、可追溯资源与可用性生产环境建议为容器补充resources.requests/limitsCPU/内存声明并为minio容器配置就绪/存活探针readinessProbe / livenessProbe让负载均衡与故障恢复更精准副本数与纠删码分布式示例固定为 4 副本。实际副本数可根据容量与可靠性需求调整但所有节点的启动参数必须保持一致每个节点都要传入全部节点的地址这是分布式 MinIO 组建集群的硬性要求。结语本文基于 examples 仓库的归档文档与配套清单完整复现了 MinIO 在 Kubernetes 上的两套部署路径单机模式用 Deployment PVC 快速起一个带持久化的 S3 兼容存储分布式模式用 StatefulSet Headless Service 编排 4 节点存储集群。两者覆盖了 Kubernetes 有状态应用部署中最核心的组件组合PVC、Deployment、Service、Headless Service、StatefulSet、volumeClaimTemplates直接复用仓库中的清单即可在符合前置条件的集群上运行验证。赞分享示例工程【免费下载链接】examplesKubernetes application example tutorials项目地址https://gitcode.com/gh_mirrors/examp/examples点击查看免费下载相关推荐在 Kubernetes 上部署 Spark Standalone 集群基于 kubernetes-handbook 的 Master、Worker 与 Zeppelin 完整实战指南在 Kubernetes 上部署 Spark Standalone 集群基于 kubernetes handbook 的 Master、Worker 与 Ze教程云原生容器编排6 步解除 Wand 2 小时限制Wand-Enhancer 自建补丁完整指南6 步解除 Wand 2 小时限制Wand Enhancer 自建补丁完整指南 Wand 免费版每次只给 2 小时游戏时间AI 攻略还藏在付费墙后面。Wan桌面应用前端Kubernetes Handbook基于 Rook 在 Kubernetes 上编排部署 Ceph 分布式存储的完整实战指南Kubernetes Handbook基于 Rook 在 Kubernetes 上编排部署 Ceph 分布式存储的完整实战指南 本指南以 practice/r教程云原生容器编排上一篇macOS录屏新选择QuickRecorder的5大核心优势下一篇MELPA生态系统构建从单一仓库到完整开发平台的转型创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考