Cloud Native 12 min read

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.

Linux Ops Smart Journey
Linux Ops Smart Journey
Linux Ops Smart Journey
Master Kubernetes Vertical Pod Autoscaler (VPA): Installation, Configuration, and Real‑World Tuning

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-server

in the cluster.

Create a TLS certificate for VPA using a

Certificate

resource.

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.

cloud nativeKubernetesresource optimizationK8sVertical Pod AutoscalerVPA
Linux Ops Smart Journey
Written by

Linux Ops Smart Journey

The operations journey never stops—pursuing excellence endlessly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.