From 2dee9b217c2c220564d3fa2e6c101b9a6c4b1c43 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 18:26:07 -0700 Subject: [PATCH 01/15] add admin and worker to helm charts --- k8s/charts/seaweedfs/README.md | 129 +++++++ .../templates/admin/admin-deployment.yaml | 315 ++++++++++++++++++ .../templates/admin/admin-ingress.yaml | 47 +++ .../templates/admin/admin-service.yaml | 39 +++ .../templates/admin/admin-servicemonitor.yaml | 34 ++ .../seaweedfs/templates/shared/_helpers.tpl | 38 +++ .../templates/worker/worker-deployment.yaml | 272 +++++++++++++++ .../worker/worker-servicemonitor.yaml | 34 ++ k8s/charts/seaweedfs/values.yaml | 165 +++++++++ 9 files changed, 1073 insertions(+) create mode 100644 k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml create mode 100644 k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml create mode 100644 k8s/charts/seaweedfs/templates/admin/admin-service.yaml create mode 100644 k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml create mode 100644 k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml create mode 100644 k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index 30885aee3..ccc0e87c5 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -145,6 +145,135 @@ stringData: seaweedfs_s3_config: '{"identities":[{"name":"anvAdmin","credentials":[{"accessKey":"snu8yoP6QAlY0ne4","secretKey":"PNzBcmeLNEdR0oviwm04NQAicOrDH1Km"}],"actions":["Admin","Read","Write"]},{"name":"anvReadOnly","credentials":[{"accessKey":"SCigFee6c5lbi04A","secretKey":"kgFhbT38R8WUYVtiFQ1OiSVOrYr3NKku"}],"actions":["Read"]}]}' ``` +## Admin Component + +The admin component provides a modern web-based administration interface for managing SeaweedFS clusters. It includes: + +- **Dashboard**: Real-time cluster status and metrics +- **Volume Management**: Monitor volume servers, capacity, and health +- **File Browser**: Browse and manage files in the filer +- **Maintenance Operations**: Trigger maintenance tasks via workers +- **Object Store Management**: Create and manage buckets with web interface + +### Enabling Admin + +To enable the admin interface, add the following to your values.yaml: + +```yaml +admin: + enabled: true + port: 23646 + grpcPort: 33646 # For worker connections + adminUser: "admin" + adminPassword: "your-secure-password" # Leave empty to disable auth + + # Optional: persist admin data + data: + type: "persistentVolumeClaim" + size: "10Gi" + storageClass: "your-storage-class" + + # Optional: enable ingress + ingress: + enabled: true + host: "admin.seaweedfs.local" + className: "nginx" +``` + +The admin interface will be available at `http://:23646` (or via ingress). Workers connect to the admin server via gRPC on port `33646`. + +### Admin Authentication + +If `adminPassword` is set, the admin interface requires authentication: +- Username: Value of `adminUser` (default: `admin`) +- Password: Value of `adminPassword` + +If `adminPassword` is empty or not set, the admin interface runs without authentication (not recommended for production). + +### Admin Data Persistence + +The admin component can store configuration and maintenance data. You can configure storage in several ways: + +- **emptyDir** (default): Data is lost when pod restarts +- **persistentVolumeClaim**: Data persists across pod restarts +- **hostPath**: Data stored on the host filesystem +- **existingClaim**: Use an existing PVC + +## Worker Component + +Workers are maintenance agents that execute cluster maintenance tasks such as vacuum, volume balancing, and erasure coding. Workers connect to the admin server via gRPC and receive task assignments. + +### Enabling Workers + +To enable workers, add the following to your values.yaml: + +```yaml +worker: + enabled: true + replicas: 2 # Scale based on workload + capabilities: "vacuum,balance,erasure_coding" # Tasks this worker can handle + maxConcurrent: 3 # Maximum concurrent tasks per worker + workingDir: "/tmp/seaweedfs-worker" + + # Optional: configure admin server address + # If not specified, auto-discovers from admin service + adminServer: "seaweedfs-admin.seaweedfs:33646" + + # Workers need storage for task execution + data: + type: "persistentVolumeClaim" + size: "50Gi" # Adjust based on volume size + storageClass: "your-storage-class" + + # Resource limits for worker pods + resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" +``` + +### Worker Capabilities + +Workers can be configured with different capabilities: +- **vacuum**: Reclaim deleted file space +- **balance**: Balance volumes across volume servers +- **erasure_coding**: Handle erasure coding operations + +You can configure workers with all capabilities or create specialized worker pools with specific capabilities. + +### Worker Deployment Strategy + +For production deployments, consider: + +1. **Multiple Workers**: Deploy 2+ worker replicas for high availability +2. **Resource Allocation**: Workers need sufficient CPU/memory for maintenance tasks +3. **Storage**: Workers need temporary storage for vacuum and balance operations (size depends on volume size) +4. **Specialized Workers**: Create separate worker deployments for different capabilities if needed + +Example specialized worker configuration: + +```yaml +# In your values.yaml - deploy multiple worker deployments manually +# One for vacuum operations +worker: + enabled: true + replicas: 2 + capabilities: "vacuum" + maxConcurrent: 2 + +# Deploy another release for balance operations +# helm install seaweedfs-worker-balance seaweedfs/seaweedfs --values worker-balance-values.yaml +# worker-balance-values.yaml: +worker: + enabled: true + replicas: 1 + capabilities: "balance" + maxConcurrent: 1 +``` + ## Enterprise For enterprise users, please visit [seaweedfs.com](https://seaweedfs.com) for the SeaweedFS Enterprise Edition, diff --git a/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml b/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml new file mode 100644 index 000000000..826eefb17 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml @@ -0,0 +1,315 @@ +{{- if .Values.admin.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "seaweedfs.name" . }}-admin + 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: admin +{{- if .Values.admin.annotations }} + annotations: + {{- toYaml .Values.admin.annotations | nindent 4 }} +{{- end }} +spec: + replicas: {{ .Values.admin.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + 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: admin + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.admin.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.admin.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.admin.restartPolicy }} + {{- if .Values.admin.affinity }} + affinity: + {{ tpl .Values.admin.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.admin.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.tolerations }} + tolerations: + {{ tpl .Values.admin.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 30 + {{- if .Values.admin.priorityClassName }} + priorityClassName: {{ .Values.admin.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.admin.serviceAccountName }} + serviceAccountName: {{ .Values.admin.serviceAccountName | quote }} + {{- end }} + {{- if .Values.admin.initContainers }} + initContainers: + {{ tpl .Values.admin.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.podSecurityContext.enabled }} + securityContext: {{- omit .Values.admin.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "admin.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.admin.extraEnvironmentVars }} + {{- range $key, $value := .Values.admin.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.admin.loggingOverrideLevel }} + -v={{ .Values.admin.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + admin \ + -port={{ .Values.admin.port }} \ + -port.grpc={{ .Values.admin.grpcPort }} \ + {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} + -dataDir=/data \ + {{- else if .Values.admin.dataDir }} + -dataDir={{ .Values.admin.dataDir }} \ + {{- end }} + {{- if .Values.admin.adminPassword }} + -adminUser={{ .Values.admin.adminUser }} \ + -adminPassword={{ .Values.admin.adminPassword }} \ + {{- end }} + {{- if .Values.admin.masters }} + -masters={{ .Values.admin.masters }} \ + {{- else if .Values.global.masterServer }} + -masters={{ .Values.global.masterServer }} \ + {{- else }} + -masters={{ 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.admin.extraArgs }} + {{ . }} \ + {{- end }} + volumeMounts: + {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} + - name: admin-data + mountPath: /data + {{- end }} + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") (eq .Values.admin.logs.type "existingClaim") }} + - name: admin-logs + mountPath: /logs + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.admin.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.admin.port }} + name: http + - containerPort: {{ .Values.admin.grpcPort }} + name: grpc + {{- if .Values.admin.metricsPort }} + - containerPort: {{ .Values.admin.metricsPort }} + name: metrics + {{- end }} + {{- if .Values.admin.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.admin.readinessProbe.httpGet.path }} + port: {{ .Values.admin.port }} + scheme: {{ .Values.admin.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.admin.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.admin.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.admin.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.admin.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.admin.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.admin.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.admin.livenessProbe.httpGet.path }} + port: {{ .Values.admin.port }} + scheme: {{ .Values.admin.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.admin.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.admin.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.admin.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.admin.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.admin.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.admin.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.admin.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.admin.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.admin.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.admin.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.admin.data.type "hostPath" }} + - name: admin-data + hostPath: + path: {{ .Values.admin.data.hostPathPrefix }}/seaweedfs-admin-data + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.admin.data.type "emptyDir" }} + - name: admin-data + emptyDir: {} + {{- end }} + {{- if eq .Values.admin.data.type "existingClaim" }} + - name: admin-data + persistentVolumeClaim: + claimName: {{ .Values.admin.data.claimName }} + {{- end }} + {{- if eq .Values.admin.logs.type "hostPath" }} + - name: admin-logs + hostPath: + path: {{ .Values.admin.logs.hostPathPrefix }}/logs/seaweedfs/admin + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.admin.logs.type "emptyDir" }} + - name: admin-logs + emptyDir: {} + {{- end }} + {{- if eq .Values.admin.logs.type "existingClaim" }} + - name: admin-logs + persistentVolumeClaim: + claimName: {{ .Values.admin.logs.claimName }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.admin.extraVolumes . | indent 8 | trim }} + {{- if .Values.admin.nodeSelector }} + nodeSelector: + {{ tpl .Values.admin.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- $pvc_exists := include "admin.pvc_exists" . -}} + {{- if $pvc_exists }} + volumeClaimTemplates: + {{- if eq .Values.admin.data.type "persistentVolumeClaim" }} + - metadata: + name: admin-data + {{- with .Values.admin.data.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.admin.data.storageClass }} + resources: + requests: + storage: {{ .Values.admin.data.size }} + {{- end }} + {{- if eq .Values.admin.logs.type "persistentVolumeClaim" }} + - metadata: + name: admin-logs + {{- with .Values.admin.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.admin.logs.storageClass }} + resources: + requests: + storage: {{ .Values.admin.logs.size }} + {{- end }} + {{- end }} +{{- end }} + diff --git a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml new file mode 100644 index 000000000..c4f7efdf9 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.admin.enabled .Values.admin.ingress.enabled }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: ingress-{{ template "seaweedfs.name" . }}-admin + namespace: {{ .Release.Namespace }} + {{- with .Values.admin.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + 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: admin +spec: + ingressClassName: {{ .Values.admin.ingress.className | quote }} + tls: + {{ .Values.admin.ingress.tls | default list | toYaml | nindent 6}} + rules: + - http: + paths: + - path: {{ .Values.admin.ingress.path | quote }} + pathType: {{ .Values.admin.ingress.pathType | quote }} + backend: +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} + service: + name: {{ template "seaweedfs.name" . }}-admin + port: + number: {{ .Values.admin.port }} + #name: +{{- else }} + serviceName: {{ template "seaweedfs.name" . }}-admin + servicePort: {{ .Values.admin.port }} +{{- end }} +{{- if .Values.admin.ingress.host }} + host: {{ .Values.admin.ingress.host | quote }} +{{- end }} +{{- end }} + diff --git a/k8s/charts/seaweedfs/templates/admin/admin-service.yaml b/k8s/charts/seaweedfs/templates/admin/admin-service.yaml new file mode 100644 index 000000000..825049a44 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/admin/admin-service.yaml @@ -0,0 +1,39 @@ +{{- if .Values.admin.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-admin + 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: admin +{{- if .Values.admin.service.annotations }} + annotations: + {{- toYaml .Values.admin.service.annotations | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.admin.service.type }} + ports: + - name: "http" + port: {{ .Values.admin.port }} + targetPort: {{ .Values.admin.port }} + protocol: TCP + - name: "grpc" + port: {{ .Values.admin.grpcPort }} + targetPort: {{ .Values.admin.grpcPort }} + protocol: TCP + {{- if .Values.admin.metricsPort }} + - name: "metrics" + port: {{ .Values.admin.metricsPort }} + targetPort: {{ .Values.admin.metricsPort }} + protocol: TCP + {{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin +{{- end }} + diff --git a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml new file mode 100644 index 000000000..510044a62 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml @@ -0,0 +1,34 @@ +{{- if .Values.admin.enabled }} +{{- if .Values.admin.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-admin + 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: admin + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.admin.annotations }} + annotations: + {{- toYaml .Values.admin.annotations | nindent 4 }} +{{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: admin +{{- end }} +{{- end }} +{{- end }} + diff --git a/k8s/charts/seaweedfs/templates/shared/_helpers.tpl b/k8s/charts/seaweedfs/templates/shared/_helpers.tpl index d22d14224..8255657cc 100644 --- a/k8s/charts/seaweedfs/templates/shared/_helpers.tpl +++ b/k8s/charts/seaweedfs/templates/shared/_helpers.tpl @@ -83,6 +83,26 @@ Inject extra environment vars in the format key:value, if populated {{- end -}} {{- end -}} +{{/* Return the proper admin image */}} +{{- define "admin.image" -}} +{{- if .Values.admin.imageOverride -}} +{{- $imageOverride := .Values.admin.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + +{{/* Return the proper worker image */}} +{{- define "worker.image" -}} +{{- if .Values.worker.imageOverride -}} +{{- $imageOverride := .Values.worker.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + {{/* Return the proper volume image */}} {{- define "volume.image" -}} {{- if .Values.volume.imageOverride -}} @@ -136,6 +156,24 @@ Inject extra environment vars in the format key:value, if populated {{- end -}} {{- end -}} +{{/* check if any Admin PVC exists */}} +{{- define "admin.pvc_exists" -}} +{{- if or (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.logs.type "persistentVolumeClaim") -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + +{{/* check if any Worker PVC exists */}} +{{- define "worker.pvc_exists" -}} +{{- if or (eq .Values.worker.data.type "persistentVolumeClaim") (eq .Values.worker.logs.type "persistentVolumeClaim") -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + {{/* check if any InitContainers exist for Volumes */}} {{- define "volume.initContainers_exists" -}} {{- if or (not (empty .Values.volume.idx )) (not (empty .Values.volume.initContainers )) -}} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml new file mode 100644 index 000000000..1c1dd5f29 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -0,0 +1,272 @@ +{{- if .Values.worker.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "seaweedfs.name" . }}-worker + 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: worker +{{- if .Values.worker.annotations }} + annotations: + {{- toYaml .Values.worker.annotations | nindent 4 }} +{{- end }} +spec: + replicas: {{ .Values.worker.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + 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: worker + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.worker.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.worker.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.worker.restartPolicy }} + {{- if .Values.worker.affinity }} + affinity: + {{ tpl .Values.worker.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.worker.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.worker.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + {{- if .Values.worker.tolerations }} + tolerations: + {{ tpl .Values.worker.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 60 + {{- if .Values.worker.priorityClassName }} + priorityClassName: {{ .Values.worker.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.worker.serviceAccountName }} + serviceAccountName: {{ .Values.worker.serviceAccountName | quote }} + {{- end }} + {{- if .Values.worker.initContainers }} + initContainers: + {{ tpl .Values.worker.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.worker.podSecurityContext.enabled }} + securityContext: {{- omit .Values.worker.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "worker.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.worker.extraEnvironmentVars }} + {{- range $key, $value := .Values.worker.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "persistentVolumeClaim") (eq .Values.worker.logs.type "emptyDir") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.worker.loggingOverrideLevel }} + -v={{ .Values.worker.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + worker \ + {{- if .Values.worker.adminServer }} + -adminServer={{ .Values.worker.adminServer }} \ + {{- else }} + -adminServer={{ template "seaweedfs.name" . }}-admin.{{ .Release.Namespace }}:{{ .Values.admin.grpcPort }} \ + {{- end }} + -capabilities={{ .Values.worker.capabilities }} \ + -maxConcurrent={{ .Values.worker.maxConcurrent }} \ + -workingDir={{ .Values.worker.workingDir }} \ + {{- range .Values.worker.extraArgs }} + {{ . }} \ + {{- end }} + volumeMounts: + {{- if or (eq .Values.worker.data.type "hostPath") (eq .Values.worker.data.type "persistentVolumeClaim") (eq .Values.worker.data.type "emptyDir") (eq .Values.worker.data.type "existingClaim") }} + - name: worker-data + mountPath: {{ .Values.worker.workingDir }} + {{- end }} + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "persistentVolumeClaim") (eq .Values.worker.logs.type "emptyDir") (eq .Values.worker.logs.type "existingClaim") }} + - name: worker-logs + mountPath: /logs + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.worker.extraVolumeMounts . | nindent 12 | trim }} + {{- with .Values.worker.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.worker.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.worker.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.worker.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.worker.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.worker.data.type "hostPath" }} + - name: worker-data + hostPath: + path: {{ .Values.worker.data.hostPathPrefix }}/seaweedfs-worker-data + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.worker.data.type "emptyDir" }} + - name: worker-data + emptyDir: {} + {{- end }} + {{- if eq .Values.worker.data.type "existingClaim" }} + - name: worker-data + persistentVolumeClaim: + claimName: {{ .Values.worker.data.claimName }} + {{- end }} + {{- if eq .Values.worker.logs.type "hostPath" }} + - name: worker-logs + hostPath: + path: {{ .Values.worker.logs.hostPathPrefix }}/logs/seaweedfs/worker + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.worker.logs.type "emptyDir" }} + - name: worker-logs + emptyDir: {} + {{- end }} + {{- if eq .Values.worker.logs.type "existingClaim" }} + - name: worker-logs + persistentVolumeClaim: + claimName: {{ .Values.worker.logs.claimName }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.worker.extraVolumes . | indent 8 | trim }} + {{- if .Values.worker.nodeSelector }} + nodeSelector: + {{ tpl .Values.worker.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- $pvc_exists := include "worker.pvc_exists" . -}} + {{- if $pvc_exists }} + volumeClaimTemplates: + {{- if eq .Values.worker.data.type "persistentVolumeClaim" }} + - metadata: + name: worker-data + {{- with .Values.worker.data.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.worker.data.storageClass }} + resources: + requests: + storage: {{ .Values.worker.data.size }} + {{- end }} + {{- if eq .Values.worker.logs.type "persistentVolumeClaim" }} + - metadata: + name: worker-logs + {{- with .Values.worker.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.worker.logs.storageClass }} + resources: + requests: + storage: {{ .Values.worker.logs.size }} + {{- end }} + {{- end }} +{{- end }} + diff --git a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml new file mode 100644 index 000000000..9a99d3fd9 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml @@ -0,0 +1,34 @@ +{{- if .Values.worker.enabled }} +{{- if .Values.worker.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-worker + 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: worker + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.worker.annotations }} + annotations: + {{- toYaml .Values.worker.annotations | nindent 4 }} +{{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: worker +{{- end }} +{{- end }} +{{- end }} + diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index f75794dae..d269ed783 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1090,6 +1090,171 @@ sftp: failureThreshold: 100 timeoutSeconds: 10 +admin: + enabled: false + imageOverride: null + restartPolicy: null + replicas: 1 + bindAddress: 0.0.0.0 + port: 23646 # Default admin port + grpcPort: 33646 # Default gRPC port for worker connections + metricsPort: 9327 + loggingOverrideLevel: null + + # Admin authentication + adminUser: "admin" + adminPassword: "" # If empty, auth is disabled + + # Data directory for admin configuration and maintenance data + dataDir: "" # If empty, configuration is kept in memory only + + # Master servers to connect to + # If empty, uses global.masterServer or auto-discovers from master statefulset + masters: "" + + # Custom command line arguments to add to the admin command + # Example: ["-customFlag", "value", "-anotherFlag"] + extraArgs: [] + + # Storage configuration + data: + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" + size: "10Gi" + storageClass: "" + hostPathPrefix: /storage + claimName: "" + annotations: {} + + logs: + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" + size: "5Gi" + storageClass: "" + hostPathPrefix: /storage + claimName: "" + annotations: {} + + # Additional resources + sidecars: [] + initContainers: "" + extraVolumes: "" + extraVolumeMounts: "" + podLabels: {} + podAnnotations: {} + annotations: {} + resources: {} + tolerations: "" + nodeSelector: "" + priorityClassName: "" + serviceAccountName: "" + podSecurityContext: {} + containerSecurityContext: {} + + extraEnvironmentVars: {} + + # Health checks + livenessProbe: + enabled: true + httpGet: + path: /health + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 60 + successThreshold: 1 + failureThreshold: 5 + timeoutSeconds: 10 + + readinessProbe: + enabled: true + httpGet: + path: /health + scheme: HTTP + initialDelaySeconds: 15 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 10 + + ingress: + enabled: false + className: "nginx" + # host: false for "*" hostname + host: "admin.seaweedfs.local" + path: "/" + pathType: Prefix + annotations: {} + tls: [] + + service: + type: ClusterIP + annotations: {} + +worker: + enabled: false + imageOverride: null + restartPolicy: null + replicas: 1 + loggingOverrideLevel: null + + # Admin server to connect to + # Format: "host:port" or auto-discover from admin service + adminServer: "" + + # Worker capabilities - comma-separated list + # Available: vacuum, balance, erasure_coding + # Default: "vacuum,balance,erasure_coding" (all capabilities) + capabilities: "vacuum,balance,erasure_coding" + + # Maximum number of concurrent tasks + maxConcurrent: 3 + + # Working directory for task execution + workingDir: "/tmp/seaweedfs-worker" + + # Custom command line arguments to add to the worker command + # Example: ["-customFlag", "value", "-anotherFlag"] + extraArgs: [] + + # Storage configuration for working directory + data: + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" + size: "50Gi" # Workers need space for vacuum, balance, etc. + storageClass: "" + hostPathPrefix: /storage + claimName: "" + annotations: {} + + logs: + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" + size: "5Gi" + storageClass: "" + hostPathPrefix: /storage + claimName: "" + annotations: {} + + # Additional resources + sidecars: [] + initContainers: "" + extraVolumes: "" + extraVolumeMounts: "" + podLabels: {} + podAnnotations: {} + annotations: {} + resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" + tolerations: "" + nodeSelector: "" + priorityClassName: "" + serviceAccountName: "" + podSecurityContext: {} + containerSecurityContext: {} + + extraEnvironmentVars: {} + # All-in-one deployment configuration allInOne: enabled: false From fb4cedd5a7617bb7f165bba03e14a1e150964080 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 18:31:36 -0700 Subject: [PATCH 02/15] lint --- k8s/charts/seaweedfs/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index d269ed783..873968c77 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -979,7 +979,7 @@ s3: # Custom command line arguments to add to the s3 command # Example to fix connection idle seconds: extraArgs: ["-idleTimeout=30"] - #extraArgs: [] + # extraArgs: [] # used to configure livenessProbe on s3 containers # From 8400e102427f8347933b02e41e3b5fd76b3f5cad Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 18:38:56 -0700 Subject: [PATCH 03/15] workers are stateless, admin is stateful --- k8s/charts/seaweedfs/README.md | 46 ++- .../templates/admin/admin-deployment.yaml | 4 +- .../templates/admin/admin-statefulset.yaml | 317 ++++++++++++++++++ .../templates/worker/worker-deployment.yaml | 43 +-- .../templates/worker/worker-service.yaml | 27 ++ k8s/charts/seaweedfs/values.yaml | 5 + 6 files changed, 400 insertions(+), 42 deletions(-) create mode 100644 k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml create mode 100644 k8s/charts/seaweedfs/templates/worker/worker-service.yaml diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index ccc0e87c5..f75c4feae 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -255,18 +255,43 @@ For production deployments, consider: Example specialized worker configuration: +For specialized worker pools, deploy separate Helm releases with different capabilities: + +**values-worker-vacuum.yaml** (for vacuum operations): ```yaml -# In your values.yaml - deploy multiple worker deployments manually -# One for vacuum operations +# Disable all other components, enable only workers +master: + enabled: false +volume: + enabled: false +filer: + enabled: false +s3: + enabled: false +admin: + enabled: false + worker: enabled: true replicas: 2 capabilities: "vacuum" maxConcurrent: 2 - -# Deploy another release for balance operations -# helm install seaweedfs-worker-balance seaweedfs/seaweedfs --values worker-balance-values.yaml -# worker-balance-values.yaml: +``` + +**values-worker-balance.yaml** (for balance operations): +```yaml +# Disable all other components, enable only workers +master: + enabled: false +volume: + enabled: false +filer: + enabled: false +s3: + enabled: false +admin: + enabled: false + worker: enabled: true replicas: 1 @@ -274,6 +299,15 @@ worker: maxConcurrent: 1 ``` +Deploy the specialized workers as separate releases: +```bash +# Deploy vacuum workers +helm install seaweedfs-worker-vacuum seaweedfs/seaweedfs -f values-worker-vacuum.yaml + +# Deploy balance workers +helm install seaweedfs-worker-balance seaweedfs/seaweedfs -f values-worker-balance.yaml +``` + ## Enterprise For enterprise users, please visit [seaweedfs.com](https://seaweedfs.com) for the SeaweedFS Enterprise Edition, diff --git a/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml b/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml index 826eefb17..4e922ced3 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml @@ -1,6 +1,6 @@ {{- if .Values.admin.enabled }} apiVersion: apps/v1 -kind: Deployment +kind: StatefulSet metadata: name: {{ template "seaweedfs.name" . }}-admin namespace: {{ .Release.Namespace }} @@ -15,6 +15,8 @@ metadata: {{- toYaml .Values.admin.annotations | nindent 4 }} {{- end }} spec: + serviceName: {{ template "seaweedfs.name" . }}-admin + podManagementPolicy: {{ .Values.admin.podManagementPolicy }} replicas: {{ .Values.admin.replicas }} selector: matchLabels: diff --git a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml new file mode 100644 index 000000000..4e922ced3 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml @@ -0,0 +1,317 @@ +{{- if .Values.admin.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "seaweedfs.name" . }}-admin + 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: admin +{{- if .Values.admin.annotations }} + annotations: + {{- toYaml .Values.admin.annotations | nindent 4 }} +{{- end }} +spec: + serviceName: {{ template "seaweedfs.name" . }}-admin + podManagementPolicy: {{ .Values.admin.podManagementPolicy }} + replicas: {{ .Values.admin.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + 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: admin + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.admin.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.admin.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.admin.restartPolicy }} + {{- if .Values.admin.affinity }} + affinity: + {{ tpl .Values.admin.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.admin.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.tolerations }} + tolerations: + {{ tpl .Values.admin.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 30 + {{- if .Values.admin.priorityClassName }} + priorityClassName: {{ .Values.admin.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.admin.serviceAccountName }} + serviceAccountName: {{ .Values.admin.serviceAccountName | quote }} + {{- end }} + {{- if .Values.admin.initContainers }} + initContainers: + {{ tpl .Values.admin.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.podSecurityContext.enabled }} + securityContext: {{- omit .Values.admin.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "admin.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.admin.extraEnvironmentVars }} + {{- range $key, $value := .Values.admin.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.admin.loggingOverrideLevel }} + -v={{ .Values.admin.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + admin \ + -port={{ .Values.admin.port }} \ + -port.grpc={{ .Values.admin.grpcPort }} \ + {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} + -dataDir=/data \ + {{- else if .Values.admin.dataDir }} + -dataDir={{ .Values.admin.dataDir }} \ + {{- end }} + {{- if .Values.admin.adminPassword }} + -adminUser={{ .Values.admin.adminUser }} \ + -adminPassword={{ .Values.admin.adminPassword }} \ + {{- end }} + {{- if .Values.admin.masters }} + -masters={{ .Values.admin.masters }} \ + {{- else if .Values.global.masterServer }} + -masters={{ .Values.global.masterServer }} \ + {{- else }} + -masters={{ 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.admin.extraArgs }} + {{ . }} \ + {{- end }} + volumeMounts: + {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} + - name: admin-data + mountPath: /data + {{- end }} + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") (eq .Values.admin.logs.type "existingClaim") }} + - name: admin-logs + mountPath: /logs + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.admin.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.admin.port }} + name: http + - containerPort: {{ .Values.admin.grpcPort }} + name: grpc + {{- if .Values.admin.metricsPort }} + - containerPort: {{ .Values.admin.metricsPort }} + name: metrics + {{- end }} + {{- if .Values.admin.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.admin.readinessProbe.httpGet.path }} + port: {{ .Values.admin.port }} + scheme: {{ .Values.admin.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.admin.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.admin.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.admin.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.admin.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.admin.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.admin.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.admin.livenessProbe.httpGet.path }} + port: {{ .Values.admin.port }} + scheme: {{ .Values.admin.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.admin.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.admin.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.admin.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.admin.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.admin.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.admin.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.admin.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.admin.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.admin.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.admin.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.admin.data.type "hostPath" }} + - name: admin-data + hostPath: + path: {{ .Values.admin.data.hostPathPrefix }}/seaweedfs-admin-data + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.admin.data.type "emptyDir" }} + - name: admin-data + emptyDir: {} + {{- end }} + {{- if eq .Values.admin.data.type "existingClaim" }} + - name: admin-data + persistentVolumeClaim: + claimName: {{ .Values.admin.data.claimName }} + {{- end }} + {{- if eq .Values.admin.logs.type "hostPath" }} + - name: admin-logs + hostPath: + path: {{ .Values.admin.logs.hostPathPrefix }}/logs/seaweedfs/admin + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.admin.logs.type "emptyDir" }} + - name: admin-logs + emptyDir: {} + {{- end }} + {{- if eq .Values.admin.logs.type "existingClaim" }} + - name: admin-logs + persistentVolumeClaim: + claimName: {{ .Values.admin.logs.claimName }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.admin.extraVolumes . | indent 8 | trim }} + {{- if .Values.admin.nodeSelector }} + nodeSelector: + {{ tpl .Values.admin.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- $pvc_exists := include "admin.pvc_exists" . -}} + {{- if $pvc_exists }} + volumeClaimTemplates: + {{- if eq .Values.admin.data.type "persistentVolumeClaim" }} + - metadata: + name: admin-data + {{- with .Values.admin.data.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.admin.data.storageClass }} + resources: + requests: + storage: {{ .Values.admin.data.size }} + {{- end }} + {{- if eq .Values.admin.logs.type "persistentVolumeClaim" }} + - metadata: + name: admin-logs + {{- with .Values.admin.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.admin.logs.storageClass }} + resources: + requests: + storage: {{ .Values.admin.logs.size }} + {{- end }} + {{- end }} +{{- end }} + diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index 1c1dd5f29..00994d0ec 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -117,7 +117,7 @@ spec: - "-ec" - | exec /usr/bin/weed \ - {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "persistentVolumeClaim") (eq .Values.worker.logs.type "emptyDir") }} + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "emptyDir") }} -logdir=/logs \ {{- else }} -logtostderr=true \ @@ -140,11 +140,11 @@ spec: {{ . }} \ {{- end }} volumeMounts: - {{- if or (eq .Values.worker.data.type "hostPath") (eq .Values.worker.data.type "persistentVolumeClaim") (eq .Values.worker.data.type "emptyDir") (eq .Values.worker.data.type "existingClaim") }} + {{- if or (eq .Values.worker.data.type "hostPath") (eq .Values.worker.data.type "emptyDir") (eq .Values.worker.data.type "existingClaim") }} - name: worker-data mountPath: {{ .Values.worker.workingDir }} {{- end }} - {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "persistentVolumeClaim") (eq .Values.worker.logs.type "emptyDir") (eq .Values.worker.logs.type "existingClaim") }} + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "emptyDir") (eq .Values.worker.logs.type "existingClaim") }} - name: worker-logs mountPath: /logs {{- end }} @@ -170,6 +170,11 @@ spec: mountPath: /usr/local/share/ca-certificates/client/ {{- end }} {{ tpl .Values.worker.extraVolumeMounts . | nindent 12 | trim }} + ports: + {{- if .Values.worker.metricsPort }} + - containerPort: {{ .Values.worker.metricsPort }} + name: metrics + {{- end }} {{- with .Values.worker.resources }} resources: {{- toYaml . | nindent 12 }} @@ -236,37 +241,5 @@ spec: nodeSelector: {{ tpl .Values.worker.nodeSelector . | indent 8 | trim }} {{- end }} - {{- $pvc_exists := include "worker.pvc_exists" . -}} - {{- if $pvc_exists }} - volumeClaimTemplates: - {{- if eq .Values.worker.data.type "persistentVolumeClaim" }} - - metadata: - name: worker-data - {{- with .Values.worker.data.annotations }} - annotations: - {{- toYaml . | nindent 10 }} - {{- end }} - spec: - accessModes: [ "ReadWriteOnce" ] - storageClassName: {{ .Values.worker.data.storageClass }} - resources: - requests: - storage: {{ .Values.worker.data.size }} - {{- end }} - {{- if eq .Values.worker.logs.type "persistentVolumeClaim" }} - - metadata: - name: worker-logs - {{- with .Values.worker.logs.annotations }} - annotations: - {{- toYaml . | nindent 10 }} - {{- end }} - spec: - accessModes: [ "ReadWriteOnce" ] - storageClassName: {{ .Values.worker.logs.storageClass }} - resources: - requests: - storage: {{ .Values.worker.logs.size }} - {{- end }} - {{- end }} {{- end }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml new file mode 100644 index 000000000..8faf5e1ab --- /dev/null +++ b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml @@ -0,0 +1,27 @@ +{{- if .Values.worker.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-worker + 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: worker +spec: + clusterIP: None # Headless service + ports: + {{- if .Values.worker.metricsPort }} + - name: "metrics" + port: {{ .Values.worker.metricsPort }} + targetPort: {{ .Values.worker.metricsPort }} + protocol: TCP + {{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker +{{- end }} + diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 873968c77..7ebe3617c 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1141,6 +1141,10 @@ admin: podLabels: {} podAnnotations: {} annotations: {} + + ## Set podManagementPolicy + podManagementPolicy: Parallel + resources: {} tolerations: "" nodeSelector: "" @@ -1194,6 +1198,7 @@ worker: restartPolicy: null replicas: 1 loggingOverrideLevel: null + metricsPort: 9327 # Admin server to connect to # Format: "host:port" or auto-discover from admin service From 69868a599b197f105e4c6f883564929ad0310f29 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 18:46:41 -0700 Subject: [PATCH 04/15] removed the duplicate admin-deployment.yaml --- .../templates/admin/admin-deployment.yaml | 317 ------------------ 1 file changed, 317 deletions(-) delete mode 100644 k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml diff --git a/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml b/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml deleted file mode 100644 index 4e922ced3..000000000 --- a/k8s/charts/seaweedfs/templates/admin/admin-deployment.yaml +++ /dev/null @@ -1,317 +0,0 @@ -{{- if .Values.admin.enabled }} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ template "seaweedfs.name" . }}-admin - 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: admin -{{- if .Values.admin.annotations }} - annotations: - {{- toYaml .Values.admin.annotations | nindent 4 }} -{{- end }} -spec: - serviceName: {{ template "seaweedfs.name" . }}-admin - podManagementPolicy: {{ .Values.admin.podManagementPolicy }} - replicas: {{ .Values.admin.replicas }} - selector: - matchLabels: - app.kubernetes.io/name: {{ template "seaweedfs.name" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: admin - 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: admin - {{ with .Values.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.admin.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - {{ with .Values.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.admin.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - restartPolicy: {{ default .Values.global.restartPolicy .Values.admin.restartPolicy }} - {{- if .Values.admin.affinity }} - affinity: - {{ tpl .Values.admin.affinity . | nindent 8 | trim }} - {{- end }} - {{- if .Values.admin.topologySpreadConstraints }} - topologySpreadConstraints: - {{ tpl .Values.admin.topologySpreadConstraints . | nindent 8 | trim }} - {{- end }} - {{- if .Values.admin.tolerations }} - tolerations: - {{ tpl .Values.admin.tolerations . | nindent 8 | trim }} - {{- end }} - {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} - terminationGracePeriodSeconds: 30 - {{- if .Values.admin.priorityClassName }} - priorityClassName: {{ .Values.admin.priorityClassName | quote }} - {{- end }} - enableServiceLinks: false - {{- if .Values.admin.serviceAccountName }} - serviceAccountName: {{ .Values.admin.serviceAccountName | quote }} - {{- end }} - {{- if .Values.admin.initContainers }} - initContainers: - {{ tpl .Values.admin.initContainers . | nindent 8 | trim }} - {{- end }} - {{- if .Values.admin.podSecurityContext.enabled }} - securityContext: {{- omit .Values.admin.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: seaweedfs - image: {{ template "admin.image" . }} - imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} - env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: SEAWEEDFS_FULLNAME - value: "{{ template "seaweedfs.name" . }}" - {{- if .Values.admin.extraEnvironmentVars }} - {{- range $key, $value := .Values.admin.extraEnvironmentVars }} - - name: {{ $key }} - {{- if kindIs "string" $value }} - value: {{ $value | quote }} - {{- else }} - valueFrom: - {{ toYaml $value | nindent 16 | trim }} - {{- end -}} - {{- end }} - {{- end }} - {{- if .Values.global.extraEnvironmentVars }} - {{- range $key, $value := .Values.global.extraEnvironmentVars }} - - name: {{ $key }} - {{- if kindIs "string" $value }} - value: {{ $value | quote }} - {{- else }} - valueFrom: - {{ toYaml $value | nindent 16 | trim }} - {{- end -}} - {{- end }} - {{- end }} - command: - - "/bin/sh" - - "-ec" - - | - exec /usr/bin/weed \ - {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") }} - -logdir=/logs \ - {{- else }} - -logtostderr=true \ - {{- end }} - {{- if .Values.admin.loggingOverrideLevel }} - -v={{ .Values.admin.loggingOverrideLevel }} \ - {{- else }} - -v={{ .Values.global.loggingLevel }} \ - {{- end }} - admin \ - -port={{ .Values.admin.port }} \ - -port.grpc={{ .Values.admin.grpcPort }} \ - {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} - -dataDir=/data \ - {{- else if .Values.admin.dataDir }} - -dataDir={{ .Values.admin.dataDir }} \ - {{- end }} - {{- if .Values.admin.adminPassword }} - -adminUser={{ .Values.admin.adminUser }} \ - -adminPassword={{ .Values.admin.adminPassword }} \ - {{- end }} - {{- if .Values.admin.masters }} - -masters={{ .Values.admin.masters }} \ - {{- else if .Values.global.masterServer }} - -masters={{ .Values.global.masterServer }} \ - {{- else }} - -masters={{ 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.admin.extraArgs }} - {{ . }} \ - {{- end }} - volumeMounts: - {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} - - name: admin-data - mountPath: /data - {{- end }} - {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") (eq .Values.admin.logs.type "existingClaim") }} - - name: admin-logs - mountPath: /logs - {{- end }} - {{- if .Values.global.enableSecurity }} - - name: security-config - readOnly: true - mountPath: /etc/seaweedfs/security.toml - subPath: security.toml - - name: ca-cert - readOnly: true - mountPath: /usr/local/share/ca-certificates/ca/ - - name: master-cert - readOnly: true - mountPath: /usr/local/share/ca-certificates/master/ - - name: volume-cert - readOnly: true - mountPath: /usr/local/share/ca-certificates/volume/ - - name: filer-cert - readOnly: true - mountPath: /usr/local/share/ca-certificates/filer/ - - name: client-cert - readOnly: true - mountPath: /usr/local/share/ca-certificates/client/ - {{- end }} - {{ tpl .Values.admin.extraVolumeMounts . | nindent 12 | trim }} - ports: - - containerPort: {{ .Values.admin.port }} - name: http - - containerPort: {{ .Values.admin.grpcPort }} - name: grpc - {{- if .Values.admin.metricsPort }} - - containerPort: {{ .Values.admin.metricsPort }} - name: metrics - {{- end }} - {{- if .Values.admin.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: {{ .Values.admin.readinessProbe.httpGet.path }} - port: {{ .Values.admin.port }} - scheme: {{ .Values.admin.readinessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.admin.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.admin.readinessProbe.periodSeconds }} - successThreshold: {{ .Values.admin.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.admin.readinessProbe.failureThreshold }} - timeoutSeconds: {{ .Values.admin.readinessProbe.timeoutSeconds }} - {{- end }} - {{- if .Values.admin.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: {{ .Values.admin.livenessProbe.httpGet.path }} - port: {{ .Values.admin.port }} - scheme: {{ .Values.admin.livenessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.admin.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.admin.livenessProbe.periodSeconds }} - successThreshold: {{ .Values.admin.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.admin.livenessProbe.failureThreshold }} - timeoutSeconds: {{ .Values.admin.livenessProbe.timeoutSeconds }} - {{- end }} - {{- with .Values.admin.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- if .Values.admin.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.admin.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.admin.sidecars }} - {{- include "common.tplvalues.render" (dict "value" .Values.admin.sidecars "context" $) | nindent 8 }} - {{- end }} - volumes: - {{- if eq .Values.admin.data.type "hostPath" }} - - name: admin-data - hostPath: - path: {{ .Values.admin.data.hostPathPrefix }}/seaweedfs-admin-data - type: DirectoryOrCreate - {{- end }} - {{- if eq .Values.admin.data.type "emptyDir" }} - - name: admin-data - emptyDir: {} - {{- end }} - {{- if eq .Values.admin.data.type "existingClaim" }} - - name: admin-data - persistentVolumeClaim: - claimName: {{ .Values.admin.data.claimName }} - {{- end }} - {{- if eq .Values.admin.logs.type "hostPath" }} - - name: admin-logs - hostPath: - path: {{ .Values.admin.logs.hostPathPrefix }}/logs/seaweedfs/admin - type: DirectoryOrCreate - {{- end }} - {{- if eq .Values.admin.logs.type "emptyDir" }} - - name: admin-logs - emptyDir: {} - {{- end }} - {{- if eq .Values.admin.logs.type "existingClaim" }} - - name: admin-logs - persistentVolumeClaim: - claimName: {{ .Values.admin.logs.claimName }} - {{- end }} - {{- if .Values.global.enableSecurity }} - - name: security-config - configMap: - name: {{ template "seaweedfs.name" . }}-security-config - - name: ca-cert - secret: - secretName: {{ template "seaweedfs.name" . }}-ca-cert - - name: master-cert - secret: - secretName: {{ template "seaweedfs.name" . }}-master-cert - - name: volume-cert - secret: - secretName: {{ template "seaweedfs.name" . }}-volume-cert - - name: filer-cert - secret: - secretName: {{ template "seaweedfs.name" . }}-filer-cert - - name: client-cert - secret: - secretName: {{ template "seaweedfs.name" . }}-client-cert - {{- end }} - {{ tpl .Values.admin.extraVolumes . | indent 8 | trim }} - {{- if .Values.admin.nodeSelector }} - nodeSelector: - {{ tpl .Values.admin.nodeSelector . | indent 8 | trim }} - {{- end }} - {{- $pvc_exists := include "admin.pvc_exists" . -}} - {{- if $pvc_exists }} - volumeClaimTemplates: - {{- if eq .Values.admin.data.type "persistentVolumeClaim" }} - - metadata: - name: admin-data - {{- with .Values.admin.data.annotations }} - annotations: - {{- toYaml . | nindent 10 }} - {{- end }} - spec: - accessModes: [ "ReadWriteOnce" ] - storageClassName: {{ .Values.admin.data.storageClass }} - resources: - requests: - storage: {{ .Values.admin.data.size }} - {{- end }} - {{- if eq .Values.admin.logs.type "persistentVolumeClaim" }} - - metadata: - name: admin-logs - {{- with .Values.admin.logs.annotations }} - annotations: - {{- toYaml . | nindent 10 }} - {{- end }} - spec: - accessModes: [ "ReadWriteOnce" ] - storageClassName: {{ .Values.admin.logs.storageClass }} - resources: - requests: - storage: {{ .Values.admin.logs.size }} - {{- end }} - {{- end }} -{{- end }} - From 04f2ea1c701ba164b26a85b093db228b24514d5c Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 19:07:33 -0700 Subject: [PATCH 05/15] address comments --- k8s/charts/seaweedfs/README.md | 8 ++++--- .../templates/admin/admin-servicemonitor.yaml | 4 ++-- .../templates/admin/admin-statefulset.yaml | 10 ++++---- .../templates/worker/worker-deployment.yaml | 6 ++--- .../worker/worker-servicemonitor.yaml | 4 ++-- k8s/charts/seaweedfs/values.yaml | 24 +++++++++++-------- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index f75c4feae..210ff7696 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -220,10 +220,12 @@ worker: adminServer: "seaweedfs-admin.seaweedfs:33646" # Workers need storage for task execution + # Note: Workers use Deployment, so they can't use dynamically provisioned PVCs + # Use emptyDir, hostPath, or existingClaim with a pre-provisioned PVC data: - type: "persistentVolumeClaim" - size: "50Gi" # Adjust based on volume size - storageClass: "your-storage-class" + type: "emptyDir" # Or "hostPath" or "existingClaim" + hostPathPrefix: /storage # For hostPath + # claimName: "worker-pvc" # For existingClaim with pre-provisioned PVC # Resource limits for worker pods resources: diff --git a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml index 510044a62..9b3d0d718 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml @@ -15,9 +15,9 @@ metadata: {{- with .Values.global.monitoring.additionalLabels }} {{- toYaml . | nindent 4 }} {{- end }} -{{- if .Values.admin.annotations }} +{{- with .Values.admin.serviceMonitor.annotations }} annotations: - {{- toYaml .Values.admin.annotations | nindent 4 }} + {{- toYaml . | nindent 4 }} {{- end }} spec: endpoints: diff --git a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml index 4e922ced3..236ec919a 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml @@ -142,14 +142,14 @@ spec: -adminPassword={{ .Values.admin.adminPassword }} \ {{- end }} {{- if .Values.admin.masters }} - -masters={{ .Values.admin.masters }} \ + -masters={{ .Values.admin.masters }}{{- if .Values.admin.extraArgs }} \{{ end }} {{- else if .Values.global.masterServer }} - -masters={{ .Values.global.masterServer }} \ + -masters={{ .Values.global.masterServer }}{{- if .Values.admin.extraArgs }} \{{ end }} {{- else }} - -masters={{ 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 }} \ + -masters={{ 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 }}{{- if .Values.admin.extraArgs }} \{{ end }} {{- end }} - {{- range .Values.admin.extraArgs }} - {{ . }} \ + {{- range $index, $arg := .Values.admin.extraArgs }} + {{ $arg }}{{- if lt $index (sub (len $.Values.admin.extraArgs) 1) }} \{{ end }} {{- end }} volumeMounts: {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index 00994d0ec..39cd00aed 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -135,9 +135,9 @@ spec: {{- end }} -capabilities={{ .Values.worker.capabilities }} \ -maxConcurrent={{ .Values.worker.maxConcurrent }} \ - -workingDir={{ .Values.worker.workingDir }} \ - {{- range .Values.worker.extraArgs }} - {{ . }} \ + -workingDir={{ .Values.worker.workingDir }}{{- if .Values.worker.extraArgs }} \{{ end }} + {{- range $index, $arg := .Values.worker.extraArgs }} + {{ $arg }}{{- if lt $index (sub (len $.Values.worker.extraArgs) 1) }} \{{ end }} {{- end }} volumeMounts: {{- if or (eq .Values.worker.data.type "hostPath") (eq .Values.worker.data.type "emptyDir") (eq .Values.worker.data.type "existingClaim") }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml index 9a99d3fd9..681128ee4 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml @@ -15,9 +15,9 @@ metadata: {{- with .Values.global.monitoring.additionalLabels }} {{- toYaml . | nindent 4 }} {{- end }} -{{- if .Values.worker.annotations }} +{{- with .Values.worker.serviceMonitor.annotations }} annotations: - {{- toYaml .Values.worker.annotations | nindent 4 }} + {{- toYaml . | nindent 4 }} {{- end }} spec: endpoints: diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 7ebe3617c..9837bcc1f 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1192,6 +1192,10 @@ admin: type: ClusterIP annotations: {} + # ServiceMonitor annotations (separate from pod/deployment annotations) + serviceMonitor: + annotations: {} + worker: enabled: false imageOverride: null @@ -1220,21 +1224,17 @@ worker: extraArgs: [] # Storage configuration for working directory + # Note: Workers use Deployment, so use "emptyDir", "hostPath", or "existingClaim" + # Do NOT use "persistentVolumeClaim" - use "existingClaim" with pre-provisioned PVC instead data: - type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" - size: "50Gi" # Workers need space for vacuum, balance, etc. - storageClass: "" + type: "emptyDir" # Options: "hostPath", "emptyDir", "existingClaim" hostPathPrefix: /storage - claimName: "" - annotations: {} + claimName: "" # For existingClaim type logs: - type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" - size: "5Gi" - storageClass: "" + type: "emptyDir" # Options: "hostPath", "emptyDir", "existingClaim" hostPathPrefix: /storage - claimName: "" - annotations: {} + claimName: "" # For existingClaim type # Additional resources sidecars: [] @@ -1260,6 +1260,10 @@ worker: extraEnvironmentVars: {} + # ServiceMonitor annotations (separate from pod/deployment annotations) + serviceMonitor: + annotations: {} + # All-in-one deployment configuration allInOne: enabled: false From 522d933b2ffc35eb221c970bd8260a9f43594818 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 19:34:38 -0700 Subject: [PATCH 06/15] address comments --- .../seaweedfs/templates/admin/admin-ingress.yaml | 11 +++++------ .../templates/admin/admin-servicemonitor.yaml | 3 +-- .../seaweedfs/templates/admin/admin-statefulset.yaml | 5 ++--- .../seaweedfs/templates/worker/worker-deployment.yaml | 5 ++--- k8s/charts/seaweedfs/values.yaml | 1 - 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml index c4f7efdf9..b1972217d 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml @@ -25,7 +25,10 @@ spec: tls: {{ .Values.admin.ingress.tls | default list | toYaml | nindent 6}} rules: - - http: + - {{- if .Values.admin.ingress.host }} + host: {{ .Values.admin.ingress.host | quote }} + {{- end }} + http: paths: - path: {{ .Values.admin.ingress.path | quote }} pathType: {{ .Values.admin.ingress.pathType | quote }} @@ -40,8 +43,4 @@ spec: serviceName: {{ template "seaweedfs.name" . }}-admin servicePort: {{ .Values.admin.port }} {{- end }} -{{- if .Values.admin.ingress.host }} - host: {{ .Values.admin.ingress.host | quote }} -{{- end }} -{{- end }} - +{{- end }} \ No newline at end of file diff --git a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml index 9b3d0d718..4c2c0b162 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml @@ -30,5 +30,4 @@ spec: app.kubernetes.io/component: admin {{- end }} {{- end }} -{{- end }} - +{{- end }} \ No newline at end of file diff --git a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml index 236ec919a..f38eb83bf 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml @@ -119,7 +119,7 @@ spec: - "-ec" - | exec /usr/bin/weed \ - {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") }} + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") (eq .Values.admin.logs.type "existingClaim") }} -logdir=/logs \ {{- else }} -logtostderr=true \ @@ -313,5 +313,4 @@ spec: storage: {{ .Values.admin.logs.size }} {{- end }} {{- end }} -{{- end }} - +{{- end }} \ No newline at end of file diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index 39cd00aed..a4069ab1f 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -117,7 +117,7 @@ spec: - "-ec" - | exec /usr/bin/weed \ - {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "emptyDir") }} + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "emptyDir") (eq .Values.worker.logs.type "existingClaim") }} -logdir=/logs \ {{- else }} -logtostderr=true \ @@ -241,5 +241,4 @@ spec: nodeSelector: {{ tpl .Values.worker.nodeSelector . | indent 8 | trim }} {{- end }} -{{- end }} - +{{- end }} \ No newline at end of file diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 9837bcc1f..17e6b7931 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1095,7 +1095,6 @@ admin: imageOverride: null restartPolicy: null replicas: 1 - bindAddress: 0.0.0.0 port: 23646 # Default admin port grpcPort: 33646 # Default gRPC port for worker connections metricsPort: 9327 From c5b0b2b00357434a3314665223db50bedbfe72d8 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 19:51:49 -0700 Subject: [PATCH 07/15] purge --- k8s/charts/seaweedfs/templates/shared/_helpers.tpl | 9 --------- 1 file changed, 9 deletions(-) diff --git a/k8s/charts/seaweedfs/templates/shared/_helpers.tpl b/k8s/charts/seaweedfs/templates/shared/_helpers.tpl index 8255657cc..28e0b0906 100644 --- a/k8s/charts/seaweedfs/templates/shared/_helpers.tpl +++ b/k8s/charts/seaweedfs/templates/shared/_helpers.tpl @@ -165,15 +165,6 @@ Inject extra environment vars in the format key:value, if populated {{- end -}} {{- end -}} -{{/* check if any Worker PVC exists */}} -{{- define "worker.pvc_exists" -}} -{{- if or (eq .Values.worker.data.type "persistentVolumeClaim") (eq .Values.worker.logs.type "persistentVolumeClaim") -}} -{{- printf "true" -}} -{{- else -}} -{{- printf "" -}} -{{- end -}} -{{- end -}} - {{/* check if any InitContainers exist for Volumes */}} {{- define "volume.initContainers_exists" -}} {{- if or (not (empty .Values.volume.idx )) (not (empty .Values.volume.initContainers )) -}} From c5b345febe0eaafe93c6c72ebf9b64851c4c2ec7 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 20:11:03 -0700 Subject: [PATCH 08/15] Update README.md --- k8s/charts/seaweedfs/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index 210ff7696..32f814ab8 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -216,8 +216,9 @@ worker: workingDir: "/tmp/seaweedfs-worker" # Optional: configure admin server address - # If not specified, auto-discovers from admin service - adminServer: "seaweedfs-admin.seaweedfs:33646" + # If not specified, auto-discovers from admin service in the same namespace + # Replace with your actual namespace + adminServer: "seaweedfs-admin.:33646" # Workers need storage for task execution # Note: Workers use Deployment, so they can't use dynamically provisioned PVCs @@ -278,6 +279,9 @@ worker: replicas: 2 capabilities: "vacuum" maxConcurrent: 2 + # REQUIRED: Point to the admin service of your main SeaweedFS release + # Replace with the namespace where your main seaweedfs is deployed + adminServer: "seaweedfs-admin.:33646" ``` **values-worker-balance.yaml** (for balance operations): @@ -299,6 +303,9 @@ worker: replicas: 1 capabilities: "balance" maxConcurrent: 1 + # REQUIRED: Point to the admin service of your main SeaweedFS release + # Replace with the namespace where your main seaweedfs is deployed + adminServer: "seaweedfs-admin.:33646" ``` Deploy the specialized workers as separate releases: From c5264bf93305ce34921df567751b04f7157c2119 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sat, 25 Oct 2025 20:12:50 -0700 Subject: [PATCH 09/15] Update k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml index b1972217d..45450e90d 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml @@ -38,7 +38,6 @@ spec: name: {{ template "seaweedfs.name" . }}-admin port: number: {{ .Values.admin.port }} - #name: {{- else }} serviceName: {{ template "seaweedfs.name" . }}-admin servicePort: {{ .Values.admin.port }} From a450055fed1949169fd537dab80da1a3bea91c6e Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 20:15:07 -0700 Subject: [PATCH 10/15] address comments --- k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml | 3 +++ k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml | 3 +++ k8s/charts/seaweedfs/templates/worker/worker-service.yaml | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml index f38eb83bf..671f6a81b 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml @@ -1,4 +1,7 @@ {{- if .Values.admin.enabled }} +{{- if and (not .Values.admin.masters) (not .Values.global.masterServer) (not .Values.master.enabled) }} +{{- fail "admin.masters or global.masterServer must be set if master.enabled is false" -}} +{{- end }} apiVersion: apps/v1 kind: StatefulSet metadata: diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index a4069ab1f..d5fb1f164 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -1,4 +1,7 @@ {{- if .Values.worker.enabled }} +{{- if and (not .Values.worker.adminServer) (not .Values.admin.enabled) }} +{{- fail "worker.adminServer must be set if admin.enabled is false within the same release" -}} +{{- end }} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml index 8faf5e1ab..b7f60e52f 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml @@ -12,8 +12,8 @@ metadata: app.kubernetes.io/component: worker spec: clusterIP: None # Headless service - ports: {{- if .Values.worker.metricsPort }} + ports: - name: "metrics" port: {{ .Values.worker.metricsPort }} targetPort: {{ .Values.worker.metricsPort }} From 6050e0c3aa4f7e61d008160a5d1cf5a43c147ef5 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 20:30:25 -0700 Subject: [PATCH 11/15] address comments --- k8s/charts/seaweedfs/README.md | 7 ++-- .../templates/admin/admin-ingress.yaml | 2 +- .../templates/admin/admin-servicemonitor.yaml | 2 +- .../templates/admin/admin-statefulset.yaml | 2 +- .../templates/worker/worker-deployment.yaml | 2 +- .../worker/worker-servicemonitor.yaml | 1 + k8s/charts/seaweedfs/values.yaml | 37 +++++++++++++++++++ 7 files changed, 46 insertions(+), 7 deletions(-) diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index 32f814ab8..273f82e80 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -221,10 +221,11 @@ worker: adminServer: "seaweedfs-admin.:33646" # Workers need storage for task execution - # Note: Workers use Deployment, so they can't use dynamically provisioned PVCs - # Use emptyDir, hostPath, or existingClaim with a pre-provisioned PVC + # Note: Workers use a Deployment, which does not support `volumeClaimTemplates` + # for dynamic PVC creation per pod. To use persistent storage, you must + # pre-provision a PersistentVolumeClaim and use `type: "existingClaim"`. data: - type: "emptyDir" # Or "hostPath" or "existingClaim" + type: "emptyDir" # Options: "emptyDir", "hostPath", or "existingClaim" hostPathPrefix: /storage # For hostPath # claimName: "worker-pvc" # For existingClaim with pre-provisioned PVC diff --git a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml index 45450e90d..ad222c704 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml @@ -42,4 +42,4 @@ spec: serviceName: {{ template "seaweedfs.name" . }}-admin servicePort: {{ .Values.admin.port }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml index 4c2c0b162..271197a3a 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml @@ -30,4 +30,4 @@ spec: app.kubernetes.io/component: admin {{- end }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml index 671f6a81b..5b6757439 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-statefulset.yaml @@ -316,4 +316,4 @@ spec: storage: {{ .Values.admin.logs.size }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index d5fb1f164..f7222857a 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -244,4 +244,4 @@ spec: nodeSelector: {{ tpl .Values.worker.nodeSelector . | indent 8 | trim }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml index 681128ee4..63ac3ba7a 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml @@ -32,3 +32,4 @@ spec: {{- end }} {{- end }} + diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 17e6b7931..b70a6b94d 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1144,6 +1144,24 @@ admin: ## Set podManagementPolicy podManagementPolicy: Parallel + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + 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: "" + resources: {} tolerations: "" nodeSelector: "" @@ -1243,6 +1261,25 @@ worker: podLabels: {} podAnnotations: {} annotations: {} + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + 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: "" + resources: requests: cpu: "500m" From cee8969bd1ac797655807bdb7791fb9b33d268af Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 20:39:23 -0700 Subject: [PATCH 12/15] supports Kubernetes versions from v1.14 to v1.30+, ensuring broad compatibility --- k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml index ad222c704..216ef8a86 100644 --- a/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml +++ b/k8s/charts/seaweedfs/templates/admin/admin-ingress.yaml @@ -10,8 +10,11 @@ kind: Ingress metadata: name: ingress-{{ template "seaweedfs.name" . }}-admin namespace: {{ .Release.Namespace }} - {{- with .Values.admin.ingress.annotations }} annotations: + {{- if and (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) .Values.admin.ingress.className }} + kubernetes.io/ingress.class: {{ .Values.admin.ingress.className }} + {{- end }} + {{- with .Values.admin.ingress.annotations }} {{- toYaml . | nindent 4 }} {{- end }} labels: @@ -21,7 +24,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: admin spec: + {{- if and (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) .Values.admin.ingress.className }} ingressClassName: {{ .Values.admin.ingress.className | quote }} + {{- end }} tls: {{ .Values.admin.ingress.tls | default list | toYaml | nindent 6}} rules: @@ -31,7 +36,9 @@ spec: http: paths: - path: {{ .Values.admin.ingress.path | quote }} + {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} pathType: {{ .Values.admin.ingress.pathType | quote }} + {{- end }} backend: {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} service: From e4076dad9a2ab0f311bbc52106e7622c4b57e66f Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 20:46:00 -0700 Subject: [PATCH 13/15] add probe for workers --- k8s/charts/seaweedfs/README.md | 10 ++++---- .../templates/worker/worker-deployment.yaml | 24 +++++++++++++++++++ k8s/charts/seaweedfs/values.yaml | 22 +++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index 273f82e80..736d5dd59 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -216,9 +216,9 @@ worker: workingDir: "/tmp/seaweedfs-worker" # Optional: configure admin server address - # If not specified, auto-discovers from admin service in the same namespace - # Replace with your actual namespace - adminServer: "seaweedfs-admin.:33646" + # If not specified, auto-discovers from admin service in the same namespace. + # Replace with the namespace where the admin service is deployed. + adminServer: "seaweedfs-admin..svc:33646" # Workers need storage for task execution # Note: Workers use a Deployment, which does not support `volumeClaimTemplates` @@ -282,7 +282,7 @@ worker: maxConcurrent: 2 # REQUIRED: Point to the admin service of your main SeaweedFS release # Replace with the namespace where your main seaweedfs is deployed - adminServer: "seaweedfs-admin.:33646" + adminServer: "seaweedfs-admin..svc:33646" ``` **values-worker-balance.yaml** (for balance operations): @@ -306,7 +306,7 @@ worker: maxConcurrent: 1 # REQUIRED: Point to the admin service of your main SeaweedFS release # Replace with the namespace where your main seaweedfs is deployed - adminServer: "seaweedfs-admin.:33646" + adminServer: "seaweedfs-admin..svc:33646" ``` Deploy the specialized workers as separate releases: diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index f7222857a..40c1e32af 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -182,6 +182,30 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- if .Values.worker.livenessProbe.enabled }} + livenessProbe: + {{- with .Values.worker.livenessProbe.tcpSocket }} + tcpSocket: + port: {{ .port }} + {{- end }} + initialDelaySeconds: {{ .Values.worker.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.worker.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.worker.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.worker.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.worker.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.worker.readinessProbe.enabled }} + readinessProbe: + {{- with .Values.worker.readinessProbe.tcpSocket }} + tcpSocket: + port: {{ .port }} + {{- end }} + initialDelaySeconds: {{ .Values.worker.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.worker.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.worker.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.worker.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.worker.readinessProbe.timeoutSeconds }} + {{- end }} {{- if .Values.worker.containerSecurityContext.enabled }} securityContext: {{- omit .Values.worker.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index b70a6b94d..479a40e13 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1296,6 +1296,28 @@ worker: extraEnvironmentVars: {} + # Health checks for worker pods + # Since workers do not have an HTTP endpoint, a tcpSocket probe on the metrics port is recommended. + livenessProbe: + enabled: true + tcpSocket: + port: metrics + initialDelaySeconds: 30 + periodSeconds: 60 + successThreshold: 1 + failureThreshold: 5 + timeoutSeconds: 10 + + readinessProbe: + enabled: true + tcpSocket: + port: metrics + initialDelaySeconds: 20 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 10 + # ServiceMonitor annotations (separate from pod/deployment annotations) serviceMonitor: annotations: {} From bcdbc461b3c1dec6c98d9ccfc2389a0155c2dd88 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 20:47:17 -0700 Subject: [PATCH 14/15] address comments --- k8s/charts/seaweedfs/README.md | 18 +++++++++++++++--- .../templates/worker/worker-service.yaml | 1 - .../worker/worker-servicemonitor.yaml | 2 -- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/k8s/charts/seaweedfs/README.md b/k8s/charts/seaweedfs/README.md index 736d5dd59..7f27cb22e 100644 --- a/k8s/charts/seaweedfs/README.md +++ b/k8s/charts/seaweedfs/README.md @@ -213,12 +213,20 @@ worker: replicas: 2 # Scale based on workload capabilities: "vacuum,balance,erasure_coding" # Tasks this worker can handle maxConcurrent: 3 # Maximum concurrent tasks per worker + + # Working directory for task execution + # Default: "/tmp/seaweedfs-worker" + # Note: /tmp is ephemeral - use persistent storage (hostPath/existingClaim) for long-running tasks workingDir: "/tmp/seaweedfs-worker" # Optional: configure admin server address - # If not specified, auto-discovers from admin service in the same namespace. - # Replace with the namespace where the admin service is deployed. - adminServer: "seaweedfs-admin..svc:33646" + # If not specified, auto-discovers from admin service in the same namespace by looking for + # a service named "-admin" (e.g., "seaweedfs-admin"). + # Auto-discovery only works if the admin is in the same namespace and same Helm release. + # For cross-namespace or separate release scenarios, explicitly set this value. + # Example: If main SeaweedFS is deployed in "production" namespace: + # adminServer: "seaweedfs-admin.production.svc:33646" + adminServer: "" # Workers need storage for task execution # Note: Workers use a Deployment, which does not support `volumeClaimTemplates` @@ -282,6 +290,8 @@ worker: maxConcurrent: 2 # REQUIRED: Point to the admin service of your main SeaweedFS release # Replace with the namespace where your main seaweedfs is deployed + # Example: If deploying in namespace "production": + # adminServer: "seaweedfs-admin.production.svc:33646" adminServer: "seaweedfs-admin..svc:33646" ``` @@ -306,6 +316,8 @@ worker: maxConcurrent: 1 # REQUIRED: Point to the admin service of your main SeaweedFS release # Replace with the namespace where your main seaweedfs is deployed + # Example: If deploying in namespace "production": + # adminServer: "seaweedfs-admin.production.svc:33646" adminServer: "seaweedfs-admin..svc:33646" ``` diff --git a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml index b7f60e52f..cf9885e2f 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml @@ -24,4 +24,3 @@ spec: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: worker {{- end }} - diff --git a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml index 63ac3ba7a..7f9590dab 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml @@ -31,5 +31,3 @@ spec: {{- end }} {{- end }} {{- end }} - - From b73b14d87a5d09882fe18d7989ded33957308c40 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 25 Oct 2025 21:02:07 -0700 Subject: [PATCH 15/15] add a todo --- weed/command/worker.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/weed/command/worker.go b/weed/command/worker.go index 6e592f73f..1a36899e2 100644 --- a/weed/command/worker.go +++ b/weed/command/worker.go @@ -19,6 +19,9 @@ import ( _ "github.com/seaweedfs/seaweedfs/weed/worker/tasks/balance" _ "github.com/seaweedfs/seaweedfs/weed/worker/tasks/erasure_coding" _ "github.com/seaweedfs/seaweedfs/weed/worker/tasks/vacuum" + // TODO: Implement additional task packages: + // _ "github.com/seaweedfs/seaweedfs/weed/worker/tasks/remote" - for uploading volumes to remote/cloud storage + // _ "github.com/seaweedfs/seaweedfs/weed/worker/tasks/replication" - for fixing replication issues and maintaining data consistency ) var cmdWorker = &Command{