feat: add topologyMinDomains opt-in field to force AZ spreading with Karpenter/Cluster Autoscaler - #330
Open
gangavh1008 wants to merge 2 commits into
Open
feat: add topologyMinDomains opt-in field to force AZ spreading with Karpenter/Cluster Autoscaler#330gangavh1008 wants to merge 2 commits into
gangavh1008 wants to merge 2 commits into
Conversation
With demand-driven autoscalers (Karpenter, Cluster Autoscaler), the Kubernetes
scheduler counts only topology domains (AZs) that already have eligible nodes.
When topologyZoneKey generates a maxSkew:1/DoNotSchedule constraint and nodes
exist in only two AZs at scheduling time, the constraint is satisfied with a
2/1 split — the autoscaler never provisions into a third AZ, leaving one replica
unspread.
Setting minDomains on the TopologySpreadConstraint tells the scheduler to treat
N zones as domains regardless of whether nodes currently exist in all of them,
forcing the autoscaler to provision into the missing zone.
This commit adds an opt-in TopologyMinDomains *int32 field to PodTemplateSpec.
When nil (the default), behaviour is unchanged. When set (e.g. 3 for a
three-AZ cluster), minDomains is forwarded to the generated constraint for
both ClickHouseCluster and KeeperCluster.
Example usage:
podTemplate:
topologyZoneKey: topology.kubernetes.io/zone
topologyMinDomains: 3
gangavh1008
force-pushed
the
feature/topology-min-domains
branch
from
September 13, 2026 23:56
1f5da84 to
062fa0d
Compare
…docs Fixes golangci-lint wsl_v5 failures: adds required blank lines before assignments that follow a closing block and before return statements in templates_test.go for both clickhouse and keeper controllers. Also adds the missing topologyMinDomains row to docs/reference/api-reference.mdx so the API Reference Generated CI check passes.
Author
|
@GrigoryPervakov , please review the PR. Thank you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
topologyZoneKeyshorthand generates aTopologySpreadConstraintwithmaxSkew: 1andwhenUnsatisfiable: DoNotSchedule. This is the right setup for spreading pods across availability zones — but with demand-driven autoscalers (Karpenter, Cluster Autoscaler), the constraint alone is insufficient.The Kubernetes scheduler counts only topology domains (AZs) that already have eligible nodes when evaluating spread. If nodes exist in only two AZs at scheduling time, the scheduler considers the constraint satisfied with a 2/1 split — the autoscaler never receives a signal to provision a node in the third AZ. The result: one replica is stuck permanently unspread, and the cluster loses a zone of fault tolerance without any warning.
This is a known Kubernetes limitation addressed by the
minDomainsfield introduced in KEP-3022 (beta in Kubernetes 1.25, GA in 1.28).Solution
Setting
minDomainson theTopologySpreadConstrainttells the scheduler to treat N zones as topology domains even if nodes don't exist in all of them. This makes the constraint unsatisfiable until the autoscaler provisions into all required zones.Change
This PR adds an opt-in
topologyMinDomainsfield (*int32) toPodTemplateSpec. When set, it is forwarded tominDomainson theTopologySpreadConstraintgenerated bytopologyZoneKey— for bothClickHouseCluster(per-shard constraint) andKeeperCluster.Disabled by default: when
topologyMinDomainsis nil (the default), nominDomainsis set and behaviour is completely unchanged.Usage
API change (
api/v1alpha1/common.go)Tests
New test blocks for both
ClickHouseClusterandKeeperClustercovering:topologyZoneKeyis unset (baseline — no change)minDomainswhentopologyMinDomainsis nil (baseline — no change)minDomainsforwarded correctly when the field is setClickHouseCluster(each shard's replicas spread independently)Compatibility
topologyMinDomainsdefaults to nil; omitting it preserves all existing behaviour.minDomainsGA. Clusters on earlier versions should leavetopologyMinDomainsunset or ensure theMinDomainsInPodTopologySpreadfeature gate is enabled (available from 1.25+).