Vertical Pod Autoscaler automatically right-sizes container CPU and memory requests based on actual usage. When it works, your cluster runs leaner and cheaper. When it breaks — admission webhook down, recommender stuck, OOMKills spiking — workloads crash or waste money and nobody notices until the next billing cycle or a 3 AM page.
This tutorial shows you how to monitor VPA itself so your cost optimization stays reliable.
What Is Vertical Pod Autoscaler?
VPA has three components that each need to stay healthy:
- Recommender — watches historical resource usage and computes optimal
requestandlimitvalues - Updater — evicts pods whose current requests deviate too far from recommendations so they restart with better values
- Admission Controller — mutating webhook that patches resource requests on new pods at creation time
A failure in any component silently degrades the others. The Recommender going down means stale recommendations. The Admission Controller going down means pods launch with the old (wasteful or too-small) requests defined in the Deployment spec.
Why VPA Monitoring Matters
VPA failures are silent by default:
Admission webhook downtime — if the admission controller pod crashes, Kubernetes falls back to the resource requests in your Deployment manifests. Pods may OOMKill (requests too low) or waste memory for weeks (requests too high) while Kubernetes reports everything healthy.
Recommender data staleness — the Recommender needs a continuous stream of metrics from the Metrics Server or Prometheus. If that pipeline breaks, recommendations freeze. VPA keeps applying the last known values, which may no longer reflect current load patterns.
Updater over-eviction — under high churn, the Updater can evict healthy pods too aggressively, creating rolling restarts that look like a deployment rollout but are actually VPA adjusting to a load spike.
Mode misconfiguration — VPA updateMode: Auto and Off behave very differently. A misconfigured VPA object silently stops adjusting resources without any error visible to engineers.
What You'll Set Up
- External health monitoring for the VPA admission webhook endpoint
- Heartbeat monitoring to verify the Recommender is updating recommendations
- Alert routing for OOMKill spikes and webhook latency
You'll need a free Vigilmon account — no credit card required.
Step 1: Expose a Health Endpoint for the VPA Admission Controller
The VPA Admission Controller runs as a webhook server. Expose its /healthz endpoint through an Ingress or NodePort so Vigilmon can probe it externally:
# vpa-webhook-monitor-service.yaml
apiVersion: v1
kind: Service
metadata:
name: vpa-webhook-monitor
namespace: kube-system
spec:
selector:
app: vpa-admission-controller
ports:
- name: https
port: 443
targetPort: 8000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vpa-webhook-health
namespace: kube-system
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: vpa-health.internal.yourdomain.com
http:
paths:
- path: /healthz
pathType: Prefix
backend:
service:
name: vpa-webhook-monitor
port:
number: 443
Verify the endpoint returns 200 before adding it to Vigilmon:
curl -sk https://vpa-health.internal.yourdomain.com/healthz
# Expected: ok
Step 2: Add an HTTP Monitor for the VPA Admission Webhook
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS
- Set the URL:
https://vpa-health.internal.yourdomain.com/healthz - Set the check interval to 1 minute
- Under Expected response, configure:
- Status code:
200 - Response body contains:
ok - Response time threshold:
500ms
- Status code:
- Save the monitor
If the VPA admission controller crashes or becomes unreachable, you'll receive an alert within 2 minutes — long before misconfigured pod resources cause production impact.
Step 3: Heartbeat Monitoring for the VPA Recommender
The Recommender updates recommendations on a continuous loop. A CronJob that verifies recommendations are fresh and pings Vigilmon on success gives you a dead-man's switch:
# save as vpa-recommender-check.sh
#!/bin/bash
set -e
NAMESPACE="${VPA_NAMESPACE:-kube-system}"
MAX_AGE_SECONDS=600 # alert if no recommendation updated in 10 minutes
HEARTBEAT_URL="${VIGILMON_HEARTBEAT_URL}"
# Find the most recently updated VPA recommendation
LATEST=$(kubectl get vpa -A -o json | \
jq -r '[.items[].status.recommendation.containerRecommendations[0].target] |
map(select(. != null)) | length')
if [ "$LATEST" -eq "0" ]; then
echo "ERROR: No VPA recommendations found — Recommender may be stalled"
exit 1
fi
echo "VPA Recommender active: $LATEST container recommendations present"
curl -fsS "$HEARTBEAT_URL" > /dev/null
echo "Heartbeat sent."
Deploy as a Kubernetes CronJob:
apiVersion: batch/v1
kind: CronJob
metadata:
name: vpa-recommender-heartbeat
namespace: kube-system
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
serviceAccountName: vpa-monitor-sa
containers:
- name: check
image: bitnami/kubectl:latest
env:
- name: VIGILMON_HEARTBEAT_URL
valueFrom:
secretKeyRef:
name: vigilmon-secrets
key: vpa-recommender-heartbeat-url
command: ["/bin/sh", "-c"]
args: ["/scripts/vpa-recommender-check.sh"]
volumeMounts:
- name: scripts
mountPath: /scripts
volumes:
- name: scripts
configMap:
name: vpa-check-scripts
defaultMode: 0755
Set up the heartbeat in Vigilmon:
- Go to Monitors → New Monitor → Heartbeat
- Name it
VPA Recommender Active - Set the expected interval: 5 minutes
- Set grace period: 3 minutes
- Copy the ping URL into your Kubernetes Secret
Step 4: OOMKill Rate Monitoring
OOMKill spikes indicate VPA is under-provisioning memory — either because the Recommender has stale data or because the updateMode is Off. Add a script that counts OOMKill events and reports them:
#!/bin/bash
# Check for recent OOMKills — run as a CronJob every 5 minutes
THRESHOLD=3
WINDOW_MINUTES=5
OOMKILLS=$(kubectl get events -A --field-selector reason=OOMKilling \
--sort-by='.lastTimestamp' -o json | \
jq --arg cutoff "$(date -u -d "$WINDOW_MINUTES minutes ago" +%Y-%m-%dT%H:%M:%SZ)" \
'[.items[] | select(.lastTimestamp > $cutoff)] | length')
if [ "$OOMKILLS" -ge "$THRESHOLD" ]; then
echo "WARNING: $OOMKILLS OOMKills in last ${WINDOW_MINUTES}m — VPA may be under-provisioning"
# Do NOT ping heartbeat — allow the monitor to fire
exit 1
fi
echo "OOMKill rate normal: $OOMKILLS events in last ${WINDOW_MINUTES}m"
curl -fsS "$VIGILMON_OOMKILL_HEARTBEAT_URL" > /dev/null
Set the heartbeat interval to 5 minutes with a 6-minute grace period. If OOMKills exceed the threshold, the heartbeat goes silent and Vigilmon fires an alert.
Step 5: Alert Routing
Slack Alerts for VPA Issues
- In Vigilmon go to Alert Channels → New Channel → Webhook
- Add your Slack Incoming Webhook URL
- Assign the channel to all three VPA monitors
A typical alert payload when the admission controller goes down:
{
"monitor_name": "VPA Admission Webhook /healthz",
"status": "down",
"url": "https://vpa-health.internal.yourdomain.com/healthz",
"started_at": "2026-07-12T08:15:00Z",
"duration_seconds": 0,
"regions_failing": ["eu-west", "us-east"]
}
Recommended Alert Thresholds
| Monitor | Interval | Grace Period | Action | |---|---|---|---| | VPA Admission Webhook | 1 min | — | Page on-call immediately | | VPA Recommender heartbeat | 5 min | 3 min | Page on-call | | OOMKill rate | 5 min | 6 min | Alert SRE channel |
Key Metrics to Watch
| Metric | What it signals | Threshold to alert |
|---|---|---|
| Admission webhook response time | Controller load / degradation | > 500ms |
| Recommender heartbeat age | Recommender stall | > 10 minutes |
| OOMKill event count | Under-provisioning | > 3 in 5 minutes |
| Pods evicted by Updater | Over-aggressive tuning | > 10% of pod count per hour |
| VPA objects with Off mode | Cost opt disabled | > 0 unexpected |
Summary
VPA silently breaks in ways that cost you money or cause pod crashes. External monitoring closes the gap:
| Component | What breaks silently | Vigilmon monitor type |
|---|---|---|
| Admission Controller | Pods launch with wrong resources | HTTP /healthz monitor |
| Recommender | Stale recommendations | Heartbeat monitor |
| OOMKill rate | Under-provisioning | Heartbeat with threshold script |
Start free at vigilmon.online — your first VPA monitor is running in under two minutes.