aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chrislusf@users.noreply.github.com>2025-12-06 18:54:28 -0800
committerGitHub <noreply@github.com>2025-12-06 18:54:28 -0800
commit62a83ed4699292d76267b8d6343d1ed968f485f6 (patch)
tree5758929db86af4a4f06604d8fdfd73992bfdfa44
parent9c266fac2914c390437eaebe3270b0a229858e61 (diff)
downloadseaweedfs-62a83ed4699292d76267b8d6343d1ed968f485f6.tar.xz
seaweedfs-62a83ed4699292d76267b8d6343d1ed968f485f6.zip
helm: enhance all-in-one deployment configuration (#7639)
* helm: enhance all-in-one deployment configuration Fixes #7110 This PR addresses multiple issues with the all-in-one Helm chart configuration: ## New Features ### Configurable Replicas - Added `allInOne.replicas` (was hardcoded to 1) ### S3 Gateway Configuration - Added full S3 config under `allInOne.s3`: - port, httpsPort, domainName, allowEmptyFolder - enableAuth, existingConfigSecret, auditLogConfig - createBuckets for declarative bucket creation ### SFTP Server Configuration - Added full SFTP config under `allInOne.sftp`: - port, sshPrivateKey, hostKeysFolder, authMethods - maxAuthTries, bannerMessage, loginGraceTime - clientAliveInterval, clientAliveCountMax, enableAuth ### Command Line Arguments - Added `allInOne.extraArgs` for custom CLI arguments ### Update Strategy - Added `allInOne.updateStrategy.type` (Recreate/RollingUpdate) ### Secret Environment Variables - Added `allInOne.secretExtraEnvironmentVars` for injecting secrets ### Ingress Support - Added `allInOne.ingress` with S3, filer, and master sub-configs ### Storage Options - Enhanced `allInOne.data` with existingClaim support - Added PVC template for persistentVolumeClaim type ## CI Enhancements - Added comprehensive tests for all-in-one configurations - Tests cover replicas, S3, SFTP, extraArgs, strategies, PVC, ingress * helm: add real cluster deployment tests to CI - Deploy all-in-one cluster with S3 enabled on kind cluster - Test Master API (/cluster/status endpoint) - Test Filer API (file upload/download) - Test S3 API (/status endpoint) - Test S3 operations with AWS CLI: - Create/delete buckets - Upload/download/delete objects - Verify file content integrity * helm: simplify CI and remove all-in-one ingress Address review comments: - Remove detailed all-in-one template rendering tests from CI - Remove real cluster deployment tests from CI - Remove all-in-one ingress template and values configuration Keep the core improvements: - allInOne.replicas configuration - allInOne.s3.* full configuration - allInOne.sftp.* full configuration - allInOne.extraArgs support - allInOne.updateStrategy configuration - allInOne.secretExtraEnvironmentVars support * helm: address review comments - Fix post-install-bucket-hook.yaml: add filer.s3.enableAuth and filer.s3.existingConfigSecret to or statements for consistency - Fix all-in-one-deployment.yaml: use default function for s3.domainName - Fix all-in-one-deployment.yaml: use hasKey function for s3.allowEmptyFolder * helm: clarify updateStrategy multi-replica behavior Expand comment to warn users that RollingUpdate with multiple replicas requires shared storage (ReadWriteMany) to avoid data loss. * helm: address gemini-code-assist review comments - Make PVC accessModes configurable to support ReadWriteMany for multi-replica deployments (defaults to ReadWriteOnce) - Use configured readiness probe paths in post-install bucket hook instead of hardcoded paths, respecting custom configurations * helm: simplify allowEmptyFolder logic using coalesce Use coalesce function for cleaner template code as suggested in review. * helm: fix extraArgs trailing backslash issue Remove trailing backslash after the last extraArgs argument to avoid shell syntax error. Use counter to only add backslash between arguments. * helm: fix fallback logic for allInOne s3/sftp configuration Changes: - Set allInOne.s3.* and allInOne.sftp.* override parameters to null by default This allows proper inheritance from global s3.* and sftp.* settings - Fix allowEmptyFolder logic to use explicit nil checking instead of coalesce The coalesce/default functions treat 'false' as empty, causing incorrect fallback behavior when users want to explicitly set false values Addresses review feedback about default value conflicts with fallback logic. * helm: fix exec in bucket creation loop causing premature termination Remove 'exec' from the range loops that create and configure S3 buckets. The exec command replaces the current shell process, causing the script to terminate after the first bucket, preventing creation/configuration of subsequent buckets. * helm: quote extraArgs to handle arguments with spaces Use the quote function to ensure each item in extraArgs is treated as a single, complete argument even if it contains spaces. * helm: make s3/filer ingress work for both normal and all-in-one modes Modified s3-ingress.yaml and filer-ingress.yaml to dynamically select the service name based on deployment mode: - Normal mode: points to seaweedfs-s3 / seaweedfs-filer services - All-in-one mode: points to seaweedfs-all-in-one service This eliminates the need for separate all-in-one ingress templates. Users can now use the standard s3.ingress and filer.ingress settings for both deployment modes. * helm: fix allInOne.data.size and storageClass to use null defaults Change size and storageClass from empty strings to null so the template defaults (10Gi for size, cluster default for storageClass) will apply correctly. Empty strings prevent the Helm | default function from working. * helm: fix S3 ingress to include standalone S3 gateway case Add s3.enabled check to the $s3Enabled logic so the ingress works for: 1. Standalone S3 gateway (s3.enabled) 2. S3 on Filer (filer.s3.enabled) when not in all-in-one mode 3. S3 in all-in-one mode (allInOne.s3.enabled)
-rw-r--r--k8s/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml113
-rw-r--r--k8s/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml25
-rw-r--r--k8s/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml18
-rw-r--r--k8s/charts/seaweedfs/templates/filer/filer-ingress.yaml13
-rw-r--r--k8s/charts/seaweedfs/templates/s3/s3-ingress.yaml16
-rw-r--r--k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml71
-rw-r--r--k8s/charts/seaweedfs/values.yaml93
7 files changed, 254 insertions, 95 deletions
diff --git a/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml b/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml
index 6f176ae19..7e1b993cf 100644
--- a/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml
+++ b/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml
@@ -15,9 +15,9 @@ metadata:
{{- toYaml .Values.allInOne.annotations | nindent 4 }}
{{- end }}
spec:
- replicas: 1
+ replicas: {{ .Values.allInOne.replicas | default 1 }}
strategy:
- type: Recreate
+ type: {{ .Values.allInOne.updateStrategy.type | default "Recreate" }}
selector:
matchLabels:
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
@@ -130,12 +130,23 @@ spec:
value: {{ include "seaweedfs.cluster.masterAddress" . | quote }}
- name: {{ $clusterFilerKey }}
value: {{ include "seaweedfs.cluster.filerAddress" . | quote }}
+ {{- if .Values.allInOne.secretExtraEnvironmentVars }}
+ {{- range $key, $value := .Values.allInOne.secretExtraEnvironmentVars }}
+ - name: {{ $key }}
+ valueFrom:
+ {{ toYaml $value | nindent 16 }}
+ {{- end }}
+ {{- end }}
command:
- "/bin/sh"
- "-ec"
- |
/usr/bin/weed \
+ {{- if .Values.allInOne.loggingOverrideLevel }}
+ -v={{ .Values.allInOne.loggingOverrideLevel }} \
+ {{- else }}
-v={{ .Values.global.loggingLevel }} \
+ {{- end }}
server \
-dir=/data \
-master \
@@ -191,6 +202,9 @@ spec:
{{- else if .Values.master.metricsPort }}
-metricsPort={{ .Values.master.metricsPort }} \
{{- end }}
+ {{- if .Values.allInOne.metricsIp }}
+ -metricsIp={{ .Values.allInOne.metricsIp }} \
+ {{- end }}
-filer \
-filer.port={{ .Values.filer.port }} \
{{- if .Values.filer.disableDirListing }}
@@ -219,61 +233,80 @@ spec:
{{- end }}
{{- if .Values.allInOne.s3.enabled }}
-s3 \
- -s3.port={{ .Values.s3.port }} \
- {{- if .Values.s3.domainName }}
- -s3.domainName={{ .Values.s3.domainName }} \
+ -s3.port={{ .Values.allInOne.s3.port | default .Values.s3.port }} \
+ {{- $domainName := .Values.allInOne.s3.domainName | default .Values.s3.domainName }}
+ {{- if $domainName }}
+ -s3.domainName={{ $domainName }} \
{{- end }}
{{- if .Values.global.enableSecurity }}
- {{- if .Values.s3.httpsPort }}
- -s3.port.https={{ .Values.s3.httpsPort }} \
+ {{- $httpsPort := .Values.allInOne.s3.httpsPort | default .Values.s3.httpsPort }}
+ {{- if $httpsPort }}
+ -s3.port.https={{ $httpsPort }} \
{{- end }}
-s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \
-s3.key.file=/usr/local/share/ca-certificates/client/tls.key \
{{- end }}
- {{- if eq (typeOf .Values.s3.allowEmptyFolder) "bool" }}
+ {{- if ne .Values.allInOne.s3.allowEmptyFolder nil }}
+ -s3.allowEmptyFolder={{ .Values.allInOne.s3.allowEmptyFolder }} \
+ {{- else if ne .Values.s3.allowEmptyFolder nil }}
-s3.allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \
{{- end }}
- {{- if .Values.s3.enableAuth }}
+ {{- if or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth }}
-s3.config=/etc/sw/s3/seaweedfs_s3_config \
{{- end }}
- {{- if .Values.s3.auditLogConfig }}
+ {{- $auditLogConfig := .Values.allInOne.s3.auditLogConfig | default .Values.s3.auditLogConfig }}
+ {{- if $auditLogConfig }}
-s3.auditLogConfig=/etc/sw/s3/s3_auditLogConfig.json \
{{- end }}
{{- end }}
{{- if .Values.allInOne.sftp.enabled }}
-sftp \
- -sftp.port={{ .Values.sftp.port }} \
- {{- if .Values.sftp.sshPrivateKey }}
- -sftp.sshPrivateKey={{ .Values.sftp.sshPrivateKey }} \
+ -sftp.port={{ .Values.allInOne.sftp.port | default .Values.sftp.port }} \
+ {{- $sshPrivateKey := .Values.allInOne.sftp.sshPrivateKey | default .Values.sftp.sshPrivateKey }}
+ {{- if $sshPrivateKey }}
+ -sftp.sshPrivateKey={{ $sshPrivateKey }} \
{{- end }}
- {{- if .Values.sftp.hostKeysFolder }}
- -sftp.hostKeysFolder={{ .Values.sftp.hostKeysFolder }} \
+ {{- $hostKeysFolder := .Values.allInOne.sftp.hostKeysFolder | default .Values.sftp.hostKeysFolder }}
+ {{- if $hostKeysFolder }}
+ -sftp.hostKeysFolder={{ $hostKeysFolder }} \
{{- end }}
- {{- if .Values.sftp.authMethods }}
- -sftp.authMethods={{ .Values.sftp.authMethods }} \
+ {{- $authMethods := .Values.allInOne.sftp.authMethods | default .Values.sftp.authMethods }}
+ {{- if $authMethods }}
+ -sftp.authMethods={{ $authMethods }} \
{{- end }}
- {{- if .Values.sftp.maxAuthTries }}
- -sftp.maxAuthTries={{ .Values.sftp.maxAuthTries }} \
+ {{- $maxAuthTries := .Values.allInOne.sftp.maxAuthTries | default .Values.sftp.maxAuthTries }}
+ {{- if $maxAuthTries }}
+ -sftp.maxAuthTries={{ $maxAuthTries }} \
{{- end }}
- {{- if .Values.sftp.bannerMessage }}
- -sftp.bannerMessage="{{ .Values.sftp.bannerMessage }}" \
+ {{- $bannerMessage := .Values.allInOne.sftp.bannerMessage | default .Values.sftp.bannerMessage }}
+ {{- if $bannerMessage }}
+ -sftp.bannerMessage="{{ $bannerMessage }}" \
{{- end }}
- {{- if .Values.sftp.loginGraceTime }}
- -sftp.loginGraceTime={{ .Values.sftp.loginGraceTime }} \
+ {{- $loginGraceTime := .Values.allInOne.sftp.loginGraceTime | default .Values.sftp.loginGraceTime }}
+ {{- if $loginGraceTime }}
+ -sftp.loginGraceTime={{ $loginGraceTime }} \
{{- end }}
- {{- if .Values.sftp.clientAliveInterval }}
- -sftp.clientAliveInterval={{ .Values.sftp.clientAliveInterval }} \
+ {{- $clientAliveInterval := .Values.allInOne.sftp.clientAliveInterval | default .Values.sftp.clientAliveInterval }}
+ {{- if $clientAliveInterval }}
+ -sftp.clientAliveInterval={{ $clientAliveInterval }} \
{{- end }}
- {{- if .Values.sftp.clientAliveCountMax }}
- -sftp.clientAliveCountMax={{ .Values.sftp.clientAliveCountMax }} \
+ {{- $clientAliveCountMax := .Values.allInOne.sftp.clientAliveCountMax | default .Values.sftp.clientAliveCountMax }}
+ {{- if $clientAliveCountMax }}
+ -sftp.clientAliveCountMax={{ $clientAliveCountMax }} \
{{- end }}
+ {{- if or .Values.allInOne.sftp.enableAuth .Values.sftp.enableAuth }}
-sftp.userStoreFile=/etc/sw/sftp/seaweedfs_sftp_config \
{{- end }}
+ {{- end }}
+ {{- $extraArgsCount := len .Values.allInOne.extraArgs }}
+ {{- range $i, $arg := .Values.allInOne.extraArgs }}
+ {{ $arg | quote }}{{ if ne (add1 $i) $extraArgsCount }} \{{ end }}
+ {{- end }}
volumeMounts:
- name: data
mountPath: /data
- {{- if and .Values.allInOne.s3.enabled (or .Values.s3.enableAuth .Values.filer.s3.enableAuth) }}
+ {{- if and .Values.allInOne.s3.enabled (or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth) }}
- name: config-s3-users
mountPath: /etc/sw/s3
readOnly: true
@@ -282,10 +315,12 @@ spec:
- name: config-ssh
mountPath: /etc/sw/ssh
readOnly: true
+ {{- if or .Values.allInOne.sftp.enableAuth .Values.sftp.enableAuth }}
- mountPath: /etc/sw/sftp
name: config-users
readOnly: true
{{- end }}
+ {{- end }}
{{- if .Values.filer.notificationConfig }}
- name: notification-config
mountPath: /etc/seaweedfs/notification.toml
@@ -332,15 +367,16 @@ spec:
- containerPort: {{ .Values.filer.grpcPort }}
name: swfs-fil-grpc
{{- if .Values.allInOne.s3.enabled }}
- - containerPort: {{ .Values.s3.port }}
+ - containerPort: {{ .Values.allInOne.s3.port | default .Values.s3.port }}
name: swfs-s3
- {{- if .Values.s3.httpsPort }}
- - containerPort: {{ .Values.s3.httpsPort }}
+ {{- $httpsPort := .Values.allInOne.s3.httpsPort | default .Values.s3.httpsPort }}
+ {{- if $httpsPort }}
+ - containerPort: {{ $httpsPort }}
name: swfs-s3-tls
{{- end }}
{{- end }}
{{- if .Values.allInOne.sftp.enabled }}
- - containerPort: {{ .Values.sftp.port }}
+ - containerPort: {{ .Values.allInOne.sftp.port | default .Values.sftp.port }}
name: swfs-sftp
{{- end }}
{{- if .Values.allInOne.metricsPort }}
@@ -390,25 +426,30 @@ spec:
type: DirectoryOrCreate
{{- else if eq .Values.allInOne.data.type "persistentVolumeClaim" }}
persistentVolumeClaim:
+ claimName: {{ template "seaweedfs.name" . }}-all-in-one-data
+ {{- else if eq .Values.allInOne.data.type "existingClaim" }}
+ persistentVolumeClaim:
claimName: {{ .Values.allInOne.data.claimName }}
{{- else if eq .Values.allInOne.data.type "emptyDir" }}
emptyDir: {}
{{- end }}
- {{- if and .Values.allInOne.s3.enabled (or .Values.s3.enableAuth .Values.filer.s3.enableAuth) }}
+ {{- if and .Values.allInOne.s3.enabled (or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth) }}
- name: config-s3-users
secret:
defaultMode: 420
- secretName: {{ default (printf "%s-s3-secret" (include "seaweedfs.name" .)) (or .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret) }}
+ secretName: {{ default (printf "%s-s3-secret" (include "seaweedfs.name" .)) (or .Values.allInOne.s3.existingConfigSecret .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret) }}
{{- end }}
{{- if .Values.allInOne.sftp.enabled }}
- name: config-ssh
secret:
defaultMode: 420
- secretName: {{ default (printf "%s-sftp-ssh-secret" (include "seaweedfs.name" .)) .Values.sftp.existingSshConfigSecret }}
+ secretName: {{ default (printf "%s-sftp-ssh-secret" (include "seaweedfs.name" .)) (or .Values.allInOne.sftp.existingSshConfigSecret .Values.sftp.existingSshConfigSecret) }}
+ {{- if or .Values.allInOne.sftp.enableAuth .Values.sftp.enableAuth }}
- name: config-users
secret:
defaultMode: 420
- secretName: {{ default (printf "%s-sftp-secret" (include "seaweedfs.name" .)) .Values.sftp.existingConfigSecret }}
+ secretName: {{ default (printf "%s-sftp-secret" (include "seaweedfs.name" .)) (or .Values.allInOne.sftp.existingConfigSecret .Values.sftp.existingConfigSecret) }}
+ {{- end }}
{{- end }}
{{- if .Values.filer.notificationConfig }}
- name: notification-config
diff --git a/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml b/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml
index 49ac20148..a62450c3d 100644
--- a/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml
+++ b/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml
@@ -1,21 +1,28 @@
-{{- if and .Values.allInOne.enabled (eq .Values.allInOne.data.type "persistentVolumeClaim") }}
+{{- if .Values.allInOne.enabled }}
+{{- if eq .Values.allInOne.data.type "persistentVolumeClaim" }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
- name: {{ .Values.allInOne.data.claimName }}
+ name: {{ template "seaweedfs.name" . }}-all-in-one-data
+ 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: seaweedfs-all-in-one
- {{- if .Values.allInOne.annotations }}
+ {{- with .Values.allInOne.data.annotations }}
annotations:
- {{- toYaml .Values.allInOne.annotations | nindent 4 }}
+ {{- toYaml . | nindent 4 }}
{{- end }}
spec:
accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: {{ .Values.allInOne.data.size }}
+ {{- toYaml (.Values.allInOne.data.accessModes | default (list "ReadWriteOnce")) | nindent 4 }}
{{- if .Values.allInOne.data.storageClass }}
storageClassName: {{ .Values.allInOne.data.storageClass }}
{{- end }}
-{{- end }} \ No newline at end of file
+ resources:
+ requests:
+ storage: {{ .Values.allInOne.data.size | default "10Gi" }}
+{{- end }}
+{{- end }}
diff --git a/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml b/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml
index 14076a9c3..b13f57899 100644
--- a/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml
+++ b/k8s/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml
@@ -15,6 +15,7 @@ metadata:
{{- toYaml .Values.allInOne.service.annotations | nindent 4 }}
{{- end }}
spec:
+ type: {{ .Values.allInOne.service.type | default "ClusterIP" }}
internalTrafficPolicy: {{ .Values.allInOne.service.internalTrafficPolicy | default "Cluster" }}
ports:
# Master ports
@@ -50,13 +51,14 @@ spec:
# S3 ports (if enabled)
{{- if .Values.allInOne.s3.enabled }}
- name: "swfs-s3"
- port: {{ if .Values.allInOne.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }}
- targetPort: {{ if .Values.allInOne.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }}
+ port: {{ .Values.allInOne.s3.port | default .Values.s3.port }}
+ targetPort: {{ .Values.allInOne.s3.port | default .Values.s3.port }}
protocol: TCP
- {{- if and .Values.allInOne.s3.enabled .Values.s3.httpsPort }}
+ {{- $httpsPort := .Values.allInOne.s3.httpsPort | default .Values.s3.httpsPort }}
+ {{- if $httpsPort }}
- name: "swfs-s3-tls"
- port: {{ .Values.s3.httpsPort }}
- targetPort: {{ .Values.s3.httpsPort }}
+ port: {{ $httpsPort }}
+ targetPort: {{ $httpsPort }}
protocol: TCP
{{- end }}
{{- end }}
@@ -64,8 +66,8 @@ spec:
# SFTP ports (if enabled)
{{- if .Values.allInOne.sftp.enabled }}
- name: "swfs-sftp"
- port: {{ .Values.sftp.port }}
- targetPort: {{ .Values.sftp.port }}
+ port: {{ .Values.allInOne.sftp.port | default .Values.sftp.port }}
+ targetPort: {{ .Values.allInOne.sftp.port | default .Values.sftp.port }}
protocol: TCP
{{- end }}
@@ -80,4 +82,4 @@ spec:
selector:
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
app.kubernetes.io/component: seaweedfs-all-in-one
-{{- end }} \ No newline at end of file
+{{- end }}
diff --git a/k8s/charts/seaweedfs/templates/filer/filer-ingress.yaml b/k8s/charts/seaweedfs/templates/filer/filer-ingress.yaml
index 9ce15ae90..b185a58ba 100644
--- a/k8s/charts/seaweedfs/templates/filer/filer-ingress.yaml
+++ b/k8s/charts/seaweedfs/templates/filer/filer-ingress.yaml
@@ -1,5 +1,8 @@
-{{- if .Values.filer.enabled }}
-{{- if .Values.filer.ingress.enabled }}
+{{- /* Filer ingress works for both normal mode (filer.enabled) and all-in-one mode (allInOne.enabled) */}}
+{{- $filerEnabled := or .Values.filer.enabled .Values.allInOne.enabled }}
+{{- if and $filerEnabled .Values.filer.ingress.enabled }}
+{{- /* Determine service name based on deployment mode */}}
+{{- $serviceName := ternary (printf "%s-all-in-one" (include "seaweedfs.name" .)) (printf "%s-filer" (include "seaweedfs.name" .)) .Values.allInOne.enabled }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }}
@@ -33,16 +36,14 @@ spec:
backend:
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
service:
- name: {{ template "seaweedfs.name" . }}-filer
+ name: {{ $serviceName }}
port:
number: {{ .Values.filer.port }}
- #name:
{{- else }}
- serviceName: {{ template "seaweedfs.name" . }}-filer
+ serviceName: {{ $serviceName }}
servicePort: {{ .Values.filer.port }}
{{- end }}
{{- if .Values.filer.ingress.host }}
host: {{ .Values.filer.ingress.host }}
{{- end }}
{{- end }}
-{{- end }}
diff --git a/k8s/charts/seaweedfs/templates/s3/s3-ingress.yaml b/k8s/charts/seaweedfs/templates/s3/s3-ingress.yaml
index a856923e9..899773ae3 100644
--- a/k8s/charts/seaweedfs/templates/s3/s3-ingress.yaml
+++ b/k8s/charts/seaweedfs/templates/s3/s3-ingress.yaml
@@ -1,4 +1,9 @@
-{{- if .Values.s3.ingress.enabled }}
+{{- /* S3 ingress works for standalone S3 gateway (s3.enabled), S3 on Filer (filer.s3.enabled), and all-in-one mode (allInOne.s3.enabled) */}}
+{{- $s3Enabled := or .Values.s3.enabled (and .Values.filer.s3.enabled (not .Values.allInOne.enabled)) (and .Values.allInOne.enabled .Values.allInOne.s3.enabled) }}
+{{- if and $s3Enabled .Values.s3.ingress.enabled }}
+{{- /* Determine service name based on deployment mode */}}
+{{- $serviceName := ternary (printf "%s-all-in-one" (include "seaweedfs.name" .)) (printf "%s-s3" (include "seaweedfs.name" .)) .Values.allInOne.enabled }}
+{{- $s3Port := .Values.allInOne.s3.port | default .Values.s3.port }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }}
@@ -32,13 +37,12 @@ spec:
backend:
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
service:
- name: {{ template "seaweedfs.name" . }}-s3
+ name: {{ $serviceName }}
port:
- number: {{ .Values.s3.port }}
- #name:
+ number: {{ $s3Port }}
{{- else }}
- serviceName: {{ template "seaweedfs.name" . }}-s3
- servicePort: {{ .Values.s3.port }}
+ serviceName: {{ $serviceName }}
+ servicePort: {{ $s3Port }}
{{- end }}
{{- if .Values.s3.ingress.host }}
host: {{ .Values.s3.ingress.host | quote }}
diff --git a/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml b/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml
index 44d650898..a0c56edc4 100644
--- a/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml
+++ b/k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml
@@ -1,6 +1,32 @@
-{{- if .Values.master.enabled }}
-{{- if .Values.filer.s3.enabled }}
-{{- if .Values.filer.s3.createBuckets }}
+{{- /* Support bucket creation for both standalone filer.s3 and allInOne modes */}}
+{{- $createBuckets := list }}
+{{- $s3Enabled := false }}
+{{- $enableAuth := false }}
+{{- $existingConfigSecret := "" }}
+
+{{- /* Check allInOne mode first */}}
+{{- if .Values.allInOne.enabled }}
+ {{- if .Values.allInOne.s3.enabled }}
+ {{- $s3Enabled = true }}
+ {{- if .Values.allInOne.s3.createBuckets }}
+ {{- $createBuckets = .Values.allInOne.s3.createBuckets }}
+ {{- end }}
+ {{- $enableAuth = or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth }}
+ {{- $existingConfigSecret = or .Values.allInOne.s3.existingConfigSecret .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret }}
+ {{- end }}
+{{- else if .Values.master.enabled }}
+ {{- /* Check standalone filer.s3 mode */}}
+ {{- if .Values.filer.s3.enabled }}
+ {{- $s3Enabled = true }}
+ {{- if .Values.filer.s3.createBuckets }}
+ {{- $createBuckets = .Values.filer.s3.createBuckets }}
+ {{- end }}
+ {{- $enableAuth = .Values.filer.s3.enableAuth }}
+ {{- $existingConfigSecret = .Values.filer.s3.existingConfigSecret }}
+ {{- end }}
+{{- end }}
+
+{{- if and $s3Enabled $createBuckets }}
---
apiVersion: batch/v1
kind: Job
@@ -32,9 +58,9 @@ spec:
- name: WEED_CLUSTER_DEFAULT
value: "sw"
- name: WEED_CLUSTER_SW_MASTER
- value: "{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}:{{ .Values.master.port }}"
+ value: {{ include "seaweedfs.cluster.masterAddress" . | quote }}
- name: WEED_CLUSTER_SW_FILER
- value: "{{ template "seaweedfs.name" . }}-filer-client.{{ .Release.Namespace }}:{{ .Values.filer.port }}"
+ value: {{ include "seaweedfs.cluster.filerAddress" . | quote }}
- name: POD_IP
valueFrom:
fieldRef:
@@ -71,24 +97,29 @@ spec:
echo "Service at $url failed to become ready within 5 minutes"
exit 1
}
+ {{- if .Values.allInOne.enabled }}
+ wait_for_service "http://$WEED_CLUSTER_SW_MASTER{{ .Values.allInOne.readinessProbe.httpGet.path }}"
+ wait_for_service "http://$WEED_CLUSTER_SW_FILER{{ .Values.filer.readinessProbe.httpGet.path }}"
+ {{- else }}
wait_for_service "http://$WEED_CLUSTER_SW_MASTER{{ .Values.master.readinessProbe.httpGet.path }}"
wait_for_service "http://$WEED_CLUSTER_SW_FILER{{ .Values.filer.readinessProbe.httpGet.path }}"
- {{- range $reg, $props := $.Values.filer.s3.createBuckets }}
- exec /bin/echo \
- "s3.bucket.create --name {{ $props.name }}" |\
+ {{- end }}
+ {{- range $createBuckets }}
+ /bin/echo \
+ "s3.bucket.create --name {{ .name }}" |\
/usr/bin/weed shell
{{- end }}
- {{- range $reg, $props := $.Values.filer.s3.createBuckets }}
- {{- if $props.anonymousRead }}
- exec /bin/echo \
+ {{- range $createBuckets }}
+ {{- if .anonymousRead }}
+ /bin/echo \
"s3.configure --user anonymous \
- --buckets {{ $props.name }} \
+ --buckets {{ .name }} \
--actions Read \
--apply true" |\
/usr/bin/weed shell
{{- end }}
{{- end }}
- {{- if .Values.filer.s3.enableAuth }}
+ {{- if $enableAuth }}
volumeMounts:
- name: config-users
mountPath: /etc/sw
@@ -106,17 +137,15 @@ spec:
{{- if .Values.filer.containerSecurityContext.enabled }}
securityContext: {{- omit .Values.filer.containerSecurityContext "enabled" | toYaml | nindent 12 }}
{{- end }}
- {{- if .Values.filer.s3.enableAuth }}
+ {{- if $enableAuth }}
volumes:
- name: config-users
secret:
defaultMode: 420
- {{- if not (empty .Values.filer.s3.existingConfigSecret) }}
- secretName: {{ .Values.filer.s3.existingConfigSecret }}
+ {{- if $existingConfigSecret }}
+ secretName: {{ $existingConfigSecret }}
{{- else }}
- secretName: seaweedfs-s3-secret
+ secretName: {{ template "seaweedfs.name" . }}-s3-secret
{{- end }}
- {{- end }}{{/** if .Values.filer.s3.enableAuth **/}}
-{{- end }}{{/** if .Values.master.enabled **/}}
-{{- end }}{{/** if .Values.filer.s3.enabled **/}}
-{{- end }}{{/** if .Values.filer.s3.createBuckets **/}}
+ {{- end }}
+{{- end }}
diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml
index bddfd622d..0f3f94fc2 100644
--- a/k8s/charts/seaweedfs/values.yaml
+++ b/k8s/charts/seaweedfs/values.yaml
@@ -1097,6 +1097,7 @@ allInOne:
enabled: false
imageOverride: null
restartPolicy: Always
+ replicas: 1 # Number of replicas (note: multiple replicas may require shared storage)
# Core configuration
idleTimeout: 30 # Connection idle seconds
@@ -1108,24 +1109,86 @@ allInOne:
metricsIp: "" # Metrics listen IP. If empty, defaults to bindAddress
loggingOverrideLevel: null # Override logging level
- # Service configuration
+ # Custom command line arguments to add to the server command
+ # Example to fix IPv6 metrics connectivity issues:
+ # extraArgs: ["-metricsIp", "0.0.0.0"]
+ # Example with multiple args:
+ # extraArgs: ["-customFlag", "value", "-anotherFlag"]
+ extraArgs: []
+
+ # Update strategy configuration
+ # type: Recreate or RollingUpdate
+ # For single replica, Recreate is recommended to avoid data conflicts.
+ # For multiple replicas with RollingUpdate, you MUST use shared storage
+ # (e.g., data.type: persistentVolumeClaim with ReadWriteMany access mode)
+ # to avoid data loss or inconsistency between pods.
+ updateStrategy:
+ type: Recreate
+
+ # S3 gateway configuration
+ # Note: Most parameters below default to null, which means they inherit from
+ # the global s3.* settings. Set explicit values here to override for allInOne only.
s3:
enabled: false # Whether to enable S3 gateway
+ port: null # S3 gateway port (null inherits from s3.port)
+ httpsPort: null # S3 gateway HTTPS port (null inherits from s3.httpsPort)
+ domainName: null # Suffix of the host name (null inherits from s3.domainName)
+ allowEmptyFolder: null # Allow empty folders in S3 (null inherits from s3.allowEmptyFolder)
+ enableAuth: false # Enable user & permission to S3
+ # Set to the name of an existing kubernetes Secret with the s3 json config file
+ # should have a secret key called seaweedfs_s3_config with an inline json config
+ existingConfigSecret: null
+ auditLogConfig: null # S3 audit log configuration (null inherits from s3.auditLogConfig)
+ # You may specify buckets to be created during the install process.
+ # Buckets may be exposed publicly by setting `anonymousRead` to `true`
+ # createBuckets:
+ # - name: bucket-a
+ # anonymousRead: true
+ # - name: bucket-b
+ # anonymousRead: false
+
+ # SFTP server configuration
+ # Note: Most parameters below default to null, which means they inherit from
+ # the global sftp.* settings. Set explicit values here to override for allInOne only.
sftp:
enabled: false # Whether to enable SFTP server
+ port: null # SFTP port (null inherits from sftp.port)
+ sshPrivateKey: null # Path to SSH private key (null inherits from sftp.sshPrivateKey)
+ hostKeysFolder: null # Path to SSH host keys folder (null inherits from sftp.hostKeysFolder)
+ authMethods: null # Comma-separated auth methods (null inherits from sftp.authMethods)
+ maxAuthTries: null # Maximum authentication attempts (null inherits from sftp.maxAuthTries)
+ bannerMessage: null # Banner message (null inherits from sftp.bannerMessage)
+ loginGraceTime: null # Login grace time (null inherits from sftp.loginGraceTime)
+ clientAliveInterval: null # Client keep-alive interval (null inherits from sftp.clientAliveInterval)
+ clientAliveCountMax: null # Maximum missed keep-alive messages (null inherits from sftp.clientAliveCountMax)
+ enableAuth: false # Enable SFTP authentication
+ # Set to the name of an existing kubernetes Secret with the sftp json config file
+ existingConfigSecret: null
+ # Set to the name of an existing kubernetes Secret with the SSH keys
+ existingSshConfigSecret: null
# Service settings
service:
annotations: {} # Annotations for the service
type: ClusterIP # Service type (ClusterIP, NodePort, LoadBalancer)
+ internalTrafficPolicy: Cluster # Internal traffic policy
+
+ # Note: For ingress in all-in-one mode, use the standard s3.ingress and
+ # filer.ingress settings. The templates automatically detect all-in-one mode
+ # and point to the correct service (seaweedfs-all-in-one instead of
+ # seaweedfs-s3 or seaweedfs-filer).
# Storage configuration
data:
- type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir"
+ type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim"
hostPathPrefix: /mnt/data # Path prefix for hostPath volumes
- claimName: seaweedfs-data-pvc # Name of the PVC to use
- size: "" # Size of the PVC
- storageClass: "" # Storage class for the PVC
+ claimName: seaweedfs-data-pvc # Name of the PVC to use (for existingClaim type)
+ size: null # Size of the PVC (null defaults to 10Gi for persistentVolumeClaim type)
+ storageClass: null # Storage class for the PVC (null uses cluster default)
+ # accessModes for the PVC. Default is ["ReadWriteOnce"].
+ # For multi-replica deployments, use ["ReadWriteMany"] with a compatible storage class.
+ accessModes: []
+ annotations: {} # Annotations for the PVC
# Health checks
readinessProbe:
@@ -1154,6 +1217,18 @@ allInOne:
# Additional resources
extraEnvironmentVars: {} # Additional environment variables
+ # Secret environment variables (for database credentials, etc.)
+ # Example:
+ # secretExtraEnvironmentVars:
+ # WEED_POSTGRES_USERNAME:
+ # secretKeyRef:
+ # name: postgres-credentials
+ # key: username
+ # WEED_POSTGRES_PASSWORD:
+ # secretKeyRef:
+ # name: postgres-credentials
+ # key: password
+ secretExtraEnvironmentVars: {}
extraVolumeMounts: "" # Additional volume mounts
extraVolumes: "" # Additional volumes
initContainers: "" # Init containers
@@ -1173,7 +1248,7 @@ allInOne:
matchLabels:
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
- app.kubernetes.io/component: master
+ app.kubernetes.io/component: seaweedfs-all-in-one
topologyKey: kubernetes.io/hostname
# Topology Spread Constraints Settings
@@ -1181,16 +1256,16 @@ allInOne:
# for a PodSpec. By Default no constraints are set.
topologySpreadConstraints: ""
- # Toleration Settings for master pods
+ # Toleration Settings for pods
# This should be a multi-line string matching the Toleration array
# in a PodSpec.
tolerations: ""
- # nodeSelector labels for master pod assignment, formatted as a muli-line string.
+ # nodeSelector labels for pod assignment, formatted as a muli-line string.
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
nodeSelector: ""
- # Used to assign priority to master pods
+ # Used to assign priority to pods
# ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
priorityClassName: ""