fix(seaweedfs): soften master anti-affinity for small clusters (#3197)

## What this PR does

Overrides the seaweedfs master anti-affinity in the package values from
a hard `requiredDuringSchedulingIgnoredDuringExecution` hostname term to
a strong preference (`preferredDuringSchedulingIgnoredDuringExecution`,
weight 100). The selector and topologyKey are unchanged.

The vendored subchart pins the master to a hard hostname anti-affinity —
its own comment notes that emptying it is what allows single-node
deployment. With the master StatefulSet at three replicas, the surplus
master Pods stay Pending forever on clusters with fewer than three
nodes, so `helm install --wait` never returns and the S3 stack never
comes up.

Softening to a strong preference keeps the masters spread across
distinct nodes whenever the cluster has them (the scheduler only
co-locates when there is no alternative — exactly the small-cluster
case), while letting single- and dual-node clusters bring the master up.
This mirrors the posture already applied to the s3 component in the same
values file.

A helm-unittest pins the softened term (asserts the hard term is gone
and the preferred term carries the right weight, topologyKey, and
component selector) so a future subchart bump cannot silently re-harden
it.

### Screenshots

N/A — no UI changes.

### Release note

```release-note
fix(seaweedfs): soften the master anti-affinity to a preference so the S3 stack installs on clusters with fewer than three nodes
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* SeaweedFS master pods now use a softer scheduling preference for
hostname separation, improving deployment success on smaller clusters.
* **Tests**
* Added a Helm chart validation to confirm the anti-affinity behavior is
now expressed as a weighted preference (not a hard requirement),
including the expected selector and topology key.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Aleksei Sviridkin authored and GitHub committed 2026-07-15 11:32:01 +03:00
commit 3763c528da
2 files changed
+55

No files matched your search

@@ -0,0 +1,33 @@
suite: seaweedfs master anti-affinity
# Pins the master anti-affinity override that keeps the 3-replica master
# StatefulSet schedulable on clusters with fewer than three nodes. The upstream
# subchart ships a HARD hostname anti-affinity
# (requiredDuringSchedulingIgnoredDuringExecution); with three replicas that
# leaves the surplus master Pods Pending forever on a single- or dual-node
# cluster, so `helm install --wait` never returns. The overlay softens it to a
# strong preference (weight 100) so the masters still spread across distinct
# nodes when the cluster has them. This guards against a subchart bump silently
# re-hardening the term back to required.
templates:
- charts/seaweedfs/templates/master/master-statefulset.yaml
release:
name: seaweedfs
namespace: cozy-seaweedfs
tests:
- it: softens the master hostname anti-affinity to a preference
asserts:
- notExists:
path: spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution
- equal:
path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].weight
value: 100
- equal:
path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.topologyKey
value: kubernetes.io/hostname
- equal:
path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.labelSelector.matchLabels["app.kubernetes.io/component"]
value: master
+22
View File
@@ -45,6 +45,28 @@ seaweedfs:
timeoutSeconds: 30
readinessProbe:
timeoutSeconds: 30
# The upstream subchart pins the master to a HARD hostname anti-affinity
# (requiredDuringSchedulingIgnoredDuringExecution). With the 3-replica
# StatefulSet above, that makes the master unschedulable on clusters with
# fewer than three nodes: the surplus master Pods stay Pending forever, so
# `helm install --wait` never returns and Flux loops install/uninstall —
# the whole S3 stack never comes up. Soften it to a strong preference
# (weight 100) so the masters still spread across distinct nodes whenever
# the cluster has them, while single- and dual-node clusters can still
# bring the master up. Same posture already used for the s3 component
# below. Selector and topologyKey are unchanged from the subchart default;
# only required -> preferred.
affinity: |
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: master
topologyKey: kubernetes.io/hostname
volume:
replicas: 2
resizeHook: