Skip to content
98 changes: 98 additions & 0 deletions content/en/blog/_posts/2026/inplace-pod-level-resources-beta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
layout: blog
title: "Kubernetes v1.36: In-Place Vertical Scaling for Pod-Level Resources Graduates to Beta"
date: 2026-04-02T10:30:00-08:00
slug: kubernetes-v1-36-inplace-pod-level-resources-beta
author: Narang Dixita Sohanlal (Google)
---

Following the graduation of [Pod-Level Resources to Beta in v1.34](/blog/2025/09/22/kubernetes-v1-34-pod-level-resources/), I am thrilled to announce another major milestone in Kubernetes resource management: **In-Place Pod-Level Resources Vertical Scaling** has graduated to **Beta** in the Kubernetes v1.36 release and is now enabled by default!

This feature bridges the gap between static Pod-level resource declarations and the [In-Place Pod Resize](/blog/2025/05/16/kubernetes-v1-33-in-place-pod-resize-beta/) capability for containers. You can now adjust the aggregate CPU and memory limits of a running Pod without the disruption of a restart, providing a truly flexible resource envelope for your workloads.

## The "Envelope" Concept

To understand why this matters, think of the Pod-level resource specification as an **envelope** that surrounds all containers within the Pod. While individual containers can have their own boundaries, the Pod-level limit acts as the absolute hard ceiling for the aggregate consumption.

{{< mermaid >}}
graph TD
subgraph PodEnvelope ["Pod Envelope (spec.resources)"]
direction TB
C1["Container 1 (Explicit Limit)"]
C2["Container 2 (No Limit - Implicitly Inherited)"]
end
PodEnvelope -.->|Stretches to Envelope| C2
PodEnvelope -.->|Enforces Hard Ceiling| C1
{{< /mermaid >}}

When you resize this envelope in-place, the underlying resource enforcement (such as cgroups) is updated dynamically.

## The "Secret" Interaction: Pod Limits and Container Policies

One of the most important technical nuances for senior engineers is how Pod-level limits interact with container-level restart policies. If a container in your Pod does *not* have an explicit resource limit, it **implicitly inherits** the Pod-level limit as its effective maximum.

This creates a crucial behavior: **Updating a Pod-level limit can trigger a container restart if that container's `resizePolicy` requires it.**

Consider this scenario:
* **Container A** has no explicit limit and a `resizePolicy` of `RestartContainer` for memory.
* When you increase the **Pod-level memory limit**, the Kubelet recognizes that Container A's effective environment has changed.
* Because the policy is set to `RestartContainer`, the Kubelet will restart the container to safely apply the new memory boundary.

## Deep Dive: Observing the Resize

Kubernetes v1.36 introduces new fields in the `PodStatus` API to provide transparency into what the Kubelet is doing. When you initiate a resize, you can observe the convergence in the Pod's status:

```yaml
status:
# The 'Resources' field is the single source of truth for
# what the Kubelet has actually applied.
resources:
requests:
cpu: "500m"
limits:
cpu: "1"
# 'AllocatedResources' shows what the Node has reserved.
allocatedResources:
cpu: "500m"
containerStatuses:
- name: my-app
# Observe the convergence of container-level actuation
resources:
requests:
cpu: "500m"
```

## Technical Requirements: cgroup v2

A critical requirement for this feature is **cgroup v2**. As cgroup v1 has been in maintenance mode since Kubernetes v1.31, this feature is supported exclusively on nodes running cgroup v2. The Kubelet will reject Pods with Pod-level resources on cgroup v1 nodes to prevent inconsistent resource enforcement.

## Container Resize vs. Pod-Level Resize

| Feature | Container-Level Resize | Pod-Level Resize |
| :--- | :--- | :--- |
| **Target Field** | `spec.containers[*].resources` | `spec.resources` |
| **Granularity** | Per-container | Aggregate (Pod-wide) |
| **Restart Policy** | Explicitly defined | Implicitly inherited |
| **Best For** | Independent container scaling | Shared resource envelopes (Sidecars) |

## How to use it in v1.36

With the `InPlacePodLevelResourcesVerticalScaling` feature gate enabled by default, you can resize a Pod in-place using the `resize` subresource:

```bash
kubectl patch pod my-pod --subresource resize --patch \
'{"spec":{"resources":{"requests":{"cpu":"1"}, "limits":{"cpu":"2"}}}}'
```

