Skip to content

Commit a15520f

Browse files
committed
Move pod resize status to pod conditions
1 parent e950e51 commit a15520f

File tree

24 files changed

+596
-140
lines changed

24 files changed

+596
-140
lines changed

api/openapi-spec/swagger.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/openapi-spec/v3/api__v1_openapi.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/pod/testing/make.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,6 @@ func MakeContainerStatus(name string, allocatedResources api.ResourceList) api.C
336336
return cs
337337
}
338338

339-
func SetResizeStatus(resizeStatus api.PodResizeStatus) TweakPodStatus {
340-
return func(podstatus *api.PodStatus) {
341-
podstatus.Resize = resizeStatus
342-
}
343-
}
344-
345339
// TweakContainers applies the container tweaks to all containers (regular & init) in the pod.
346340
// Note: this should typically be added to pod tweaks after all containers have been added.
347341
func TweakContainers(tweaks ...TweakContainer) Tweak {

pkg/api/pod/util.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ func dropDisabledPodStatusFields(podStatus, oldPodStatus *api.PodStatus, podSpec
791791
}
792792

793793
if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) && !inPlacePodVerticalScalingInUse(oldPodSpec) {
794-
// Drop Resize and Resources fields
794+
// Drop Resources fields
795795
dropResourcesField := func(csl []api.ContainerStatus) {
796796
for i := range csl {
797797
csl[i].Resources = nil
@@ -800,7 +800,6 @@ func dropDisabledPodStatusFields(podStatus, oldPodStatus *api.PodStatus, podSpec
800800
dropResourcesField(podStatus.ContainerStatuses)
801801
dropResourcesField(podStatus.InitContainerStatuses)
802802
dropResourcesField(podStatus.EphemeralContainerStatuses)
803-
podStatus.Resize = ""
804803
}
805804
if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) ||
806805
!utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingAllocatedStatus) {

pkg/api/pod/util_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2675,7 +2675,6 @@ func TestDropInPlacePodVerticalScaling(t *testing.T) {
26752675
},
26762676
},
26772677
Status: api.PodStatus{
2678-
Resize: api.PodResizeStatusInProgress,
26792678
ContainerStatuses: []api.ContainerStatus{
26802679
{
26812680
Name: "c1",

pkg/apis/core/types.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2951,6 +2951,17 @@ const (
29512951
// DisruptionTarget indicates the pod is about to be terminated due to a
29522952
// disruption (such as preemption, eviction API or garbage-collection).
29532953
DisruptionTarget PodConditionType = "DisruptionTarget"
2954+
// PodResizePending indicates that the pod has been resized, but kubelet has not
2955+
// yet allocated the resources. If both PodResizePending and PodResizeInProgress
2956+
// are set, it means that a new resize was requested in the middle of a previous
2957+
// pod resize that is still in progress.
2958+
PodResizePending PodConditionType = "PodResizePending"
2959+
// PodResizeInProgress indicates that a resize is in progress, and is present whenever
2960+
// the Kubelet has allocated resources for the resize, but has not yet actuated all of
2961+
// the required changes.
2962+
// If both PodResizePending and PodResizeInProgress are set, it means that a new resize was
2963+
// requested in the middle of a previous pod resize that is still in progress.
2964+
PodResizeInProgress PodConditionType = "PodResizeInProgress"
29542965
)
29552966

29562967
// PodCondition represents pod's condition
@@ -2970,7 +2981,7 @@ type PodCondition struct {
29702981
Message string
29712982
}
29722983

2973-
// PodResizeStatus shows status of desired resize of a pod's containers.
2984+
// Deprecated: PodResizeStatus shows status of desired resize of a pod's containers.
29742985
type PodResizeStatus string
29752986

29762987
const (
@@ -4251,6 +4262,9 @@ type PodStatus struct {
42514262
// Status of resources resize desired for pod's containers.
42524263
// It is empty if no resources resize is pending.
42534264
// Any changes to container resources will automatically set this to "Proposed"
4265+
// Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress.
4266+
// PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources.
4267+
// PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources.
42544268
// +featureGate=InPlacePodVerticalScaling
42554269
// +optional
42564270
Resize PodResizeStatus

pkg/generated/openapi/zz_generated.openapi.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/kubelet/kubelet.go

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2863,21 +2863,23 @@ func (kl *Kubelet) HandlePodSyncs(pods []*v1.Pod) {
28632863

28642864
// canResizePod determines if the requested resize is currently feasible.
28652865
// pod should hold the desired (pre-allocated) spec.
2866-
// Returns true if the resize can proceed.
2867-
func (kl *Kubelet) canResizePod(pod *v1.Pod) (bool, v1.PodResizeStatus, string) {
2866+
// Returns true if the resize can proceed; returns a reason and message
2867+
// otherwise.
2868+
func (kl *Kubelet) canResizePod(pod *v1.Pod) (bool, string, string) {
28682869
if v1qos.GetPodQOS(pod) == v1.PodQOSGuaranteed && !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingExclusiveCPUs) {
28692870
if utilfeature.DefaultFeatureGate.Enabled(features.CPUManager) {
28702871
if kl.containerManager.GetNodeConfig().CPUManagerPolicy == "static" {
28712872
msg := "Resize is infeasible for Guaranteed Pods alongside CPU Manager static policy"
28722873
klog.V(3).InfoS(msg, "pod", format.Pod(pod))
2873-
return false, v1.PodResizeStatusInfeasible, msg
2874+
return false, v1.PodReasonInfeasible, msg
28742875
}
28752876
}
28762877
if utilfeature.DefaultFeatureGate.Enabled(features.MemoryManager) {
28772878
if kl.containerManager.GetNodeConfig().MemoryManagerPolicy == "Static" {
28782879
msg := "Resize is infeasible for Guaranteed Pods alongside Memory Manager static policy"
28792880
klog.V(3).InfoS(msg, "pod", format.Pod(pod))
2880-
return false, v1.PodResizeStatusInfeasible, msg
2881+
return false, v1.PodReasonInfeasible, msg
2882+
28812883
}
28822884
}
28832885
}
@@ -2900,7 +2902,8 @@ func (kl *Kubelet) canResizePod(pod *v1.Pod) (bool, v1.PodResizeStatus, string)
29002902
}
29012903
msg = "Node didn't have enough capacity: " + msg
29022904
klog.V(3).InfoS(msg, "pod", klog.KObj(pod))
2903-
return false, v1.PodResizeStatusInfeasible, msg
2905+
return false, v1.PodReasonInfeasible, msg
2906+
29042907
}
29052908

29062909
// Treat the existing pod needing resize as a new pod with desired resources seeking admit.
@@ -2911,83 +2914,75 @@ func (kl *Kubelet) canResizePod(pod *v1.Pod) (bool, v1.PodResizeStatus, string)
29112914
if ok, failReason, failMessage := kl.canAdmitPod(allocatedPods, pod); !ok {
29122915
// Log reason and return. Let the next sync iteration retry the resize
29132916
klog.V(3).InfoS("Resize cannot be accommodated", "pod", klog.KObj(pod), "reason", failReason, "message", failMessage)
2914-
return false, v1.PodResizeStatusDeferred, failMessage
2917+
return false, v1.PodReasonDeferred, failMessage
29152918
}
29162919

2917-
return true, v1.PodResizeStatusInProgress, ""
2920+
return true, "", ""
29182921
}
29192922

29202923
// handlePodResourcesResize returns the "allocated pod", which should be used for all resource
29212924
// calculations after this function is called. It also updates the cached ResizeStatus according to
29222925
// the allocation decision and pod status.
2923-
func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (*v1.Pod, error) {
2924-
allocatedPod, updated := kl.allocationManager.UpdatePodFromAllocation(pod)
2925-
2926-
if !updated {
2927-
// Desired resources == allocated resources. Check whether a resize is in progress.
2926+
func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (allocatedPod *v1.Pod, err error) {
2927+
// Always check whether a resize is in progress so we can set the PodResizeInProgressCondition
2928+
// accordingly.
2929+
defer func() {
2930+
if err != nil {
2931+
return
2932+
}
29282933
if kl.isPodResizeInProgress(allocatedPod, podStatus) {
29292934
// If a resize is in progress, make sure the cache has the correct state in case the Kubelet restarted.
2930-
kl.statusManager.SetPodResizeStatus(pod.UID, v1.PodResizeStatusInProgress)
2935+
kl.statusManager.SetPodResizeInProgressCondition(pod.UID, "", "")
29312936
} else {
2932-
// (Desired == Allocated == Actual) => clear the resize status.
2933-
kl.statusManager.SetPodResizeStatus(pod.UID, "")
2937+
// (Allocated == Actual) => clear the resize in-progress status.
2938+
kl.statusManager.ClearPodResizeInProgressCondition(pod.UID)
29342939
}
2935-
// Pod allocation does not need to be updated.
2936-
return allocatedPod, nil
2940+
}()
2941+
2942+
podFromAllocation, updated := kl.allocationManager.UpdatePodFromAllocation(pod)
2943+
if !updated {
2944+
// Desired resources == allocated resources. Pod allocation does not need to be updated.
2945+
kl.statusManager.ClearPodResizePendingCondition(pod.UID)
2946+
return podFromAllocation, nil
2947+
29372948
} else if resizable, msg := kuberuntime.IsInPlacePodVerticalScalingAllowed(pod); !resizable {
29382949
// If there is a pending resize but the resize is not allowed, always use the allocated resources.
2939-
kl.recorder.Eventf(pod, v1.EventTypeWarning, events.ResizeInfeasible, msg)
2940-
kl.statusManager.SetPodResizeStatus(pod.UID, v1.PodResizeStatusInfeasible)
2941-
return allocatedPod, nil
2950+
kl.statusManager.SetPodResizePendingCondition(pod.UID, v1.PodReasonInfeasible, msg)
2951+
return podFromAllocation, nil
29422952
}
29432953

29442954
kl.podResizeMutex.Lock()
29452955
defer kl.podResizeMutex.Unlock()
29462956
// Desired resources != allocated resources. Can we update the allocation to the desired resources?
2947-
fit, resizeStatus, resizeMsg := kl.canResizePod(pod)
2957+
fit, reason, message := kl.canResizePod(pod)
29482958
if fit {
29492959
// Update pod resource allocation checkpoint
29502960
if err := kl.allocationManager.SetAllocatedResources(pod); err != nil {
29512961
return nil, err
29522962
}
2963+
kl.statusManager.ClearPodResizePendingCondition(pod.UID)
29532964
for i, container := range pod.Spec.Containers {
2954-
if !apiequality.Semantic.DeepEqual(container.Resources, allocatedPod.Spec.Containers[i].Resources) {
2965+
if !apiequality.Semantic.DeepEqual(container.Resources, podFromAllocation.Spec.Containers[i].Resources) {
29552966
key := kuberuntime.GetStableKey(pod, &container)
29562967
kl.crashLoopBackOff.Reset(key)
29572968
}
29582969
}
29592970
for i, container := range pod.Spec.InitContainers {
29602971
if podutil.IsRestartableInitContainer(&container) {
2961-
if !apiequality.Semantic.DeepEqual(container.Resources, allocatedPod.Spec.InitContainers[i].Resources) {
2972+
if !apiequality.Semantic.DeepEqual(container.Resources, podFromAllocation.Spec.InitContainers[i].Resources) {
29622973
key := kuberuntime.GetStableKey(pod, &container)
29632974
kl.crashLoopBackOff.Reset(key)
29642975
}
29652976
}
29662977
}
2967-
allocatedPod = pod
2968-
2969-
// Special case when the updated allocation matches the actuated resources. This can occur
2970-
// when reverting a resize that hasn't been actuated, or when making an equivalent change
2971-
// (such as CPU requests below MinShares). This is an optimization to clear the resize
2972-
// status immediately, rather than waiting for the next SyncPod iteration.
2973-
if !kl.isPodResizeInProgress(allocatedPod, podStatus) {
2974-
// In this case, consider the resize complete.
2975-
kl.statusManager.SetPodResizeStatus(pod.UID, "")
2976-
return allocatedPod, nil
2977-
}
2978-
}
2979-
if resizeStatus != "" {
2980-
kl.statusManager.SetPodResizeStatus(pod.UID, resizeStatus)
2981-
if resizeMsg != "" {
2982-
switch resizeStatus {
2983-
case v1.PodResizeStatusDeferred:
2984-
kl.recorder.Eventf(pod, v1.EventTypeWarning, events.ResizeDeferred, resizeMsg)
2985-
case v1.PodResizeStatusInfeasible:
2986-
kl.recorder.Eventf(pod, v1.EventTypeWarning, events.ResizeInfeasible, resizeMsg)
2987-
}
2988-
}
2978+
return pod, nil
2979+
}
2980+
2981+
if reason != "" {
2982+
kl.statusManager.SetPodResizePendingCondition(pod.UID, reason, message)
29892983
}
2990-
return allocatedPod, nil
2984+
2985+
return podFromAllocation, nil
29912986
}
29922987

29932988
// isPodResizingInProgress checks whether the actuated resizable resources differ from the allocated resources

pkg/kubelet/kubelet_pods.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,14 +1738,15 @@ func getPhase(pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal bool) v1.Pod
17381738
}
17391739
}
17401740

1741-
func (kl *Kubelet) determinePodResizeStatus(allocatedPod *v1.Pod, podStatus *kubecontainer.PodStatus, podIsTerminal bool) v1.PodResizeStatus {
1741+
func (kl *Kubelet) determinePodResizeStatus(allocatedPod *v1.Pod, podIsTerminal bool) []*v1.PodCondition {
17421742
// If pod is terminal, clear the resize status.
17431743
if podIsTerminal {
1744-
kl.statusManager.SetPodResizeStatus(allocatedPod.UID, "")
1745-
return ""
1744+
kl.statusManager.ClearPodResizeInProgressCondition(allocatedPod.UID)
1745+
kl.statusManager.ClearPodResizePendingCondition(allocatedPod.UID)
1746+
return nil
17461747
}
17471748

1748-
resizeStatus := kl.statusManager.GetPodResizeStatus(allocatedPod.UID)
1749+
resizeStatus := kl.statusManager.GetPodResizeConditions(allocatedPod.UID)
17491750
return resizeStatus
17501751
}
17511752

@@ -1759,9 +1760,6 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po
17591760
oldPodStatus = pod.Status
17601761
}
17611762
s := kl.convertStatusToAPIStatus(pod, podStatus, oldPodStatus)
1762-
if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) {
1763-
s.Resize = kl.determinePodResizeStatus(pod, podStatus, podIsTerminal)
1764-
}
17651763
// calculate the next phase and preserve reason
17661764
allStatus := append(append([]v1.ContainerStatus{}, s.ContainerStatuses...), s.InitContainerStatuses...)
17671765
s.Phase = getPhase(pod, allStatus, podIsTerminal)
@@ -1827,6 +1825,12 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po
18271825
s.Conditions = append(s.Conditions, c)
18281826
}
18291827
}
1828+
if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) {
1829+
resizeStatus := kl.determinePodResizeStatus(pod, podIsTerminal)
1830+
for _, c := range resizeStatus {
1831+
s.Conditions = append(s.Conditions, *c)
1832+
}
1833+
}
18301834

18311835
// copy over the pod disruption conditions from state which is already
18321836
// updated during the eviciton (due to either node resource pressure or

pkg/kubelet/kubelet_pods_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3881,7 +3881,6 @@ func Test_generateAPIPodStatusForInPlaceVPAEnabled(t *testing.T) {
38813881
AllocatedResources: CPU1AndMem1GAndStorage2GAndCustomResource,
38823882
},
38833883
},
3884-
Resize: "InProgress",
38853884
},
38863885
},
38873886
},
@@ -3912,7 +3911,6 @@ func Test_generateAPIPodStatusForInPlaceVPAEnabled(t *testing.T) {
39123911
AllocatedResources: CPU1AndMem1GAndStorage2G,
39133912
},
39143913
},
3915-
Resize: "InProgress",
39163914
},
39173915
},
39183916
},
@@ -3926,9 +3924,10 @@ func Test_generateAPIPodStatusForInPlaceVPAEnabled(t *testing.T) {
39263924
oldStatus := test.pod.Status
39273925
kl.statusManager.SetPodStatus(test.pod, oldStatus)
39283926
actual := kl.generateAPIPodStatus(test.pod, &testKubecontainerPodStatus /* criStatus */, false /* test.isPodTerminal */)
3929-
3930-
if actual.Resize != "" {
3931-
t.Fatalf("Unexpected Resize status: %s", actual.Resize)
3927+
for _, c := range actual.Conditions {
3928+
if c.Type == v1.PodResizePending || c.Type == v1.PodResizeInProgress {
3929+
t.Fatalf("unexpected resize status: %v", c)
3930+
}
39323931
}
39333932
})
39343933
}

0 commit comments

Comments
 (0)