Master Kubernetes Vertical Pod Autoscaler (VPA): Installation, Configuration, and Real‑World Tuning
This guide explains what Kubernetes VPA is, its architecture, version compatibility, step‑by‑step installation, certificate setup, manifest generation, practical VPA configuration, validation procedures, performance testing, and known limitations, enabling you to optimize pod resources in cloud‑native clusters.
What is Kubernetes VPA?
Kubernetes Vertical Pod Autoscaler (VPA) automatically adjusts pod CPU and memory requests based on actual usage, improving resource utilization and application performance.
VPA Architecture
The VPA system consists of three components:
recommender : monitors current and historical resource consumption and provides recommended CPU and memory requests.
updater : checks pods with outdated resources, evicts them, and lets the controller recreate them with updated requests.
admission plugin : sets correct resource requests on newly created pods or pods recreated by the updater.
Version Compatibility
VPA version
Kubernetes version
1.2.x
1.27+
0.12 to 1.1.x
1.25+
0.11
1.22 - 1.24
0.10
1.22+
0.9
1.16+
0.8
1.13+
0.4 to 0.7
1.11+
0.3.X and lower
1.7+
Install VPA Service
Prerequisites
Deploy
metrics-serverin the cluster.
Create a TLS certificate for VPA using a
Certificateresource.
Generate the certificate:
<code>$ cat <<'EOF' | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: vpa
namespace: default
spec:
secretName: vpa-cert
commonName: vpa-webhook.kube-system.svc
privateKey:
algorithm: RSA
size: 2048
usages:
- server auth
- client auth
- digital signature
- key encipherment
duration: 876000h # 36500d
renewBefore: 744h # 31d
dnsNames:
- "vpa-webhook.kube-system.svc"
ipAddresses:
- "127.0.0.1"
issuerRef:
name: ca-cluster-issuer
kind: ClusterIssuer
EOF</code>Extract the certificate and key:
<code># Service certificate
$ kubectl get secret vpa-cert -ojsonpath='{.data.tls\.crt}' | base64 -d > /tmp/serverCert.pem
$ kubectl get secret vpa-cert -ojsonpath='{.data.tls\.key}' | base64 -d > /tmp/serverKey.pem
# CA certificate
$ kubectl -n kube-system get secret ca-clusterissuer-secret -ojsonpath='{.data.tls\.crt}' | base64 -d > /tmp/caCert.pem
$ kubectl -n kube-system get secret ca-clusterissuer-secret -ojsonpath='{.data.tls\.key}' | base64 -d > /tmp/caKey.pem</code>Create a secret containing the certificates:
<code>$ kubectl create secret --namespace=kube-system generic vpa-tls-certs \
--from-file=/tmp/caKey.pem \
--from-file=/tmp/caCert.pem \
--from-file=/tmp/serverKey.pem \
--from-file=/tmp/serverCert.pem
secret/vpa-tls-certs created</code>Download VPA source files and generate manifests:
<code>$ curl -L -O https://github.com/kubernetes/autoscaler/archive/refs/tags/vertical-pod-autoscaler-1.2.1.tar.gz
$ tar xf vertical-pod-autoscaler-1.2.1.tar.gz
$ ./autoscaler-vertical-pod-autoscaler-1.2.1/vertical-pod-autoscaler/hack/vpa-process-yamls.sh print | sudo tee /etc/kubernetes/addons/vertical-pod-autoscaler.yaml</code>Adjust the image registry and apply the manifests:
<code>$ sudo sed -ri '[email protected]@core.jiaxzeng.com/library@g' /etc/kubernetes/addons/vertical-pod-autoscaler.yaml
$ kubectl apply -f /etc/kubernetes/addons/vertical-pod-autoscaler.yaml</code>Verify VPA pods are running:
<code>$ kubectl -n kube-system get pod | grep vpa
vpa-admission-controller-... 1/1 Running
vpa-recommender-... 1/1 Running
vpa-updater-... 1/1 Running</code>Practical VPA Configuration
Example deployment resources:
CPU request: 10m, limit: 100m
Memory request: 10Mi, limit: 100Mi
Create a VPA resource for the deployment:
<code>$ cat <<'EOF' | kubectl apply -f -
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: simple
namespace: default
spec:
updatePolicy:
updateMode: Auto
targetRef:
apiVersion: apps/v1
name: simple
kind: Deployment
resourcePolicy:
containerPolicies:
- containerName: "*"
controlledResources:
- cpu
- memory
maxAllowed:
cpu: 1000m
memory: 1024Mi
EOF</code>Tip: Both CPU and memory must change together to trigger an update; the example only configures CPU.
Check VPA status:
<code>$ kubectl get vpa
NAME MODE CPU MEM PROVIDED AGE
simple Auto True 1s
$ kubectl get vpa simple
NAME MODE CPU MEM PROVIDED AGE
simple Auto 25m True 4m7s</code>During a load test, VPA will adjust pod resources. Example load test using
wrk:
<code>$ kubectl exec -it deploy/tools -- wrk -c 50 -t 5 -d 60s http://simple.default.svc/who/hostname</code>Observe VPA recommendations and pod changes:
<code>$ kubectl get vpa simple -w
... (output shows CPU request increasing over time) ...
$ kubectl get pod -l app=simple -w
... (pods are terminated and recreated with new resources) ...</code>Final pod resource configuration after VPA adjustments:
<code>$ kubectl get pod -l app=simple -o yaml | grep -A6 resources:
resources:
limits:
cpu: 2960m
memory: 100Mi
requests:
cpu: 296m
memory: 10Mi</code>Tip: The deployment spec remains unchanged; VPA admission controller mutates pod requests based on recommendations. The displayed VPA values are the request settings; limits are derived from the original limit/request ratio.
Conclusion
After following this tutorial you should be able to deploy and use VPA in a Kubernetes cluster, simplifying resource management and enhancing system adaptability.
VPA Limitations
Updating running pod resources is experimental and causes pod recreation and possible rescheduling.
VPA cannot run alongside the Horizontal Pod Autoscaler (HPA) that monitors CPU/memory unless HPA targets custom metrics.
VPA handles most OOM events but does not guarantee coverage for every scenario.
Linux Ops Smart Journey
The operations journey never stops—pursuing excellence endlessly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.