@@ -27,6 +27,7 @@ import (
27
27
utilfeature "k8s.io/apiserver/pkg/util/feature"
28
28
resourcehelper "k8s.io/component-helpers/resource"
29
29
"k8s.io/kubernetes/pkg/api/v1/service"
30
+ corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
30
31
"k8s.io/kubernetes/pkg/features"
31
32
"k8s.io/kubernetes/pkg/util/parsers"
32
33
)
@@ -199,6 +200,7 @@ func SetDefaults_Pod(obj *v1.Pod) {
199
200
// Pod Requests default values must be applied after container-level default values
200
201
// have been populated.
201
202
if utilfeature .DefaultFeatureGate .Enabled (features .PodLevelResources ) {
203
+ defaultHugePagePodLimits (obj )
202
204
defaultPodRequests (obj )
203
205
}
204
206
@@ -456,14 +458,18 @@ func defaultPodRequests(obj *v1.Pod) {
456
458
// PodLevelResources feature) and pod-level requests are not set, the pod-level requests
457
459
// default to the effective requests of all the containers for that resource.
458
460
for key , aggrCtrLim := range aggrCtrReqs {
459
- if _ , exists := podReqs [key ]; ! exists && resourcehelper .IsSupportedPodLevelResource (key ) {
461
+ // Defaulting for pod level hugepages requests takes them directly from the pod limit,
462
+ // hugepages cannot be overcommited and must have the limit, so we skip them here.
463
+ if _ , exists := podReqs [key ]; ! exists && resourcehelper .IsSupportedPodLevelResource (key ) && ! corev1helper .IsHugePageResourceName (key ) {
460
464
podReqs [key ] = aggrCtrLim .DeepCopy ()
461
465
}
462
466
}
463
467
464
468
// When no containers specify requests for a resource, the pod-level requests
465
469
// will default to match the pod-level limits, if pod-level
466
470
// limits exist for that resource.
471
+ // Defaulting for pod level hugepages requests is dependent on defaultHugePagePodLimits,
472
+ // if defaultHugePagePodLimits defined the limit, the request will be set here.
467
473
for key , podLim := range obj .Spec .Resources .Limits {
468
474
if _ , exists := podReqs [key ]; ! exists && resourcehelper .IsSupportedPodLevelResource (key ) {
469
475
podReqs [key ] = podLim .DeepCopy ()
@@ -476,3 +482,44 @@ func defaultPodRequests(obj *v1.Pod) {
476
482
obj .Spec .Resources .Requests = podReqs
477
483
}
478
484
}
485
+
486
+ // defaultHugePagePodLimits applies default values for pod-level limits, only when
487
+ // container hugepage limits are set, but not at pod level, in following
488
+ // scenario:
489
+ // 1. When at least one container (regular, init or sidecar) has hugepage
490
+ // limits set:
491
+ // The pod-level limit becomes equal to the aggregated hugepages limit of all
492
+ // the containers in the pod.
493
+ func defaultHugePagePodLimits (obj * v1.Pod ) {
494
+ // We only populate defaults when the pod-level resources are partly specified already.
495
+ if obj .Spec .Resources == nil {
496
+ return
497
+ }
498
+
499
+ if len (obj .Spec .Resources .Limits ) == 0 && len (obj .Spec .Resources .Requests ) == 0 {
500
+ return
501
+ }
502
+
503
+ var podLims v1.ResourceList
504
+ podLims = obj .Spec .Resources .Limits
505
+ if podLims == nil {
506
+ podLims = make (v1.ResourceList )
507
+ }
508
+
509
+ aggrCtrLims := resourcehelper .AggregateContainerLimits (obj , resourcehelper.PodResourcesOptions {})
510
+
511
+ // When containers specify limits for hugepages and pod-level limits are not
512
+ // set for that resource, the pod-level limit will default to the aggregated
513
+ // hugepages limit of all the containers.
514
+ for key , aggrCtrLim := range aggrCtrLims {
515
+ if _ , exists := podLims [key ]; ! exists && resourcehelper .IsSupportedPodLevelResource (key ) && corev1helper .IsHugePageResourceName (key ) {
516
+ podLims [key ] = aggrCtrLim .DeepCopy ()
517
+ }
518
+ }
519
+
520
+ // Only set pod-level resource limits in the PodSpec if the requirements map
521
+ // contains entries after collecting container-level limits and pod-level limits for hugepages.
522
+ if len (podLims ) > 0 {
523
+ obj .Spec .Resources .Limits = podLims
524
+ }
525
+ }
0 commit comments