Extract isInPlacePodVerticalScalingAllowed to shared function

This commit is contained in:
Tim Allclair 2025-01-28 15:18:55 -08:00
parent 460db5c137
commit 523a19aa44
7 changed files with 94 additions and 37 deletions

View File

@ -2873,19 +2873,8 @@ func (kl *Kubelet) canResizePod(pod *v1.Pod) (bool, v1.PodResizeStatus, string)
// the allocation decision and pod status.
func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (*v1.Pod, error) {
allocatedPod, updated := kl.allocationManager.UpdatePodFromAllocation(pod)
// Keep this logic in sync with kuberuntime.isInPlacePodVerticalScalingAllowed
if goos == "windows" || kubetypes.IsStaticPod(pod) {
if resizable, msg := kuberuntime.IsInPlacePodVerticalScalingAllowed(pod); !resizable {
if updated {
// A resize is requested but not supported.
var msg string
switch {
case goos == "windows":
msg = "Resizing Windows pods is not supported"
case kubetypes.IsStaticPod(pod):
msg = "Resizing static pods is not supported"
default:
msg = "Resizing this pod is not supported"
}
kl.recorder.Eventf(pod, v1.EventTypeWarning, events.ResizeInfeasible, msg)
kl.statusManager.SetPodResizeStatus(pod.UID, v1.PodResizeStatusInfeasible)
} else {

View File

@ -2711,7 +2711,6 @@ func TestHandlePodResourcesResize(t *testing.T) {
expectedAllocatedLims v1.ResourceList
expectedResize v1.PodResizeStatus
expectBackoffReset bool
goos string
annotations map[string]string
}{
{
@ -2781,14 +2780,6 @@ func TestHandlePodResourcesResize(t *testing.T) {
expectedAllocatedReqs: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
expectedResize: "",
},
{
name: "windows node, expect Infeasible",
originalRequests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
newRequests: v1.ResourceList{v1.ResourceCPU: cpu500m, v1.ResourceMemory: mem500M},
expectedAllocatedReqs: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
expectedResize: v1.PodResizeStatusInfeasible,
goos: "windows",
},
{
name: "static pod, expect Infeasible",
originalRequests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
@ -2882,11 +2873,6 @@ func TestHandlePodResourcesResize(t *testing.T) {
for _, tt := range tests {
for _, isSidecarContainer := range []bool{false, true} {
t.Run(tt.name, func(t *testing.T) {
oldGOOS := goos
defer func() { goos = oldGOOS }()
if tt.goos != "" {
goos = tt.goos
}
kubelet.statusManager = status.NewFakeManager()
var originalPod *v1.Pod

View File

@ -0,0 +1,37 @@
//go:build linux
// +build linux
/*
Copyright 2025 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kuberuntime
import (
v1 "k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
)
func IsInPlacePodVerticalScalingAllowed(pod *v1.Pod) (allowed bool, msg string) {
if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) {
return false, "InPlacePodVerticalScaling is disabled"
}
if kubetypes.IsStaticPod(pod) {
return false, "In-place resize of static-pods is not supported"
}
return true, ""
}

View File

@ -0,0 +1,26 @@
//go:build !linux && !windows
// +build !linux,!windows
/*
Copyright 2025 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kuberuntime
import v1 "k8s.io/api/core/v1"
func IsInPlacePodVerticalScalingAllowed(_ *v1.Pod) (allowed bool, msg string) {
return false, "In-place pod resize is not supported on this node"
}

View File

@ -0,0 +1,26 @@
//go:build windows
// +build windows
/*
Copyright 2025 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kuberuntime
import v1 "k8s.io/api/core/v1"
func IsInPlacePodVerticalScalingAllowed(_ *v1.Pod) (allowed bool, msg string) {
return false, "In-place pod resize is not supported on Windows"
}

View File

@ -1164,7 +1164,7 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, pod
}
}
if IsInPlacePodVerticalScalingAllowed(pod) && !m.computePodResizeAction(pod, i, true, status, changes) {
if !m.computePodResizeAction(pod, i, true, status, changes) {
// computePodResizeAction updates 'changes' if resize policy requires restarting this container
break
}

View File

@ -22,7 +22,6 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"sort"
"time"
@ -551,17 +550,11 @@ func containerSucceeded(c *v1.Container, podStatus *kubecontainer.PodStatus) boo
return cStatus.State == kubecontainer.ContainerStateExited && cStatus.ExitCode == 0
}
func isInPlacePodVerticalScalingAllowed(pod *v1.Pod) bool {
return utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) &&
!types.IsStaticPod(pod) &&
runtime.GOOS != "windows"
}
// computePodResizeAction determines the actions required (if any) to resize the given container.
// Returns whether to keep (true) or restart (false) the container.
// TODO(vibansal): Make this function to be agnostic to whether it is dealing with a restartable init container or not (i.e. remove the argument `isRestartableInitContainer`).
func (m *kubeGenericRuntimeManager) computePodResizeAction(pod *v1.Pod, containerIdx int, isRestartableInitContainer bool, kubeContainerStatus *kubecontainer.Status, changes *podActions) (keepContainer bool) {
if !isInPlacePodVerticalScalingAllowed(pod) {
if resizable, _ := IsInPlacePodVerticalScalingAllowed(pod); !resizable {
return true
}
@ -998,7 +991,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod *
}
}
if isInPlacePodVerticalScalingAllowed(pod) {
if resizable, _ := IsInPlacePodVerticalScalingAllowed(pod); resizable {
changes.ContainersToUpdate = make(map[v1.ResourceName][]containerToUpdateInfo)
}
@ -1414,7 +1407,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po
}
// Step 7: For containers in podContainerChanges.ContainersToUpdate[CPU,Memory] list, invoke UpdateContainerResources
if isInPlacePodVerticalScalingAllowed(pod) {
if resizable, _ := IsInPlacePodVerticalScalingAllowed(pod); resizable {
if len(podContainerChanges.ContainersToUpdate) > 0 || podContainerChanges.UpdatePodResources {
m.doPodResizeAction(pod, podContainerChanges, &result)
}