feat(helm): add minio object storage resources

This commit is contained in:
sligter
2026-07-06 23:10:01 +08:00
parent a23761ae05
commit 08e9d51bb8
10 changed files with 339 additions and 4 deletions
+3
View File
@@ -87,6 +87,9 @@ storage:
bucket: landppt
region: us-east-1
forcePathStyle: true
existingSecret: landppt-s3
minio:
enabled: false
```
Secret 中需要包含 `S3_ACCESS_KEY_ID``S3_SECRET_ACCESS_KEY`。本地开发可设置 `storage.backend=local`
+35
View File
@@ -67,3 +67,38 @@ valkey://{{ include "landppt.fullname" . }}-valkey:6379
{{ required "externalValkey.url is required when valkey.enabled=false" .Values.externalValkey.url }}
{{- end -}}
{{- end }}
{{/*
S3/MinIO endpoint URL.
*/}}
{{- define "landppt.s3EndpointUrl" -}}
{{- if .Values.minio.enabled -}}
http://{{ include "landppt.fullname" . }}-minio:9000
{{- else if ne .Values.storage.backend "s3" -}}
{{ .Values.storage.s3.endpointUrl | default "" }}
{{- else -}}
{{ required "storage.s3.endpointUrl is required when minio.enabled=false and storage.backend=s3" .Values.storage.s3.endpointUrl }}
{{- end -}}
{{- end }}
{{/*
Secret containing S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY.
*/}}
{{- define "landppt.s3SecretName" -}}
{{- if .Values.storage.s3.existingSecret -}}
{{ .Values.storage.s3.existingSecret }}
{{- else -}}
{{ include "landppt.fullname" . }}
{{- end -}}
{{- end }}
{{/*
Secret containing MinIO root credentials.
*/}}
{{- define "landppt.minioSecretName" -}}
{{- if .Values.minio.auth.existingSecret -}}
{{ .Values.minio.auth.existingSecret }}
{{- else -}}
{{ include "landppt.fullname" . }}-minio
{{- end -}}
{{- end }}
+1 -1
View File
@@ -19,7 +19,7 @@ data:
STORAGE_BACKEND: {{ .Values.storage.backend | quote }}
LOCAL_STORAGE_ROOT: {{ .Values.storage.local.root | quote }}
LOCAL_STORAGE_PUBLIC_BASE_URL: {{ .Values.storage.local.publicBaseUrl | quote }}
S3_ENDPOINT_URL: {{ .Values.storage.s3.endpointUrl | quote }}
S3_ENDPOINT_URL: {{ include "landppt.s3EndpointUrl" . | quote }}
S3_REGION: {{ .Values.storage.s3.region | quote }}
S3_BUCKET: {{ .Values.storage.s3.bucket | quote }}
S3_FORCE_PATH_STYLE: {{ .Values.storage.s3.forcePathStyle | quote }}
+42 -1
View File
@@ -33,8 +33,44 @@ spec:
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.postgresql.enabled }}
{{- if or .Values.postgresql.enabled .Values.minio.enabled }}
initContainers:
{{- if .Values.minio.enabled }}
- name: wait-for-minio
image: busybox:1.36
command:
- sh
- -c
- |
until nc -z {{ include "landppt.fullname" . }}-minio 9000; do
echo "waiting for minio..."; sleep 2;
done
- name: ensure-minio-bucket
image: {{ .Values.minio.mcImage }}
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_PASSWORD
- name: S3_BUCKET
value: {{ .Values.storage.s3.bucket | quote }}
command:
- /bin/sh
- -c
- |
set -eu
until mc alias set local http://{{ include "landppt.fullname" . }}-minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"; do
echo "waiting for minio..."; sleep 2;
done
mc mb -p "local/$S3_BUCKET" || true
{{- end }}
{{- if .Values.postgresql.enabled }}
- name: wait-for-postgres
image: busybox:1.36
command:
@@ -44,6 +80,7 @@ spec:
until nc -z {{ include "landppt.fullname" . }}-postgresql 5432; do
echo "waiting for postgresql..."; sleep 2;
done
{{- end }}
{{- end }}
containers:
- name: landppt
@@ -66,6 +103,10 @@ spec:
- secretRef:
name: {{ .Values.app.existingSecret }}
{{- end }}
{{- if .Values.storage.s3.existingSecret }}
- secretRef:
name: {{ .Values.storage.s3.existingSecret }}
{{- end }}
{{- with .Values.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
@@ -49,6 +49,10 @@ spec:
- secretRef:
name: {{ .Values.app.existingSecret }}
{{- end }}
{{- if .Values.storage.s3.existingSecret }}
- secretRef:
name: {{ .Values.storage.s3.existingSecret }}
{{- end }}
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
+160
View File
@@ -0,0 +1,160 @@
{{- if .Values.minio.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "landppt.fullname" . }}-minio
labels:
{{- include "landppt.labels" . | nindent 4 }}
app.kubernetes.io/component: minio
spec:
type: ClusterIP
ports:
- port: 9000
targetPort: api
protocol: TCP
name: api
- port: 9001
targetPort: console
protocol: TCP
name: console
selector:
{{- include "landppt.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: minio
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "landppt.fullname" . }}-minio
labels:
{{- include "landppt.labels" . | nindent 4 }}
app.kubernetes.io/component: minio
spec:
serviceName: {{ include "landppt.fullname" . }}-minio
replicas: 1
selector:
matchLabels:
{{- include "landppt.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: minio
template:
metadata:
labels:
{{- include "landppt.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: minio
spec:
containers:
- name: minio
image: {{ .Values.minio.image }}
args:
- server
- /data
- --console-address
- :9001
ports:
- name: api
containerPort: 9000
- name: console
containerPort: 9001
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_PASSWORD
livenessProbe:
httpGet:
path: /minio/health/live
port: api
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /minio/health/ready
port: api
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
{{- with .Values.minio.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
{{- with .Values.minio.persistence.storageClass }}
storageClassName: {{ . }}
{{- end }}
resources:
requests:
storage: {{ .Values.minio.persistence.size }}
---
{{- if not .Values.minio.auth.existingSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "landppt.minioSecretName" . }}
labels:
{{- include "landppt.labels" . | nindent 4 }}
app.kubernetes.io/component: minio
type: Opaque
stringData:
MINIO_ROOT_USER: {{ required "minio.auth.rootUser is required when minio.enabled=true" .Values.minio.auth.rootUser | quote }}
MINIO_ROOT_PASSWORD: {{ required "minio.auth.rootPassword is required when minio.enabled=true" .Values.minio.auth.rootPassword | quote }}
---
{{- end }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "landppt.fullname" . }}-minio-init
labels:
{{- include "landppt.labels" . | nindent 4 }}
app.kubernetes.io/component: minio-init
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
backoffLimit: 6
template:
metadata:
labels:
{{- include "landppt.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: minio-init
spec:
restartPolicy: OnFailure
containers:
- name: minio-init
image: {{ .Values.minio.mcImage }}
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_PASSWORD
- name: S3_BUCKET
value: {{ .Values.storage.s3.bucket | quote }}
command:
- /bin/sh
- -c
- |
set -eu
until mc alias set local http://{{ include "landppt.fullname" . }}-minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"; do
echo "waiting for minio..."; sleep 2;
done
mc mb -p "local/$S3_BUCKET" || true
{{- end }}
+12
View File
@@ -18,6 +18,18 @@ spec:
ports:
- protocol: TCP
port: {{ .Values.service.port }}
{{- if .Values.postgresql.enabled }}
- protocol: TCP
port: 5432
{{- end }}
{{- if .Values.valkey.enabled }}
- protocol: TCP
port: 6379
{{- end }}
{{- if .Values.minio.enabled }}
- protocol: TCP
port: 9000
{{- end }}
egress:
- to:
- namespaceSelector: {}
+13
View File
@@ -15,3 +15,16 @@ stringData:
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
{{- if and (eq .Values.storage.backend "s3") (not .Values.storage.s3.existingSecret) }}
{{- if .Values.minio.enabled }}
{{- if not .Values.minio.auth.existingSecret }}
S3_ACCESS_KEY_ID: {{ required "minio.auth.rootUser is required when minio.enabled=true" .Values.minio.auth.rootUser | quote }}
S3_SECRET_ACCESS_KEY: {{ required "minio.auth.rootPassword is required when minio.enabled=true" .Values.minio.auth.rootPassword | quote }}
{{- else }}
{{- fail "storage.s3.existingSecret must be set when minio.auth.existingSecret is used" }}
{{- end }}
{{- else }}
S3_ACCESS_KEY_ID: {{ required "storage.s3.accessKeyId or storage.s3.existingSecret is required when storage.backend=s3" .Values.storage.s3.accessKeyId | quote }}
S3_SECRET_ACCESS_KEY: {{ required "storage.s3.secretAccessKey or storage.s3.existingSecret is required when storage.backend=s3" .Values.storage.s3.secretAccessKey | quote }}
{{- end }}
{{- end }}
+42 -1
View File
@@ -25,8 +25,44 @@ spec:
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.postgresql.enabled }}
{{- if or .Values.postgresql.enabled .Values.minio.enabled }}
initContainers:
{{- if .Values.minio.enabled }}
- name: wait-for-minio
image: busybox:1.36
command:
- sh
- -c
- |
until nc -z {{ include "landppt.fullname" . }}-minio 9000; do
echo "waiting for minio..."; sleep 2;
done
- name: ensure-minio-bucket
image: {{ .Values.minio.mcImage }}
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "landppt.minioSecretName" . }}
key: MINIO_ROOT_PASSWORD
- name: S3_BUCKET
value: {{ .Values.storage.s3.bucket | quote }}
command:
- /bin/sh
- -c
- |
set -eu
until mc alias set local http://{{ include "landppt.fullname" . }}-minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"; do
echo "waiting for minio..."; sleep 2;
done
mc mb -p "local/$S3_BUCKET" || true
{{- end }}
{{- if .Values.postgresql.enabled }}
- name: wait-for-postgres
image: busybox:1.36
command:
@@ -36,6 +72,7 @@ spec:
until nc -z {{ include "landppt.fullname" . }}-postgresql 5432; do
echo "waiting for postgresql..."; sleep 2;
done
{{- end }}
{{- end }}
containers:
- name: worker
@@ -57,6 +94,10 @@ spec:
- secretRef:
name: {{ .Values.app.existingSecret }}
{{- end }}
{{- if .Values.storage.s3.existingSecret }}
- secretRef:
name: {{ .Values.storage.s3.existingSecret }}
{{- end }}
{{- with .Values.worker.resources }}
resources:
{{- toYaml . | nindent 12 }}
+27 -1
View File
@@ -74,12 +74,38 @@ storage:
root: /app/data/artifacts
publicBaseUrl: ""
s3:
endpointUrl: http://minio.minio.svc.cluster.local:9000
# Used when minio.enabled=false. When minio.enabled=true, the in-chart MinIO service is used.
endpointUrl: ""
region: us-east-1
bucket: landppt
forcePathStyle: true
publicBaseUrl: ""
presignedUrlExpiresSeconds: 3600
# Optional secret containing S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY.
existingSecret: ""
# Used only when existingSecret is empty and minio.enabled=false.
accessKeyId: ""
secretAccessKey: ""
minio:
enabled: true
image: minio/minio:RELEASE.2025-04-22T22-12-26Z
mcImage: minio/mc:RELEASE.2025-04-16T18-13-26Z
auth:
existingSecret: ""
rootUser: landppt
# Override for production, or provide minio.auth.existingSecret.
rootPassword: landppt-minio-secret
persistence:
storageClass: ""
size: 20Gi
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi
service:
type: ClusterIP