<h2>Horizontal Pod Autoscaler: Visão Geral e Arquitetura</h2>
<p>O Horizontal Pod Autoscaler (HPA) é um recurso nativo do Kubernetes que automatiza a escalabilidade horizontal de suas aplicações. Em vez de você gerenciar manualmente o número de réplicas de um Deployment, StatefulSet ou ReplicaSet, o HPA monitora métricas em tempo real e ajusta o número de pods baseado em regras que você define. Esse comportamento é fundamental para aplicações que enfrentam variação de carga.</p>
<p>A arquitetura do HPA funciona em um ciclo contínuo: o controller do HPA consulta as métricas da sua aplicação (CPU, memória ou métricas customizadas) a cada 15 segundos por padrão, compara com os thresholds configurados e toma decisões de scale-up ou scale-down. Esse processo é totalmente automatizado e reduz significativamente a necessidade de intervenção manual, economizando recursos e melhorando a disponibilidade da aplicação durante picos de demanda.</p>
<h3>Pré-requisitos Técnicos</h3>
<p>Para que o HPA funcione corretamente, você precisa de dois componentes críticos: o Metrics Server e os resource requests definidos nos seus pods. O Metrics Server coleta métricas de CPU e memória dos nodes e as expõe via API, permitindo que o HPA tome decisões baseadas em dados reais. Sem ele, o HPA não consegue funcionar. Além disso, <strong>todo pod monitorado pelo HPA precisa ter requests de CPU e memória declarados</strong>, pois o HPA calcula percentuais de utilização com base nesses valores.</p>
<pre><code class="language-yaml"># Exemplo de Deployment com requests e limits
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-exemplo
spec:
replicas: 2
selector:
matchLabels:
app: app-exemplo
template:
metadata:
labels:
app: app-exemplo
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
cpu: 100m # 0.1 CPU - OBRIGATÓRIO para HPA
memory: 128Mi # 128 MB - OBRIGATÓRIO para HPA
limits:
cpu: 500m
memory: 512Mi
ports:
- containerPort: 80</code></pre>
<h2>Métricas do HPA: Tipos e Cálculos</h2>
<p>O HPA suporta três categorias principais de métricas: métricas de recursos (CPU e memória), métricas customizadas e métricas externas. Cada uma tem um propósito específico e é calculada de forma diferente pelo controller.</p>
<h3>Métricas de Recursos (CPU e Memória)</h3>
<p>As métricas de recursos são as mais simples e diretas. O HPA calcula a porcentagem de utilização de CPU e memória comparando o uso atual com o request definido no container. Por exemplo, se você configurar um request de 100m (miliCPU) e o pod está usando 50m, a utilização está em 50%. O cálculo é feito para todos os pods de um Deployment e depois é feita uma média: se você tem 3 pods, o HPA calcula a média de todos os três antes de tomar a decisão de escalar.</p>
<pre><code class="language-yaml"># Exemplo: HPA baseado em CPU
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa-cpu
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-exemplo
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # Escala quando CPU média > 70%
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15</code></pre>
<p>No exemplo acima, o HPA monitorará a CPU média de todos os pods do Deployment <code>app-exemplo</code>. Quando a média ultrapassar 70% do request configurado (100m × 0.70 = 70m), o HPA começará a adicionar pods. O comportamento de scale é controlado pela seção <code>behavior</code> que detalharemos mais adiante.</p>
<h3>Métricas Customizadas</h3>
<p>Métricas customizadas são ideais quando você quer escalar baseado em lógica de negócio específica: número de requisições por segundo, tamanho de fila, latência, ou qualquer outro indicador relevante para sua aplicação. Para usar métricas customizadas, você precisa de um provedor de métricas, como o Prometheus com um adapter customizado.</p>
<pre><code class="language-yaml"># Exemplo: HPA baseado em métrica customizada (requisições por segundo)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa-custom
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-exemplo
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 1000 # Escala quando RPS médio > 1000
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80 # Escala quando CPU > 80%</code></pre>
<p>Neste exemplo, o HPA usa <strong>dois critérios simultaneamente</strong>: ele escalará quando qualquer um dos limites for atingido. Isso oferece mais controle e permite que sua aplicação responda a diferentes tipos de pressão. Se você exponha a métrica <code>http_requests_per_second</code> via Prometheus, o HPA a considerará nas decisões.</p>
<h3>Métricas Externas</h3>
<p>Métricas externas permitem integração com sistemas de monitoramento externos como Google Cloud Monitoring, AWS CloudWatch ou Datadog. Você referencia a métrica pelo nome e o HPA consulta o sistema externo para tomar decisões.</p>
<pre><code class="language-yaml"># Exemplo: HPA baseado em métrica externa (AWS SQS)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-hpa-sqs
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sqs-worker
minReplicas: 1
maxReplicas: 50
metrics:
- type: External
external:
metric:
name: sqs_queue_depth
selector:
matchLabels:
queue-name: minha-fila
target:
type: AverageValue
averageValue: "30" # 30 mensagens por pod</code></pre>
<h2>Thresholds, Comportamento e Estratégias de Escala</h2>
<p>Os thresholds definem os limites que disparam a escalabilidade, mas o comportamento da escala (como rápido ela ocorre, com que agressividade) é controlado pela seção <code>behavior</code> do HPA. Essa é uma das partes mais críticas e frequentemente negligenciada na configuração.</p>
<h3>Configuração de Thresholds</h3>
<p>Um threshold é simplesmente o valor limite que, quando atingido, causa uma ação de escala. No exemplo anterior de CPU, 70% era o threshold. O HPA calcula se a métrica atual está acima ou abaixo do threshold e faz as contas sobre quantos pods são necessários para trazer a métrica de volta ao nível desejado.</p>
<p>A fórmula básica que o HPA usa internamente é:</p>
<pre><code>desiredReplicas = ceil[currentReplicas × (currentMetricValue / targetMetricValue)]</code></pre>
<p>Se você tem 5 pods usando 85% de CPU e seu target é 70%, o cálculo seria: <code>ceil[5 × (85 / 70)] = ceil[6.07] = 7 pods</code>. Isso é uma decisão de scale-up. Inversamente, se estiver usando 35% de CPU, o cálculo daria menos replicas e ocorreria um scale-down.</p>
<h3>Behavior: Controlando Agressividade</h3>
<p>A seção <code>behavior</code> controla <strong>como</strong> e <strong>com que rapidez</strong> o HPA escala. Sem ela configurada corretamente, você pode enfrentar "flapping" — escalas constantes para cima e para baixo — ou respostas muito lentas a picos de carga.</p>
<pre><code class="language-yaml"># Exemplo completo com behavior refinado
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa-produção
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: aplicacao-critica
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
Configuração para SCALE UP (aumentar pods)
scaleUp:
stabilizationWindowSeconds: 0 # Sem espera, reage rápido
policies:
- type: Percent
value: 100 # Dobra a cada período
periodSeconds: 15
- type: Pods
value: 4 # Ou adiciona 4 pods (o que for maior)
periodSeconds: 15
selectPolicy: Max # Escolhe a política que resulta em mais pods
Configuração para SCALE DOWN (reduzir pods)
scaleDown:
stabilizationWindowSeconds: 300 # Espera 5 min antes de desescalar
policies:
- type: Percent
value: 50 # Remove até 50% dos pods
periodSeconds: 15
- type: Pods
value: 2 # Ou remove 2 pods no máximo
periodSeconds: 15
selectPolicy: Min # Escolhe a política que resulta em menos pods</code></pre>
<h3>Entendendo Stabilization Window</h3>
<p>A <code>stabilizationWindowSeconds</code> é um conceito crucial. No scale-up, geralmente colocamos <code>0</code> para responder imediatamente a picos. No scale-down, colocamos um valor maior (300 segundos = 5 minutos é comum) para evitar remover pods prematuramente quando a carga cai temporariamente. Isso previne flapping e garante estabilidade.</p>
<p>Durante a janela de estabilização, o HPA procura pelo <strong>maior valor de métrica observado</strong> naquele período. Isso significa que se em 5 minutos de scale-down a métrica subir novamente, o HPA pode cancelar o scale-down planejado. É um mecanismo de amortecimento muito inteligente.</p>
<h2>Comportamento Prático e Monitoramento</h2>
<p>Entender como o HPA se comporta em tempo real é essencial para debugging e otimização. Você pode inspecionar o estado do HPA, seus eventos e decisões através de comandos kubectl e pela análise de logs.</p>
<h3>Inspecionando Status do HPA</h3>
<pre><code class="language-bash"># Ver status atual do HPA
kubectl get hpa -n seu-namespace
Ver detalhes completos (muito útil!)
kubectl describe hpa app-hpa-cpu -n seu-namespace
Exemplo de saída do describe:
Name: app-hpa-cpu
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Mon, 15 Jan 2024 10:30:00 +0000
Reference: Deployment/app-exemplo
Metrics: ( current / target )
resource cpu on pods ( 65% / 70% )
Min replicas: 2
Max replicas: 10
Deployment pods: 5 current / 5 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale recommended size matches current size
ScalingActive True ValidMetricsFound the HPA was able to compute the replica count
ScalingLimited False DesiredWithinRange the desired count is within the acceptable range</code></pre>
<p>Essa saída te diz exatamente o que está acontecendo: qual é o uso atual, qual é o target, quantos pods existem, e por que o HPA está ou não escalando.</p>
<h3>Monitorando Decisões do HPA</h3>
<p>O HPA registra eventos importantes no Kubernetes. Você pode consultá-los para entender todas as decisões:</p>
<pre><code class="language-bash"># Ver eventos do HPA em tempo real
kubectl get events -n seu-namespace --field-selector involvedObject.name=app-hpa-cpu --sort-by='.lastTimestamp'
Exemplo de eventos:
LAST SEEN TYPE REASON OBJECT MESSAGE
2m Normal SuccessfulRescale hpa/app-hpa-cpu New size: 7; reason: cpu resource utilization (actual: 75%, target: 70%)
5m Normal SuccessfulRescale hpa/app-hpa-cpu New size: 5; reason: cpu resource utilization (actual: 68%, target: 70%)</code></pre>
<h3>Caso Prático: Diagnóstico de Problemas</h3>
<p>Um problema comum é o HPA não funcionar. Aqui está como diagnosticar:</p>
<pre><code class="language-bash"># 1. Verificar se Metrics Server está instalado
kubectl get deployment metrics-server -n kube-system
2. Verificar se métricas estão disponíveis
kubectl top pods -n seu-namespace
kubectl top nodes
3. Verificar requests nos containers
kubectl get pods seu-pod -o yaml | grep -A 10 "resources:"
4. Se nada disso mostrar métricas, o HPA ficará em estado:
ScalingActive: False, Reason: UnableComputeReplicaCountReason</code></pre>
<p>Se você vir <code>ScalingActive: False</code>, o problema é falta de métricas. Sempre comece verificando o Metrics Server e os requests nos containers.</p>
<h2>Exemplos Avançados: Combinando Tudo</h2>
<p>Vamos construir um exemplo realista que combina tudo que aprendemos:</p>
<pre><code class="language-yaml"># Aplicação web com auto-scaling inteligente
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-produção
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: minha-api:v1.2.0
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-produção-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-produção
minReplicas: 3 # Sempre manter ao menos 3 (alta disponibilidade)
maxReplicas: 50 # Não gastar demais em recursos
metrics:
Métrica 1: CPU é o trigger primário
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Métrica 2: Memória como failsafe
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 85
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 50
periodSeconds: 15
- type: Pods
value: 2
periodSeconds: 15
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300 # 5 minutos
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 1
periodSeconds: 60
selectPolicy: Min</code></pre>
<p>Neste exemplo produção:</p>
<ul>
<li><strong>Scale-up é agressivo</strong>: responde imediatamente e pode dobrar os pods (50% + limites significam crescimento rápido)</li>
<li><strong>Scale-down é conservador</strong>: aguarda 5 minutos e remove pods lentamente (10% + máximo 1 pod)</li>
<li><strong>Dois critérios de métrica</strong>: se CPU OU memória atingirem o limite, escala</li>
<li><strong>Min/Max realista</strong>: começa com 3 pods (redundância) e máximo 50 (custo controlado)</li>
</ul>
<h2>Conclusão</h2>
<p>Três aprendizados fundamentais que você deve levar daqui: primeiro, o HPA é inútil sem Metrics Server e requests bem definidos nos containers — esses são pré-requisitos absolutos, não opcionais. Segundo, o <code>behavior</code> é mais importante que os thresholds — você pode ter um threshold perfeito, mas com um behavior mal configurado, sua aplicação sofrerá com flapping ou respostas lentas a picos. Terceiro, sempre monitore os eventos do HPA com <code>describe</code> e <code>events</code> para entender exatamente o que está acontecendo; o Kubernetes oferece visibilidade completa, basta saber onde olhar.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/" target="_blank" rel="noopener noreferrer">Documentação Oficial do HPA - Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#horizontalpodautoscaler-v2-autoscaling" target="_blank" rel="noopener noreferrer">API Reference: HorizontalPodAutoscaler v2</a></li>
<li><a href="https://github.com/kubernetes-sigs/metrics-server" target="_blank" rel="noopener noreferrer">Metrics Server - GitHub</a></li>
<li><a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/" target="_blank" rel="noopener noreferrer">Best Practices for HPA - Kubernetes Documentation</a></li>
<li><a href="https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/" target="_blank" rel="noopener noreferrer">Understanding Kubernetes Resource Requests and Limits</a></li>
</ul>
<p><!-- FIM --></p>