*Note: You’ll need `kubectl` v1.32 or later to use the `--subresource resize` flag.*

## What's Next?

Graduating to Beta is a major step toward production readiness. The community is now focusing on:
* **VPA Integration:** Enabling the Vertical Pod Autoscaler to automatically leverage Pod-level in-place resizing.
* **Enhanced Instrumentation:** Improving metrics to help operators detect "stuck" or "infeasible" resizes more quickly.
* **CRI Runtime Optimization:** Continuing to harden the interface between the Kubelet and runtimes like `containerd` and `CRI-O`.

## Get Involved

We’d love to hear how you’re using this feature! Join us in **#sig-node** on the Kubernetes Slack or share your feedback via our mailing lists. Your input is invaluable as we move toward General Availability (GA).
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ stages:
- stage: stable
defaultValue: true
fromVersion: "1.33"
toVersion: "1.35"

removed: true
---
Enables shims and translation logic to route volume operations
from the Portworx in-tree plugin to Portworx CSI plugin.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ stages:
- stage: beta
defaultValue: true
fromVersion: "1.35"
toVersion: "1.35"
- stage: stable
defaultValue: true
fromVersion: "1.36"
---
Enables CSI drivers to opt-in for receiving service account tokens from kubelet
through the dedicated secrets field in NodePublishVolumeRequest instead of the volume_context field.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ stages:
defaultValue: true
locked: true
fromVersion: "1.33"
toVersion: "1.35"

removed: true
---
Honor persistent volume reclaim policy when it is `Delete` irrespective of PV-PVC deletion ordering.
For more details, check the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ stages:
- stage: beta
defaultValue: true
fromVersion: "1.35"
toVersion: "1.35"
- stage: stable
defaultValue: true
fromVersion: "1.36"
---
Allow using the [`image`](/docs/concepts/storage/volumes/) volume source in a Pod.
This volume source lets you mount a container image as a read-only volume.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ stages:
- stage: alpha
defaultValue: false
fromVersion: "1.23"
toVersion: "1.35"

removed: true
---
Stops registering the Portworx in-tree plugin in kubelet
and volume controllers.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ stages:
- stage: stable
defaultValue: true
fromVersion: "1.34"
toVersion: "1.35"
- stage: stable
defaultValue: true
locked: true
fromVersion: "1.36"
---
Enable support for VolumeAttributesClasses.
See [Volume Attributes Classes](/docs/concepts/storage/volume-attributes-classes/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ containerd 1.y and below) do not support the `RuntimeConfig` CRI RPC, and
may not respond correctly to this query, and thus the Kubelet falls back to using the
value in its own `--cgroup-driver` flag.

In Kubernetes 1.36, this fallback behavior will be dropped, and older versions
In Kubernetes 1.37, this fallback behavior will be dropped, and older versions
of containerd will fail with newer kubelets.

{{< caution >}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ mount content from OCI registries inside containers.
- The container runtime needs to support the image volumes feature
- You need to exec commands in the host
- You need to be able to exec into pods
- You need to enable the `ImageVolume` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)

<!-- steps -->

Expand Down
20 changes: 10 additions & 10 deletions hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ time_format_default = "January 02, 2006 at 3:04 PM PST"
description = "Production-Grade Container Orchestration"
showedit = true

latest = "v1.35"
latest = "v1.36"

version = "v1.35"
version = "v1.36"
githubbranch = "main"
docsbranch = "main"
# Should be changed to Docsy provided `archived_version` in the future.
Expand Down Expand Up @@ -183,11 +183,17 @@ js = [
]

[[params.versions]]
version = "v1.35"
githubbranch = "v1.35.0"
version = "v1.36"
githubbranch = "v1.36.0"
docsbranch = "main"
url = "https://kubernetes.io"

[[params.versions]]
version = "v1.35"
githubbranch = "v1.35.0"
docsbranch = "release-1.35"
url = "https://v1-35.docs.kubernetes.io"

[[params.versions]]
version = "v1.34"
githubbranch = "v1.34.0"
Expand All @@ -206,12 +212,6 @@ githubbranch = "v1.32.8"
docsbranch = "release-1.32"
url = "https://v1-32.docs.kubernetes.io"

[[params.versions]]
version = "v1.31"
githubbranch = "v1.31.12"
docsbranch = "release-1.31"
url = "https://v1-31.docs.kubernetes.io"

# User interface configuration
[params.ui]
# Enable to show the side bar menu in its compact state.
Expand Down