Skip to content

Commit 4f88e3d

Browse files
Add topologySpreadConstraints configuration.
1 parent 8a1b2f4 commit 4f88e3d

File tree

6 files changed

+243
-87
lines changed

6 files changed

+243
-87
lines changed

pkg/apis/acid.zalan.do/v1/crds.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,9 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
13231323
"enable_sidecars": {
13241324
Type: "boolean",
13251325
},
1326+
"enable_topology_spread_constraints": {
1327+
Type: "boolean",
1328+
},
13261329
"ignored_annotations": {
13271330
Type: "array",
13281331
Items: &apiextv1.JSONSchemaPropsOrArray{
@@ -1531,6 +1534,74 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
15311534
},
15321535
},
15331536
},
1537+
"topology_spread_constraints": {
1538+
Type: "array",
1539+
Nullable: true,
1540+
Items: &apiextv1.JSONSchemaPropsOrArray{
1541+
Schema: &apiextv1.JSONSchemaProps{
1542+
Type: "object",
1543+
Required: []string{"max_skew", "topology_key", "when_unsatisfiable"},
1544+
Properties: map[string]apiextv1.JSONSchemaProps{
1545+
"max_skew": {
1546+
Type: "integer",
1547+
Format: "int32",
1548+
},
1549+
"topology_key": {
1550+
Type: "string",
1551+
},
1552+
"when_unsatisfiable": {
1553+
Type: "string",
1554+
Enum: []apiextv1.JSON{
1555+
{
1556+
Raw: []byte(`"DoNotSchedule"`),
1557+
},
1558+
{
1559+
Raw: []byte(`"ScheduleAnyway"`),
1560+
},
1561+
},
1562+
},
1563+
"min_domains": {
1564+
Type: "integer",
1565+
Nullable: true,
1566+
Format: "int32",
1567+
},
1568+
"node_affinity_policy": {
1569+
Type: "string",
1570+
Nullable: true,
1571+
Enum: []apiextv1.JSON{
1572+
{
1573+
Raw: []byte(`"Ignore"`),
1574+
},
1575+
{
1576+
Raw: []byte(`"Honor"`),
1577+
},
1578+
},
1579+
},
1580+
"node_taints_policy": {
1581+
Type: "string",
1582+
Nullable: true,
1583+
Enum: []apiextv1.JSON{
1584+
{
1585+
Raw: []byte(`"Ignore"`),
1586+
},
1587+
{
1588+
Raw: []byte(`"Honor"`),
1589+
},
1590+
},
1591+
},
1592+
"match_label_keys": {
1593+
Type: "array",
1594+
Nullable: true,
1595+
Items: &apiextv1.JSONSchemaPropsOrArray{
1596+
Schema: &apiextv1.JSONSchemaProps{
1597+
Type: "string",
1598+
},
1599+
},
1600+
},
1601+
},
1602+
},
1603+
},
1604+
},
15341605
"watched_namespace": {
15351606
Type: "string",
15361607
},

pkg/apis/acid.zalan.do/v1/operator_configuration_type.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,21 @@ type KubernetesMetaConfiguration struct {
9292
NodeReadinessLabelMerge string `json:"node_readiness_label_merge,omitempty"`
9393
CustomPodAnnotations map[string]string `json:"custom_pod_annotations,omitempty"`
9494
// TODO: use a proper toleration structure?
95-
PodToleration map[string]string `json:"toleration,omitempty"`
96-
PodEnvironmentConfigMap spec.NamespacedName `json:"pod_environment_configmap,omitempty"`
97-
PodEnvironmentSecret string `json:"pod_environment_secret,omitempty"`
98-
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
99-
MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"`
100-
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
101-
PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
102-
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
103-
PodManagementPolicy string `json:"pod_management_policy,omitempty"`
104-
PersistentVolumeClaimRetentionPolicy map[string]string `json:"persistent_volume_claim_retention_policy,omitempty"`
105-
EnableReadinessProbe bool `json:"enable_readiness_probe,omitempty"`
106-
EnableCrossNamespaceSecret bool `json:"enable_cross_namespace_secret,omitempty"`
107-
EnableFinalizers *bool `json:"enable_finalizers,omitempty"`
95+
PodToleration map[string]string `json:"toleration,omitempty"`
96+
PodEnvironmentConfigMap spec.NamespacedName `json:"pod_environment_configmap,omitempty"`
97+
PodEnvironmentSecret string `json:"pod_environment_secret,omitempty"`
98+
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
99+
MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"`
100+
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
101+
PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
102+
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
103+
PodManagementPolicy string `json:"pod_management_policy,omitempty"`
104+
PersistentVolumeClaimRetentionPolicy map[string]string `json:"persistent_volume_claim_retention_policy,omitempty"`
105+
EnableReadinessProbe bool `json:"enable_readiness_probe,omitempty"`
106+
EnableCrossNamespaceSecret bool `json:"enable_cross_namespace_secret,omitempty"`
107+
EnableFinalizers *bool `json:"enable_finalizers,omitempty"`
108+
EnableTopologySpreadConstraints bool `json:"enable_topology_spread_constraints,omitempty"`
109+
TopologySpreadConstraints []*config.TopologySpreadConstraint `json:"topology_spread_constraints,omitempty"`
108110
}
109111

110112
// PostgresPodResourcesDefaults defines the spec of default resources

pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cluster/k8sres.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,36 @@ func generatePodAntiAffinity(podAffinityTerm v1.PodAffinityTerm, preferredDuring
578578
return podAntiAffinity
579579
}
580580

