Browse Source

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
pull/7640/head
chrislu 5 days ago
parent
commit
a1ca496e70
  1. 172
      .github/workflows/helm_ci.yml
  2. 112
      k8s/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml
  3. 154
      k8s/charts/seaweedfs/templates/all-in-one/all-in-one-ingress.yaml
  4. 23
      k8s/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml
  5. 18
      k8s/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml
  6. 66
      k8s/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml
  7. 108
      k8s/charts/seaweedfs/values.yaml

172
.github/workflows/helm_ci.yml

@ -118,6 +118,178 @@ jobs:
echo ""
echo "✅ All template rendering tests passed!"
- name: Verify all-in-one template rendering
run: |
set -e
CHART_DIR="k8s/charts/seaweedfs"
echo "=== Testing all-in-one with custom replicas ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.replicas=2 > /tmp/allinone-replicas.yaml
grep -q "replicas: 2" /tmp/allinone-replicas.yaml
echo "✓ All-in-one replicas configuration works"
echo "=== Testing all-in-one with S3 enabled ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.s3.enabled=true > /tmp/allinone-s3.yaml
grep -q "\-s3" /tmp/allinone-s3.yaml
grep -q "swfs-s3" /tmp/allinone-s3.yaml
echo "✓ All-in-one S3 configuration works"
echo "=== Testing all-in-one with custom S3 port ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.s3.enabled=true \
--set allInOne.s3.port=9000 > /tmp/allinone-s3-port.yaml
grep -q "port: 9000" /tmp/allinone-s3-port.yaml
echo "✓ All-in-one custom S3 port works"
echo "=== Testing all-in-one with S3 auth ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.s3.enabled=true \
--set allInOne.s3.enableAuth=true > /tmp/allinone-s3-auth.yaml
grep -q "config-s3-users" /tmp/allinone-s3-auth.yaml
grep -q "s3.config=" /tmp/allinone-s3-auth.yaml
echo "✓ All-in-one S3 auth configuration works"
echo "=== Testing all-in-one with S3 domainName ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.s3.enabled=true \
--set allInOne.s3.domainName=s3.example.com > /tmp/allinone-s3-domain.yaml
grep -q "s3.domainName=s3.example.com" /tmp/allinone-s3-domain.yaml
echo "✓ All-in-one S3 domain name configuration works"
echo "=== Testing all-in-one with SFTP enabled ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.sftp.enabled=true > /tmp/allinone-sftp.yaml
grep -q "\-sftp" /tmp/allinone-sftp.yaml
grep -q "swfs-sftp" /tmp/allinone-sftp.yaml
echo "✓ All-in-one SFTP configuration works"
echo "=== Testing all-in-one with custom SFTP port ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.sftp.enabled=true \
--set allInOne.sftp.port=2222 > /tmp/allinone-sftp-port.yaml
grep -q "sftp.port=2222" /tmp/allinone-sftp-port.yaml
echo "✓ All-in-one custom SFTP port works"
echo "=== Testing all-in-one with extraArgs ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set 'allInOne.extraArgs[0]=-customFlag' \
--set 'allInOne.extraArgs[1]=customValue' > /tmp/allinone-extraargs.yaml
grep -q "\-customFlag" /tmp/allinone-extraargs.yaml
echo "✓ All-in-one extraArgs configuration works"
echo "=== Testing all-in-one with RollingUpdate strategy ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.updateStrategy.type=RollingUpdate > /tmp/allinone-strategy.yaml
grep -q "type: RollingUpdate" /tmp/allinone-strategy.yaml
echo "✓ All-in-one update strategy configuration works"
echo "=== Testing all-in-one with PVC storage ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.data.type=persistentVolumeClaim \
--set allInOne.data.size=50Gi \
--set allInOne.data.storageClass=fast > /tmp/allinone-pvc.yaml
grep -q "PersistentVolumeClaim" /tmp/allinone-pvc.yaml
grep -q "storage: 50Gi" /tmp/allinone-pvc.yaml
grep -q "storageClassName: fast" /tmp/allinone-pvc.yaml
echo "✓ All-in-one PVC configuration works"
echo "=== Testing all-in-one with existing claim ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.data.type=existingClaim \
--set allInOne.data.claimName=my-existing-pvc > /tmp/allinone-existing-claim.yaml
grep -q "claimName: my-existing-pvc" /tmp/allinone-existing-claim.yaml
echo "✓ All-in-one existing claim configuration works"
echo "=== Testing all-in-one with hostPath storage ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.data.type=hostPath \
--set allInOne.data.hostPathPrefix=/mnt/seaweedfs > /tmp/allinone-hostpath.yaml
grep -q "hostPath:" /tmp/allinone-hostpath.yaml
grep -q "/mnt/seaweedfs/seaweedfs-all-in-one-data" /tmp/allinone-hostpath.yaml
echo "✓ All-in-one hostPath configuration works"
echo "=== Testing all-in-one with ingress (S3) ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.s3.enabled=true \
--set allInOne.ingress.enabled=true \
--set allInOne.ingress.s3.enabled=true \
--set allInOne.ingress.host=seaweedfs.example.com > /tmp/allinone-ingress-s3.yaml
grep -q "kind: Ingress" /tmp/allinone-ingress-s3.yaml
grep -q "seaweedfs-all-in-one-s3" /tmp/allinone-ingress-s3.yaml
echo "✓ All-in-one S3 ingress configuration works"
echo "=== Testing all-in-one with ingress (filer) ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.ingress.enabled=true \
--set allInOne.ingress.filer.enabled=true > /tmp/allinone-ingress-filer.yaml
grep -q "seaweedfs-all-in-one-filer" /tmp/allinone-ingress-filer.yaml
echo "✓ All-in-one filer ingress configuration works"
echo "=== Testing all-in-one with ingress (master) ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.ingress.enabled=true \
--set allInOne.ingress.master.enabled=true > /tmp/allinone-ingress-master.yaml
grep -q "seaweedfs-all-in-one-master" /tmp/allinone-ingress-master.yaml
echo "✓ All-in-one master ingress configuration works"
echo "=== Testing all-in-one with secretExtraEnvironmentVars ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set 'allInOne.secretExtraEnvironmentVars.DB_PASSWORD.secretKeyRef.name=db-secret' \
--set 'allInOne.secretExtraEnvironmentVars.DB_PASSWORD.secretKeyRef.key=password' > /tmp/allinone-secret-env.yaml
grep -q "DB_PASSWORD" /tmp/allinone-secret-env.yaml
grep -q "secretKeyRef" /tmp/allinone-secret-env.yaml
echo "✓ All-in-one secretExtraEnvironmentVars configuration works"
echo "=== Testing all-in-one with security enabled ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set global.enableSecurity=true > /tmp/allinone-security.yaml
grep -q "security-config" /tmp/allinone-security.yaml
grep -q "ca-cert" /tmp/allinone-security.yaml
echo "✓ All-in-one security configuration works"
echo "=== Testing all-in-one combined configuration ==="
helm template test $CHART_DIR \
--set allInOne.enabled=true \
--set allInOne.replicas=1 \
--set allInOne.s3.enabled=true \
--set allInOne.s3.port=9000 \
--set allInOne.s3.enableAuth=true \
--set allInOne.sftp.enabled=true \
--set allInOne.sftp.port=2222 \
--set allInOne.data.type=persistentVolumeClaim \
--set allInOne.data.size=100Gi \
--set allInOne.ingress.enabled=true \
--set allInOne.ingress.s3.enabled=true \
--set allInOne.ingress.filer.enabled=true > /tmp/allinone-combined.yaml
grep -q "replicas: 1" /tmp/allinone-combined.yaml
grep -q "s3.port=9000" /tmp/allinone-combined.yaml
grep -q "sftp.port=2222" /tmp/allinone-combined.yaml
grep -q "storage: 100Gi" /tmp/allinone-combined.yaml
grep -q "kind: Ingress" /tmp/allinone-combined.yaml
echo "✓ All-in-one combined configuration works"
echo ""
echo "✅ All all-in-one template rendering tests passed!"
- name: Create kind cluster
uses: helm/kind-action@v1.13.0

