Skip to content

Commit 4a4748d

Browse files
committed
Determine resize status from state in handlePodResourcesResize
1 parent a28f140 commit 4a4748d

File tree

3 files changed

+66
-30
lines changed

3 files changed

+66
-30
lines changed

pkg/kubelet/kubelet.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType
18281828
// this conveniently retries any Deferred resize requests
18291829
// TODO(vinaykul,InPlacePodVerticalScaling): Investigate doing this in HandlePodUpdates + periodic SyncLoop scan
18301830
// See: https://github.com/kubernetes/kubernetes/pull/102884#discussion_r663160060
1831-
pod, err = kl.handlePodResourcesResize(pod)
1831+
pod, err = kl.handlePodResourcesResize(pod, podStatus)
18321832
if err != nil {
18331833
return false, err
18341834
}
@@ -2793,12 +2793,20 @@ func (kl *Kubelet) canResizePod(pod *v1.Pod) (bool, v1.PodResizeStatus) {
27932793
return true, v1.PodResizeStatusInProgress
27942794
}
27952795

2796-
func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod) (*v1.Pod, error) {
2796+
// handlePodResourcesResize returns the "allocated pod", which should be used for all resource
2797+
// calculations after this function is called. It also updates the cached ResizeStatus according to
2798+
// the allocation decision and pod status.
2799+
func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (*v1.Pod, error) {
27972800
allocatedPod, updated := kl.statusManager.UpdatePodFromAllocation(pod)
27982801
if !updated {
2799-
// Unless a resize is in-progress, clear the resize status.
2800-
resizeStatus, _ := kl.statusManager.GetPodResizeStatus(string(pod.UID))
2801-
if resizeStatus != v1.PodResizeStatusInProgress {
2802+
resizeInProgress := !allocatedResourcesMatchStatus(allocatedPod, podStatus)
2803+
if resizeInProgress {
2804+
// If a resize in progress, make sure the cache has the correct state in case the Kubelet restarted.
2805+
if err := kl.statusManager.SetPodResizeStatus(pod.UID, v1.PodResizeStatusInProgress); err != nil {
2806+
klog.ErrorS(err, "Failed to set resize status to InProgress", "pod", format.Pod(pod))
2807+
}
2808+
} else {
2809+
// (Desired == Allocated == Actual) => clear the resize status.
28022810
if err := kl.statusManager.SetPodResizeStatus(pod.UID, ""); err != nil {
28032811
klog.ErrorS(err, "Failed to clear resize status", "pod", format.Pod(pod))
28042812
}
@@ -2819,10 +2827,8 @@ func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod) (*v1.Pod, error) {
28192827
allocatedPod = pod
28202828
}
28212829
if resizeStatus != "" {
2822-
// Save resize decision to checkpoint
2823-
if err := kl.statusManager.SetPodResizeStatus(allocatedPod.UID, resizeStatus); err != nil {
2824-
//TODO(vinaykul,InPlacePodVerticalScaling): Can we recover from this in some way? Investigate
2825-
klog.ErrorS(err, "SetPodResizeStatus failed", "pod", klog.KObj(allocatedPod))
2830+
if err := kl.statusManager.SetPodResizeStatus(pod.UID, resizeStatus); err != nil {
2831+
klog.ErrorS(err, "Failed to set resize status", "pod", format.Pod(pod), "resizeStatus", resizeStatus)
28262832
}
28272833
}
28282834
return allocatedPod, nil

pkg/kubelet/kubelet_pods.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,15 +1757,6 @@ func (kl *Kubelet) determinePodResizeStatus(allocatedPod *v1.Pod, podStatus *kub
17571757
}
17581758

17591759
resizeStatus, _ := kl.statusManager.GetPodResizeStatus(string(allocatedPod.UID))
1760-
// If the resize was in-progress and the actual resources match the allocated resources, mark
1761-
// the resize as complete by clearing the resize status.
1762-
if resizeStatus == v1.PodResizeStatusInProgress &&
1763-
allocatedResourcesMatchStatus(allocatedPod, podStatus) {
1764-
if err := kl.statusManager.SetPodResizeStatus(allocatedPod.UID, ""); err != nil {
1765-
klog.ErrorS(err, "SetPodResizeStatus failed", "pod", format.Pod(allocatedPod))
1766-
}
1767-
return ""
1768-
}
17691760
return resizeStatus
17701761
}
17711762

pkg/kubelet/kubelet_test.go

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,11 +2665,12 @@ func TestHandlePodResourcesResize(t *testing.T) {
26652665
defer kubelet.podManager.RemovePod(testPod1)
26662666

26672667
tests := []struct {
2668-
name string
2669-
pod *v1.Pod
2670-
newRequests v1.ResourceList
2671-
expectedAllocations v1.ResourceList
2672-
expectedResize v1.PodResizeStatus
2668+
name string
2669+
pod *v1.Pod
2670+
newRequests v1.ResourceList
2671+
newRequestsAllocated bool // Whether the new requests have already been allocated (but not actuated)
2672+
expectedAllocations v1.ResourceList
2673+
expectedResize v1.PodResizeStatus
26732674
}{
26742675
{
26752676
name: "Request CPU and memory decrease - expect InProgress",
@@ -2720,25 +2721,63 @@ func TestHandlePodResourcesResize(t *testing.T) {
27202721
expectedAllocations: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
27212722
expectedResize: v1.PodResizeStatusInfeasible,
27222723
},
2724+
{
2725+
name: "CPU increase in progress - expect InProgress",
2726+
pod: testPod2,
2727+
newRequests: v1.ResourceList{v1.ResourceCPU: cpu1500m, v1.ResourceMemory: mem1000M},
2728+
newRequestsAllocated: true,
2729+
expectedAllocations: v1.ResourceList{v1.ResourceCPU: cpu1500m, v1.ResourceMemory: mem1000M},
2730+
expectedResize: v1.PodResizeStatusInProgress,
2731+
},
2732+
{
2733+
name: "No resize",
2734+
pod: testPod2,
2735+
newRequests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
2736+
expectedAllocations: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M},
2737+
expectedResize: "",
2738+
},
27232739
}
27242740

27252741
for _, tt := range tests {
27262742
t.Run(tt.name, func(t *testing.T) {
27272743
kubelet.statusManager = status.NewFakeManager()
2728-
require.NoError(t, kubelet.statusManager.SetPodAllocation(tt.pod))
27292744

2730-
pod := tt.pod.DeepCopy()
2731-
pod.Spec.Containers[0].Resources.Requests = tt.newRequests
2732-
updatedPod, err := kubelet.handlePodResourcesResize(pod)
2745+
newPod := tt.pod.DeepCopy()
2746+
newPod.Spec.Containers[0].Resources.Requests = tt.newRequests
2747+
2748+
if !tt.newRequestsAllocated {
2749+
require.NoError(t, kubelet.statusManager.SetPodAllocation(tt.pod))
2750+
} else {
2751+
require.NoError(t, kubelet.statusManager.SetPodAllocation(newPod))
2752+
}
2753+
2754+
podStatus := &kubecontainer.PodStatus{
2755+
ID: tt.pod.UID,
2756+
Name: tt.pod.Name,
2757+
Namespace: tt.pod.Namespace,
2758+
ContainerStatuses: make([]*kubecontainer.Status, len(tt.pod.Spec.Containers)),
2759+
}
2760+
for i, c := range tt.pod.Spec.Containers {
2761+
podStatus.ContainerStatuses[i] = &kubecontainer.Status{
2762+
Name: c.Name,
2763+
State: kubecontainer.ContainerStateRunning,
2764+
Resources: &kubecontainer.ContainerResources{
2765+
CPURequest: c.Resources.Requests.Cpu(),
2766+
CPULimit: c.Resources.Limits.Cpu(),
2767+
MemoryLimit: c.Resources.Limits.Memory(),
2768+
},
2769+
}
2770+
}
2771+
2772+
updatedPod, err := kubelet.handlePodResourcesResize(newPod, podStatus)
27332773
require.NoError(t, err)
27342774
assert.Equal(t, tt.expectedAllocations, updatedPod.Spec.Containers[0].Resources.Requests, "updated pod spec resources")
27352775

2736-
alloc, found := kubelet.statusManager.GetContainerResourceAllocation(string(pod.UID), pod.Spec.Containers[0].Name)
2776+
alloc, found := kubelet.statusManager.GetContainerResourceAllocation(string(newPod.UID), newPod.Spec.Containers[0].Name)
27372777
require.True(t, found, "container allocation")
27382778
assert.Equal(t, tt.expectedAllocations, alloc.Requests, "stored container allocation")
27392779

2740-
resizeStatus, found := kubelet.statusManager.GetPodResizeStatus(string(pod.UID))
2741-
require.True(t, found, "pod resize status")
2780+
resizeStatus, _ := kubelet.statusManager.GetPodResizeStatus(string(newPod.UID))
27422781
assert.Equal(t, tt.expectedResize, resizeStatus)
27432782
})
27442783
}

0 commit comments

Comments
 (0)