mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 13:55:41 +00:00
Merge pull request #120001 from qingwave/hpa-sidecar
HPA: calculate sidecar container resource in pod autoscaler
This commit is contained in:
commit
2b16f7b6bb
@ -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")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user