Ever found yourself in that classic Kubernetes predicament? You meticulously set up your pod resources, patted yourself on the back, deployed to production... and then reality hits. Your application is either gasping for resources like a marathon runner at mile 25, or it's hoarding CPU like it's preparing for the computing apocalypse.
What happens next? In the dark ages of pre-1.33 Kubernetes, you'd have to restart the poor pod! It was like performing open-heart surgery just to adjust someone's diet.
But rejoice, fellow Kubernetes wranglers! Version 1.33 has arrived bearing gifts, and the showstopper is in-place pod vertical scaling in beta and enabled by default! π
What Is This Sorcery? π§ββοΈ
In-place pod resizing allows you to change the CPU and memory allocations of running pods without restarting them. Let that sink in for a second.
No restarts. No connection drops. No disruption. Just smooth resource adjustment while your application keeps humming along.
It works by making the resources.requests
and resources.limits
in your pod spec mutable - they can be changed on the fly without triggering a pod recreation. This is made possible through the new resize subresource feature and kubelet's ability to dynamically reconfigure container cgroups.
Why Should You Care? π€
If you're thinking "neat trick, but why does it matter?", consider these scenarios:
Stateful Applications - Your database pod suddenly needs more memory during a heavy analytics query. Previously: restart required, connections dropped, cache flushed. Now: bump the memory, carry on!
Cost Optimization - Over-provisioning "just in case" becomes unnecessary. Start conservative, scale up only when needed, scale down when the traffic subsides.
Performance Tuning - Experiment with different resource allocations to find the sweet spot, without annoying your users or operation teams.
Spiky Workloads - That batch job that needs tons of resources for 5 minutes every hour? No more choosing between wasting resources or constant restarts.
Under the Hood: How It Works π§
When you resize a pod, here's what happens:
- You update the pod's resource specification using the new
resize
subresource - Kubelet validates the request against node capacity
- If approved, kubelet instructs the container runtime to adjust cgroups
- Container runtime updates the limits without restarting
- The pod status is updated to reflect the new allocations
The pod can report its resize status through conditions:
-
PodResizePending - Can't resize right now (reasons include
Infeasible
orDeferred
) - PodResizeInProgress - Changes are being applied
Show Me the Code! π»
Here's a simple example that demonstrates this feature in action:
# Create a resource-monitoring pod
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
spec:
containers:
- name: resource-watcher
image: ubuntu:22.04
command:
- "/bin/bash"
- "-c"
- |
apt-get update && apt-get install -y procps bc
echo "=== Pod Started: $(date) ==="
# Functions to read container resource limits
get_cpu_limit() {
if [ -f /sys/fs/cgroup/cpu.max ]; then
# cgroup v2
local cpu_data=$(cat /sys/fs/cgroup/cpu.max)
local quota=$(echo $cpu_data | awk '{print $1}')
local period=$(echo $cpu_data | awk '{print $2}')
if [ "$quota" = "max" ]; then
echo "unlimited"
else
echo "$(echo "scale=3; $quota / $period" | bc) cores"
fi
else
# cgroup v1
local quota=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)
local period=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)
if [ "$quota" = "-1" ]; then
echo "unlimited"
else
echo "$(echo "scale=3; $quota / $period" | bc) cores"
fi
fi
}
get_memory_limit() {
if [ -f /sys/fs/cgroup/memory.max ]; then
# cgroup v2
local mem=$(cat /sys/fs/cgroup/memory.max)
if [ "$mem" = "max" ]; then
echo "unlimited"
else
echo "$((mem / 1048576)) MiB"
fi
else
# cgroup v1
local mem=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
echo "$((mem / 1048576)) MiB"
fi
}
# Print resource info every 5 seconds
while true; do
echo "---------- Resource Check: $(date) ----------"
echo "CPU limit: $(get_cpu_limit)"
echo "Memory limit: $(get_memory_limit)"
echo "Available memory: $(free -h | grep Mem | awk '{print $7}')"
sleep 5
done
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: NotRequired
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "100m"
EOF
After your pod is running, double the CPU:
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"resource-watcher", "resources":{"requests":{"cpu":"200m"}, "limits":{"cpu":"200m"}}}]}}'
Check the pod logs, and you'll see the CPU limit magically change from 0.100 cores to 0.200 cores without any restart!
Control the Resize Behavior with resizePolicy βοΈ
Sometimes you do want a restart when changing certain resources. For example, many applications can't dynamically adjust to memory changes without restarting. That's where resizePolicy
comes in:
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Live CPU tweaks!
- resourceName: memory
restartPolicy: RestartContainer # Safer memory changes
With this configuration, CPU changes happen in-place, but memory changes trigger a container restart.
The Fine Print: Limitations π
While this feature is cooler than a penguin in sunglasses, it does have some limitations:
- Windows Support: None yet, only Linux containers
- Resource Types: Only CPU and memory can be resized in-place
- QoS Class Immutability: You can't change a pod's QoS class through resizing
-
Memory Decrease: You can't decrease memory limits without a restart (unless using
RestartContainer
policy) - Special Pods: Pods with static CPU/memory management policies can't use this feature
- Cluster Requirements: Requires Kubernetes 1.33+ with a compatible container runtime
What This Means for VPA π€
The Vertical Pod Autoscaler has long been the awkward cousin at the Kubernetes scaling family reunion. Its main limitation? It had to recreate pods to adjust resources.
While VPA doesn't yet support in-place resizing in Kubernetes 1.33, this feature lays the groundwork for future integration. Soon, we might see VPA attempting in-place resizes first, falling back to recreation only when necessary.
Until then, you can use VPA in "Off" mode to get recommendations, then apply them manually via in-place resizing.
Conclusion: A Smoother Vertical Scaling Future π
In-place pod resizing in Kubernetes 1.33 is a game-changer for vertical scaling workflows. It removes one of the most significant barriers to efficient resource management - the disruption caused by pod recreation.
Whether you're fine-tuning performance, responding to traffic spikes, or optimizing cloud costs, the ability to adjust resources without service interruption opens up new possibilities for Kubernetes-based applications.
Give it a try in your non-production clusters, and prepare to say goodbye to the "restart to resize" era of Kubernetes!
For the full blog post including more details, examples, and the future of vertical scaling in Kubernetes, check out my article on Medium.
Top comments (0)