@@ -740,6 +740,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
740
740
kubeDeps .ContainerManager ,
741
741
klet .containerLogManager ,
742
742
klet .runtimeClassManager ,
743
+ klet .allocationManager ,
743
744
seccompDefault ,
744
745
kubeCfg .MemorySwap .SwapBehavior ,
745
746
kubeDeps .ContainerManager .GetNodeAllocatableAbsolute ,
@@ -2886,8 +2887,7 @@ func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontaine
2886
2887
2887
2888
if ! updated {
2888
2889
// Desired resources == allocated resources. Check whether a resize is in progress.
2889
- resizeInProgress := ! allocatedResourcesMatchStatus (allocatedPod , podStatus )
2890
- if resizeInProgress {
2890
+ if kl .isPodResizeInProgress (allocatedPod , podStatus ) {
2891
2891
// If a resize is in progress, make sure the cache has the correct state in case the Kubelet restarted.
2892
2892
kl .statusManager .SetPodResizeStatus (pod .UID , v1 .PodResizeStatusInProgress )
2893
2893
} else {
@@ -2928,11 +2928,11 @@ func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontaine
2928
2928
}
2929
2929
allocatedPod = pod
2930
2930
2931
- // Special case when the updated allocation matches the actual resources. This can occur
2931
+ // Special case when the updated allocation matches the actuated resources. This can occur
2932
2932
// when reverting a resize that hasn't been actuated, or when making an equivalent change
2933
2933
// (such as CPU requests below MinShares). This is an optimization to clear the resize
2934
2934
// status immediately, rather than waiting for the next SyncPod iteration.
2935
- if allocatedResourcesMatchStatus (allocatedPod , podStatus ) {
2935
+ if ! kl . isPodResizeInProgress (allocatedPod , podStatus ) {
2936
2936
// In this case, consider the resize complete.
2937
2937
kl .statusManager .SetPodResizeStatus (pod .UID , "" )
2938
2938
return allocatedPod , nil
@@ -2952,6 +2952,46 @@ func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontaine
2952
2952
return allocatedPod , nil
2953
2953
}
2954
2954
2955
+ // isPodResizingInProgress checks whether the actuated resizable resources differ from the allocated resources
2956
+ // for any running containers. Specifically, the following differences are ignored:
2957
+ // - Non-resizable containers: non-restartable init containers, ephemeral containers
2958
+ // - Non-resizable resources: only CPU & memory are resizable
2959
+ // - Non-actuated resources: memory requests are not actuated
2960
+ // - Non-running containers: they will be sized correctly when (re)started
2961
+ func (kl * Kubelet ) isPodResizeInProgress (allocatedPod * v1.Pod , podStatus * kubecontainer.PodStatus ) bool {
2962
+ return ! podutil .VisitContainers (& allocatedPod .Spec , podutil .InitContainers | podutil .Containers ,
2963
+ func (allocatedContainer * v1.Container , containerType podutil.ContainerType ) (shouldContinue bool ) {
2964
+ if ! isResizableContainer (allocatedContainer , containerType ) {
2965
+ return true
2966
+ }
2967
+
2968
+ containerStatus := podStatus .FindContainerStatusByName (allocatedContainer .Name )
2969
+ if containerStatus == nil || containerStatus .State != kubecontainer .ContainerStateRunning {
2970
+ // If the container isn't running, it doesn't need to be resized.
2971
+ return true
2972
+ }
2973
+
2974
+ actuatedResources , _ := kl .allocationManager .GetActuatedResources (allocatedPod .UID , allocatedContainer .Name )
2975
+ allocatedResources := allocatedContainer .Resources
2976
+
2977
+ // Memory requests are excluded since they don't need to be actuated.
2978
+ return allocatedResources .Requests [v1 .ResourceCPU ].Equal (actuatedResources .Requests [v1 .ResourceCPU ]) &&
2979
+ allocatedResources .Limits [v1 .ResourceCPU ].Equal (actuatedResources .Limits [v1 .ResourceCPU ]) &&
2980
+ allocatedResources .Limits [v1 .ResourceMemory ].Equal (actuatedResources .Limits [v1 .ResourceMemory ])
2981
+ })
2982
+ }
2983
+
2984
+ func isResizableContainer (container * v1.Container , containerType podutil.ContainerType ) bool {
2985
+ switch containerType {
2986
+ case podutil .InitContainers :
2987
+ return podutil .IsRestartableInitContainer (container )
2988
+ case podutil .Containers :
2989
+ return true
2990
+ default :
2991
+ return false
2992
+ }
2993
+ }
2994
+
2955
2995
// LatestLoopEntryTime returns the last time in the sync loop monitor.
2956
2996
func (kl * Kubelet ) LatestLoopEntryTime () time.Time {
2957
2997
val := kl .syncLoopMonitor .Load ()
0 commit comments