Escalonamento
Esta aula aborda o escalonamento em Kubernetes, cobrindo o Horizontal Pod Autoscaler (HPA), a definição de recursos (requests/limits), o escalonamento de nós e as principais estratégias de escalonamento. O aluno aprenderá a configurar e gerenciar o dimensionamento automático de aplicações e infraestrutura.
Nesta aula, vamos explorar os mecanismos de escalonamento em Kubernetes, essenciais para garantir que suas aplicações tenham os recursos necessários para atender à demanda, sem desperdício de infraestrutura. O escalonamento é uma das principais vantagens de usar orquestradores de contêineres, pois permite ajustar dinamicamente o número de réplicas de pods e até mesmo o tamanho do cluster.
Vamos nos concentrar em três aspectos fundamentais: o Horizontal Pod Autoscaler (HPA), que ajusta automaticamente o número de pods com base em métricas; a definição de recursos (requests e limits) que influencia o agendamento e o desempenho; e o escalonamento de nós, que ajusta a capacidade do cluster. Também discutiremos estratégias de escalonamento, incluindo o escalonamento preditivo e o uso de métricas customizadas.
Horizontal Pod Autoscaler
O Horizontal Pod Autoscaler (HPA) é um recurso do Kubernetes que ajusta automaticamente o número de réplicas de um Deployment, ReplicaSet ou StatefulSet com base em métricas observadas, como uso de CPU, memória ou métricas customizadas. Ele faz parte do controlador de autoscaling do kube-controller-manager e opera de forma contínua, verificando as métricas em intervalos regulares (padrão: 30 segundos).
O HPA funciona em um ciclo: ele consulta as métricas (geralmente via Metrics Server), calcula o número desejado de réplicas com base na utilização atual e no valor alvo, e atualiza o recurso de escala (como um Deployment) para ajustar o número de pods. A fórmula básica é:
desiredReplicas = ceil(currentReplicas * (currentMetric / targetMetric))Por exemplo, se você define um alvo de 50% de utilização de CPU e os pods atuais estão usando 100%, o HPA dobrará o número de réplicas (com um teto máximo definido).
Para criar um HPA, você pode usar um arquivo YAML ou o comando kubectl autoscale. Vamos ver um exemplo de manifest:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: meu-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: minha-aplicacao
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70Nesse exemplo, o HPA vai escalar a aplicação entre 2 e 10 réplicas, tentando manter a utilização de CPU em 50% e a de memória em 70%. Ele usa a média de utilização entre todos os pods.
É importante destacar que o HPA requer o Metrics Server instalado no cluster para coletar métricas de recursos. Sem ele, o HPA não funciona.
Recursos (requests/limits)
Definir recursos (requests e limits) é fundamental para o escalonamento eficiente. Os requests indicam a quantidade mínima de CPU e memória que o contêiner precisa, e são usados pelo agendador (scheduler) para decidir em qual nó colocar o pod. Já os limits definem o máximo que o contêiner pode usar; se exceder, o Kubernetes pode restringir ou até matar o processo (no caso de CPU, pode throttling; no caso de memória, OOMKill).
Quando você define requests, o HPA pode usar essas métricas para calcular a utilização. Por exemplo, se um pod tem request de CPU de 100m (0.1 vCPU) e o alvo é 50%, o HPA tentará manter o uso em 50% de 100m, ou seja, 50m. Isso é útil para dimensionar a capacidade de forma previsível.
Vejamos um exemplo de definição de recursos em um Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: minha-aplicacao
spec:
replicas: 2
selector:
matchLabels:
app: minha-aplicacao
template:
metadata:
labels:
app: minha-aplicacao
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"Nesse exemplo, cada pod solicita 100m de CPU e 128Mi de memória, com limites de 200m e 256Mi. O agendador usará esses valores para garantir que o nó tenha capacidade suficiente. Se um nó tiver, por exemplo, 1 CPU (1000m), ele poderá agendar no máximo 10 pods com request de 100m cada.
Uma boa prática é definir requests realistas com base no consumo típico da aplicação, e limits para evitar que um contêiner consuma todos os recursos do nó. Isso também ajuda no escalonamento, pois o HPA considera os requests para calcular a utilização.
Escalonamento de nós (visão geral)
O escalonamento de nós, também conhecido como cluster autoscaling, ajusta o número de nós do cluster com base na demanda de recursos. Em provedores de nuvem, isso geralmente é feito por componentes como o Cluster Autoscaler, que observa pods não agendáveis (Pending) e adiciona ou remove nós automaticamente.
O Cluster Autoscaler funciona da seguinte forma: ele verifica se há pods em estado Pending que não podem ser agendados por falta de recursos. Se houver, ele aumenta o número de nós (criando novas VMs). Quando há nós subutilizados por um período, ele pode removê-los. Ele é integrado com a API do provedor de nuvem (AWS, GCP, Azure) para gerenciar os nós.
Para usar o Cluster Autoscaler, você precisa configurar o provedor de nuvem e o grupo de nós (node group) com limites mínimo e máximo. Por exemplo, no AWS EKS, você pode usar o auto scaling group com políticas de escala. No GKE, você pode habilitar o autoscaling no node pool.
Vejamos um exemplo de configuração no GKE:
gcloud container node-pools create meu-pool \
--cluster meu-cluster \
--num-nodes 3 \
--min-nodes 1 \
--max-nodes 10 \
--enable-autoscalingEsse comando cria um node pool com autoscaling habilitado, variando de 1 a 10 nós. O Cluster Autoscaler ajustará o número de nós conforme a demanda.
É importante notar que o escalonamento de nós é mais lento que o de pods (leva minutos), então é comum combinar o HPA (rápido) com o Cluster Autoscaler (lento) para uma resposta eficiente.
Estratégias
Existem várias estratégias de escalonamento que podem ser adotadas, dependendo do cenário. Vamos listar as principais:
- Escalonamento reativo: baseado em métricas em tempo real, como CPU e memória. É o padrão do HPA.
- Escalonamento preditivo: usa previsões de carga futura (ex.: com base em histórico) para ajustar recursos antecipadamente. Pode ser feito com ferramentas como o KEDA (Kubernetes Event-driven Autoscaling) e métricas customizadas.
- Escalonamento por eventos: usa eventos de filas (como Kafka, RabbitMQ) ou outros sinais para escalar. O KEDA é uma ótima opção para isso.
- Escalonamento sazonal: ajusta recursos com base em padrões sazonais (ex.: horário de pico). Pode ser implementado com cron jobs ou autoscaling por horário.
- Escalonamento de nós: além do Cluster Autoscaler, pode-se usar escalonamento manual ou baseado em agendamento.
Uma prática comum é combinar o HPA com o Cluster Autoscaler para obter escalonamento horizontal de pods e nós. Além disso, o uso de métricas customizadas (como requisições por segundo) pode ser mais adequado para aplicações web do que apenas CPU/memória.
Veja um exemplo de HPA com métricas customizadas usando o KEDA (embora não seja o foco, é uma estratégia avançada):
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: meu-scaledobject
spec:
scaleTargetRef:
name: minha-aplicacao
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
metricName: http_requests_total
query: sum(rate(http_requests_total[2m]))
threshold: "100"Esse exemplo escalaria a aplicação com base no número de requisições HTTP por segundo, usando o Prometheus como fonte de métricas.
Boas práticas e observações finais
Ao implementar escalonamento, considere as seguintes boas práticas:
- Defina sempre requests e limits para todos os contêineres.
- Use o HPA com alvos realistas (por exemplo, 50-70% de CPU) para evitar flutuações constantes.
- Configure o HPA com um período de estabilização (stabilizationWindow) para evitar mudanças bruscas.
- Combine HPA com Cluster Autoscaler para lidar com picos de demanda.
- Monitore o desempenho e ajuste os alvos conforme o comportamento da aplicação.
- Use métricas customizadas quando a CPU/memória não refletirem a real carga de trabalho.
O escalonamento é uma área complexa, mas dominá-lo é essencial para operar clusters Kubernetes de forma eficiente e econômica.
Referências
- Documentação oficial do Horizontal Pod Autoscaler
- Gerenciamento de Recursos em Contêineres
- Cluster Autoscaler no GitHub
- GKE Cluster Autoscaler
- Labels e Anotações do Kubernetes
- KEDA - Escalonamento baseado em eventos
- Passo a passo do HPA
Exercícios
- Exercício 1: Crie um Deployment com 2 réplicas de um contêiner nginx, com requests de CPU de 100m e limits de 200m. Em seguida, crie um HPA que mantenha a utilização de CPU em 50%, com mínimo de 2 e máximo de 8 réplicas. Escreva os comandos YAML ou kubectl necessários.✓ Resposta:
# Deployment YAML (deployment.yaml) apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 resources: requests: cpu: "100m" limits: cpu: "200m" --- # HPA YAML (hpa.yaml) apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx-deployment minReplicas: 2 maxReplicas: 8 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - Exercício 2: Explique a diferença entre requests e limits e como eles afetam o agendamento de pods e o escalonamento.✓ Resposta: Requests são a quantidade mínima de recursos que o contêiner garante, usada pelo scheduler para decidir em qual nó colocar o pod. Limits são o máximo permitido; se o contêiner tentar usar mais, pode ser limitado (CPU) ou morto (memória). No escalonamento, o HPA usa os requests para calcular a utilização, portanto, requests realistas são importantes para um escalonamento preciso.
- Exercício 3: Cite três estratégias de escalonamento além do HPA e explique brevemente cada uma.✓ Resposta: 1) Escalonamento preditivo: usa previsões de carga futura para ajustar recursos antecipadamente (ex.: com base em histórico). 2) Escalonamento por eventos: usa eventos de filas ou mensageria para escalar (ex.: KEDA). 3) Escalonamento de nós: ajusta o número de nós do cluster com Cluster Autoscaler.
- Exercício 4: Suponha que você tenha um Deployment com 4 réplicas e o HPA configurado para manter a utilização de CPU em 50%. As métricas atuais mostram que a utilização média de CPU é de 80%. Qual será o novo número de réplicas (considerando o teto máximo de 10)?✓ Resposta: Usando a fórmula: desiredReplicas = ceil(4 * (80/50)) = ceil(4 * 1.6) = ceil(6.4) = 7. Como 7 <= 10, o novo número de réplicas será 7.
- Exercício 5: Descreva como o Cluster Autoscaler funciona e qual a sua principal limitação em comparação com o HPA.✓ Resposta: O Cluster Autoscaler observa pods não agendáveis (Pending) e adiciona nós ao cluster para acomodá-los; também remove nós subutilizados. Sua principal limitação é a latência: criar novos nós pode levar minutos, enquanto o HPA escala pods em segundos. Portanto, é recomendável combinar ambos para uma resposta rápida e capacidade adequada.