From 3c64cc6c6b6b83f9957acc12f7b2b83a9f5fcccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20=C5=BByli=C5=84ski?= Date: Wed, 25 Oct 2023 15:18:13 +0200 Subject: [PATCH] Fix: Include restartable init containers in Pod utilization calc --- .../simulator/utilization/info.go | 9 ++++++- .../simulator/utilization/info_test.go | 27 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cluster-autoscaler/simulator/utilization/info.go b/cluster-autoscaler/simulator/utilization/info.go index 30c78cb95f29..7abc7c1e4160 100644 --- a/cluster-autoscaler/simulator/utilization/info.go +++ b/cluster-autoscaler/simulator/utilization/info.go @@ -118,7 +118,14 @@ func CalculateUtilizationOfResource(nodeInfo *schedulerframework.NodeInfo, resou if drain.IsPodLongTerminating(podInfo.Pod, currentTime) { continue } - for _, container := range podInfo.Pod.Spec.Containers { + // calculate all regular containers and restartable init containers requests + containers := append([]apiv1.Container{}, podInfo.Pod.Spec.Containers...) + for _, c := range podInfo.Pod.Spec.InitContainers { + if c.RestartPolicy != nil && *c.RestartPolicy == apiv1.ContainerRestartPolicyAlways { + containers = append(containers, c) + } + } + for _, container := range containers { if resourceValue, found := container.Resources.Requests[resourceName]; found { podsRequest.Add(resourceValue) } diff --git a/cluster-autoscaler/simulator/utilization/info_test.go b/cluster-autoscaler/simulator/utilization/info_test.go index d6d697bd1a35..452eab4c8b14 100644 --- a/cluster-autoscaler/simulator/utilization/info_test.go +++ b/cluster-autoscaler/simulator/utilization/info_test.go @@ -21,6 +21,7 @@ import ( "time" apiv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" . "k8s.io/autoscaler/cluster-autoscaler/utils/test" "k8s.io/kubernetes/pkg/kubelet/types" @@ -33,6 +34,19 @@ func TestCalculate(t *testing.T) { testTime := time.Date(2020, time.December, 18, 17, 0, 0, 0, time.UTC) pod := BuildTestPod("p1", 100, 200000) pod2 := BuildTestPod("p2", -1, -1) + podWithInitContainers := BuildTestPod("p-init", 100, 200000) + restartAlways := apiv1.ContainerRestartPolicyAlways + podWithInitContainers.Spec.InitContainers = []apiv1.Container{ + { + Resources: apiv1.ResourceRequirements{ + Requests: apiv1.ResourceList{ + apiv1.ResourceCPU: *resource.NewMilliQuantity(50, resource.DecimalSI), + apiv1.ResourceMemory: *resource.NewQuantity(100000, resource.DecimalSI), + }, + }, + RestartPolicy: &restartAlways, + }, + } node := BuildTestNode("node1", 2000, 2000000) SetNodeReadyState(node, true, time.Time{}) @@ -42,14 +56,25 @@ func TestCalculate(t *testing.T) { utilInfo, err := Calculate(nodeInfo, false, false, gpuConfig, testTime) assert.NoError(t, err) assert.InEpsilon(t, 2.0/10, utilInfo.Utilization, 0.01) + assert.Equal(t, 0.1, utilInfo.CpuUtil) - node2 := BuildTestNode("node1", 2000, -1) + node2 := BuildTestNode("node2", 2000, -1) nodeInfo = newNodeInfo(node2, pod, pod, pod2) gpuConfig = GetGpuConfigFromNode(nodeInfo.Node()) _, err = Calculate(nodeInfo, false, false, gpuConfig, testTime) assert.Error(t, err) + node3 := BuildTestNode("node3", 2000, 2000000) + SetNodeReadyState(node3, true, time.Time{}) + nodeInfo = newNodeInfo(node3, pod, podWithInitContainers, pod2) + + gpuConfig = GetGpuConfigFromNode(nodeInfo.Node()) + utilInfo, err = Calculate(nodeInfo, false, false, gpuConfig, testTime) + assert.NoError(t, err) + assert.InEpsilon(t, 2.5/10, utilInfo.Utilization, 0.01) + assert.Equal(t, 0.125, utilInfo.CpuUtil) + daemonSetPod3 := BuildTestPod("p3", 100, 200000) daemonSetPod3.OwnerReferences = GenerateOwnerReferences("ds", "DaemonSet", "apps/v1", "")