1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-28 14:41:10 +01:00

Check whether pod matches the inter-pod anti-affinity of another Pod in a given Node in NodeFit() (#1356)

* Check if Pod matches inter-pod anti-affinity of other pod on node as part of NodeFit()

* Add unit tests for checking inter-pod anti-affinity match in NodeFit()
* Export setPodAntiAffinity() helper func to test utils

* Add docs for inter-pod anti-affinity in README

* Refactor logic for inter-pod anti-affinity to use in multiple pkgs
* Move logic for finding match between pods with antiaffinity out of framework to reuse in other pkgs
* Move interpod antiaffinity funcs to pkg/utils/predicates.go

* Add unit tests for inter-pod anti-affinity check
* Test logic in GroupByNodeName
* Test NodeFit() case where pods matches inter-pod anti-affinity
* Test for inter-pod anti-affinity pods  match terms, have label selector

* NodeFit inter-pod anti-affinity check returns early if affinity spec not set
This commit is contained in:
Niki Manoledaki
2024-03-13 03:50:03 +01:00
committed by GitHub
parent dc2cf723bc
commit 749e81c51c
12 changed files with 328 additions and 132 deletions

View File

@@ -6,6 +6,7 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/descheduler/test"
)
func TestUniqueSortTolerations(t *testing.T) {
@@ -1041,3 +1042,71 @@ func TestPodNodeAffinityWeight(t *testing.T) {
})
}
}
func TestCheckPodsWithAntiAffinityExist(t *testing.T) {
tests := []struct {
name string
pod *v1.Pod
podsInNamespace map[string][]*v1.Pod
nodeMap map[string]*v1.Node
affinity *v1.PodAntiAffinity
expMatch bool
}{
{
name: "found pod matching pod anti-affinity",
pod: test.PodWithPodAntiAffinity(test.BuildTestPod("p1", 1000, 1000, "node", nil), "foo", "bar"),
podsInNamespace: map[string][]*v1.Pod{
"default": {
test.PodWithPodAntiAffinity(test.BuildTestPod("p2", 1000, 1000, "node", nil), "foo", "bar"),
},
},
nodeMap: map[string]*v1.Node{
"node": test.BuildTestNode("node", 64000, 128*1000*1000*1000, 2, func(node *v1.Node) {
node.ObjectMeta.Labels = map[string]string{
"region": "main-region",
}
}),
},
expMatch: true,
},
{
name: "no match with invalid label selector",
pod: &v1.Pod{
Spec: v1.PodSpec{
Affinity: &v1.Affinity{
PodAntiAffinity: &v1.PodAntiAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{
{
LabelSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"wrong": "selector",
},
},
},
},
},
},
},
},
podsInNamespace: map[string][]*v1.Pod{},
nodeMap: map[string]*v1.Node{},
expMatch: false,
},
{
name: "no match if pod does not match terms namespace",
pod: test.PodWithPodAntiAffinity(test.BuildTestPod("p1", 1000, 1000, "node", func(pod *v1.Pod) {
pod.Namespace = "other"
}), "foo", "bar"),
podsInNamespace: map[string][]*v1.Pod{},
nodeMap: map[string]*v1.Node{},
expMatch: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if match := CheckPodsWithAntiAffinityExist(test.pod, test.podsInNamespace, test.nodeMap); match != test.expMatch {
t.Errorf("exp %v got %v", test.expMatch, match)
}
})
}
}