From 660941138bea6a39c7fef7667e7db20dda389012 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 14 Jul 2025 20:00:02 +0200 Subject: [PATCH] Introduce named volumes in Helm chart (#6972) --- k8s/charts/seaweedfs/templates/_helpers.tpl | 43 ++- .../templates/all-in-one-deployment.yaml | 5 +- .../seaweedfs/templates/cosi-deployment.yaml | 3 +- .../templates/filer-statefulset.yaml | 2 +- .../templates/master-statefulset.yaml | 3 +- .../seaweedfs/templates/s3-deployment.yaml | 3 +- .../seaweedfs/templates/sftp-deployment.yaml | 5 +- .../templates/volume-resize-hook.yaml | 100 +++--- .../seaweedfs/templates/volume-service.yaml | 45 +-- .../templates/volume-servicemonitor.yaml | 33 +- .../templates/volume-statefulset.yaml | 313 +++++++++--------- k8s/charts/seaweedfs/values.yaml | 35 +- 12 files changed, 325 insertions(+), 265 deletions(-) diff --git a/k8s/charts/seaweedfs/templates/_helpers.tpl b/k8s/charts/seaweedfs/templates/_helpers.tpl index 897251e1a..b15b07fa0 100644 --- a/k8s/charts/seaweedfs/templates/_helpers.tpl +++ b/k8s/charts/seaweedfs/templates/_helpers.tpl @@ -179,6 +179,27 @@ Usage: {{- end }} {{- end -}} +{{/* +Converts a Kubernetes quantity like "256Mi" or "2G" to a float64 in base units, +handling both binary (Ki, Mi, Gi) and decimal (m, k, M) suffixes; numeric inputs +Usage: +{{ include "common.resource-quantity" "10Gi" }} +*/}} +{{- define "common.resource-quantity" -}} + {{- $value := . -}} + {{- $unit := 1.0 -}} + {{- if typeIs "string" . -}} + {{- $base2 := dict "Ki" 0x1p10 "Mi" 0x1p20 "Gi" 0x1p30 "Ti" 0x1p40 "Pi" 0x1p50 "Ei" 0x1p60 -}} + {{- $base10 := dict "m" 1e-3 "k" 1e3 "M" 1e6 "G" 1e9 "T" 1e12 "P" 1e15 "E" 1e18 -}} + {{- range $k, $v := merge $base2 $base10 -}} + {{- if hasSuffix $k $ -}} + {{- $value = trimSuffix $k $ -}} + {{- $unit = $v -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- mulf (float64 $value) $unit -}} +{{- end -}} {{/* getOrGeneratePassword will check if a password exists in a secret and return it, @@ -198,25 +219,3 @@ or generate a new random password if it doesn't exist. {{- randAlphaNum $length -}} {{- end -}} {{- end -}} - -{{- /* -Render a component’s topologySpreadConstraints exactly as given in values, -respecting string vs. list, and providing the component name for tpl lookups. - -Usage: - {{ include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "filer") | nindent 8 }} -*/ -}} -{{- define "seaweedfs.topologySpreadConstraints" -}} - {{- $vals := .Values -}} - {{- $comp := .component -}} - {{- $section := index $vals $comp | default dict -}} - {{- $tsp := index $section "topologySpreadConstraints" -}} - {{- with $tsp }} -topologySpreadConstraints: -{{- if kindIs "string" $tsp }} -{{ tpl $tsp (dict "Values" $vals "component" $comp) }} -{{- else }} -{{ toYaml $tsp }} -{{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/k8s/charts/seaweedfs/templates/all-in-one-deployment.yaml b/k8s/charts/seaweedfs/templates/all-in-one-deployment.yaml index 0aa035370..1086d6a4d 100644 --- a/k8s/charts/seaweedfs/templates/all-in-one-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/all-in-one-deployment.yaml @@ -50,7 +50,8 @@ spec: {{ tpl .Values.allInOne.affinity . | nindent 8 | trim }} {{- end }} {{- if .Values.allInOne.topologySpreadConstraints }} - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "all-in-one") | nindent 6 }} + topologySpreadConstraints: + {{ tpl .Values.allInOne.topologySpreadConstraint . | nindent 8 | trim }} {{- end }} {{- if .Values.allInOne.tolerations }} tolerations: @@ -424,4 +425,4 @@ spec: nodeSelector: {{ tpl .Values.allInOne.nodeSelector . | nindent 8 }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/cosi-deployment.yaml b/k8s/charts/seaweedfs/templates/cosi-deployment.yaml index 32db4c64d..b200c89ae 100644 --- a/k8s/charts/seaweedfs/templates/cosi-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/cosi-deployment.yaml @@ -45,7 +45,8 @@ spec: {{ tpl .Values.cosi.affinity . | nindent 8 | trim }} {{- end }} {{- if .Values.cosi.topologySpreadConstraints }} - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "objectstorage-provisioner") | nindent 6 }} + topologySpreadConstraints: + {{ tpl .Values.cosi.topologySpreadConstraint . | nindent 8 | trim }} {{- end }} {{- if .Values.cosi.tolerations }} tolerations: diff --git a/k8s/charts/seaweedfs/templates/filer-statefulset.yaml b/k8s/charts/seaweedfs/templates/filer-statefulset.yaml index e977f8c69..d2dad0097 100644 --- a/k8s/charts/seaweedfs/templates/filer-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/filer-statefulset.yaml @@ -63,7 +63,7 @@ spec: {{- end }} {{- if .Values.filer.topologySpreadConstraints }} topologySpreadConstraints: - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "filer") | nindent 6 }} + {{ tpl .Values.filer.topologySpreadConstraints . | nindent 8 | trim }} {{- end }} {{- if .Values.filer.tolerations }} tolerations: diff --git a/k8s/charts/seaweedfs/templates/master-statefulset.yaml b/k8s/charts/seaweedfs/templates/master-statefulset.yaml index 4eb709559..01387fc91 100644 --- a/k8s/charts/seaweedfs/templates/master-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/master-statefulset.yaml @@ -56,7 +56,8 @@ spec: {{ tpl .Values.master.affinity . | nindent 8 | trim }} {{- end }} {{- if .Values.master.topologySpreadConstraints }} - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "master") | nindent 6 }} + topologySpreadConstraints: + {{ tpl .Values.master.topologySpreadConstraints . | nindent 8 | trim }} {{- end }} {{- if .Values.master.tolerations }} tolerations: diff --git a/k8s/charts/seaweedfs/templates/s3-deployment.yaml b/k8s/charts/seaweedfs/templates/s3-deployment.yaml index afcfd5c2e..d710fecbc 100644 --- a/k8s/charts/seaweedfs/templates/s3-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/s3-deployment.yaml @@ -48,7 +48,8 @@ spec: {{ tpl .Values.s3.affinity . | nindent 8 | trim }} {{- end }} {{- if .Values.s3.topologySpreadConstraints }} - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "s3") | nindent 6 }} + topologySpreadConstraints: + {{ tpl .Values.s3.topologySpreadConstraints . | nindent 8 | trim }} {{- end }} {{- if .Values.s3.tolerations }} tolerations: diff --git a/k8s/charts/seaweedfs/templates/sftp-deployment.yaml b/k8s/charts/seaweedfs/templates/sftp-deployment.yaml index 8f7268a7a..c0bcb2c4a 100644 --- a/k8s/charts/seaweedfs/templates/sftp-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/sftp-deployment.yaml @@ -48,7 +48,8 @@ spec: {{ tpl .Values.sftp.affinity . | nindent 8 | trim }} {{- end }} {{- if .Values.sftp.topologySpreadConstraints }} - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "sftp") | nindent 6 }} + topologySpreadConstraints: + {{ tpl .Values.sftp.topologySpreadConstraint . | nindent 8 | trim }} {{- end }} {{- if .Values.sftp.tolerations }} tolerations: @@ -297,4 +298,4 @@ spec: nodeSelector: {{ tpl .Values.sftp.nodeSelector . | indent 8 | trim }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/volume-resize-hook.yaml b/k8s/charts/seaweedfs/templates/volume-resize-hook.yaml index 436a785e1..8e3b5932c 100644 --- a/k8s/charts/seaweedfs/templates/volume-resize-hook.yaml +++ b/k8s/charts/seaweedfs/templates/volume-resize-hook.yaml @@ -1,40 +1,54 @@ -{{- if and .Values.volume.enabled .Values.volume.resizeHook.enabled }} {{- $seaweedfsName := include "seaweedfs.name" $ }} -{{- $replicas := int .Values.volume.replicas -}} -{{- $statefulsetName := printf "%s-volume" $seaweedfsName -}} -{{- $statefulset := (lookup "apps/v1" "StatefulSet" .Release.Namespace $statefulsetName) -}} +{{- $volumes := deepCopy .Values.volumes | mergeOverwrite (dict "" .Values.volume) }} -{{/* Check for changes in volumeClaimTemplates */}} -{{- $templateChangesRequired := false -}} -{{- if $statefulset -}} - {{- range $dir := .Values.volume.dataDirs -}} - {{- if eq .type "persistentVolumeClaim" -}} - {{- $desiredSize := .size -}} - {{- range $statefulset.spec.volumeClaimTemplates -}} - {{- if and (eq .metadata.name $dir.name) (ne .spec.resources.requests.storage $desiredSize) -}} - {{- $templateChangesRequired = true -}} - {{- end -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{/* Check for the need for patching existing PVCs */}} -{{- $pvcChangesRequired := false -}} -{{- range $dir := .Values.volume.dataDirs -}} - {{- if eq .type "persistentVolumeClaim" -}} - {{- $desiredSize := .size -}} - {{- range $i, $e := until $replicas }} - {{- $pvcName := printf "%s-%s-volume-%d" $dir.name $seaweedfsName $e -}} - {{- $currentPVC := (lookup "v1" "PersistentVolumeClaim" $.Release.Namespace $pvcName) -}} - {{- if and $currentPVC (ne ($currentPVC.spec.resources.requests.storage | toString) $desiredSize) -}} - {{- $pvcChangesRequired = true -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- end -}} +{{- if .Values.volume.resizeHook.enabled }} +{{- $commands := list }} +{{- range $vname, $volume := $volumes }} +{{- $volumeName := trimSuffix "-" (printf "volume-%s" $vname) }} +{{- $volume := mergeOverwrite (deepCopy $.Values.volume) (dict "enabled" true) $volume }} -{{- if or $templateChangesRequired $pvcChangesRequired }} +{{- if $volume.enabled }} +{{- $replicas := int $volume.replicas -}} +{{- $statefulsetName := printf "%s-%s" $seaweedfsName $volumeName -}} +{{- $statefulset := (lookup "apps/v1" "StatefulSet" $.Release.Namespace $statefulsetName) -}} + +{{/* Check for changes in volumeClaimTemplates */}} +{{- if $statefulset }} +{{- range $dir := $volume.dataDirs }} +{{- if eq .type "persistentVolumeClaim" }} +{{- $desiredSize := .size }} +{{- range $statefulset.spec.volumeClaimTemplates }} +{{- if and (eq .metadata.name $dir.name) (ne .spec.resources.requests.storage $desiredSize) }} +{{- $commands = append $commands (printf "kubectl delete statefulset %s --cascade=orphan" $statefulsetName) }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Check for the need for patching existing PVCs */}} +{{- range $dir := $volume.dataDirs }} +{{- if eq .type "persistentVolumeClaim" }} +{{- $desiredSize := .size }} +{{- range $i, $e := until $replicas }} +{{- $pvcName := printf "%s-%s-%s-%d" $dir.name $seaweedfsName $volumeName $e }} +{{- $currentPVC := (lookup "v1" "PersistentVolumeClaim" $.Release.Namespace $pvcName) }} +{{- if and $currentPVC }} +{{- $oldSize := include "common.resource-quantity" $currentPVC.spec.resources.requests.storage }} +{{- $newSize := include "common.resource-quantity" $desiredSize }} +{{- if gt $newSize $oldSize }} +{{- $commands = append $commands (printf "kubectl patch pvc %s-%s-%s-%d -p '{\"spec\":{\"resources\":{\"requests\":{\"storage\":\"%s\"}}}}'" $dir.name $seaweedfsName $volumeName $e $desiredSize) }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{- end }} +{{- end }} + +{{- if $commands }} apiVersion: batch/v1 kind: Job metadata: @@ -45,6 +59,9 @@ metadata: helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation spec: template: + metadata: + labels: + policy.cozystack.io/allow-to-apiserver: "true" spec: serviceAccountName: {{ $seaweedfsName }}-volume-resize-hook restartPolicy: Never @@ -55,21 +72,9 @@ spec: command: ["sh", "-xec"] args: - | - {{- if $pvcChangesRequired -}} - {{- range $dir := .Values.volume.dataDirs -}} - {{- if eq .type "persistentVolumeClaim" -}} - {{- $desiredSize := .size -}} - {{- range $i, $e := until $replicas }} - kubectl patch pvc {{ printf "%s-%s-volume-%d" $dir.name $seaweedfsName $e }} -p '{"spec":{"resources":{"requests":{"storage":"{{ $desiredSize }}"}}}}' - {{- end }} + {{- range $commands }} + {{ . }} {{- end }} - {{- end }} - {{- end -}} - - {{- if $templateChangesRequired }} - kubectl delete statefulset {{ $statefulsetName }} --cascade=orphan - {{- end }} -{{- end }} --- apiVersion: v1 kind: ServiceAccount @@ -111,4 +116,5 @@ roleRef: kind: Role name: {{ $seaweedfsName }}-volume-resize-hook apiGroup: rbac.authorization.k8s.io +{{- end }} {{- end }} diff --git a/k8s/charts/seaweedfs/templates/volume-service.yaml b/k8s/charts/seaweedfs/templates/volume-service.yaml index f881d27f3..dfafc8163 100644 --- a/k8s/charts/seaweedfs/templates/volume-service.yaml +++ b/k8s/charts/seaweedfs/templates/volume-service.yaml @@ -1,37 +1,44 @@ -{{- if .Values.volume.enabled }} +{{ $volumes := deepCopy .Values.volumes | mergeOverwrite (dict "" .Values.volume) }} +{{- range $vname, $volume := $volumes }} +{{- $volumeName := trimSuffix "-" (printf "volume-%s" $vname) }} +{{- $volume := mergeOverwrite (deepCopy $.Values.volume) (dict "enabled" true) $volume }} + +{{- if $volume.enabled }} +--- apiVersion: v1 kind: Service metadata: - name: {{ template "seaweedfs.name" . }}-volume - namespace: {{ .Release.Namespace }} + name: {{ template "seaweedfs.name" $ }}-{{ $volumeName }} + namespace: {{ $.Release.Namespace }} labels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - app.kubernetes.io/component: volume - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- if .Values.volume.annotations }} + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + app.kubernetes.io/component: {{ $volumeName }} + helm.sh/chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ $.Release.Service }} +{{- if $volume.annotations }} annotations: - {{- toYaml .Values.volume.annotations | nindent 4 }} + {{- toYaml $volume.annotations | nindent 4 }} {{- end }} spec: clusterIP: None - internalTrafficPolicy: {{ .Values.volume.internalTrafficPolicy | default "Cluster" }} + internalTrafficPolicy: {{ $volume.internalTrafficPolicy | default "Cluster" }} ports: - name: "swfs-volume" - port: {{ .Values.volume.port }} - targetPort: {{ .Values.volume.port }} + port: {{ $volume.port }} + targetPort: {{ $volume.port }} protocol: TCP - name: "swfs-volume-18080" - port: {{ .Values.volume.grpcPort }} - targetPort: {{ .Values.volume.grpcPort }} + port: {{ $volume.grpcPort }} + targetPort: {{ $volume.grpcPort }} protocol: TCP -{{- if .Values.volume.metricsPort }} +{{- if $volume.metricsPort }} - name: "metrics" - port: {{ .Values.volume.metricsPort }} - targetPort: {{ .Values.volume.metricsPort }} + port: {{ $volume.metricsPort }} + targetPort: {{ $volume.metricsPort }} protocol: TCP {{- end }} selector: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - app.kubernetes.io/component: volume + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + app.kubernetes.io/component: {{ $volumeName }} +{{- end }} {{- end }} diff --git a/k8s/charts/seaweedfs/templates/volume-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/volume-servicemonitor.yaml index 8dfa96c97..dd8a9f9d7 100644 --- a/k8s/charts/seaweedfs/templates/volume-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/volume-servicemonitor.yaml @@ -1,18 +1,24 @@ -{{- if .Values.volume.enabled }} -{{- if .Values.volume.metricsPort }} -{{- if .Values.global.monitoring.enabled }} +{{ $volumes := deepCopy .Values.volumes | mergeOverwrite (dict "" .Values.volume) }} +{{- range $vname, $volume := $volumes }} +{{- $volumeName := trimSuffix "-" (printf "volume-%s" $vname) }} +{{- $volume := mergeOverwrite (deepCopy $.Values.volume) (dict "enabled" true) $volume }} + +{{- if $volume.enabled }} +{{- if $volume.metricsPort }} +{{- if $.Values.global.monitoring.enabled }} +--- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: - name: {{ template "seaweedfs.name" . }}-volume - namespace: {{ .Release.Namespace }} + name: {{ template "seaweedfs.name" $ }}-{{ $volumeName }} + namespace: {{ $.Release.Namespace }} labels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: volume - {{- with .Values.global.monitoring.additionalLabels }} + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + helm.sh/chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ $.Release.Service }} + app.kubernetes.io/instance: {{ $.Release.Name }} + app.kubernetes.io/component: {{ $volumeName }} + {{- with $.Values.global.monitoring.additionalLabels }} {{- toYaml . | nindent 4 }} {{- end }} {{- if .Values.volume.annotations }} @@ -26,8 +32,9 @@ spec: scrapeTimeout: 5s selector: matchLabels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - app.kubernetes.io/component: volume + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + app.kubernetes.io/component: {{ $volumeName }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/k8s/charts/seaweedfs/templates/volume-statefulset.yaml b/k8s/charts/seaweedfs/templates/volume-statefulset.yaml index 924125607..ccfffc101 100644 --- a/k8s/charts/seaweedfs/templates/volume-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/volume-statefulset.yaml @@ -1,98 +1,108 @@ -{{- if .Values.volume.enabled }} +{{ $volumes := deepCopy .Values.volumes | mergeOverwrite (dict "" .Values.volume) }} +{{- range $vname, $volume := $volumes }} +{{- $volumeName := trimSuffix "-" (printf "volume-%s" $vname) }} +{{- $volume := mergeOverwrite (deepCopy $.Values.volume) (dict "enabled" true) $volume }} + +{{- if $volume.enabled }} +--- apiVersion: apps/v1 kind: StatefulSet metadata: - name: {{ template "seaweedfs.name" . }}-volume - namespace: {{ .Release.Namespace }} + name: {{ template "seaweedfs.name" $ }}-{{ $volumeName }} + namespace: {{ $.Release.Namespace }} labels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: volume -{{- if .Values.volume.annotations }} + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + helm.sh/chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ $.Release.Service }} + app.kubernetes.io/instance: {{ $.Release.Name }} + app.kubernetes.io/component: {{ $volumeName }} +{{- if $volume.annotations }} annotations: - {{- toYaml .Values.volume.annotations | nindent 4 }} + {{- toYaml $volume.annotations | nindent 4 }} {{- end }} spec: - serviceName: {{ template "seaweedfs.name" . }}-volume - replicas: {{ .Values.volume.replicas }} - podManagementPolicy: {{ .Values.volume.podManagementPolicy }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + serviceName: {{ template "seaweedfs.name" $ }}-{{ $volumeName }} + replicas: {{ $volume.replicas }} + podManagementPolicy: {{ $volume.podManagementPolicy }} selector: matchLabels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: volume + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + app.kubernetes.io/instance: {{ $.Release.Name }} + app.kubernetes.io/component: {{ $volumeName }} template: metadata: labels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: volume - {{ with .Values.podLabels }} + app.kubernetes.io/name: {{ template "seaweedfs.name" $ }} + helm.sh/chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ $.Release.Name }} + app.kubernetes.io/component: {{ $volumeName }} + {{ with $.Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.volume.podLabels }} + {{- with $volume.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} annotations: - {{ with .Values.podAnnotations }} + {{ with $.Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.volume.podAnnotations }} + {{- with $volume.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} spec: - {{- if .Values.volume.affinity }} + {{- if $volume.affinity }} affinity: - {{ tpl .Values.volume.affinity . | nindent 8 | trim }} + {{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.affinity) $ | indent 8 | trim }} {{- end }} - {{- if .Values.volume.topologySpreadConstraints }} - {{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "volume") | nindent 6 }} + {{- if $volume.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.topologySpreadConstraints) $ | nindent 8 | trim }} {{- end }} - restartPolicy: {{ default .Values.global.restartPolicy .Values.volume.restartPolicy }} - {{- if .Values.volume.tolerations }} + restartPolicy: {{ default $.Values.global.restartPolicy $volume.restartPolicy }} + {{- if $volume.tolerations }} tolerations: - {{ tpl .Values.volume.tolerations . | nindent 8 | trim }} + {{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.tolerations) $ | indent 8 | trim }} {{- end }} - {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + {{- include "seaweedfs.imagePullSecrets" $ | nindent 6 }} terminationGracePeriodSeconds: 150 - {{- if .Values.volume.priorityClassName }} - priorityClassName: {{ .Values.volume.priorityClassName | quote }} + {{- if $volume.priorityClassName }} + priorityClassName: {{ $volume.priorityClassName | quote }} {{- end }} enableServiceLinks: false - {{- if .Values.global.createClusterRole }} - serviceAccountName: {{ .Values.volume.serviceAccountName | default .Values.global.serviceAccountName | quote }} # for deleting statefulset pods after migration + {{- if $.Values.global.createClusterRole }} + serviceAccountName: {{ $volume.serviceAccountName | default $.Values.global.serviceAccountName | quote }} # for deleting statefulset pods after migration {{- end }} - {{- $initContainers_exists := include "volume.initContainers_exists" . -}} + {{- $initContainers_exists := include "volume.initContainers_exists" $ -}} {{- if $initContainers_exists }} initContainers: - {{- if .Values.volume.idx }} + {{- if $volume.idx }} - name: seaweedfs-vol-move-idx - image: {{ template "volume.image" . }} - imagePullPolicy: {{ .Values.global.imagePullPolicy | default "IfNotPresent" }} + image: {{ template "volume.image" $ }} + imagePullPolicy: {{ $.Values.global.imagePullPolicy | default "IfNotPresent" }} command: [ '/bin/sh', '-c' ] - args: [ '{{range $dir := .Values.volume.dataDirs }}if ls /{{$dir.name}}/*.idx >/dev/null 2>&1; then mv /{{$dir.name}}/*.idx /idx/ ; fi; {{end}}' ] + args: [ '{{range $dir := $volume.dataDirs }}if ls /{{$dir.name}}/*.idx >/dev/null 2>&1; then mv /{{$dir.name}}/*.idx /idx/ ; fi; {{end}}' ] volumeMounts: - name: idx mountPath: /idx - {{- range $dir := .Values.volume.dataDirs }} + {{- range $dir := $volume.dataDirs }} - name: {{ $dir.name }} mountPath: /{{ $dir.name }} {{- end }} {{- end }} - {{- if .Values.volume.initContainers }} - {{ tpl .Values.volume.initContainers . | nindent 8 | trim }} + {{- if $volume.initContainers }} + {{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.initContainers) $ | indent 8 | trim }} {{- end }} {{- end }} - {{- if .Values.volume.podSecurityContext.enabled }} - securityContext: {{- omit .Values.volume.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- if $volume.podSecurityContext.enabled }} + securityContext: {{- omit $volume.podSecurityContext "enabled" | toYaml | nindent 8 }} {{- end }} containers: - name: seaweedfs - image: {{ template "volume.image" . }} - imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + image: {{ template "volume.image" $ }} + imagePullPolicy: {{ default "IfNotPresent" $.Values.global.imagePullPolicy }} env: - name: POD_NAME valueFrom: @@ -107,9 +117,9 @@ spec: fieldRef: fieldPath: status.hostIP - name: SEAWEEDFS_FULLNAME - value: "{{ template "seaweedfs.name" . }}" - {{- if .Values.volume.extraEnvironmentVars }} - {{- range $key, $value := .Values.volume.extraEnvironmentVars }} + value: "{{ template "seaweedfs.name" $ }}" + {{- if $volume.extraEnvironmentVars }} + {{- range $key, $value := $volume.extraEnvironmentVars }} - name: {{ $key }} {{- if kindIs "string" $value }} value: {{ $value | quote }} @@ -119,8 +129,8 @@ spec: {{- end -}} {{- end }} {{- end }} - {{- if .Values.global.extraEnvironmentVars }} - {{- range $key, $value := .Values.global.extraEnvironmentVars }} + {{- if $.Values.global.extraEnvironmentVars }} + {{- range $key, $value := $.Values.global.extraEnvironmentVars }} - name: {{ $key }} {{- if kindIs "string" $value }} value: {{ $value | quote }} @@ -135,77 +145,77 @@ spec: - "-ec" - | exec /usr/bin/weed \ - {{- if .Values.volume.logs }} + {{- if $volume.logs }} -logdir=/logs \ {{- else }} -logtostderr=true \ {{- end }} - {{- if .Values.volume.loggingOverrideLevel }} - -v={{ .Values.volume.loggingOverrideLevel }} \ + {{- if $volume.loggingOverrideLevel }} + -v={{ $volume.loggingOverrideLevel }} \ {{- else }} - -v={{ .Values.global.loggingLevel }} \ + -v={{ $.Values.global.loggingLevel }} \ {{- end }} volume \ - -port={{ .Values.volume.port }} \ - {{- if .Values.volume.metricsPort }} - -metricsPort={{ .Values.volume.metricsPort }} \ + -port={{ $volume.port }} \ + {{- if $volume.metricsPort }} + -metricsPort={{ $volume.metricsPort }} \ {{- end }} - {{- if .Values.volume.metricsIp }} - -metricsIp={{ .Values.volume.metricsIp }} \ + {{- if $volume.metricsIp }} + -metricsIp={{ $volume.metricsIp }} \ {{- end }} - -dir {{range $index, $dir := .Values.volume.dataDirs }}{{if ne $index 0}},{{end}}/{{$dir.name}}{{end}} \ - {{- if .Values.volume.idx }} + -dir {{range $index, $dir := $volume.dataDirs }}{{if ne $index 0}},{{end}}/{{$dir.name}}{{end}} \ + {{- if $volume.idx }} -dir.idx=/idx \ {{- end }} - -max {{range $index, $dir := .Values.volume.dataDirs }}{{if ne $index 0}},{{end}} + -max {{range $index, $dir := $volume.dataDirs }}{{if ne $index 0}},{{end}} {{- if eq ($dir.maxVolumes | toString) "0" }}0{{ else if not $dir.maxVolumes }}7{{ else }}{{$dir.maxVolumes}}{{ end }} {{- end }} \ - {{- if .Values.volume.rack }} - -rack={{ .Values.volume.rack }} \ + {{- if $volume.rack }} + -rack={{ $volume.rack }} \ {{- end }} - {{- if .Values.volume.dataCenter }} - -dataCenter={{ .Values.volume.dataCenter }} \ + {{- if $volume.dataCenter }} + -dataCenter={{ $volume.dataCenter }} \ {{- end }} - -ip.bind={{ .Values.volume.ipBind }} \ - -readMode={{ .Values.volume.readMode }} \ - {{- if .Values.volume.whiteList }} - -whiteList={{ .Values.volume.whiteList }} \ + -ip.bind={{ $volume.ipBind }} \ + -readMode={{ $volume.readMode }} \ + {{- if $volume.whiteList }} + -whiteList={{ $volume.whiteList }} \ {{- end }} - {{- if .Values.volume.imagesFixOrientation }} + {{- if $volume.imagesFixOrientation }} -images.fix.orientation \ {{- end }} - {{- if .Values.volume.pulseSeconds }} - -pulseSeconds={{ .Values.volume.pulseSeconds }} \ + {{- if $volume.pulseSeconds }} + -pulseSeconds={{ $volume.pulseSeconds }} \ {{- end }} - {{- if .Values.volume.index }} - -index={{ .Values.volume.index }} \ + {{- if $volume.index }} + -index={{ $volume.index }} \ {{- end }} - {{- if .Values.volume.fileSizeLimitMB }} - -fileSizeLimitMB={{ .Values.volume.fileSizeLimitMB }} \ + {{- if $volume.fileSizeLimitMB }} + -fileSizeLimitMB={{ $volume.fileSizeLimitMB }} \ {{- end }} - -minFreeSpacePercent={{ .Values.volume.minFreeSpacePercent }} \ - -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-volume.{{ .Release.Namespace }} \ - -compactionMBps={{ .Values.volume.compactionMBps }} \ - -mserver={{ if .Values.global.masterServer }}{{.Values.global.masterServer}}{{ else }}{{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{ end }} \ - {{- range .Values.volume.extraArgs }} + -minFreeSpacePercent={{ $volume.minFreeSpacePercent }} \ + -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-{{ $volumeName }}.{{ $.Release.Namespace }} \ + -compactionMBps={{ $volume.compactionMBps }} \ + -mserver={{ if $.Values.global.masterServer }}{{ $.Values.global.masterServer}}{{ else }}{{ range $index := until ($.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{ end }} + {{- range $volume.extraArgs }} {{ . }} \ {{- end }} volumeMounts: - {{- range $dir := .Values.volume.dataDirs }} + {{- range $dir := $volume.dataDirs }} {{- if not ( eq $dir.type "custom" ) }} - name: {{ $dir.name }} mountPath: "/{{ $dir.name }}/" {{- end }} {{- end }} - {{- if .Values.volume.logs }} + {{- if $volume.logs }} - name: logs mountPath: "/logs/" {{- end }} - {{- if .Values.volume.idx }} + {{- if $volume.idx }} - name: idx mountPath: "/idx/" {{- end }} - {{- if .Values.global.enableSecurity }} + {{- if $.Values.global.enableSecurity }} - name: security-config readOnly: true mountPath: /etc/seaweedfs/security.toml @@ -226,53 +236,53 @@ spec: readOnly: true mountPath: /usr/local/share/ca-certificates/client/ {{- end }} - {{ tpl .Values.volume.extraVolumeMounts . | nindent 12 | trim }} + {{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.extraVolumeMounts) $ | indent 12 | trim }} ports: - - containerPort: {{ .Values.volume.port }} + - containerPort: {{ $volume.port }} name: swfs-vol - {{- if .Values.volume.metricsPort }} - - containerPort: {{ .Values.volume.metricsPort }} + {{- if $volume.metricsPort }} + - containerPort: {{ $volume.metricsPort }} name: metrics {{- end }} - - containerPort: {{ .Values.volume.grpcPort }} + - containerPort: {{ $volume.grpcPort }} name: swfs-vol-grpc - {{- if .Values.volume.readinessProbe.enabled }} + {{- if $volume.readinessProbe.enabled }} readinessProbe: httpGet: - path: {{ .Values.volume.readinessProbe.httpGet.path }} - port: {{ .Values.volume.port }} - scheme: {{ .Values.volume.readinessProbe.scheme }} - initialDelaySeconds: {{ .Values.volume.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.volume.readinessProbe.periodSeconds }} - successThreshold: {{ .Values.volume.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.volume.readinessProbe.failureThreshold }} - timeoutSeconds: {{ .Values.volume.readinessProbe.timeoutSeconds }} + path: {{ $volume.readinessProbe.httpGet.path }} + port: {{ $volume.port }} + scheme: {{ $volume.readinessProbe.scheme }} + initialDelaySeconds: {{ $volume.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ $volume.readinessProbe.periodSeconds }} + successThreshold: {{ $volume.readinessProbe.successThreshold }} + failureThreshold: {{ $volume.readinessProbe.failureThreshold }} + timeoutSeconds: {{ $volume.readinessProbe.timeoutSeconds }} {{- end }} - {{- if .Values.volume.livenessProbe.enabled }} + {{- if $volume.livenessProbe.enabled }} livenessProbe: httpGet: - path: {{ .Values.volume.livenessProbe.httpGet.path }} - port: {{ .Values.volume.port }} - scheme: {{ .Values.volume.livenessProbe.scheme }} - initialDelaySeconds: {{ .Values.volume.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.volume.livenessProbe.periodSeconds }} - successThreshold: {{ .Values.volume.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.volume.livenessProbe.failureThreshold }} - timeoutSeconds: {{ .Values.volume.livenessProbe.timeoutSeconds }} + path: {{ $volume.livenessProbe.httpGet.path }} + port: {{ $volume.port }} + scheme: {{ $volume.livenessProbe.scheme }} + initialDelaySeconds: {{ $volume.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ $volume.livenessProbe.periodSeconds }} + successThreshold: {{ $volume.livenessProbe.successThreshold }} + failureThreshold: {{ $volume.livenessProbe.failureThreshold }} + timeoutSeconds: {{ $volume.livenessProbe.timeoutSeconds }} {{- end }} - {{- with .Values.volume.resources }} + {{- with $volume.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} - {{- if .Values.volume.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.volume.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- if $volume.containerSecurityContext.enabled }} + securityContext: {{- omit $volume.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} - {{- if .Values.volume.sidecars }} - {{- include "common.tplvalues.render" (dict "value" .Values.volume.sidecars "context" $) | nindent 8 }} + {{- if $volume.sidecars }} + {{- include "common.tplvalues.render" (dict "value" (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.sidecars) "context" $) | nindent 8 }} {{- end }} volumes: - {{- range $dir := .Values.volume.dataDirs }} + {{- range $dir := $volume.dataDirs }} {{- if eq $dir.type "hostPath" }} - name: {{ $dir.name }} @@ -292,70 +302,70 @@ spec: {{- end }} - {{- if .Values.volume.idx }} - {{- if eq .Values.volume.idx.type "hostPath" }} + {{- if $volume.idx }} + {{- if eq $volume.idx.type "hostPath" }} - name: idx hostPath: - path: {{ .Values.volume.idx.hostPathPrefix }}/seaweedfs-volume-idx/ + path: {{ $volume.idx.hostPathPrefix }}/seaweedfs-volume-idx/ type: DirectoryOrCreate {{- end }} - {{- if eq .Values.volume.idx.type "existingClaim" }} + {{- if eq $volume.idx.type "existingClaim" }} - name: idx persistentVolumeClaim: - claimName: {{ .Values.volume.idx.claimName }} + claimName: {{ $volume.idx.claimName }} {{- end }} - {{- if eq .Values.volume.idx.type "emptyDir" }} + {{- if eq $volume.idx.type "emptyDir" }} - name: idx emptyDir: {} {{- end }} {{- end }} - {{- if .Values.volume.logs }} - {{- if eq .Values.volume.logs.type "hostPath" }} + {{- if $volume.logs }} + {{- if eq $volume.logs.type "hostPath" }} - name: logs hostPath: - path: {{ .Values.volume.logs.hostPathPrefix }}/logs/seaweedfs/volume + path: {{ $volume.logs.hostPathPrefix }}/logs/seaweedfs/volume type: DirectoryOrCreate {{- end }} - {{- if eq .Values.volume.logs.type "existingClaim" }} + {{- if eq $volume.logs.type "existingClaim" }} - name: logs persistentVolumeClaim: - claimName: {{ .Values.volume.logs.claimName }} + claimName: {{ $volume.logs.claimName }} {{- end }} - {{- if eq .Values.volume.logs.type "emptyDir" }} + {{- if eq $volume.logs.type "emptyDir" }} - name: logs emptyDir: {} {{- end }} {{- end }} - {{- if .Values.global.enableSecurity }} + {{- if $.Values.global.enableSecurity }} - name: security-config configMap: - name: {{ template "seaweedfs.name" . }}-security-config + name: {{ template "seaweedfs.name" $ }}-security-config - name: ca-cert secret: - secretName: {{ template "seaweedfs.name" . }}-ca-cert + secretName: {{ template "seaweedfs.name" $ }}-ca-cert - name: master-cert secret: - secretName: {{ template "seaweedfs.name" . }}-master-cert + secretName: {{ template "seaweedfs.name" $ }}-master-cert - name: volume-cert secret: - secretName: {{ template "seaweedfs.name" . }}-volume-cert + secretName: {{ template "seaweedfs.name" $ }}-volume-cert - name: filer-cert secret: - secretName: {{ template "seaweedfs.name" . }}-filer-cert + secretName: {{ template "seaweedfs.name" $ }}-filer-cert - name: client-cert secret: - secretName: {{ template "seaweedfs.name" . }}-client-cert + secretName: {{ template "seaweedfs.name" $ }}-client-cert {{- end }} - {{- if .Values.volume.extraVolumes }} - {{ tpl .Values.volume.extraVolumes . | indent 8 | trim }} + {{- if $volume.extraVolumes }} + {{ tpl $volume.extraVolumes $ | indent 8 | trim }} {{- end }} - {{- if .Values.volume.nodeSelector }} + {{- if $volume.nodeSelector }} nodeSelector: - {{ tpl .Values.volume.nodeSelector . | indent 8 | trim }} + {{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.nodeSelector) $ | indent 8 | trim }} {{- end }} volumeClaimTemplates: - {{- range $dir := .Values.volume.dataDirs }} + {{- range $dir := $volume.dataDirs }} {{- if eq $dir.type "persistentVolumeClaim" }} - apiVersion: v1 kind: PersistentVolumeClaim @@ -374,36 +384,37 @@ spec: {{- end }} {{- end }} - {{- if and .Values.volume.idx (eq .Values.volume.idx.type "persistentVolumeClaim") }} + {{- if and $volume.idx (eq $volume.idx.type "persistentVolumeClaim") }} - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: idx - {{- with .Values.volume.idx.annotations }} + {{- with $volume.idx.annotations }} annotations: {{- toYaml . | nindent 10 }} {{- end }} spec: accessModes: [ "ReadWriteOnce" ] - storageClassName: {{ .Values.volume.idx.storageClass }} + storageClassName: {{ $volume.idx.storageClass }} resources: requests: - storage: {{ .Values.volume.idx.size }} + storage: {{ $volume.idx.size }} {{- end }} - {{- if and .Values.volume.logs (eq .Values.volume.logs.type "persistentVolumeClaim") }} + {{- if and $volume.logs (eq $volume.logs.type "persistentVolumeClaim") }} - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: logs - {{- with .Values.volume.logs.annotations }} + {{- with $volume.logs.annotations }} annotations: {{- toYaml . | nindent 10 }} {{- end }} spec: accessModes: [ "ReadWriteOnce" ] - storageClassName: {{ .Values.volume.logs.storageClass }} + storageClassName: {{ $volume.logs.storageClass }} resources: requests: - storage: {{ .Values.volume.logs.size }} - {{- end }} + storage: {{ $volume.logs.size }} {{- end }} +{{- end }} +{{- end }} diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 53cc7ef7f..b1b97de16 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -191,7 +191,7 @@ master: # Topology Spread Constraints Settings # This should map directly to the value of the topologySpreadConstraints # for a PodSpec. By Default no constraints are set. - topologySpreadConstraints: null + topologySpreadConstraints: "" # Toleration Settings for master pods # This should be a multi-line string matching the Toleration array @@ -456,13 +456,13 @@ volume: matchLabels: app.kubernetes.io/name: {{ template "seaweedfs.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: volume + app.kubernetes.io/component: {{ $volumeName }} topologyKey: kubernetes.io/hostname # Topology Spread Constraints Settings # This should map directly to the value of the topologySpreadConstraints # for a PodSpec. By Default no constraints are set. - topologySpreadConstraints: null + topologySpreadConstraints: "" # Resource requests, limits, etc. for the server cluster placement. This # should map directly to the value of the resources field for a PodSpec, @@ -538,6 +538,31 @@ volume: failureThreshold: 100 timeoutSeconds: 30 +# Map of named volume groups for topology-aware deployments. +# Each key inherits all fields from the `volume` section but can override +# them locally—for example, replicas, nodeSelector, dataCenter, etc. +# To switch entirely to this scheme, set `volume.enabled: false` +# and define one entry per zone/data-center under `volumes`. +# +# volumes: +# dc1: +# replicas: 2 +# dataCenter: "dc1" +# nodeSelector: | +# topology.kubernetes.io/zone: dc1 +# dc2: +# replicas: 2 +# dataCenter: "dc2" +# nodeSelector: | +# topology.kubernetes.io/zone: dc2 +# dc3: +# replicas: 2 +# dataCenter: "dc3" +# nodeSelector: | +# topology.kubernetes.io/zone: dc3 +# +volumes: {} + filer: enabled: true imageOverride: null @@ -690,7 +715,7 @@ filer: # Topology Spread Constraints Settings # This should map directly to the value of the topologySpreadConstraints # for a PodSpec. By Default no constraints are set. - topologySpreadConstraints: null + topologySpreadConstraints: "" # updatePartition is used to control a careful rolling update of SeaweedFS # masters. @@ -1146,7 +1171,7 @@ allInOne: # Topology Spread Constraints Settings # This should map directly to the value of the topologySpreadConstraints # for a PodSpec. By Default no constraints are set. - topologySpreadConstraints: null + topologySpreadConstraints: "" # Toleration Settings for master pods # This should be a multi-line string matching the Toleration array