581+
func generateTopologySpreadConstraints(labels labels.Set, topologySpreadConstraintObjs []*config.TopologySpreadConstraint) []v1.TopologySpreadConstraint {
582+
var topologySpreadConstraints []v1.TopologySpreadConstraint
583+
var nodeAffinityPolicy *v1.NodeInclusionPolicy
584+
var nodeTaintsPolicy *v1.NodeInclusionPolicy
585+
for _, topologySpreadConstraintObj := range topologySpreadConstraintObjs {
586+
if topologySpreadConstraintObj.NodeAffinityPolicy != nil {
587+
nodeAffinityPolicy = (*v1.NodeInclusionPolicy)(topologySpreadConstraintObj.NodeAffinityPolicy)
588+
}
589+
if topologySpreadConstraintObj.NodeTaintsPolicy != nil {
590+
nodeTaintsPolicy = (*v1.NodeInclusionPolicy)(topologySpreadConstraintObj.NodeTaintsPolicy)
591+
}
592+
topologySpreadConstraint := v1.TopologySpreadConstraint{
593+
MaxSkew: topologySpreadConstraintObj.MaxSkew,
594+
TopologyKey: topologySpreadConstraintObj.TopologyKey,
595+
WhenUnsatisfiable: v1.UnsatisfiableConstraintAction(topologySpreadConstraintObj.WhenUnsatisfiable),
596+
LabelSelector: &metav1.LabelSelector{
597+
MatchLabels: labels,
598+
},
599+
MinDomains: topologySpreadConstraintObj.MinDomains,
600+
NodeAffinityPolicy: nodeAffinityPolicy,
601+
NodeTaintsPolicy: nodeTaintsPolicy,
602+
MatchLabelKeys: topologySpreadConstraintObj.MatchLabelKeys,
603+
}
604+
topologySpreadConstraints = append(topologySpreadConstraints, topologySpreadConstraint)
605+
nodeAffinityPolicy = nil
606+
nodeTaintsPolicy = nil
607+
}
608+
return topologySpreadConstraints
609+
}
610+
581611
func tolerations(tolerationsSpec *[]v1.Toleration, podToleration map[string]string) []v1.Toleration {
582612
// allow to override tolerations by postgresql manifest
583613
if len(*tolerationsSpec) > 0 {
@@ -794,6 +824,8 @@ func (c *Cluster) generatePodTemplate(
794824
additionalSecretMount string,
795825
additionalSecretMountPath string,
796826
additionalVolumes []acidv1.AdditionalVolume,
827+
topologySpreadConstraint bool,
828+
topologySpreadConstraintsArr []*config.TopologySpreadConstraint,
797829
) (*v1.PodTemplateSpec, error) {
798830

799831
terminateGracePeriodSeconds := terminateGracePeriod
@@ -842,6 +874,10 @@ func (c *Cluster) generatePodTemplate(
842874
podSpec.Affinity = nodeAffinity
843875
}
844876

877+
if topologySpreadConstraint && len(topologySpreadConstraintsArr) > 0 {
878+
podSpec.TopologySpreadConstraints = generateTopologySpreadConstraints(labels, topologySpreadConstraintsArr)
879+
}
880+
845881
if priorityClassName != "" {
846882
podSpec.PriorityClassName = priorityClassName
847883
}
@@ -1449,7 +1485,9 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
14491485
c.OpConfig.PodAntiAffinityPreferredDuringScheduling,
14501486
c.OpConfig.AdditionalSecretMount,
14511487
c.OpConfig.AdditionalSecretMountPath,
1452-
additionalVolumes)
1488+
additionalVolumes,
1489+
c.OpConfig.EnableTopologySpreadConstraints,
1490+
c.OpConfig.TopologySpreadConstraints)
14531491

14541492
if err != nil {
14551493
return nil, fmt.Errorf("could not generate pod template: %v", err)
@@ -2284,7 +2322,9 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1.CronJob, error) {
22842322
false,
22852323
c.OpConfig.AdditionalSecretMount,
22862324
c.OpConfig.AdditionalSecretMountPath,
2287-
[]acidv1.AdditionalVolume{}); err != nil {
2325+
[]acidv1.AdditionalVolume{},
2326+
false,
2327+
[]*config.TopologySpreadConstraint{}); err != nil {
22882328
return nil, fmt.Errorf("could not generate pod template for logical backup pod: %v", err)
22892329
}
22902330

pkg/controller/operator_config.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,5 +285,23 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
285285
fromCRD.ConnectionPooler.MaxDBConnections,
286286
k8sutil.Int32ToPointer(constants.ConnectionPoolerMaxDBConnections))
287287

288+
result.EnableTopologySpreadConstraints = fromCRD.Kubernetes.EnableTopologySpreadConstraints
289+
if fromCRD.Kubernetes.TopologySpreadConstraints != nil {
290+
result.TopologySpreadConstraints = []*config.TopologySpreadConstraint{}
291+
for _, topologySpreadConstraint := range fromCRD.Kubernetes.TopologySpreadConstraints {
292+
result.TopologySpreadConstraints = append(
293+
result.TopologySpreadConstraints,
294+
&config.TopologySpreadConstraint{
295+
MaxSkew: topologySpreadConstraint.MaxSkew,
296+
TopologyKey: topologySpreadConstraint.TopologyKey,
297+
WhenUnsatisfiable: topologySpreadConstraint.WhenUnsatisfiable,
298+
MinDomains: topologySpreadConstraint.MinDomains,
299+
NodeAffinityPolicy: topologySpreadConstraint.NodeAffinityPolicy,
300+
NodeTaintsPolicy: topologySpreadConstraint.NodeTaintsPolicy,
301+
MatchLabelKeys: topologySpreadConstraint.MatchLabelKeys,
302+
})
303+
}
304+
}
305+
288306
return result
289307
}

0 commit comments

Comments
 (0)