Skip to content

Commit

Permalink
Replace anti-affinity with topology spread
Browse files Browse the repository at this point in the history
Co-authored-by: Johannes Dillmann <[email protected]>
  • Loading branch information
c0d1ngm0nk3y and modulo11 committed Sep 25, 2024
1 parent 96c77ac commit ade9d79
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 42 deletions.
2 changes: 0 additions & 2 deletions statefulset-runner/controllers/appworkload_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ const (

LivenessFailureThreshold = 4
ReadinessFailureThreshold = 1

PodAffinityTermWeight = 100
)

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
Expand Down
42 changes: 17 additions & 25 deletions statefulset-runner/controllers/appworkload_to_stset.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"maps"
"regexp"
"slices"
"sort"
Expand Down Expand Up @@ -164,18 +163,23 @@ func (r *AppWorkloadToStatefulsetConverter) Convert(appWorkload *korifiv1alpha1.
statefulSet.Spec.Template.Spec.AutomountServiceAccountToken = tools.PtrTo(false)
statefulSet.Spec.Selector = statefulSetLabelSelector(appWorkload)

statefulSet.Spec.Template.Spec.Affinity = &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{
{
Weight: PodAffinityTermWeight,
PodAffinityTerm: corev1.PodAffinityTerm{
TopologyKey: corev1.LabelHostname,
LabelSelector: &metav1.LabelSelector{
MatchExpressions: toLabelSelectorRequirements(statefulSet.Spec.Selector),
},
},
},
statefulSet.Spec.Template.Spec.TopologySpreadConstraints = []corev1.TopologySpreadConstraint{
{
TopologyKey: "topology.kubernetes.io/zone",
MaxSkew: 1,
WhenUnsatisfiable: "ScheduleAnyway",
LabelSelector: statefulSet.Spec.Selector,
MatchLabelKeys: []string{
"pod-template-hash",
},
},
{
TopologyKey: "kubernetes.io/hostname",
MaxSkew: 1,
WhenUnsatisfiable: "ScheduleAnyway",
LabelSelector: statefulSet.Spec.Selector,
MatchLabelKeys: []string{
"pod-template-hash",
},
},
}
Expand Down Expand Up @@ -232,18 +236,6 @@ func truncateString(str string, num int) string {
return str
}

func toLabelSelectorRequirements(selector *metav1.LabelSelector) []metav1.LabelSelectorRequirement {
labels := slices.Values(slices.Sorted(maps.Keys(selector.MatchLabels)))

return slices.Collect(it.Map(labels, func(label string) metav1.LabelSelectorRequirement {
return metav1.LabelSelectorRequirement{
Key: label,
Operator: metav1.LabelSelectorOpIn,
Values: []string{selector.MatchLabels[label]},
}
}))
}

func statefulSetLabelSelector(appWorkload *korifiv1alpha1.AppWorkload) *metav1.LabelSelector {
return &metav1.LabelSelector{
MatchLabels: map[string]string{
Expand Down
29 changes: 14 additions & 15 deletions statefulset-runner/controllers/appworkload_to_stset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,21 +270,20 @@ var _ = Describe("AppWorkload to StatefulSet Converter", func() {
Expect(*statefulSet.Spec.Template.Spec.SecurityContext.RunAsNonRoot).To(BeTrue())
})

It("should set soft inter-pod anti-affinity", func() {
podAntiAffinity := statefulSet.Spec.Template.Spec.Affinity.PodAntiAffinity
Expect(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution).To(BeEmpty())
Expect(podAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution).To(HaveLen(1))

weightedTerm := podAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0]
Expect(weightedTerm.Weight).To(Equal(int32(100)))
Expect(weightedTerm.PodAffinityTerm.TopologyKey).To(Equal("kubernetes.io/hostname"))
Expect(weightedTerm.PodAffinityTerm.LabelSelector.MatchExpressions).To(ConsistOf(
metav1.LabelSelectorRequirement{
Key: controllers.LabelGUID,
Operator: metav1.LabelSelectorOpIn,
Values: []string{"guid_1234"},
},
))
It("should set topology spread constraint", func() {
topologySpreadConstraints := statefulSet.Spec.Template.Spec.TopologySpreadConstraints
Expect(topologySpreadConstraints).To(HaveLen(2))
keys := []string{}

for _, constraint := range topologySpreadConstraints {
keys = append(keys, constraint.TopologyKey)
Expect(constraint.MaxSkew).To(BeEquivalentTo(1))
Expect(constraint.WhenUnsatisfiable).To(BeEquivalentTo("ScheduleAnyway"))
Expect(constraint.LabelSelector).To(Equal(statefulSet.Spec.Selector))
Expect(constraint.MatchLabelKeys).To(ConsistOf("pod-template-hash"))
}

Expect(keys).To(ConsistOf("topology.kubernetes.io/zone", "kubernetes.io/hostname"))
})

It("should set the container environment variables", func() {
Expand Down

0 comments on commit ade9d79

Please sign in to comment.