Merge pull request #120001 from qingwave/hpa-sidecar

HPA: calculate sidecar container resource in pod autoscaler
This commit is contained in:
Kubernetes Prow Robot 2023-10-23 18:39:31 +02:00 committed by GitHub
commit 2b16f7b6bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 1 deletions

View File

@ -425,7 +425,14 @@ func calculatePodRequests(pods []*v1.Pod, container string, resource v1.Resource
requests := make(map[string]int64, len(pods))
for _, pod := range pods {
podSum := int64(0)
for _, c := range pod.Spec.Containers {
// Calculate all regular containers and restartable init containers requests.
containers := append([]v1.Container{}, pod.Spec.Containers...)
for _, c := range pod.Spec.InitContainers {
if c.RestartPolicy != nil && *c.RestartPolicy == v1.ContainerRestartPolicyAlways {
containers = append(containers, c)
}
}
for _, c := range containers {
if container == "" || container == c.Name {
if containerRequest, ok := c.Resources.Requests[resource]; ok {
podSum += containerRequest.MilliValue()

View File

@ -1999,3 +1999,112 @@ func TestGroupPods(t *testing.T) {
})
}
}
func TestCalculatePodRequests(t *testing.T) {
containerRestartPolicyAlways := v1.ContainerRestartPolicyAlways
testPod := "test-pod"
tests := []struct {
name string
pods []*v1.Pod
container string
resource v1.ResourceName
expectedRequests map[string]int64
expectedError error
}{
{
name: "void",
pods: []*v1.Pod{},
container: "",
resource: v1.ResourceCPU,
expectedRequests: map[string]int64{},
expectedError: nil,
},
{
name: "pod with regular containers",
pods: []*v1.Pod{{
ObjectMeta: metav1.ObjectMeta{
Name: testPod,
Namespace: testNamespace,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{Name: "container1", Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI)}}},
{Name: "container2", Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(50, resource.DecimalSI)}}},
},
},
}},
container: "",
resource: v1.ResourceCPU,
expectedRequests: map[string]int64{testPod: 150},
expectedError: nil,
},
{
name: "calculate requests with special container",
pods: []*v1.Pod{{
ObjectMeta: metav1.ObjectMeta{
Name: testPod,
Namespace: testNamespace,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{Name: "container1", Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI)}}},
{Name: "container2", Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(50, resource.DecimalSI)}}},
},
},
}},
container: "container1",
resource: v1.ResourceCPU,
expectedRequests: map[string]int64{testPod: 100},
expectedError: nil,
},
{
name: "container missing requests",
pods: []*v1.Pod{{
ObjectMeta: metav1.ObjectMeta{
Name: testPod,
Namespace: testNamespace,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{Name: "container1"},
},
},
}},
container: "",
resource: v1.ResourceCPU,
expectedRequests: nil,
expectedError: fmt.Errorf("missing request for %s in container %s of Pod %s", v1.ResourceCPU, "container1", testPod),
},
{
name: "pod with restartable init containers",
pods: []*v1.Pod{{
ObjectMeta: metav1.ObjectMeta{
Name: testPod,
Namespace: testNamespace,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{Name: "container1", Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI)}}},
},
InitContainers: []v1.Container{
{Name: "init-container1", Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(20, resource.DecimalSI)}}},
{Name: "restartable-container1", RestartPolicy: &containerRestartPolicyAlways, Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: *resource.NewMilliQuantity(50, resource.DecimalSI)}}},
},
},
}},
container: "",
resource: v1.ResourceCPU,
expectedRequests: map[string]int64{testPod: 150},
expectedError: nil,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
requests, err := calculatePodRequests(tc.pods, tc.container, tc.resource)
assert.Equal(t, tc.expectedRequests, requests, "requests should be as expected")
assert.Equal(t, tc.expectedError, err, "error should be as expected")
})
}
}