[seaweedfs] Support MultiZone topology

Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
This commit is contained in:
Andrei Kvapil
2025-07-14 21:22:32 +02:00
parent c01462d3f9
commit 493ad821c1
5 changed files with 139 additions and 35 deletions

View File

@@ -4,3 +4,4 @@ include ../../../scripts/package.mk
generate:
readme-generator -v values.yaml -s values.schema.json -r README.md
yq -o json -i '.properties.topology.enum = ["Simple","MultiZone"]' values.schema.json

View File

@@ -4,10 +4,13 @@
### Common parameters
| Name | Description | Value |
| -------------- | --------------------------------------------------------------------------------------------------------- | ------ |
| `host` | The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host). | `""` |
| `replicas` | Persistent Volume size for NATS | `2` |
| `size` | Persistent Volume size | `10Gi` |
| `storageClass` | StorageClass used to store the data | `""` |
| Name | Description | Value |
| ------------------- | ------------------------------------------------------------------------------------------------------ | -------- |
| `host` | The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host). | `""` |
| `topology` | The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone) | `Simple` |
| `replicationFactor` | The number of replicas for each volume in the SeaweedFS cluster. | `2` |
| `replicas` | Persistent Volume size for SeaweedFS | `2` |
| `size` | Persistent Volume size | `10Gi` |
| `storageClass` | StorageClass used to store the data | `""` |
| `zones` | A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. | `{}` |

View File

@@ -1,3 +1,28 @@
{{- /* Preflight checks for Helm template */ -}}
{{- if not (has .Values.topology (list "Simple" "MultiZone")) }}
{{- fail "Invalid value for .Values.topology. Must be one of 'Simple' or 'MultiZone'." }}
{{- end }}
{{- if lt (int .Values.replicationFactor) 1 }}
{{- fail "Invalid value for .Values.replicationFactor. Must be at least 1." }}
{{- end }}
{{- if eq .Values.topology "MultiZone" }}
{{- if (eq (len .Values.zones) 0) }}
{{- fail "Zones must be defined for MultiZone topology." }}
{{- end }}
{{- if and (hasKey .Values "zones") (gt (int .Values.replicationFactor) (len .Values.zones)) }}
{{- fail "replicationFactor must be less than or equal to the number of zones defined in .Values.zones." }}
{{- end }}
{{- end }}
{{- if lookup "v1" "PersistentVolumeClaim" "" (printf "%s-data1-seaweedfs-volume-0" .Release.Name) }}
{{- if eq .Values.topology "MultiZone" }}
{{- fail "Not allowed to switch between Simple and MultiZone topologies after the first deployment." }}
{{- end }}
{{- else }}
{{- if and (eq .Values.topology "Simple") (.Release.IsUpgrade) }}
{{- fail "Not allowed to switch between Simple and MultiZone topologies after the first deployment." }}
{{- end }}
{{- end }}
{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
@@ -22,6 +47,11 @@ spec:
serviceAccountName: "{{ .Release.Namespace }}-seaweedfs"
seaweedfs:
master:
{{ if eq .Values.topology "Simple" }}
defaultReplicaPlacement: "00{{ sub .Values.replicationFactor 1 }}"
{{- else if eq .Values.topology "MultiZone" }}
defaultReplicaPlacement: "{{ sub .Values.replicationFactor 1 }}00"
{{- end }}
resources:
requests:
cpu: "100m"
@@ -30,6 +60,9 @@ spec:
cpu: "500m"
memory: "512Mi"
volume:
{{ if eq .Values.topology "MultiZone" }}
enabled: false
{{- end }}
replicas: {{ .Values.replicas }}
resources:
requests:
@@ -38,9 +71,6 @@ spec:
limits:
cpu: "500m"
memory: "512Mi"
# TODO: workaround for non-working online resize
podAnnotations:
volume-size: "{{ .Values.size }}"
dataDirs:
- name: data1
type: "persistentVolumeClaim"
@@ -49,7 +79,37 @@ spec:
storageClass: {{ . }}
{{- end }}
maxVolumes: 0
{{ if eq .Values.topology "MultiZone" }}
volumes:
{{- range $zoneName, $zone := .Values.zones }}
{{ $zoneName }}:
{{ with $zone.replicas }}
replicas: {{ . }}
{{- end }}
dataDirs:
- name: data1
type: "persistentVolumeClaim"
{{- if $zone.size }}
size: "{{ $zone.size }}"
{{- else }}
size: "{{ $.Values.size }}"
{{- end }}
{{- if $zone.storageClass }}
storageClass: {{ $zone.storageClass }}
{{- else if $.Values.storageClass }}
storageClass: {{ $.Values.storageClass }}
{{- end }}
nodeSelector: |
topology.kubernetes.io/zone: {{ $zoneName }}
dataCenter: {{ $zone.dataCenter | default $zoneName }}
{{- end }}
{{- end }}
filer:
{{ if eq .Values.topology "Simple" }}
defaultReplicaPlacement: "00{{ sub .Values.replicationFactor 1 }}"
{{- else if eq .Values.topology "MultiZone" }}
defaultReplicaPlacement: "{{ sub .Values.replicationFactor 1 }}00"
{{- end }}
s3:
domainName: {{ .Values.host | default (printf "s3.%s" $host) }}
resources:

View File

@@ -1,26 +1,45 @@
{
"title": "Chart Values",
"type": "object",
"properties": {
"host": {
"type": "string",
"description": "The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host).",
"default": ""
},
"replicas": {
"type": "number",
"description": "Persistent Volume size for NATS",
"default": 2
},
"size": {
"type": "string",
"description": "Persistent Volume size",
"default": "10Gi"
},
"storageClass": {
"type": "string",
"description": "StorageClass used to store the data",
"default": ""
}
"title": "Chart Values",
"type": "object",
"properties": {
"host": {
"type": "string",
"description": "The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host).",
"default": ""
},
"topology": {
"type": "string",
"description": "The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone)",
"default": "Simple",
"enum": [
"Simple",
"MultiZone"
]
},
"replicationFactor": {
"type": "number",
"description": "The number of replicas for each volume in the SeaweedFS cluster.",
"default": 2
},
"replicas": {
"type": "number",
"description": "Persistent Volume size for SeaweedFS",
"default": 2
},
"size": {
"type": "string",
"description": "Persistent Volume size",
"default": "10Gi"
},
"storageClass": {
"type": "string",
"description": "StorageClass used to store the data",
"default": ""
},
"zones": {
"type": "object",
"description": "A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.",
"default": {}
}
}
}
}

View File

@@ -1,12 +1,33 @@
## @section Common parameters
## @param host The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host).
## @param host The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host).
host: ""
## @param replicas Persistent Volume size for NATS
## @param topology The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone)
##
topology: Simple
## @param replicationFactor The number of replicas for each volume in the SeaweedFS cluster.
replicationFactor: 2
## @param replicas Persistent Volume size for SeaweedFS
## @param size Persistent Volume size
## @param storageClass StorageClass used to store the data
##
replicas: 2
size: 10Gi
storageClass: ""
## @param zones A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.
## Example:
## zones:
## dc1:
## replicas: 2
## size: 10Gi
## dc2:
## replicas: 2
## size: 10Gi
## dc3:
## replicas: 2
## size: 10Gi
zones: {}