From 9c0d57ad3fba2361d224c293f41256ef3e4118fa Mon Sep 17 00:00:00 2001 From: Cameron McAvoy Date: Mon, 24 Feb 2025 17:14:33 -0600 Subject: [PATCH] feat: scale disruption cost by the node utilization Signed-off-by: Cameron McAvoy --- pkg/controllers/disruption/types.go | 2 +- pkg/controllers/state/statenode.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pkg/controllers/disruption/types.go b/pkg/controllers/disruption/types.go index 7ef8059d0c..bf448d8de9 100644 --- a/pkg/controllers/disruption/types.go +++ b/pkg/controllers/disruption/types.go @@ -112,7 +112,7 @@ func NewCandidate(ctx context.Context, kubeClient client.Client, recorder events zone: node.Labels()[corev1.LabelTopologyZone], reschedulablePods: lo.Filter(pods, func(p *corev1.Pod, _ int) bool { return pod.IsReschedulable(p) }), // We get the disruption cost from all pods in the candidate, not just the reschedulable pods - disruptionCost: disruptionutils.ReschedulingCost(ctx, pods) * disruptionutils.LifetimeRemaining(clk, nodePool, node.NodeClaim), + disruptionCost: disruptionutils.ReschedulingCost(ctx, pods) * disruptionutils.LifetimeRemaining(clk, nodePool, node.NodeClaim) * node.Utilization(), }, nil } diff --git a/pkg/controllers/state/statenode.go b/pkg/controllers/state/statenode.go index e7142218c3..cc05a5d209 100644 --- a/pkg/controllers/state/statenode.go +++ b/pkg/controllers/state/statenode.go @@ -365,6 +365,21 @@ func (in *StateNode) Available() corev1.ResourceList { return resources.Subtract(in.Allocatable(), in.PodRequests()) } +// Utilization is the ratio of requested resources to allocatable resources +func (in *StateNode) Utilization() float64 { + requested := in.PodRequests() + if len(requested) == 0 { + return 0 + } + alloc := in.Allocatable() + utilization := 0.0 + for resource, request := range requested { + allocResource := alloc[resource] + utilization += float64(request.MilliValue()) / float64(allocResource.MilliValue()) + } + return utilization / float64(len(requested)) +} + func (in *StateNode) DaemonSetRequests() corev1.ResourceList { return resources.Merge(lo.Values(in.daemonSetRequests)...) }