基于k8s的MinIO高可用部署方案

Posted by Forgus on 2026-04-11

一、当前部署状态

1.1 集群架构

  • K3s 版本: v1.34.5+k3s1
  • 节点数量: 6 节点 (1x amd64 master + 5x arm64 树莓派 worker)
  • 存储: Longhorn 分布式存储 (5 节点参与)
  • StorageClass: longhorn (默认), nfs-storage

1.2 现有 MinIO 部署

项目
部署方式 Deployment (单副本)
节点 k3s-master
存储 Longhorn RWO, 10Gi
访问 NodePort (30092/30093)
凭证 minioadmin/minioadmin

二、问题分析

问题 1: 单副本无高可用

  • 仅 1 个 Pod,无冗余
  • 节点故障 = 服务中断

问题 2: Pod 调度无约束

  • 可能调度到 master (amd64)
  • 无反亲和规则

问题 3: 缺少生产级配置

  • 无健康检查 (liveness/readiness)
  • 无资源限制
  • 凭证明文存储

三、部署方案对比

方案 类型 副本数 存储 高可用 复杂度
当前方案 Deployment 1 RWO
StatefulSet StatefulSet 5 RWO (每节点) 纠删码
分布式 MinIO StatefulSet 5 RWO + 纠删码 4+1

选择方案: StatefulSet + 5 节点纠删码

设计要点:

  1. 5 节点 StatefulSet: 每个 Pod 独立 PVC,通过 Longhorn 多副本同步
  2. Pod 反亲和: 强制分布在 5 个不同节点
  3. MinIO 纠删码 (4+1):
    • 4 数据块 + 1 校验块
    • 允许 1 节点故障
    • 存储效率 80%
  4. 健康检查: liveness + readiness probes
  5. 资源限制: CPU 500m-1000m, Memory 1Gi-2Gi
  6. Ingress: minio-console.forgus.local

四、配置清单

资源 名称 说明
ServiceAccount minio 认证
Headless Service minio-headless Pod 成员发现
NodePort Service minio-service 外部访问 (30092/30093)
StatefulSet minio 5 副本
PVC minio-data-minio-{0…4} 每节点 10Gi
Ingress minio-console-ingress 控制台域名

五、关键配置

5.1 纠删码配置

1
2
3
4
minio server \
http://minio-{0...4}.minio-headless.minio.svc.cluster.local:9000/data \
--console-address ":9001" \
--address ":9000"

5.2 Pod 反亲和

1
2
3
4
5
6
7
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: minio
topologyKey: kubernetes.io/hostname

5.3 存储配置

  • StorageClass: longhorn
  • AccessMode: ReadWriteOnce (每节点独立 PVC)
  • 每节点容量: 10Gi
  • 总容量: 50Gi (实际可用 ~40Gi)

六、部署文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
apiVersion: v1
kind: ServiceAccount
metadata:
name: minio
namespace: minio
---
# Headless Service(分布式内部通信必须)
apiVersion: v1
kind: Service
metadata:
name: minio-headless
namespace: minio
spec:
clusterIP: None
ports:
- name: api
port: 9000 # API 固定 9000
- name: console
port: 9001 # 控制台固定 9001
selector:
app: minio
---
# NodePort Service(外部访问)
apiVersion: v1
kind: Service
metadata:
name: minio-service
namespace: minio
spec:
type: NodePort # 修复拼写
ports:
- name: api
port: 9000
targetPort: 9000
nodePort: 30092 # Spring Boot 连接端口
- name: console
port: 9001
targetPort: 9001
nodePort: 30093 # 浏览器访问端口
selector:
app: minio
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
namespace: minio
spec:
serviceName: minio-headless
replicas: 5
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
# 强制只调度到 arm64 节点(你环境必须加!)
nodeSelector:
kubernetes.io/arch: arm64

# 反亲和:每个节点只跑一个 minio
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: minio
topologyKey: kubernetes.io/hostname

containers:
- name: minio
image: pgsty/minio:latest-arm64
command:
- /bin/sh
- -c
- |
minio server \
http://minio-{0...4}.minio-headless.minio.svc.cluster.local:9000/data \
--console-address ":9001" \
--address ":9000"
env:
- name: MINIO_ROOT_USER
value: minioadmin
- name: MINIO_ROOT_PASSWORD
value: minioadmin
ports:
- name: api
containerPort: 9000
- name: console
containerPort: 9001
# 健康检查(正确API端口)
livenessProbe:
httpGet:
path: /minio/health/live
port: 9000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /minio/health/ready
port: 9000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
volumeMounts:
- name: data
mountPath: /data

# Longhorn 存储(每个Pod独立PVC)
volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

镜像选择说明:MinIO 官方停止分发预构建 Docker 镜像并更改了许可证。pgsty/minio 是社区维护的分支,提供与官方兼容的镜像,依据 AGPLv3 许可证分发。

七、注意事项

  1. 部署前: 备份现有数据
  2. 存储: Longhorn RWO 通过多副本同步,无需 RWX
  3. 节点限制: 5 节点分布在 5 个树莓派 worker
  4. 纠删码: 4+1 配置,允许 1 节点故障
  5. Ingress: 仅配置控制台 (minio-console.forgus.local)

八、部署命令

1
2
3
4
5
6
7
8
9
10
11
# 部署
kubectl apply -f /root/minio-statefulset.yaml

# 查看状态
kubectl get pods -n minio -l app=minio

# 查看 PVC
kubectl get pvc -n minio | grep minio

# 删除旧部署 (如需)
kubectl delete deployment minio -n minio