@@ -159,9 +159,12 @@ func (u *updater) RunOnce(ctx context.Context) {
159
159
klog .V (3 ).InfoS ("Skipping VPA object in ignored namespace" , "vpa" , klog .KObj (vpa ), "namespace" , vpa .Namespace )
160
160
continue
161
161
}
162
- if vpa_api_util .GetUpdateMode (vpa ) != vpa_types .UpdateModeRecreate &&
163
- vpa_api_util .GetUpdateMode (vpa ) != vpa_types .UpdateModeAuto && vpa_api_util .GetUpdateMode (vpa ) != vpa_types .UpdateModeInPlaceOrRecreate {
164
- klog .V (3 ).InfoS ("Skipping VPA object because its mode is not \" InPlaceOrRecreate\" , \" Recreate\" or \" Auto\" " , "vpa" , klog .KObj (vpa ))
162
+ updateMode := vpa_api_util .GetUpdateMode (vpa )
163
+ if updateMode != vpa_types .UpdateModeRecreate &&
164
+ updateMode != vpa_types .UpdateModeAuto &&
165
+ updateMode != vpa_types .UpdateModeInPlaceOrRecreate &&
166
+ vpa .Spec .StartupBoost == nil {
167
+ klog .V (3 ).InfoS ("Skipping VPA object because its mode is not \" InPlaceOrRecreate\" , \" Recreate\" or \" Auto\" and it doesn't have startupBoost configured" , "vpa" , klog .KObj (vpa ))
165
168
continue
166
169
}
167
170
selector , err := u .selectorFetcher .Fetch (ctx , vpa )
@@ -226,8 +229,6 @@ func (u *updater) RunOnce(ctx context.Context) {
226
229
defer vpasWithInPlaceUpdatablePodsCounter .Observe ()
227
230
defer vpasWithInPlaceUpdatedPodsCounter .Observe ()
228
231
229
- // NOTE: this loop assumes that controlledPods are filtered
230
- // to contain only Pods controlled by a VPA in auto, recreate, or inPlaceOrRecreate mode
231
232
for vpa , livePods := range controlledPods {
232
233
vpaSize := len (livePods )
233
234
updateMode := vpa_api_util .GetUpdateMode (vpa )
@@ -238,31 +239,80 @@ func (u *updater) RunOnce(ctx context.Context) {
238
239
continue
239
240
}
240
241
241
- evictionLimiter := u .restrictionFactory .NewPodsEvictionRestriction (creatorToSingleGroupStatsMap , podToReplicaCreatorMap )
242
242
inPlaceLimiter := u .restrictionFactory .NewPodsInPlaceRestriction (creatorToSingleGroupStatsMap , podToReplicaCreatorMap )
243
+ podsAvailableForUpdate := make ([]* apiv1.Pod , 0 )
244
+ podsToUnboost := make ([]* apiv1.Pod , 0 )
245
+ withInPlaceUpdated := false
243
246
244
- podsForInPlace := make ([]* apiv1.Pod , 0 )
247
+ if features .Enabled (features .CPUStartupBoost ) && vpa .Spec .StartupBoost != nil {
248
+ // First, handle unboosting for pods that have finished their startup period.
249
+ for _ , pod := range livePods {
250
+ if vpa_api_util .PodHasCPUBoostInProgress (pod ) {
251
+ if vpa_api_util .PodReady (pod ) && vpa_api_util .PodStartupBoostDurationPassed (pod , vpa ) {
252
+ podsToUnboost = append (podsToUnboost , pod )
253
+ }
254
+ } else {
255
+ podsAvailableForUpdate = append (podsAvailableForUpdate , pod )
256
+ }
257
+ }
258
+
259
+ // Perform unboosting
260
+ for _ , pod := range podsToUnboost {
261
+ if inPlaceLimiter .CanUnboost (pod , vpa ) {
262
+ klog .V (2 ).InfoS ("Unboosting pod" , "pod" , klog .KObj (pod ))
263
+ err = u .inPlaceRateLimiter .Wait (ctx )
264
+ if err != nil {
265
+ klog .V (0 ).InfoS ("In-place rate limiter wait failed for unboosting" , "error" , err )
266
+ return
267
+ }
268
+ err := inPlaceLimiter .InPlaceUpdate (pod , vpa , u .eventRecorder )
269
+ if err != nil {
270
+ klog .V (0 ).InfoS ("Unboosting failed" , "error" , err , "pod" , klog .KObj (pod ))
271
+ metrics_updater .RecordFailedInPlaceUpdate (vpaSize , "UnboostError" )
272
+ } else {
273
+ klog .V (2 ).InfoS ("Successfully unboosted pod" , "pod" , klog .KObj (pod ))
274
+ withInPlaceUpdated = true
275
+ metrics_updater .AddInPlaceUpdatedPod (vpaSize )
276
+ }
277
+ }
278
+ }
279
+ } else {
280
+ // CPU Startup Boost is not enabled or configured for this VPA,
281
+ // so all live pods are available for potential standard VPA updates.
282
+ podsAvailableForUpdate = livePods
283
+ }
284
+
285
+ if updateMode == vpa_types .UpdateModeOff || updateMode == vpa_types .UpdateModeInitial {
286
+ continue
287
+ }
288
+
289
+ evictionLimiter := u .restrictionFactory .NewPodsEvictionRestriction (creatorToSingleGroupStatsMap , podToReplicaCreatorMap )
245
290
podsForEviction := make ([]* apiv1.Pod , 0 )
291
+ podsForInPlace := make ([]* apiv1.Pod , 0 )
292
+ withInPlaceUpdatable := false
293
+ withEvictable := false
246
294
247
295
if updateMode == vpa_types .UpdateModeInPlaceOrRecreate && features .Enabled (features .InPlaceOrRecreate ) {
248
- podsForInPlace = u .getPodsUpdateOrder (filterNonInPlaceUpdatablePods (livePods , inPlaceLimiter ), vpa )
296
+ podsForInPlace = u .getPodsUpdateOrder (filterNonInPlaceUpdatablePods (podsAvailableForUpdate , inPlaceLimiter ), vpa )
249
297
inPlaceUpdatablePodsCounter .Add (vpaSize , len (podsForInPlace ))
298
+ if len (podsForInPlace ) > 0 {
299
+ withInPlaceUpdatable = true
300
+ }
250
301
} else {
251
302
// If the feature gate is not enabled but update mode is InPlaceOrRecreate, updater will always fallback to eviction.
252
303
if updateMode == vpa_types .UpdateModeInPlaceOrRecreate {
253
304
klog .InfoS ("Warning: feature gate is not enabled for this updateMode" , "featuregate" , features .InPlaceOrRecreate , "updateMode" , vpa_types .UpdateModeInPlaceOrRecreate )
254
305
}
255
- podsForEviction = u .getPodsUpdateOrder (filterNonEvictablePods (livePods , evictionLimiter ), vpa )
306
+ podsForEviction = u .getPodsUpdateOrder (filterNonEvictablePods (podsAvailableForUpdate , evictionLimiter ), vpa )
256
307
evictablePodsCounter .Add (vpaSize , updateMode , len (podsForEviction ))
308
+ if len (podsForEviction ) > 0 {
309
+ withEvictable = true
310
+ }
257
311
}
258
312
259
- withInPlaceUpdatable := false
260
- withInPlaceUpdated := false
261
- withEvictable := false
262
313
withEvicted := false
263
314
264
315
for _ , pod := range podsForInPlace {
265
- withInPlaceUpdatable = true
266
316
decision := inPlaceLimiter .CanInPlaceUpdate (pod )
267
317
268
318
if decision == utils .InPlaceDeferred {
@@ -289,7 +339,6 @@ func (u *updater) RunOnce(ctx context.Context) {
289
339
}
290
340
291
341
for _ , pod := range podsForEviction {
292
- withEvictable = true
293
342
if ! evictionLimiter .CanEvict (pod ) {
294
343
continue
295
344
}
0 commit comments