Skip to content

Commit c292772

Browse files
committed
Consider AllocatableResources when computing pod requests
1 parent aba588c commit c292772

File tree

3 files changed

+88
-36
lines changed

3 files changed

+88
-36
lines changed

staging/src/k8s.io/component-helpers/resource/helpers.go

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,9 @@ func AggregateContainerRequests(pod *v1.Pod, opts PodResourcesOptions) v1.Resour
224224
// determineContainerReqs will return a copy of the container requests based on if resizing is feasible or not.
225225
func determineContainerReqs(pod *v1.Pod, container *v1.Container, cs *v1.ContainerStatus) v1.ResourceList {
226226
if IsPodResizeInfeasible(pod) {
227-
return cs.Resources.Requests.DeepCopy()
227+
return max(cs.Resources.Requests, cs.AllocatedResources)
228228
}
229-
return max(container.Resources.Requests, cs.Resources.Requests)
229+
return max(container.Resources.Requests, cs.Resources.Requests, cs.AllocatedResources)
230230
}
231231

232232
// determineContainerLimits will return a copy of the container limits based on if resizing is feasible or not.
@@ -399,23 +399,12 @@ func maxResourceList(list, newList v1.ResourceList) {
399399
}
400400
}
401401

402-
// max returns the result of max(a, b) for each named resource and is only used if we can't
402+
// max returns the result of max(a, b...) for each named resource and is only used if we can't
403403
// accumulate into an existing resource list
404-
func max(a v1.ResourceList, b v1.ResourceList) v1.ResourceList {
405-
result := v1.ResourceList{}
406-
for key, value := range a {
407-
if other, found := b[key]; found {
408-
if value.Cmp(other) <= 0 {
409-
result[key] = other.DeepCopy()
410-
continue
411-
}
412-
}
413-
result[key] = value.DeepCopy()
414-
}
415-
for key, value := range b {
416-
if _, found := result[key]; !found {
417-
result[key] = value.DeepCopy()
418-
}
404+
func max(a v1.ResourceList, b ...v1.ResourceList) v1.ResourceList {
405+
result := a.DeepCopy()
406+
for _, other := range b {
407+
maxResourceList(result, other)
419408
}
420409
return result
421410
}

staging/src/k8s.io/component-helpers/resource/helpers_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,41 @@ func TestPodResourceRequests(t *testing.T) {
459459
},
460460
},
461461
},
462+
{
463+
description: "resized, infeasible & in-progress",
464+
expectedRequests: v1.ResourceList{
465+
v1.ResourceCPU: resource.MustParse("4"),
466+
},
467+
podResizeStatus: []v1.PodCondition{{
468+
Type: v1.PodResizePending,
469+
Status: v1.ConditionTrue,
470+
Reason: v1.PodReasonInfeasible,
471+
}},
472+
options: PodResourcesOptions{UseStatusResources: true},
473+
containers: []v1.Container{
474+
{
475+
Name: "container-1",
476+
Resources: v1.ResourceRequirements{
477+
Requests: v1.ResourceList{
478+
v1.ResourceCPU: resource.MustParse("6"),
479+
},
480+
},
481+
},
482+
},
483+
containerStatus: []v1.ContainerStatus{
484+
{
485+
Name: "container-1",
486+
AllocatedResources: v1.ResourceList{
487+
v1.ResourceCPU: resource.MustParse("4"),
488+
},
489+
Resources: &v1.ResourceRequirements{
490+
Requests: v1.ResourceList{
491+
v1.ResourceCPU: resource.MustParse("2"),
492+
},
493+
},
494+
},
495+
},
496+
},
462497
{
463498
description: "resized, no resize status",
464499
expectedRequests: v1.ResourceList{
@@ -486,6 +521,45 @@ func TestPodResourceRequests(t *testing.T) {
486521
},
487522
},
488523
},
524+
{
525+
description: "resized: per-resource 3-way maximum",
526+
expectedRequests: v1.ResourceList{
527+
v1.ResourceCPU: resource.MustParse("30m"),
528+
v1.ResourceMemory: resource.MustParse("30M"),
529+
// Note: EphemeralStorage is not resizable, but that doesn't matter for the purposes of this test.
530+
v1.ResourceEphemeralStorage: resource.MustParse("30G"),
531+
},
532+
options: PodResourcesOptions{UseStatusResources: true},
533+
containers: []v1.Container{
534+
{
535+
Name: "container-1",
536+
Resources: v1.ResourceRequirements{
537+
Requests: v1.ResourceList{
538+
v1.ResourceCPU: resource.MustParse("30m"),
539+
v1.ResourceMemory: resource.MustParse("20M"),
540+
v1.ResourceEphemeralStorage: resource.MustParse("10G"),
541+
},
542+
},
543+
},
544+
},
545+
containerStatus: []v1.ContainerStatus{
546+
{
547+
Name: "container-1",
548+
AllocatedResources: v1.ResourceList{
549+
v1.ResourceCPU: resource.MustParse("20m"),
550+
v1.ResourceMemory: resource.MustParse("10M"),
551+
v1.ResourceEphemeralStorage: resource.MustParse("30G"),
552+
},
553+
Resources: &v1.ResourceRequirements{
554+
Requests: v1.ResourceList{
555+
v1.ResourceCPU: resource.MustParse("10m"),
556+
v1.ResourceMemory: resource.MustParse("30M"),
557+
v1.ResourceEphemeralStorage: resource.MustParse("20G"),
558+
},
559+
},
560+
},
561+
},
562+
},
489563
{
490564
description: "resized, infeasible, but don't use status",
491565
expectedRequests: v1.ResourceList{

staging/src/k8s.io/kubectl/pkg/util/resource/resource.go

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,28 +144,17 @@ func podLimits(pod *corev1.Pod) corev1.ResourceList {
144144
// determineContainerReqs will return a copy of the container requests based on if resizing is feasible or not.
145145
func determineContainerReqs(pod *corev1.Pod, container *corev1.Container, cs *corev1.ContainerStatus) corev1.ResourceList {
146146
if helpers.IsPodResizeInfeasible(pod) {
147-
return cs.Resources.Requests.DeepCopy()
147+
return max(cs.Resources.Requests, cs.AllocatedResources)
148148
}
149-
return max(container.Resources.Requests, cs.Resources.Requests)
149+
return max(container.Resources.Requests, cs.Resources.Requests, cs.AllocatedResources)
150150
}
151151

152-
// max returns the result of max(a, b) for each named resource and is only used if we can't
152+
// max returns the result of max(a, b...) for each named resource and is only used if we can't
153153
// accumulate into an existing resource list
154-
func max(a corev1.ResourceList, b corev1.ResourceList) corev1.ResourceList {
155-
result := corev1.ResourceList{}
156-
for key, value := range a {
157-
if other, found := b[key]; found {
158-
if value.Cmp(other) <= 0 {
159-
result[key] = other.DeepCopy()
160-
continue
161-
}
162-
}
163-
result[key] = value.DeepCopy()
164-
}
165-
for key, value := range b {
166-
if _, found := result[key]; !found {
167-
result[key] = value.DeepCopy()
168-
}
154+
func max(a corev1.ResourceList, b ...corev1.ResourceList) corev1.ResourceList {
155+
result := a.DeepCopy()
156+
for _, other := range b {
157+
maxResourceList(result, other)
169158
}
170159
return result
171160
}

0 commit comments

Comments
 (0)