112
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,81 @@ spec:
{{- end }}
{{- if .Values.allInOne.s3.enabled }}
-s3 \
-s3.port={{ .Values.s3.port }} \
{{- if .Values.s3.domainName }}
-s3.port={{ .Values.allInOne.s3.port | default .Values.s3.port }} \
{{- if .Values.allInOne.s3.domainName }}
-s3.domainName={{ .Values.allInOne.s3.domainName }} \
{{- else if .Values.s3.domainName }}
-s3.domainName={{ .Values.s3.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" }}
{{- $s3AllowEmptyFolder := .Values.allInOne.s3.allowEmptyFolder }}
{{- if eq (typeOf $s3AllowEmptyFolder) "bool" }}
-s3.allowEmptyFolder={{ $s3AllowEmptyFolder }} \
{{- else if eq (typeOf .Values.s3.allowEmptyFolder) "bool" }}
-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 }}
{{- range .Values.allInOne.extraArgs }}
{{ . }} \
{{- 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 +316,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 +368,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 }}
@ -389,26 +426,31 @@ spec:
path: {{ .Values.allInOne.data.hostPathPrefix }}/seaweedfs-all-in-one-data/
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

154
k8s/charts/seaweedfs/templates/all-in-one/all-in-one-ingress.yaml

@ -0,0 +1,154 @@
{{- if .Values.allInOne.enabled }}
{{- if .Values.allInOne.ingress.enabled }}
{{- $fullName := printf "%s-all-in-one" (include "seaweedfs.name" .) -}}
{{- /* S3 Ingress */}}
{{- if and .Values.allInOne.s3.enabled .Values.allInOne.ingress.s3.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}-s3
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
{{- with .Values.allInOne.ingress.s3.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.allInOne.ingress.className }}
ingressClassName: {{ .Values.allInOne.ingress.className }}
{{- end }}
{{- if .Values.allInOne.ingress.s3.tls }}
tls:
{{- range .Values.allInOne.ingress.s3.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- if .Values.allInOne.ingress.host }}
- host: {{ .Values.allInOne.ingress.host | quote }}
http:
{{- else }}
- http:
{{- end }}
paths:
- path: {{ .Values.allInOne.ingress.s3.path }}
pathType: {{ .Values.allInOne.ingress.s3.pathType }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ .Values.allInOne.s3.port | default .Values.s3.port }}
{{- end }}
{{- /* Filer Ingress */}}
{{- if .Values.allInOne.ingress.filer.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}-filer
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
{{- with .Values.allInOne.ingress.filer.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.allInOne.ingress.className }}
ingressClassName: {{ .Values.allInOne.ingress.className }}
{{- end }}
{{- if .Values.allInOne.ingress.filer.tls }}
tls:
{{- range .Values.allInOne.ingress.filer.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- if .Values.allInOne.ingress.host }}
- host: {{ .Values.allInOne.ingress.host | quote }}
http:
{{- else }}
- http:
{{- end }}
paths:
- path: {{ .Values.allInOne.ingress.filer.path }}
pathType: {{ .Values.allInOne.ingress.filer.pathType }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ .Values.filer.port }}
{{- end }}
{{- /* Master Ingress */}}
{{- if .Values.allInOne.ingress.master.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}-master
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
{{- with .Values.allInOne.ingress.master.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.allInOne.ingress.className }}
ingressClassName: {{ .Values.allInOne.ingress.className }}
{{- end }}
{{- if .Values.allInOne.ingress.master.tls }}
tls:
{{- range .Values.allInOne.ingress.master.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- if .Values.allInOne.ingress.host }}
- host: {{ .Values.allInOne.ingress.host | quote }}
http:
{{- else }}
- http:
{{- end }}
paths:
- path: {{ .Values.allInOne.ingress.master.path }}
pathType: {{ .Values.allInOne.ingress.master.pathType }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ .Values.master.port }}
{{- end }}
{{- end }}
{{- end }}

