[{"data":1,"prerenderedAt":705},["ShallowReactive",2],{"blog-en-k3s-vpa-inplaceorrecreate-pod-resize-cgroup":3,"blog-related-en-k3s-vpa-inplaceorrecreate-pod-resize-cgroup":655,"blog-en-k3s-vpa-inplaceorrecreate-pod-resize-cgroup-alt":529},{"id":4,"title":5,"author":6,"body":7,"date":639,"description":640,"extension":641,"image":642,"locale":643,"meta":644,"navigation":529,"path":645,"seo":646,"stem":647,"tags":648,"__hash__":654},"blog\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup.md","VPA InPlaceOrRecreate Didn't Stop the Restart. Testing InPlacePodVerticalScaling on K3s","Kubo Team",{"type":8,"value":9,"toc":631},"minimark",[10,15,32,39,50,57,61,80,87,107,152,156,167,180,192,211,221,227,231,243,266,269,278,284,288,294,449,466,473,562,586,592,596,604,611,619,627],[11,12,14],"h2",{"id":13},"we-tried-no-restart-resizing-and-the-pod-got-recreated-anyway","We Tried \"No-Restart Resizing,\" and the Pod Got Recreated Anyway",[16,17,18,19,23,24,27,28,31],"p",{},"We switched VPA's (Vertical Pod Autoscaler) ",[20,21,22],"code",{},"updateMode"," to ",[20,25,26],{},"InPlaceOrRecreate",", expecting to adjust CPU and memory without restarting Pods. A few days later, checking the event log, we found several Pods had been ",[20,29,30],{},"Evicted"," and recreated anyway.",[16,33,34,35],{},"To be clear upfront: this isn't a bug. ",[36,37,38],"strong",{},"In-Place Pod Resize (In-Place Pod Vertical Scaling) only avoids restarting containers when certain conditions are met, and it silently falls back to recreating the Pod when those conditions aren't satisfied.",[16,40,41,42,49],{},"This article verifies the actual behavior of VPA's InPlaceOrRecreate mode and In-Place Pod Resize on K3s, with real configuration examples, commands, and how to read the resulting status (spoiler: on a managed K3s like ",[43,44,48],"a",{"href":45,"rel":46},"https:\u002F\u002Fkubo.hexabase.io\u002F",[47],"nofollow","Kubo"," where the cgroup prerequisites are already configured, you can skip most of this investigation).",[16,51,52],{},[53,54],"img",{"alt":55,"src":56},"section01","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup\u002Fsection01.webp",[11,58,60],{"id":59},"the-basics-of-in-place-pod-resize-six-years-from-alpha-to-ga","The Basics of In-Place Pod Resize — Six Years from Alpha to GA",[16,62,63,64,67,68,73,74,79],{},"In-Place Pod Resize (built on Kubernetes' ",[20,65,66],{},"\u002Fresize"," subresource) started as alpha in v1.27 in 2023, graduated to beta in v1.33 in May 2025, and ",[43,69,72],{"href":70,"rel":71},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2025\u002F12\u002F19\u002FKubernetes-v1-35-in-place-pod-resize-ga\u002F",[47],"reached Stable (GA) in v1.35 in December 2025",". According to ",[43,75,78],{"href":76,"rel":77},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2025\u002F05\u002F16\u002FKubernetes-v1-33-in-place-pod-resize-beta\u002F",[47],"the official blog post announcing the v1.33 beta",", restart-free resource adjustment became enabled by default during this period.",[16,81,82,83,86],{},"Each container's ",[20,84,85],{},"resizePolicy"," supports two values:",[88,89,90,99],"ul",{},[91,92,93,98],"li",{},[36,94,95],{},[20,96,97],{},"NotRequired",": the container is not restarted when the resource changes (default)",[91,100,101,106],{},[36,102,103],{},[20,104,105],{},"RestartContainer",": the container is restarted when the resource changes",[16,108,109,110,115,116,119,120,123,124,127,128,131,132,135,136,139,140,142,143,145,146,151],{},"The ",[43,111,114],{"href":112,"rel":113},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Fconfigure-pod-container\u002Fresize-container-resources\u002F",[47],"official Kubernetes documentation"," describes patching resources with ",[20,117,118],{},"kubectl patch pod \u003Cname> --subresource=resize",", and checking the result via ",[20,121,122],{},"status.conditions",": ",[20,125,126],{},"PodResizePending"," (reason ",[20,129,130],{},"Deferred"," or ",[20,133,134],{},"Infeasible",") or ",[20,137,138],{},"PodResizeInProgress",". ",[20,141,130],{}," means the resize is held back due to insufficient node capacity right now; ",[20,144,134],{}," means the request exceeds the node's maximum capacity and cannot be scheduled at all. In April 2026, v1.36 also ",[43,147,150],{"href":148,"rel":149},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2026\u002F04\u002F30\u002Fkubernetes-v1-36-inplace-pod-level-resources-beta\u002F",[47],"graduated in-place resize for Pod-level resources to beta",", so the scope keeps expanding.",[11,153,155],{"id":154},"why-does-inplaceorrecreate-still-recreate-the-pod","Why Does \"InPlaceOrRecreate\" Still Recreate the Pod?",[16,157,158,159,162,163,166],{},"The first thing to check is the QoS class. As the ",[43,160,114],{"href":112,"rel":161},[47]," states, a Pod's QoS class (Guaranteed \u002F Burstable \u002F BestEffort) is fixed at creation time and ",[36,164,165],{},"cannot be changed by a resize",". A change that would make a Burstable container's requests equal its limits for both CPU and memory — effectively turning it into Guaranteed — cannot be done in-place.",[16,168,169,170,175,176,179],{},"An easy detail to miss is whether initial values are set at all. According to ",[43,171,174],{"href":172,"rel":173},"https:\u002F\u002Fdevopscube.com\u002Fvpa-in-place-pod-resize\u002F",[47],"a practical setup guide",", ",[36,177,178],{},"if a container has no requests\u002Flimits configured at all, the Pod is treated as BestEffort, and the moment VPA tries to set resources on it, the QoS class changes — forcing a recreation."," If you want to use InPlaceOrRecreate, setting at least minimal requests\u002Flimits from the start is a prerequisite.",[16,181,182,183,188,189,191],{},"VPA's own behavior matters too. According to ",[43,184,187],{"href":185,"rel":186},"https:\u002F\u002Foneuptime.com\u002Fblog\u002Fpost\u002F2026-08-25-vpa-inplaceorrecreate-feature-gate\u002Fview",[47],"an explainer on the InPlaceOrRecreate mode",", VPA attempts to patch via the ",[20,190,66],{}," subresource, and falls back to eviction (recreation) under these conditions:",[88,193,194,197,203,208],{},[91,195,196],{},"The kubelet reports the resize as infeasible or errors out",[91,198,199,200,202],{},"The resize stays ",[20,201,130],{}," for more than 5 minutes",[91,204,205,207],{},[20,206,138],{}," stays unresolved for more than 1 hour",[91,209,210],{},"The proposed resource change would alter the Pod's QoS class",[16,212,213,214,220],{},"The same article points out another easy-to-miss detail: ",[36,215,216,217,219],{},"a successful ",[20,218,66],{}," does not call the Eviction API, so PodDisruptionBudget is never consulted for that patch."," If you think your PDB is protecting you, a successful in-place resize bypasses that check entirely.",[16,222,223],{},[53,224],{"alt":225,"src":226},"section02","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup\u002Fsection02.webp",[11,228,230],{"id":229},"the-k3sedge-specific-trap-things-get-complicated-with-cgroup-drivers","The K3s\u002FEdge-Specific Trap — Things Get Complicated with cgroup Drivers",[16,232,233,234,237,238,242],{},"Running on K3s adds another layer of complexity: the cgroup version and driver. In-Place Pod Resize and Pod-Level Resources assume the node is running ",[20,235,236],{},"cgroup2"," (",[43,239,241],{"href":172,"rel":240},[47],"devopscube.com's verification guide"," also lists this as the first thing to check).",[16,244,245,246,249,250,253,254,259,260,265],{},"Since a certain version, K3s defaults to the ",[20,247,248],{},"systemd"," cgroup driver instead of ",[20,251,252],{},"cgroupfs"," whenever systemd is detected. This change improves compatibility with cgroup v2, but on setups running K3s inside Docker, or on nodes with older OS images, there are ",[43,255,258],{"href":256,"rel":257},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s\u002Fdiscussions\u002F7265",[47],"reports of startup failures caused by the switch to the systemd driver",", such as the \"kubepods\" root container not being found. On the edge-device side, there are also ",[43,261,264],{"href":262,"rel":263},"https:\u002F\u002Fdiscuss.luxonis.com\u002Fd\u002F6861-k3s-agent-fails-on-oak-4d-due-to-cgroup-v1-how-to-enable-cgroup-v2",[47],"documented cases of K3s agents failing to start when stuck on cgroup v1",".",[16,267,268],{},"Edge K3s nodes deployed in factories and stores often have their OS images updated infrequently and end up running cgroup v1 for a long time. Enabling In-Place Pod Resize or VPA's InPlaceOrRecreate on such nodes means any Pod-Level-Resources feature is effectively off the table from the start. If \"the same YAML worked on the cloud cluster but not on the edge cluster,\" the cgroup version and driver should be the first thing you suspect.",[16,270,271,272,277],{},"With ",[43,273,276],{"href":274,"rel":275},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fkubo\u002Fon-premise",[47],"Kubo On-Premise",", the K3s distribution itself is configured with the cgroup v2 + systemd driver combination as a prerequisite, removing the need to fix up individual edge nodes by hand. If you manage your own OS images, this mismatch is the single most common place things go wrong.",[16,279,280],{},[53,281],{"alt":282,"src":283},"section03","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup\u002Fsection03.webp",[11,285,287],{"id":286},"in-practice-setting-resizepolicy-and-verifying-with-kubectl","In Practice — Setting resizePolicy and Verifying with kubectl",[16,289,290,291,293],{},"Start by declaring ",[20,292,85],{}," explicitly on the container:",[295,296,301],"pre",{"className":297,"code":298,"language":299,"meta":300,"style":300},"language-yaml shiki shiki-themes tokyo-night","resources:\n  requests:\n    cpu: \"250m\"\n    memory: \"256Mi\"\n  limits:\n    cpu: \"500m\"\n    memory: \"512Mi\"\nresizePolicy:\n  - resourceName: cpu\n    restartPolicy: NotRequired\n  - resourceName: memory\n    restartPolicy: RestartContainer\n","yaml","",[20,302,303,316,324,343,358,366,380,394,401,416,427,439],{"__ignoreMap":300},[304,305,308,312],"span",{"class":306,"line":307},"line",1,[304,309,311],{"class":310},"s0U2E","resources",[304,313,315],{"class":314},"sAklC",":\n",[304,317,319,322],{"class":306,"line":318},2,[304,320,321],{"class":310},"  requests",[304,323,315],{"class":314},[304,325,327,330,333,336,340],{"class":306,"line":326},3,[304,328,329],{"class":310},"    cpu",[304,331,332],{"class":314},":",[304,334,335],{"class":314}," \"",[304,337,339],{"class":338},"sPY7s","250m",[304,341,342],{"class":314},"\"\n",[304,344,346,349,351,353,356],{"class":306,"line":345},4,[304,347,348],{"class":310},"    memory",[304,350,332],{"class":314},[304,352,335],{"class":314},[304,354,355],{"class":338},"256Mi",[304,357,342],{"class":314},[304,359,361,364],{"class":306,"line":360},5,[304,362,363],{"class":310},"  limits",[304,365,315],{"class":314},[304,367,369,371,373,375,378],{"class":306,"line":368},6,[304,370,329],{"class":310},[304,372,332],{"class":314},[304,374,335],{"class":314},[304,376,377],{"class":338},"500m",[304,379,342],{"class":314},[304,381,383,385,387,389,392],{"class":306,"line":382},7,[304,384,348],{"class":310},[304,386,332],{"class":314},[304,388,335],{"class":314},[304,390,391],{"class":338},"512Mi",[304,393,342],{"class":314},[304,395,397,399],{"class":306,"line":396},8,[304,398,85],{"class":310},[304,400,315],{"class":314},[304,402,404,408,411,413],{"class":306,"line":403},9,[304,405,407],{"class":406},"sgJMe","  -",[304,409,410],{"class":310}," resourceName",[304,412,332],{"class":314},[304,414,415],{"class":338}," cpu\n",[304,417,419,422,424],{"class":306,"line":418},10,[304,420,421],{"class":310},"    restartPolicy",[304,423,332],{"class":314},[304,425,426],{"class":338}," NotRequired\n",[304,428,430,432,434,436],{"class":306,"line":429},11,[304,431,407],{"class":406},[304,433,410],{"class":310},[304,435,332],{"class":314},[304,437,438],{"class":338}," memory\n",[304,440,442,444,446],{"class":306,"line":441},12,[304,443,421],{"class":310},[304,445,332],{"class":314},[304,447,448],{"class":338}," RestartContainer\n",[16,450,451,452,454,455,457,458,462,463,465],{},"Letting CPU resize with ",[20,453,97],{}," while keeping memory on ",[20,456,105],{}," lets applications like JVM-based services safely recompute heap sizing when needed. ",[43,459,461],{"href":172,"rel":460},[47],"DevOpsCube's guide"," also recommends using ",[20,464,105],{}," for memory changes.",[16,467,468,469,472],{},"Verification is a matter of ",[20,470,471],{},"kubectl"," alone:",[295,474,478],{"className":475,"code":476,"language":477,"meta":300,"style":300},"language-bash shiki shiki-themes tokyo-night","kubectl patch pod \u003Cpod-name> --subresource=resize -p \\\n  '{\"spec\":{\"containers\":[{\"name\":\"app\",\"resources\":{\"requests\":{\"cpu\":\"400m\"}}}]}}'\n\nkubectl get pod \u003Cpod-name> -o jsonpath='{.status.conditions}'\n","bash",[20,479,480,514,525,531],{"__ignoreMap":300},[304,481,482,485,488,491,494,497,501,504,508,511],{"class":306,"line":307},[304,483,471],{"class":484},"sE3pS",[304,486,487],{"class":338}," patch",[304,489,490],{"class":338}," pod",[304,492,493],{"class":314}," \u003C",[304,495,496],{"class":338},"pod-nam",[304,498,500],{"class":499},"sGX4V","e",[304,502,503],{"class":314},">",[304,505,507],{"class":506},"sT800"," --subresource=resize",[304,509,510],{"class":506}," -p",[304,512,513],{"class":314}," \\\n",[304,515,516,519,522],{"class":306,"line":318},[304,517,518],{"class":314},"  '",[304,520,521],{"class":338},"{\"spec\":{\"containers\":[{\"name\":\"app\",\"resources\":{\"requests\":{\"cpu\":\"400m\"}}}]}}",[304,523,524],{"class":314},"'\n",[304,526,527],{"class":306,"line":326},[304,528,530],{"emptyLinePlaceholder":529},true,"\n",[304,532,533,535,538,540,542,544,546,548,551,554,557,560],{"class":306,"line":345},[304,534,471],{"class":484},[304,536,537],{"class":338}," get",[304,539,490],{"class":338},[304,541,493],{"class":314},[304,543,496],{"class":338},[304,545,500],{"class":499},[304,547,503],{"class":314},[304,549,550],{"class":506}," -o",[304,552,553],{"class":338}," jsonpath=",[304,555,556],{"class":314},"'",[304,558,559],{"class":338},"{.status.conditions}",[304,561,524],{"class":314},[16,563,564,566,567,569,570,572,573,575,576,578,579,582,583,585],{},[20,565,138],{}," means the resize is in progress; ",[20,568,126],{}," with ",[20,571,130],{}," means the node is short on resources right now; ",[20,574,134],{}," means the current node simply can't accommodate the request. For downsizing memory, if current usage exceeds the new limit, ",[20,577,138],{}," can get stuck at ",[20,580,581],{},"Error"," — so it's safer to default to ",[20,584,105],{}," for any memory reduction.",[16,587,588],{},[53,589],{"alt":590,"src":591},"section04","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup\u002Fsection04.webp",[11,593,595],{"id":594},"conclusion-dont-design-around-the-assumption-of-no-restart","Conclusion — Don't Design Around the Assumption of \"No Restart\"",[16,597,598,599,603],{},"In-Place Pod Resize did reach GA in v1.35, and VPA's InPlaceOrRecreate mode is now solid enough for production use. But it's a feature that skips the restart ",[600,601,602],"em",{},"when conditions are met"," — not a guarantee that a restart will never happen. Fixed QoS classes, whether initial requests\u002Flimits are set, and the cgroup version and driver — get these three things wrong, and a Pod will get recreated exactly when you didn't expect it.",[16,605,606,607,610],{},"On a managed K3s environment, the cgroup v2 + systemd driver combination and other node-level prerequisites are already taken care of. ",[43,608,48],{"href":45,"rel":609},[47],", built on K3s, lets you try VPA and In-Place Pod Resize without worrying about these low-level prerequisites.",[16,612,613,614,618],{},"If you're reconsidering your VPA operational design altogether, ",[43,615,617],{"href":45,"rel":616},[47],"Kubo Cloud","'s AI-Driven Deployment lets you start from a working configuration before getting into the weeds of resource settings and cgroup prerequisites in YAML. Compared to running the same verification on EKS or AKS, being able to try a full-spec Kubernetes starting at around ¥48,000\u002Fmonth is also worth factoring into the decision.",[16,620,621,622,265],{},"If you'd like to verify this behavior in a pre-configured environment before rolling a new feature into production, feel free to reach out via ",[43,623,626],{"href":624,"rel":625},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[47],"Contact Us",[628,629,630],"style",{},"html pre.shiki code .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sE3pS, html code.shiki .sE3pS{--shiki-default:#C0CAF5}html pre.shiki code .sGX4V, html code.shiki .sGX4V{--shiki-default:#A9B1D6}html pre.shiki code .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}",{"title":300,"searchDepth":318,"depth":318,"links":632},[633,634,635,636,637,638],{"id":13,"depth":318,"text":14},{"id":59,"depth":318,"text":60},{"id":154,"depth":318,"text":155},{"id":229,"depth":318,"text":230},{"id":286,"depth":318,"text":287},{"id":594,"depth":318,"text":595},"2026-10-17","Does VPA's InPlaceOrRecreate mode and In-Place Pod Resize really avoid Pod restarts? We test QoS class constraints and the cgroup v1 trap on K3s with real configs and kubectl commands.","md","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup\u002Ftitle.webp","en",{},"\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup",{"title":5,"description":640},"blog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup",[649,650,651,652,653],"k3s","kubernetes","vpa","autoscaling","cgroup","KhEPKukDQEFeLOzTaYldvKdAN70hyANWAuL-WFt-A7s",[656,663,670,678,686,695],{"path":657,"title":658,"description":659,"date":660,"tags":661},"\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design","\"Running Both Feels Safer\" Is the Trap. Why Combining HPA and VPA in Kubernetes Can Send Autoscaling Into a Spiral","Enabling both HPA and VPA in Kubernetes can make two well-intentioned automations fight each other, sending autoscaling into an endless spiral. Here's why the conflict happens, and how to combine them safely with updateMode and metric separation.","2026-10-07",[649,650,662,651,652],"hpa",{"path":664,"title":665,"description":666,"date":667,"tags":668},"\u002Fblog\u002Fen\u002Fk3s-hpa-not-scaling-metrics-unknown-vpa-death-spiral","Your HPA Config Is Correct. So Why Won't Pods Scale? The Real Cause of 'Unknown Metrics' in K3s and the HPA\u002FVPA Death Spiral","You set up an HPA in K3s and Pods still won't scale. The usual culprits are unset resource requests silently disabling metrics, and a self-reinforcing HPA\u002FVPA feedback loop. Here's how to diagnose and fix it.","2026-09-02",[649,650,662,651,652,669],"metrics-server",{"path":671,"title":672,"description":673,"date":674,"tags":675},"\u002Fblog\u002Fen\u002Fk3s-hpa-containerresource-sidecar-utilization-dilution","HPA Was Scaling on the Sidecar's Share Too. The ContainerResource Blind Spot in Kubernetes","Kubernetes HPA sums resource usage across every container in a Pod, so Istio sidecars and logging agents dilute the scaling decision. Here's how the ContainerResource metric fixes it, in a K3s\u002FKubo context.","2026-10-21",[649,650,662,676,652,677],"containerresource","service-mesh",{"path":679,"title":680,"description":681,"date":682,"tags":683},"\u002Fblog\u002Fen\u002Fk3s-hpa-prometheus-adapter-discovery-interval-stale-metrics","Question Your discoveryInterval: Why K3s HPA Keeps Scaling on Stale Metrics from Prometheus Adapter","K3s HPA won't scale even though CPU usage looks normal. The culprit is a mismatch between Prometheus Adapter's metrics-relist-interval\u002Fmetrics-max-age and the HPA sync-period. Here's the three-layer delay chain and how to diagnose it.","2026-10-12",[649,650,662,684,652,685],"prometheus-adapter","observability",{"path":687,"title":688,"description":689,"date":690,"tags":691},"\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision","CPU Usage Looks Normal, But Requests Are Piling Up. When to Add KEDA to HPA in Kubernetes","KEDA and HPA aren't an either-or choice. When event-driven workloads grow on K3s\u002FKubernetes, here's why HPA alone hits its limits and how to decide when to add KEDA alongside it.","2026-10-03",[649,650,692,662,652,693,694],"keda","event-driven-scaling","scaledobject",{"path":696,"title":697,"description":698,"date":699,"tags":700},"\u002Fblog\u002Fen\u002Fk3s-gpu-oomkilled-vpa-resource-estimation","GPU Memory Ran Out and Killed an AI Training Job. Why VPA Can't Save You on K3s","Why AI training jobs on K3s get OOMKilled from GPU memory shortages, why Vertical Pod Autoscaler doesn't cover GPU resources, and how to size requests\u002Flimits correctly using measurement-based design.","2026-09-20",[649,650,701,702,651,703,704],"gpu","oomkilled","ai-infrastructure","resource-management",1792592640725]