Por que Autoscaling?
Em ambientes cloud-native, a demanda varia constantemente. Sem autoscaling, você escolhe entre desperdiçar recursos (over-provisioning) ou ter indisponibilidade (under-provisioning).
Redução de Custos
Scale down automaticamente em períodos de baixa demanda
Performance
Scale up para manter latência e throughput sob carga
Resiliência
Distribuição automática de carga entre réplicas
Eficiência
Right-sizing automático de recursos (CPU/memória)
Tipos de Autoscaling no Kubernetes
HPA: Horizontal Pod Autoscaler
HPA ajusta o número de réplicas baseado em métricas.
HPA Básico com CPU
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # Espera 5min antes de scale down
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0 # Scale up imediato
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
HPA calcula utilização baseado em requests, não limits. Se você não definir requests, o HPA não funcionará corretamente.
HPA com Métricas Customizadas
Para escalar baseado em métricas de aplicação (latência, fila, etc.):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa-custom
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 20
metrics:
# Métrica do Prometheus Adapter
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
# Métrica externa (ex: SQS queue length)
- type: External
external:
metric:
name: sqs_messages_visible
selector:
matchLabels:
queue: myapp-queue
target:
type: AverageValue
averageValue: "30"
Prometheus Adapter para Métricas Custom
# prometheus-adapter-config
rules:
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_total$"
as: "${1}_per_second"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
VPA: Vertical Pod Autoscaler
VPA ajusta automaticamente os requests de CPU e memória dos pods.
Instalação do VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
Modos do VPA
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: myapp-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
updatePolicy:
updateMode: "Auto" # Off, Initial, ou Auto
resourcePolicy:
containerPolicies:
- containerName: myapp
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 4
memory: 8Gi
controlledResources: ["cpu", "memory"]
controlledValues: RequestsAndLimits
VPA e HPA usando CPU não devem ser usados juntos no mesmo deployment. Use VPA para ajustar resources e HPA com métricas customizadas, ou apenas um deles.
KEDA: Event-Driven Autoscaling
KEDA permite escalar baseado em eventos de diversas fontes: filas, streams, métricas, cron, etc.
Instalação do KEDA
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda \
--namespace keda \
--create-namespace
Scale to Zero
O diferencial do KEDA é permitir scale to zero (0 réplicas quando não há trabalho):
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: myapp-scaledobject
spec:
scaleTargetRef:
name: myapp
minReplicaCount: 0 # Scale to zero!
maxReplicaCount: 100
cooldownPeriod: 300 # Tempo antes de scale to zero
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
metricName: http_requests_total
query: sum(rate(http_requests_total{app="myapp"}[2m]))
threshold: "100"
KEDA com AWS SQS
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-consumer
spec:
scaleTargetRef:
name: sqs-consumer
minReplicaCount: 0
maxReplicaCount: 50
triggers:
- type: aws-sqs-queue
authenticationRef:
name: aws-credentials
metadata:
queueURL: https://sqs.us-east-1.amazonaws.com/123456789/my-queue
queueLength: "5" # 1 pod para cada 5 mensagens
awsRegion: us-east-1
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: aws-credentials
spec:
secretTargetRef:
- parameter: awsAccessKeyID
name: aws-secret
key: access-key
- parameter: awsSecretAccessKey
name: aws-secret
key: secret-key
KEDA com Kafka
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer
spec:
scaleTargetRef:
name: kafka-consumer
minReplicaCount: 1
maxReplicaCount: 100
triggers:
- type: kafka
metadata:
bootstrapServers: kafka:9092
consumerGroup: my-consumer-group
topic: my-topic
lagThreshold: "100" # Scale quando lag > 100
offsetResetPolicy: earliest
KEDA com Cron Schedule
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: scheduled-scaler
spec:
scaleTargetRef:
name: myapp
minReplicaCount: 1
maxReplicaCount: 20
triggers:
# Scale up no horário comercial
- type: cron
metadata:
timezone: America/Sao_Paulo
start: 0 8 * * 1-5 # 8h, seg-sex
end: 0 18 * * 1-5 # 18h, seg-sex
desiredReplicas: "10"
# Scale down fora do horário
- type: cron
metadata:
timezone: America/Sao_Paulo
start: 0 18 * * 1-5
end: 0 8 * * 1-5
desiredReplicas: "2"
Estratégias Combinadas
HPA + KEDA para Diferentes Triggers
# KEDA para scale to zero e triggers baseados em eventos
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: myapp-keda
spec:
scaleTargetRef:
name: myapp
minReplicaCount: 0
maxReplicaCount: 50
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
query: sum(rate(http_requests_total{app="myapp"}[2m]))
threshold: "50"
# HPA assume quando há pelo menos 1 replica (para CPU-based)
# Usar apenas se KEDA não cobrir seu caso de uso
Cluster Autoscaler
Escala os nodes do cluster quando pods não conseguem ser schedulados:
# Para AWS EKS
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-autoscaler-config
data:
parameters: |
{
"scale-down-delay-after-add": "10m",
"scale-down-unneeded-time": "10m",
"scale-down-utilization-threshold": "0.5",
"skip-nodes-with-local-storage": "false",
"expander": "least-waste"
}
VPA para right-sizing inicial + KEDA para scale to zero e eventos + Cluster Autoscaler para nodes = máxima eficiência de custos.
Métricas para Monitorar
# Prometheus rules para alertas de autoscaling
groups:
- name: autoscaling
rules:
- alert: HPAMaxedOut
expr: |
kube_horizontalpodautoscaler_status_current_replicas
== kube_horizontalpodautoscaler_spec_max_replicas
for: 15m
labels:
severity: warning
annotations:
summary: "HPA {{ $labels.horizontalpodautoscaler }} at max replicas"
- alert: HPANotScaling
expr: |
kube_horizontalpodautoscaler_status_desired_replicas
!= kube_horizontalpodautoscaler_status_current_replicas
for: 15m
labels:
severity: warning
Quer otimizar o autoscaling dos seus workloads Kubernetes? Fale com nossos especialistas para uma análise personalizada.