Default pod level hugepage limits

This commit is contained in:
Kevin Torres 2025-02-19 19:36:05 +00:00
parent e5020285fa
commit aa17082a16

View File

@ -27,6 +27,7 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature"
resourcehelper "k8s.io/component-helpers/resource"
"k8s.io/kubernetes/pkg/api/v1/service"
corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/util/parsers"
)
@ -199,6 +200,7 @@ func SetDefaults_Pod(obj *v1.Pod) {
// Pod Requests default values must be applied after container-level default values
// have been populated.
if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) {
defaultHugePagePodLimits(obj)
defaultPodRequests(obj)
}
@ -456,7 +458,9 @@ func defaultPodRequests(obj *v1.Pod) {
// PodLevelResources feature) and pod-level requests are not set, the pod-level requests
// default to the effective requests of all the containers for that resource.
for key, aggrCtrLim := range aggrCtrReqs {
if _, exists := podReqs[key]; !exists && resourcehelper.IsSupportedPodLevelResource(key) {
// Defaulting for pod level hugepages requests takes them directly from the pod limit,
// hugepages cannot be overcommited and must have the limit, so we skip them here.
if _, exists := podReqs[key]; !exists && resourcehelper.IsSupportedPodLevelResource(key) && !corev1helper.IsHugePageResourceName(key) {
podReqs[key] = aggrCtrLim.DeepCopy()
}
}
@ -464,6 +468,8 @@ func defaultPodRequests(obj *v1.Pod) {
// When no containers specify requests for a resource, the pod-level requests
// will default to match the pod-level limits, if pod-level
// limits exist for that resource.
// Defaulting for pod level hugepages requests is dependent on defaultHugePagePodLimits,
// if defaultHugePagePodLimits defined the limit, the request will be set here.
for key, podLim := range obj.Spec.Resources.Limits {
if _, exists := podReqs[key]; !exists && resourcehelper.IsSupportedPodLevelResource(key) {
podReqs[key] = podLim.DeepCopy()
@ -476,3 +482,44 @@ func defaultPodRequests(obj *v1.Pod) {
obj.Spec.Resources.Requests = podReqs
}
}
// defaultHugePagePodLimits applies default values for pod-level limits, only when
// container hugepage limits are set, but not at pod level, in following
// scenario:
// 1. When at least one container (regular, init or sidecar) has hugepage
// limits set:
// The pod-level limit becomes equal to the aggregated hugepages limit of all
// the containers in the pod.
func defaultHugePagePodLimits(obj *v1.Pod) {
// We only populate defaults when the pod-level resources are partly specified already.
if obj.Spec.Resources == nil {
return
}
if len(obj.Spec.Resources.Limits) == 0 && len(obj.Spec.Resources.Requests) == 0 {
return
}
var podLims v1.ResourceList
podLims = obj.Spec.Resources.Limits
if podLims == nil {
podLims = make(v1.ResourceList)
}
aggrCtrLims := resourcehelper.AggregateContainerLimits(obj, resourcehelper.PodResourcesOptions{})
// When containers specify limits for hugepages and pod-level limits are not
// set for that resource, the pod-level limit will default to the aggregated
// hugepages limit of all the containers.
for key, aggrCtrLim := range aggrCtrLims {
if _, exists := podLims[key]; !exists && resourcehelper.IsSupportedPodLevelResource(key) && corev1helper.IsHugePageResourceName(key) {
podLims[key] = aggrCtrLim.DeepCopy()
}
}
// Only set pod-level resource limits in the PodSpec if the requirements map
// contains entries after collecting container-level limits and pod-level limits for hugepages.
if len(podLims) > 0 {
obj.Spec.Resources.Limits = podLims
}
}