How to Dynamically Scale Pod Resources in Kubernetes v1.36 Using In-Place Vertical Scaling

<h2>Introduction</h2><p>Kubernetes v1.36 brings a powerful new capability to beta: <strong>In-Place Vertical Scaling for Pod-Level Resources</strong>. This feature, now enabled by default via the <code>InPlacePodLevelResourcesVerticalScaling</code> feature gate, allows you to adjust the aggregate resource budget (<code>.spec.resources</code>) of a running Pod without necessarily restarting its containers. It's a game-changer for managing complex Pods with sidecars, enabling you to expand a shared pool of CPU and memory on the fly. In this guide, we'll walk through the exact steps to leverage this feature, from understanding the underlying model to executing a resize and verifying the result.</p><figure style="margin:20px 0"><img src="https://picsum.photos/seed/1599626890/800/450" alt="How to Dynamically Scale Pod Resources in Kubernetes v1.36 Using In-Place Vertical Scaling" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px"></figcaption></figure><h2>What You Need</h2><ul><li>A Kubernetes cluster running <strong>v1.36</strong> or later (the feature is beta and enabled by default).</li><li><code>kubectl</code> installed and configured to access your cluster.</li><li>A running Pod that uses <strong>Pod-level resources</strong> (i.e., <code>spec.resources.limits</code> defined without per-container limits).</li><li>Optional: a <code>resizePolicy</code> set in your container definitions to control restart behavior (see <a href="#step-1">Step 1</a>).</li><li>Administrative permissions to patch Pods (usually <code>pods/resize</code> subresource access).</li></ul><h2>Step-by-Step Guide</h2><h3 id="step-1">Step 1: Understand Pod-Level Resources and Inheritance</h3><p>Before you resize, you need a Pod that defines resources at the Pod level rather than per-container. Here's the key concept: when you set <code>spec.resources</code> (limits or requests) on a Pod, all containers that don't specify their own resource limits inherit from this shared pool. This is especially useful for sidecar patterns where you want a collective budget. The <code>resizePolicy</code> inside each container tells the Kubelet whether to attempt a non-disruptive update (via cgroup) or restart the container. Note that <code>resizePolicy</code> is currently <strong>not supported at the Pod level</strong> – each container must define its own.</p><h3 id="step-2">Step 2: Create or Identify a Suitable Pod</h3><p>You'll need a Pod definition that uses Pod-level resources and has at least one container. Consider this example YAML – it defines a shared CPU limit of 2 CPUs and 4Gi memory, with two containers that inherit these limits:</p><pre><code>apiVersion: v1 kind: Pod metadata: name: shared-pool-app spec: resources: # Pod-level limits limits: cpu: "2" memory: "4Gi" containers: - name: main-app image: my-app:v1 resources: {} # inherits from Pod resizePolicy: - resourceName: "cpu" restartPolicy: "NotRequired" - name: sidecar image: logger:v1 resources: {} # inherits resizePolicy: - resourceName: "cpu" restartPolicy: "NotRequired"</code></pre><p>Apply this to your cluster with <code>kubectl apply -f pod.yaml</code>. Ensure the Pod is in <strong>Running</strong> state.</p><h3 id="step-3">Step 3: Perform the In-Place Resize</h3><p>To double the shared CPU pool from 2 to 4 CPUs, use the <code>kubectl patch</code> command with the <code>--subresource resize</code> flag. The patch targets <code>spec.resources.limits.cpu</code>:</p><pre><code>kubectl patch pod shared-pool-app --subresource resize --patch '{ "spec": { "resources": { "limits": { "cpu": "4" } } } }'</code></pre><p>The Kubelet will immediately process this request. For each container, it checks the <code>resizePolicy</code>:</p><ul><li>If <code>restartPolicy: NotRequired</code>, it updates cgroup limits via the CRI without restarting.</li><li>If <code>restartPolicy: RestartContainer</code>, it restarts the container to apply the new aggregate boundary safely.</li></ul><p>In our example, both containers have <code>NotRequired</code>, so the update is nearly instantaneous and non-disruptive.</p><h3 id="step-4">Step 4: Verify the Resize and Monitor Node Stability</h3><p>After patching, check the Pod status:</p><pre><code>kubectl describe pod shared-pool-app</code></pre><p>Look for <code>Conditions</code> – you should see a new condition <code>PodResizePending</code> briefly, then <code>PodResizeExecuted</code> once the Kubelet applies the change. Verify the new limit by examining the container resource limits inside the node (or use a tool like <code>kubectl exec</code> to check <code>/sys/fs/cgroup</code>). The Kubelet also performs node-level feasibility checks: it ensures the node has enough capacity, evaluates the <code>NodeRestriction</code> admission plugin, and updates the Pod's resource spec only after confirming safety. If the node is overloaded, the resize may be rejected – monitor node resource usage with <code>kubectl top nodes</code>.</p><h2>Tips for Success</h2><ul><li><strong>Always define an explicit <code>resizePolicy</code></strong> on each container that inherits from Pod-level resources. Without it, the default policy may restart the container unnecessarily (check the container runtime's default).</li><li><strong>Start small</strong>: test with a non-critical Pod before applying to production. In-place resizing uses the <code>resize</code> subresource, which has its own RBAC rules – ensure your service account has <code>pods/resize</code> permissions.</li><li><strong>Combine with Horizontal Pod Autoscaler (HPA) for dynamic adjustments</strong>: you can trigger Pod-level resizes based on metrics, but note that HPA doesn't currently support this directly – you'll need a custom controller. For manual scaling, use the patch command in scripts.</li><li><strong>Understand restart implications</strong>: If a container requires <code>RestartContainer</code>, the resize will cause a brief downtime. Use <code>NotRequired</code> for sidecars that can handle cgroup updates without restarting (e.g., stateless loggers).</li><li><strong>Monitor node pressure</strong>: The Kubelet reserves resources from the node's allocatable pool. A resize may fail if the node is near capacity. Consider using <a href="#step-4">Verification</a> steps to confirm.</li><li><strong>Beware of the current limitation</strong>: <code>resizePolicy</code> cannot be set at the Pod level – you must define it per container. Future versions may address this.</li></ul>
Tags: