@@ -295,36 +295,33 @@ The `ResizePolicy` field is immutable.
295
295
296
296
#### Resize Status
297
297
298
- In addition to the above, a new field ` Pod.Status.Resize[] `
299
- will be added. This field indicates whether kubelet has accepted or rejected a
300
- proposed resize operation for a given resource. Any time the
301
- ` Pod.Spec.Containers[i].Resources.Requests ` field differs from the
302
- ` Pod.Status.ContainerStatuses[i].Resources ` field, this new field explains why.
303
-
304
- This field can be set to one of the following values:
305
- * ` InProgress ` - the proposed resize has been accepted and is being actuated. A ` Deferred ` or
306
- ` Infeasible ` resize will take precedence over ` InProgress ` .
307
- Desired resources == Allocated resources != Actual resources.
298
+ Resize status will be tracked via 2 new pod conditions: ` PodResizePending ` and ` PodResizing ` .
299
+
300
+ ** PodResizePending** will track states where the spec has been resized, but the Kubelet has not yet
301
+ allocated the resources. There are two reasons associated with this condition:
302
+
308
303
* ` Deferred ` - the proposed resize is feasible in theory (it fits on this node)
309
- but is not possible right now; it will be re-evaluated on every pod sync.
310
- Desired resources != Allocated resources.
311
- * ` Infeasible ` - the proposed resize is not feasible and is rejected; it will not
312
- be re-evaluated. Desired resources != Allocated resources.
313
- * (no value) - there is no proposed resize.
314
- Desired resources == Allocated resources == Acutal resources.
315
- * ` Error ` - if an error occurs while actuating the resize (see [ Memory Limit Decreases] ( #memory-limit-decreases )
316
- for an example), then the resize status will be set to ` Error ` and an event will report the
317
- details. The error state behaves similarly to ` InProgress ` , and the allocated resize will be
318
- retried on the next pod sync.
319
-
320
- To make this field future-safe, consumers should assume that any unknown value
321
- means the same as ` Deferred ` .
322
-
323
- Prior to v1.33, the apiserver would populate an additional ` Proposed ` state to identify a new resize
324
- that has not yet been acknowledged by the Kubelet. This state will be deprecated in v1.33 and no
325
- longer populated (due to a race to set it between the apiserver & kubelet). Instead, the new
326
- [ ` ObservedGeneration ` ] ( https://github.com/kubernetes/enhancements/pull/5068 ) feature can be used to
327
- tell whether the resize status includes the latest resize request.
304
+ but is not possible right now; it will be regularly reevaluated.
305
+ * ` Infeasible ` - the proposed resize is not feasible and is rejected; it may not
306
+ be re-evaluated.
307
+
308
+ In either case, the condition's ` message ` will include details of why the resize has not been
309
+ admitted. ` lastTransitionTime ` will be populated with the time the condition was added. ` status `
310
+ will always be ` True ` when the condition is present - if there is no longer a pending resized
311
+ (either the resize was allocated or reverted), the condition will be removed.
312
+
313
+ ** PodResizing** will track in-progress resizes, and should be present whenever allocated resources
314
+ != acknowledged resources (see [ Resource States] ( #resource-states ) ). For successful synchronous
315
+ resizes, this condition should be short lived, and ` reason ` and ` message ` will be left blank. If an
316
+ error occurs while actuating the resize, the ` reason ` will be set to ` Error ` , and ` message ` will be
317
+ populated with the error message. In the future, this condition will also be used for long-running
318
+ resizing behaviors (see [ Memory Limit Decreases] ( #memory-limit-decreases ) ).
319
+
320
+ Note that it is possible for both conditions to be present at the same time, for example if an error
321
+ is encountered while actuating a resize and a new resize comes in that gets deferred.
322
+
323
+ Prior to v1.33, the resize status was tracked by a dedicated ` Pod.Status.Resize ` field. This field
324
+ will be deprecated, and not graduate to beta.
328
325
329
326
#### CRI Changes
330
327
@@ -458,10 +455,10 @@ Spec.Containers[i].Resources.Requests) to the sum.
458
455
Container resource limits. Once all Containers are successfully updated, it
459
456
updates Status...Resources to reflect new resource values and unsets
460
457
Status.Resize.
461
- * If new desired resources don't fit, Kubelet will update the Status.Resize
462
- field to " Infeasible" and does not act on the resize .
463
- * If new desired resources fit but are in-use at the moment, Kubelet will
464
- update the Status.Resize field to "Deferred" .
458
+ * If new desired resources don't fit, Kubelet will add the ` PodResizePending ` condition with type
459
+ ` Infeasible ` and a message explaining why .
460
+ * If new desired resources fit but are in-use at the moment, Kubelet will add the ` PodResizePending `
461
+ condition with type ` Deferred ` and a message explaining why .
465
462
466
463
In addition to the above, kubelet will generate Events on the Pod whenever a
467
464
resize is accepted or rejected, and if possible at key steps during the resize
@@ -513,7 +510,6 @@ This is intentionally hitting various edge-cases for demonstration.
513
510
514
511
1 . kubelet runs the pod and updates the API
515
512
- ` spec.containers[0].resources.requests[cpu] ` = 1
516
- - ` status.resize ` = unset
517
513
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1
518
514
- ` acknowledged[cpu] ` = 1
519
515
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1
@@ -523,7 +519,6 @@ This is intentionally hitting various edge-cases for demonstration.
523
519
- apiserver validates the request (e.g. ` limits ` are not below
524
520
` requests ` , ResourceQuota not exceeded, etc) and accepts the operation
525
521
- ` spec.containers[0].resources.requests[cpu] ` = 1.5
526
- - ` status.resize ` = unset
527
522
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1
528
523
- ` acknowledged[cpu] ` = 1
529
524
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1
@@ -533,82 +528,82 @@ This is intentionally hitting various edge-cases for demonstration.
533
528
- The allocated & acknowledged resources are read back from checkpoint
534
529
- Pods are resynced from the API server, but admitted based on the allocated resources
535
530
- ` spec.containers[0].resources.requests[cpu] ` = 1.5
536
- - ` status.resize ` = unset
537
531
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1
538
532
- ` acknowledged[cpu] ` = 1
539
533
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1
540
534
- actual CPU shares = 1024
541
535
542
536
1 . Kubelet syncs the pod, sees resize #1 and admits it
543
537
- ` spec.containers[0].resources.requests[cpu] ` = 1.5
544
- - ` status.resize ` = ` "InProgress" `
545
538
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.5
546
539
- ` acknowledged[cpu] ` = 1
547
540
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1
541
+ - ` status.conditions[type==PodResizing] ` added
548
542
- actual CPU shares = 1024
549
543
550
544
1 . Resize #2 : cpu = 2
551
545
- apiserver validates the request and accepts the operation
552
546
- ` spec.containers[0].resources.requests[cpu] ` = 2
553
- - ` status.resize ` = ` "InProgress" `
554
547
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.5
555
548
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1
549
+ - ` status.conditions[type==PodResizing] `
556
550
- actual CPU shares = 1024
557
551
558
552
1 . Container runtime applied cpu=1.5
559
553
- ` spec.containers[0].resources.requests[cpu] ` = 2
560
- - ` status.resize ` = ` "InProgress" `
561
554
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.5
562
555
- ` acknowledged[cpu] ` = 1.5
563
556
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1
557
+ - ` status.conditions[type==PodResizing] `
564
558
- actual CPU shares = 1536
565
559
566
560
1 . kubelet syncs the pod, and sees resize #2 (cpu = 2)
567
561
- kubelet decides this is feasible, but currently insufficient available resources
568
562
- ` spec.containers[0].resources.requests[cpu] ` = 2
569
- - ` status.resize[cpu] ` = ` "Deferred" `
570
563
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.5
571
564
- ` acknowledged[cpu] ` = 1.5
572
565
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.5
566
+ - ` status.conditions[type==PodResizePending].type ` = ` "Deferred" `
567
+ - ` status.conditions[type==PodResizing] ` removed
573
568
- actual CPU shares = 1536
574
569
575
570
1 . Resize #3 : cpu = 1.6
576
571
- apiserver validates the request and accepts the operation
577
572
- ` spec.containers[0].resources.requests[cpu] ` = 1.6
578
- - ` status.resize[cpu] ` = ` "Deferred" `
579
573
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.5
580
574
- ` acknowledged[cpu] ` = 1.5
581
575
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.5
576
+ - ` status.conditions[type==PodResizePending].type ` = ` "Deferred" `
582
577
- actual CPU shares = 1536
583
578
584
579
1 . Kubelet syncs the pod, and sees resize #3 and admits it
585
580
- ` spec.containers[0].resources.requests[cpu] ` = 1.6
586
- - ` status.resize[cpu] ` = ` "InProgress" `
587
581
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.6
588
582
- ` acknowledged[cpu] ` = 1.5
589
583
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.5
584
+ - ` status.conditions[type==PodResizePending] ` removed
585
+ - ` status.conditions[type==PodResizing] ` added
590
586
- actual CPU shares = 1536
591
587
592
588
1 . Container runtime applied cpu=1.6
593
589
- ` spec.containers[0].resources.requests[cpu] ` = 1.6
594
- - ` status.resize[cpu] ` = ` "InProgress" `
595
590
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.6
596
591
- ` acknowledged[cpu] ` = 1.6
597
592
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.5
593
+ - ` status.conditions[type==PodResizing] `
598
594
- actual CPU shares = 1638
599
595
600
596
1 . Kubelet syncs the pod
601
597
- ` spec.containers[0].resources.requests[cpu] ` = 1.6
602
- - ` status.resize[cpu] ` = unset
603
598
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.6
604
599
- ` acknowledged[cpu] ` = 1.6
605
600
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.6
601
+ - ` status.conditions[type==PodResizing] ` removed
606
602
- actual CPU shares = 1638
607
603
608
604
1 . Resize #4 : cpu = 100
609
605
- apiserver validates the request and accepts the operation
610
606
- ` spec.containers[0].resources.requests[cpu] ` = 100
611
- - ` status.resize[cpu] ` = unset
612
607
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.6
613
608
- ` acknowledged[cpu] ` = 1.6
614
609
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.6
@@ -617,10 +612,10 @@ This is intentionally hitting various edge-cases for demonstration.
617
612
1 . Kubelet syncs the pod, and sees resize #4
618
613
- this node does not have 100 CPUs, so kubelet cannot admit it
619
614
- ` spec.containers[0].resources.requests[cpu] ` = 100
620
- - ` status.resize[cpu] ` = ` "Infeasible" `
621
615
- ` status.containerStatuses[0].allocatedResources[cpu] ` = 1.6
622
616
- ` acknowledged[cpu] ` = 1.6
623
617
- ` status.containerStatuses[0].resources.requests[cpu] ` = 1.6
618
+ - ` status.conditions[type==PodResizePending].type ` = ` "Infeasible" `
624
619
- actual CPU shares = 1638
625
620
626
621
#### Container resource limit update ordering
@@ -723,18 +718,20 @@ Impacts of a restart outside of resource configuration are out of scope.
723
718
- On restart, Kubelet reads the latest pod from the API and triggers a pod sync, so same effect as
724
719
observing the update.
725
720
1 . Updated pod is synced: Check if pod can be admitted
726
- - No: resize status is deferred , no change to allocated resources
721
+ - No: add ` PodResizePending ` condition with type ` Deferred ` , no change to allocated resources
727
722
- Restart: redo admission check, still deferred.
728
- - Yes: resize status is in-progress , update allocated checkpoint
723
+ - Yes: add ` PodResizing ` condition , update allocated checkpoint
729
724
- Restart before update: readmit, then update allocated
730
725
- Restart after update: allocated != acknowledged --> proceed with resize
731
726
1 . Allocated != Acknowledged
732
727
- Trigger an ` UpdateContainerResources ` CRI call, then update Acknowledged resources on success
733
728
- Restart before CRI call: allocated != acknowledged, will still trigger the update call
734
729
- Restart after CRI call, before acknowledged update: will redo update call
735
- - Restart after acknowledged update: allocated == acknowledged, resize status cleared
730
+ - Restart after acknowledged update: allocated == acknowledged, condition removed
731
+ - In all restart cases, ` LastTransitionTime ` is propagated from the old pod status ` PodResizing `
732
+ condition, and remains unchanged.
736
733
1 . PLEG updates PodStatus cache, triggers pod sync
737
- - Pod status updated with actual resources, resize status cleared
734
+ - Pod status updated with actual resources, ` PodResizing ` condition removed
738
735
- Desired == Allocated == Acknowledged, no resize changes needed.
739
736
740
737
#### Notes
@@ -1532,7 +1529,7 @@ _This section must be completed when targeting beta graduation to a release._
1532
1529
- Add ResourceQuota details
1533
1530
- Heuristic version skew handling in API validation
1534
1531
- 2025-01-24 - v1.33 updates for planned beta
1535
- - Remove ` Proposed ` resize status
1532
+ - Replace ResizeStatus with conditions
1536
1533
- Improve memory limit downsize handling
1537
1534
- Rename ResizeRestartPolicy ` NotRequired ` to ` PreferNoRestart ` ,
1538
1535
and update CRI ` UpdateContainerResources ` contract
0 commit comments