Also read resources from containerStatus in recommendation_provider

This commit is contained in:
Luiz Antonio 2025-04-01 12:21:38 -04:00
parent ea396b5f2b
commit a8c5030035
2 changed files with 25 additions and 7 deletions

View File

@ -24,6 +24,7 @@ import (
vpa_types "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1"
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/utils/limitrange"
resourcehelpers "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/utils/resources"
vpa_api_util "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/utils/vpa"
)
@ -53,6 +54,7 @@ func GetContainersResources(pod *core.Pod, vpaResourcePolicy *vpa_types.PodResou
addAll bool, annotations vpa_api_util.ContainerToAnnotationsMap) []vpa_api_util.ContainerResources {
resources := make([]vpa_api_util.ContainerResources, len(pod.Spec.Containers))
for i, container := range pod.Spec.Containers {
containerRequests, containerLimits := resourcehelpers.ContainerRequestsAndLimits(container.Name, pod)
recommendation := vpa_api_util.GetRecommendationForContainer(container.Name, &podRecommendation)
if recommendation == nil {
if !addAll {
@ -60,7 +62,7 @@ func GetContainersResources(pod *core.Pod, vpaResourcePolicy *vpa_types.PodResou
continue
}
klog.V(2).InfoS("No match found for container, using Pod request", "container", container.Name)
resources[i].Requests = container.Resources.Requests
resources[i].Requests = containerRequests
} else {
resources[i].Requests = recommendation.Target
}
@ -70,7 +72,7 @@ func GetContainersResources(pod *core.Pod, vpaResourcePolicy *vpa_types.PodResou
}
containerControlledValues := vpa_api_util.GetContainerControlledValues(container.Name, vpaResourcePolicy)
if containerControlledValues == vpa_types.ContainerControlledValuesRequestsAndLimits {
proportionalLimits, limitAnnotations := vpa_api_util.GetProportionalLimit(container.Resources.Limits, container.Resources.Requests, resources[i].Requests, defaultLimit)
proportionalLimits, limitAnnotations := vpa_api_util.GetProportionalLimit(containerLimits, containerRequests, resources[i].Requests, defaultLimit)
if proportionalLimits != nil {
resources[i].Limits = proportionalLimits
if len(limitAnnotations) > 0 {
@ -88,19 +90,19 @@ func GetContainersResources(pod *core.Pod, vpaResourcePolicy *vpa_types.PodResou
resources[i].Limits = core.ResourceList{}
}
cpuRequest, hasCpuRequest := container.Resources.Requests[core.ResourceCPU]
cpuRequest, hasCpuRequest := containerRequests[core.ResourceCPU]
if _, ok := resources[i].Requests[core.ResourceCPU]; !ok && hasCpuRequest {
resources[i].Requests[core.ResourceCPU] = cpuRequest
}
memRequest, hasMemRequest := container.Resources.Requests[core.ResourceMemory]
memRequest, hasMemRequest := containerRequests[core.ResourceMemory]
if _, ok := resources[i].Requests[core.ResourceMemory]; !ok && hasMemRequest {
resources[i].Requests[core.ResourceMemory] = memRequest
}
cpuLimit, hasCpuLimit := container.Resources.Limits[core.ResourceCPU]
cpuLimit, hasCpuLimit := containerLimits[core.ResourceCPU]
if _, ok := resources[i].Limits[core.ResourceCPU]; !ok && hasCpuLimit {
resources[i].Limits[core.ResourceCPU] = cpuLimit
}
memLimit, hasMemLimit := container.Resources.Limits[core.ResourceMemory]
memLimit, hasMemLimit := containerLimits[core.ResourceMemory]
if _, ok := resources[i].Limits[core.ResourceMemory]; !ok && hasMemLimit {
resources[i].Limits[core.ResourceMemory] = memLimit
}

View File

@ -365,6 +365,7 @@ func TestGetContainersResources(t *testing.T) {
testCases := []struct {
name string
container apiv1.Container
containerStatus apiv1.ContainerStatus
vpa *vpa_types.VerticalPodAutoscaler
expectedCPU *resource.Quantity
expectedMem *resource.Quantity
@ -518,11 +519,26 @@ func TestGetContainersResources(t *testing.T) {
expectedMemLimit: mustParseResourcePointer("20M"),
addAll: false,
},
{
name: "Memory only recommendation, request and limits only set in containerStatus, addAll true",
container: test.Container().WithName("container").Get(),
containerStatus: test.ContainerStatus().WithName("container").
WithCPURequest(resource.MustParse("1m")).
WithMemRequest(resource.MustParse("1M")).
WithCPULimit(resource.MustParse("40m")).
WithMemLimit(resource.MustParse("3M")).Get(),
vpa: test.VerticalPodAutoscaler().WithContainer("container").WithTargetResource(apiv1.ResourceMemory, "2M").Get(),
expectedCPU: mustParseResourcePointer("1m"),
expectedMem: mustParseResourcePointer("2M"),
expectedCPULimit: mustParseResourcePointer("40m"),
expectedMemLimit: mustParseResourcePointer("6M"),
addAll: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
pod := test.Pod().WithName("pod").AddContainer(tc.container).Get()
pod := test.Pod().WithName("pod").AddContainer(tc.container).AddContainerStatus(tc.containerStatus).Get()
resources := GetContainersResources(pod, tc.vpa.Spec.ResourcePolicy, *tc.vpa.Status.Recommendation, nil, tc.addAll, vpa_api_util.ContainerToAnnotationsMap{})
cpu, cpuPresent := resources[0].Requests[apiv1.ResourceCPU]