Skip to content

Commit a2ddde8

Browse files
committed
Adding the logic to set default pod-level request as following:
1. If pod-level limit is set, pod-level request is unset and container-level request is set: derive pod-level request from container-level requests 2. If pod-level limit is set, pod-level request is unset and container-level request is unset: set pod-level request equal to pod-level limit
1 parent 502e0f5 commit a2ddde8

File tree

5 files changed

+1574
-22
lines changed

5 files changed

+1574
-22
lines changed

pkg/apis/core/v1/defaults.go

+61
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"k8s.io/apimachinery/pkg/runtime"
2626
"k8s.io/apimachinery/pkg/util/intstr"
2727
utilfeature "k8s.io/apiserver/pkg/util/feature"
28+
resourcehelper "k8s.io/component-helpers/resource"
2829
"k8s.io/kubernetes/pkg/api/v1/service"
2930
"k8s.io/kubernetes/pkg/features"
3031
"k8s.io/kubernetes/pkg/util/parsers"
@@ -217,6 +218,13 @@ func SetDefaults_Pod(obj *v1.Pod) {
217218
}
218219
}
219220
}
221+
222+
// Pod Requests default values must be applied after container-level default values
223+
// have been populated.
224+
if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) {
225+
defaultPodRequests(obj)
226+
}
227+
220228
if obj.Spec.EnableServiceLinks == nil {
221229
enableServiceLinks := v1.DefaultEnableServiceLinks
222230
obj.Spec.EnableServiceLinks = &enableServiceLinks
@@ -438,3 +446,56 @@ func SetDefaults_PodLogOptions(obj *v1.PodLogOptions) {
438446
}
439447
}
440448
}
449+
450+
// defaultPodRequests applies default values for pod-level requests, only when
451+
// pod-level limits are set, in following scenarios:
452+
// 1. When at least one container (regular, init or sidecar) has requests set:
453+
// The pod-level requests become equal to the effective requests of all containers
454+
// in the pod.
455+
// 2. When no containers have requests set: The pod-level requests become equal to
456+
// pod-level limits.
457+
// This defaulting behavior ensures consistent resource accounting at the pod-level
458+
// while maintaining compatibility with the container-level specifications, as detailed
459+
// in KEP-2837: https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2837-pod-level-resource-spec/README.md#proposed-validation--defaulting-rules
460+
func defaultPodRequests(obj *v1.Pod) {
461+
// We only populate defaults when the pod-level resources are partly specified already.
462+
if obj.Spec.Resources == nil {
463+
return
464+
}
465+
466+
if len(obj.Spec.Resources.Limits) == 0 {
467+
return
468+
}
469+
470+
var podReqs v1.ResourceList
471+
podReqs = obj.Spec.Resources.Requests
472+
if podReqs == nil {
473+
podReqs = make(v1.ResourceList)
474+
}
475+
476+
aggrCtrReqs := resourcehelper.AggregateContainerRequests(obj, resourcehelper.PodResourcesOptions{})
477+
478+
// When containers specify requests for a resource (supported by
479+
// PodLevelResources feature) and pod-level requests are not set, the pod-level requests
480+
// default to the effective requests of all the containers for that resource.
481+
for key, aggrCtrLim := range aggrCtrReqs {
482+
if _, exists := podReqs[key]; !exists && resourcehelper.IsSupportedPodLevelResource(key) {
483+
podReqs[key] = aggrCtrLim.DeepCopy()
484+
}
485+
}
486+
487+
// When no containers specify requests for a resource, the pod-level requests
488+
// will default to match the pod-level limits, if pod-level
489+
// limits exist for that resource.
490+
for key, podLim := range obj.Spec.Resources.Limits {
491+
if _, exists := podReqs[key]; !exists && resourcehelper.IsSupportedPodLevelResource(key) {
492+
podReqs[key] = podLim.DeepCopy()
493+
}
494+
}
495+
496+
// Only set pod-level resource requests in the PodSpec if the requirements map
497+
// contains entries after collecting container-level requests and pod-level limits.
498+
if len(podReqs) > 0 {
499+
obj.Spec.Resources.Requests = podReqs
500+
}
501+
}

0 commit comments

Comments
 (0)