diff --git a/pkg/descheduler/framework/plugins/loadaware/utilization_util.go b/pkg/descheduler/framework/plugins/loadaware/utilization_util.go index 436038b18..de6e8e4cd 100644 --- a/pkg/descheduler/framework/plugins/loadaware/utilization_util.go +++ b/pkg/descheduler/framework/plugins/loadaware/utilization_util.go @@ -292,13 +292,7 @@ func evictPodsFromSourceNodes( klog.V(4).InfoS("No removable pods on node, try next node", "node", klog.KObj(srcNode.node), "nodePool", nodePoolName) continue } - - sorter.SortPodsByUsage( - removablePods, - srcNode.podMetrics, - map[string]corev1.ResourceList{srcNode.node.Name: srcNode.node.Status.Allocatable}, - resourceWeights, - ) + sortPodsOnOneOverloadedNode(srcNode, removablePods, resourceWeights) evictPods(ctx, nodePoolName, dryRun, removablePods, srcNode, totalAvailableUsages, podEvictor, podFilter, continueEviction, evictionReasonGenerator) } } @@ -472,3 +466,17 @@ func calcAverageResourceUsagePercent(nodeUsages map[string]*NodeUsage) ResourceT } return average } +func sortPodsOnOneOverloadedNode(srcNode NodeInfo, removablePods []*corev1.Pod, resourceWeights map[corev1.ResourceName]int64) { + weights := make(map[corev1.ResourceName]int64) + // get the overused resource of this node, and the weights of appropriately using resources will be zero. + overusedResources, _ := isNodeOverutilized(srcNode.usage, srcNode.thresholds.highResourceThreshold) + for or := range overusedResources { + weights[or] = resourceWeights[or] + } + sorter.SortPodsByUsage( + removablePods, + srcNode.podMetrics, + map[string]corev1.ResourceList{srcNode.node.Name: srcNode.node.Status.Allocatable}, + weights, + ) +} diff --git a/pkg/descheduler/framework/plugins/loadaware/utilization_util_test.go b/pkg/descheduler/framework/plugins/loadaware/utilization_util_test.go index c03f84cba..3024a6c98 100644 --- a/pkg/descheduler/framework/plugins/loadaware/utilization_util_test.go +++ b/pkg/descheduler/framework/plugins/loadaware/utilization_util_test.go @@ -24,6 +24,9 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + slov1alpha1 "github.com/koordinator-sh/koordinator/apis/slo/v1alpha1" ) var ( @@ -147,3 +150,82 @@ func TestSortNodesByUsageAscendingOrder(t *testing.T) { assert.Equal(t, expectedNodeList, nodeList) } +func TestSortPodsOnOneOverloadedNode(t *testing.T) { + nodeInfo := NodeInfo{ + NodeUsage: &NodeUsage{ + node: &corev1.Node{ + Status: corev1.NodeStatus{ + Allocatable: testNodeAllocatable, + }, + ObjectMeta: metav1.ObjectMeta{Name: "node0"}, + }, + // only make cpu overused + usage: map[corev1.ResourceName]*resource.Quantity{ + corev1.ResourceCPU: resource.NewMilliQuantity(30000, resource.DecimalSI), + corev1.ResourceMemory: resource.NewQuantity(998244353, resource.BinarySI), + }, + podMetrics: map[types.NamespacedName]*slov1alpha1.ResourceMap{ + { + Namespace: "ns", + Name: "pod1", + }: { + ResourceList: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(1000, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(27487790694, resource.BinarySI), + }, + }, + { + Namespace: "ns", + Name: "pod2", + }: { + ResourceList: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(3000, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(27487790694, resource.BinarySI), + }, + }, + { + Namespace: "ns", + Name: "pod3", + }: { + ResourceList: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(1, resource.BinarySI), + }, + }, + { + Namespace: "ns", + Name: "pod4", + }: { + ResourceList: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(4000, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(1, resource.BinarySI), + }, + }, + }, + }, + thresholds: NodeThresholds{ + lowResourceThreshold: nil, + highResourceThreshold: map[corev1.ResourceName]*resource.Quantity{ + corev1.ResourceCPU: resource.NewMilliQuantity(20000, resource.DecimalSI), + corev1.ResourceMemory: resource.NewQuantity(27487790694, resource.BinarySI), + }, + }, + } + removablePods := []*corev1.Pod{ + {ObjectMeta: metav1.ObjectMeta{Name: "pod1", Namespace: "ns"}, Spec: corev1.PodSpec{NodeName: "node0"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "pod2", Namespace: "ns"}, Spec: corev1.PodSpec{NodeName: "node0"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "pod3", Namespace: "ns"}, Spec: corev1.PodSpec{NodeName: "node0"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "pod4", Namespace: "ns"}, Spec: corev1.PodSpec{NodeName: "node0"}}, + } + expectedResult := make([]*corev1.Pod, 4) + expectedResult[0] = removablePods[3] + expectedResult[1] = removablePods[1] + expectedResult[2] = removablePods[2] + expectedResult[3] = removablePods[0] + resourceWeights := map[corev1.ResourceName]int64{ + corev1.ResourceCPU: int64(1), + corev1.ResourceMemory: int64(1), + } + sortPodsOnOneOverloadedNode(nodeInfo, removablePods, resourceWeights) + assert.Equal(t, expectedResult, removablePods) +}