From 08e9d51bb8cf165463fe76d529d2f79f60260d40 Mon Sep 17 00:00:00 2001 From: sligter <1771322848@qq.com> Date: Mon, 6 Jul 2026 23:10:01 +0800 Subject: [PATCH] feat(helm): add minio object storage resources --- helm/landppt/README.md | 3 + helm/landppt/templates/_helpers.tpl | 35 ++++ helm/landppt/templates/configmap.yaml | 2 +- helm/landppt/templates/deployment.yaml | 43 ++++- helm/landppt/templates/migration-job.yaml | 4 + helm/landppt/templates/minio.yaml | 160 ++++++++++++++++++ helm/landppt/templates/networkpolicy.yaml | 12 ++ helm/landppt/templates/secret.yaml | 13 ++ helm/landppt/templates/worker-deployment.yaml | 43 ++++- helm/landppt/values.yaml | 28 ++- 10 files changed, 339 insertions(+), 4 deletions(-) create mode 100644 helm/landppt/templates/minio.yaml diff --git a/helm/landppt/README.md b/helm/landppt/README.md index 7ac6b6d..1937bb8 100644 --- a/helm/landppt/README.md +++ b/helm/landppt/README.md @@ -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`。 diff --git a/helm/landppt/templates/_helpers.tpl b/helm/landppt/templates/_helpers.tpl index 1860263..eea310a 100644 --- a/helm/landppt/templates/_helpers.tpl +++ b/helm/landppt/templates/_helpers.tpl @@ -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 }} diff --git a/helm/landppt/templates/configmap.yaml b/helm/landppt/templates/configmap.yaml index ebb410d..1534809 100644 --- a/helm/landppt/templates/configmap.yaml +++ b/helm/landppt/templates/configmap.yaml @@ -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 }} diff --git a/helm/landppt/templates/deployment.yaml b/helm/landppt/templates/deployment.yaml index be17362..22a7ae9 100644 --- a/helm/landppt/templates/deployment.yaml +++ b/helm/landppt/templates/deployment.yaml @@ -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 }} diff --git a/helm/landppt/templates/migration-job.yaml b/helm/landppt/templates/migration-job.yaml index f2183d8..b76d821 100644 --- a/helm/landppt/templates/migration-job.yaml +++ b/helm/landppt/templates/migration-job.yaml @@ -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 }} diff --git a/helm/landppt/templates/minio.yaml b/helm/landppt/templates/minio.yaml new file mode 100644 index 0000000..cc6d938 --- /dev/null +++ b/helm/landppt/templates/minio.yaml @@ -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 }} diff --git a/helm/landppt/templates/networkpolicy.yaml b/helm/landppt/templates/networkpolicy.yaml index 0f819ab..ee71bbe 100644 --- a/helm/landppt/templates/networkpolicy.yaml +++ b/helm/landppt/templates/networkpolicy.yaml @@ -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: {} diff --git a/helm/landppt/templates/secret.yaml b/helm/landppt/templates/secret.yaml index 900c37f..9c7918c 100644 --- a/helm/landppt/templates/secret.yaml +++ b/helm/landppt/templates/secret.yaml @@ -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 }} diff --git a/helm/landppt/templates/worker-deployment.yaml b/helm/landppt/templates/worker-deployment.yaml index e8e77cb..a8c6797 100644 --- a/helm/landppt/templates/worker-deployment.yaml +++ b/helm/landppt/templates/worker-deployment.yaml @@ -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 }} diff --git a/helm/landppt/values.yaml b/helm/landppt/values.yaml index 6a823c4..671fa06 100644 --- a/helm/landppt/values.yaml +++ b/helm/landppt/values.yaml @@ -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