Skip to content

GKE Scaling Guide

Complete guide to autoscaling in Google Kubernetes Engine (GKE), covering Horizontal Pod Autoscaler (HPA), Vertical Pod Autoscaler (VPA), and Cluster Autoscaler.

Scaling Overview

Scaling Types

AutoscalerScalesBased OnUse Case
HPAPod replicasCPU, memory, custom metricsVariable traffic
VPAPod resourcesResource usageRight-sizing
Cluster AutoscalerNode countPending Pods, utilizationCapacity
NAPNode poolsPod requirementsDiverse workloads

Horizontal Pod Autoscaler (HPA)

Automatically adjusts the number of Pod replicas based on metrics.

HPA Algorithm

Formula: desiredReplicas = ceil(currentReplicas * (currentMetric / targetMetric))

Basic HPA (CPU)

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

HPA with Multiple Metrics

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: multi-metric-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
  # Scale on CPU
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  # Scale on Memory
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  # Scale on custom metric (requests per second)
  - type: Pods
    pods:
      metric:
        name: requests_per_second
      target:
        type: AverageValue
        averageValue: "1000"
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15

HPA Metric Types

TypeDescriptionExample
ResourceCPU or memory utilizationCPU at 50%
PodsCustom metric per PodRequests/sec
ObjectMetric from another K8s objectQueue length
ExternalMetric from outside clusterPub/Sub backlog

HPA Behavior Configuration


Vertical Pod Autoscaler (VPA)

Automatically adjusts CPU and memory requests/limits.

VPA Configuration

yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: Auto  # Off, Initial, Recreate, Auto
  resourcePolicy:
    containerPolicies:
    - containerName: '*'
      minAllowed:
        cpu: 100m
        memory: 128Mi
      maxAllowed:
        cpu: 4
        memory: 8Gi
      controlledResources: ["cpu", "memory"]

VPA Update Modes

ModeBehavior
OffOnly provides recommendations
InitialSets resources only at Pod creation
RecreateEvicts and recreates Pods to apply
AutoSame as Recreate (may change)

VPA Recommendations Only

yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Off"  # Only recommendations

Check recommendations:

bash
kubectl describe vpa my-app-vpa

Cluster Autoscaler

Automatically adds or removes nodes based on Pod scheduling needs.

How Cluster Autoscaler Works

Enable Cluster Autoscaler

bash
# Create cluster with autoscaling
gcloud container clusters create my-cluster \
    --enable-autoscaling \
    --min-nodes=1 \
    --max-nodes=10 \
    --num-nodes=3

# Enable on existing node pool
gcloud container node-pools update my-pool \
    --cluster=my-cluster \
    --enable-autoscaling \
    --min-nodes=1 \
    --max-nodes=10

Cluster Autoscaler Settings

SettingDescription
min-nodesMinimum nodes per zone
max-nodesMaximum nodes per zone
total-min-nodesTotal min across all zones
total-max-nodesTotal max across all zones

Autoscaling Profiles

bash
# Set optimize-utilization profile
gcloud container clusters update my-cluster \
    --autoscaling-profile=optimize-utilization
ProfileBehavior
balancedConservative scale-down (default)
optimize-utilizationAggressive scale-down, bin-packing

Scale-Down Conditions

Cluster Autoscaler removes nodes when:

  • Node utilization below 50% for 10+ minutes
  • All Pods can be rescheduled to other nodes
  • No Pods blocking scale-down

Pods That Block Scale-Down

Allow Pod Eviction

yaml
metadata:
  annotations:
    # Allow autoscaler to evict this Pod
    cluster-autoscaler.kubernetes.io/safe-to-evict: "true"

Node Auto-Provisioning (NAP)

Automatically creates and deletes node pools to match workload needs.

Enable NAP

bash
gcloud container clusters update my-cluster \
    --enable-autoprovisioning \
    --min-cpu=1 \
    --max-cpu=100 \
    --min-memory=1 \
    --max-memory=400

NAP Configuration

bash
gcloud container clusters update my-cluster \
    --enable-autoprovisioning \
    --autoprovisioning-config-file=config.yaml
yaml
# config.yaml
resourceLimits:
  - resourceType: cpu
    minimum: 1
    maximum: 100
  - resourceType: memory
    minimum: 1
    maximum: 400
  - resourceType: nvidia-tesla-t4
    minimum: 0
    maximum: 10
autoprovisioningLocations:
  - us-central1-a
  - us-central1-b
management:
  autoUpgrade: true
  autoRepair: true

Scaling Best Practices

Combining Autoscalers

CombinationRecommendation
HPA + Cluster AutoscalerRecommended for variable traffic
VPA (Off mode)Use for resource recommendations
HPA (CPU) + VPA (memory)Advanced, use with caution

Resource Requests Are Critical

yaml
# Always set resource requests for HPA to work
containers:
- name: app
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

Scaling Configuration Checklist

ItemDescription
Set resource requestsRequired for HPA and CA
Configure PDBProtect availability during scaling
Set HPA min/maxPrevent over/under scaling
Use stabilizationPrevent thrashing
Monitor metricsVerify scaling decisions

Quick Reference

Create HPA (CLI)

bash
# Create HPA targeting 50% CPU
kubectl autoscale deployment my-app \
    --cpu-percent=50 \
    --min=2 \
    --max=10

View Autoscaler Status

bash
# HPA status
kubectl get hpa
kubectl describe hpa my-app-hpa

# VPA status
kubectl get vpa
kubectl describe vpa my-app-vpa

# Cluster Autoscaler status
kubectl get configmap cluster-autoscaler-status -n kube-system -o yaml

Troubleshooting

IssueCheck
HPA not scalingResource requests set? Metrics available?
VPA not updatingUpdate mode? Pod can be evicted?
CA not adding nodesQuota? Max nodes? Pod schedulable?
CA not removing nodesPods blocking? PDB? System pods?

Last updated: December 2025

Built with VitePress & Mermaid diagrams