Merge pull request #120001 from qingwave/hpa-sidecar
HPA: calculate sidecar container resource in pod autoscaler
This commit is contained in:
		@@ -425,7 +425,14 @@ func calculatePodRequests(pods []*v1.Pod, container string, resource v1.Resource
 | 
				
			|||||||
	requests := make(map[string]int64, len(pods))
 | 
						requests := make(map[string]int64, len(pods))
 | 
				
			||||||
	for _, pod := range pods {
 | 
						for _, pod := range pods {
 | 
				
			||||||
		podSum := int64(0)
 | 
							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 container == "" || container == c.Name {
 | 
				
			||||||
				if containerRequest, ok := c.Resources.Requests[resource]; ok {
 | 
									if containerRequest, ok := c.Resources.Requests[resource]; ok {
 | 
				
			||||||
					podSum += containerRequest.MilliValue()
 | 
										podSum += containerRequest.MilliValue()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user