From e0f47057e0f7f1fbb459e614bebca5f9a8aeb51c Mon Sep 17 00:00:00 2001 From: "(Brien Dieterle)" <(briend@gmail.com)> Date: Mon, 8 Mar 2021 21:46:31 -0600 Subject: [PATCH 1/2] Document That Descheduler Considers StatefulSets For Eviction Similar to ReplicaSet, ReplicationController, and Jobs pods with a StatefulSet metadata.ownerReference are considered for eviction. Document this, so that it is clear to end users. --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index adbbd6af26..b1ec83a3f6 100644 --- a/README.md +++ b/README.md @@ -130,15 +130,17 @@ strategies: ### RemoveDuplicates -This strategy makes sure that there is only one pod associated with a Replica Set (RS), -Replication Controller (RC), Deployment, or Job running on the same node. If there are more, +This strategy makes sure that there is only one pod associated with a ReplicaSet (RS), +ReplicationController (RC), StatefulSet, or Job running on the same node. If there are more, those duplicate pods are evicted for better spreading of pods in a cluster. This issue could happen if some nodes went down due to whatever reasons, and pods on them were moved to other nodes leading to more than one pod associated with a RS or RC, for example, running on the same node. Once the failed nodes are ready again, this strategy could be enabled to evict those duplicate pods. -It provides one optional parameter, `ExcludeOwnerKinds`, which is a list of OwnerRef `Kind`s. If a pod -has any of these `Kind`s listed as an `OwnerRef`, that pod will not be considered for eviction. +It provides one optional parameter, `excludeOwnerKinds`, which is a list of OwnerRef `Kind`s. If a pod +has any of these `Kind`s listed as an `OwnerRef`, that pod will not be considered for eviction. Note that +pods created by Deployments are considered for eviction by this strategy. The `excludeOwnerKinds` parameter +should include `ReplicaSet` to have pods created by Deployments excluded. **Parameters:** @@ -546,7 +548,7 @@ strategies: When the descheduler decides to evict pods from a node, it employs the following general mechanism: * [Critical pods](https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/) (with priorityClassName set to system-cluster-critical or system-node-critical) are never evicted. -* Pods (static or mirrored pods or stand alone pods) not part of an RC, RS, Deployment or Job are +* Pods (static or mirrored pods or stand alone pods) not part of an ReplicationController, ReplicaSet(Deployment), StatefulSet, or Job are never evicted because these pods won't be recreated. * Pods associated with DaemonSets are never evicted. * Pods with local storage are never evicted (unless `evictLocalStoragePods: true` is set) From f80f08dca3a64da8159b8790903b9de18c2b0bd3 Mon Sep 17 00:00:00 2001 From: "(Brien Dieterle)" <(briend@gmail.com)> Date: Tue, 23 Mar 2021 00:03:36 -0500 Subject: [PATCH 2/2] Add Initial Unit Tests For StatefulSets --- pkg/descheduler/evictions/evictions_test.go | 15 +++++++++++++++ test/test_utils.go | 12 ++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pkg/descheduler/evictions/evictions_test.go b/pkg/descheduler/evictions/evictions_test.go index 20d770ce8d..986a3247af 100644 --- a/pkg/descheduler/evictions/evictions_test.go +++ b/pkg/descheduler/evictions/evictions_test.go @@ -236,6 +236,21 @@ func TestIsEvictable(t *testing.T) { evictLocalStoragePods: false, priorityThreshold: &lowPriority, result: true, + }, { + pod: test.BuildTestPod("p16", 400, 0, n1.Name, nil), + runBefore: func(pod *v1.Pod) { + pod.ObjectMeta.OwnerReferences = test.GetStatefulSetOwnerRefList() + }, + evictLocalStoragePods: false, + result: true, + }, { + pod: test.BuildTestPod("p17", 400, 0, n1.Name, nil), + runBefore: func(pod *v1.Pod) { + pod.Annotations = map[string]string{"descheduler.alpha.kubernetes.io/evict": "true"} + pod.ObjectMeta.OwnerReferences = test.GetStatefulSetOwnerRefList() + }, + evictLocalStoragePods: false, + result: true, }, } diff --git a/test/test_utils.go b/test/test_utils.go index 206fa85c48..7b35ab8e0c 100644 --- a/test/test_utils.go +++ b/test/test_utils.go @@ -79,6 +79,13 @@ func GetReplicaSetOwnerRefList() []metav1.OwnerReference { return ownerRefList } +// GetStatefulSetOwnerRefList returns the ownerRef needed for statefulset pod. +func GetStatefulSetOwnerRefList() []metav1.OwnerReference { + ownerRefList := make([]metav1.OwnerReference, 0) + ownerRefList = append(ownerRefList, metav1.OwnerReference{Kind: "StatefulSet", APIVersion: "v1", Name: "statefulset-1"}) + return ownerRefList +} + // GetDaemonSetOwnerRefList returns the ownerRef needed for daemonset pod. func GetDaemonSetOwnerRefList() []metav1.OwnerReference { ownerRefList := make([]metav1.OwnerReference, 0) @@ -142,6 +149,11 @@ func SetRSOwnerRef(pod *v1.Pod) { pod.ObjectMeta.OwnerReferences = GetReplicaSetOwnerRefList() } +// SetSSOwnerRef sets the given pod's owner to StatefulSet +func SetSSOwnerRef(pod *v1.Pod) { + pod.ObjectMeta.OwnerReferences = GetStatefulSetOwnerRefList() +} + // SetDSOwnerRef sets the given pod's owner to DaemonSet func SetDSOwnerRef(pod *v1.Pod) { pod.ObjectMeta.OwnerReferences = GetDaemonSetOwnerRefList()