23
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 }}
{{- if .Values.allInOne.data.storageClass }}
storageClassName: {{ .Values.allInOne.data.storageClass }}
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.allInOne.data.size | default "10Gi" }}
{{- end }}
{{- end }}

18
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 }}
{{- end }}

66
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 }}
{{- $existingConfigSecret = or .Values.allInOne.s3.existingConfigSecret .Values.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,24 @@ spec:
echo "Service at $url failed to become ready within 5 minutes"
exit 1
}
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 }}
wait_for_service "http://$WEED_CLUSTER_SW_MASTER/cluster/status"
wait_for_service "http://$WEED_CLUSTER_SW_FILER/"
{{- range $createBuckets }}
exec /bin/echo \
"s3.bucket.create --name {{ $props.name }}" |\
"s3.bucket.create --name {{ .name }}" |\
/usr/bin/weed shell
{{- end }}
{{- range $reg, $props := $.Values.filer.s3.createBuckets }}
{{- if $props.anonymousRead }}
{{- range $createBuckets }}
{{- if .anonymousRead }}
exec /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 +132,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 }}

108
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,71 @@ 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
updateStrategy:
type: Recreate
# S3 gateway configuration
s3:
enabled: false # Whether to enable S3 gateway
port: 8333 # S3 gateway port
httpsPort: 0 # S3 gateway HTTPS port (0 to disable)
domainName: "" # Suffix of the host name, {bucket}.{domainName}
allowEmptyFolder: true # Allow empty folders in S3
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: {} # S3 audit log configuration
# 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
sftp:
enabled: false # Whether to enable SFTP server
port: 2022 # SFTP port
sshPrivateKey: "/etc/sw/seaweedfs_sftp_ssh_private_key" # Path to SSH private key
hostKeysFolder: "/etc/sw/ssh" # Path to SSH host keys folder
authMethods: "password,publickey" # Comma-separated auth methods
maxAuthTries: 6 # Maximum authentication attempts
bannerMessage: "SeaweedFS SFTP Server" # Banner message
loginGraceTime: "2m" # Login grace time
clientAliveInterval: "5s" # Client keep-alive interval
clientAliveCountMax: 3 # Maximum missed keep-alive messages
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
# 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
claimName: seaweedfs-data-pvc # Name of the PVC to use (for existingClaim type)
size: "" # Size of the PVC (for persistentVolumeClaim type)
storageClass: "" # Storage class for the PVC
annotations: {} # Annotations for the PVC
# Health checks
readinessProbe:
@ -1154,6 +1202,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 +1233,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 +1241,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: ""
@ -1226,6 +1286,38 @@ allInOne:
cpu: "500m"
memory: "1Gi"
# Ingress configuration
ingress:
enabled: false
className: ""
# host: false for "*" hostname
host: "seaweedfs.cluster.local"
# S3 ingress settings
s3:
enabled: false
path: "/"
pathType: Prefix
annotations: {}
tls: []
# Filer ingress settings
filer:
enabled: false
path: "/sw-filer/?(.*)"
pathType: ImplementationSpecific
annotations: {}
# nginx.ingress.kubernetes.io/rewrite-target: /$1
# nginx.ingress.kubernetes.io/use-regex: "true"
tls: []
# Master ingress settings
master:
enabled: false
path: "/sw-master/?(.*)"
pathType: ImplementationSpecific
annotations: {}
# nginx.ingress.kubernetes.io/rewrite-target: /$1
# nginx.ingress.kubernetes.io/use-regex: "true"
tls: []
# Deploy Kubernetes COSI Driver for SeaweedFS
# Requires COSI CRDs and controller to be installed in the cluster
# For more information, visit: https://container-object-storage-interface.github.io/docs/deployment-guide

Loading…
Cancel
Save