Domine o Agendamento e Gestão de Recursos no Kubernetes: Guia Completo para Estabilidade e Performance
Gerenciar recursos e alocar CPU e memória de forma eficiente é fundamental para garantir a estabilidade e o desempenho de um cluster Kubernetes. Além disso, compreender conceitos como requests vs limits, classes de Quality of Service (QoS), e os principais mecanismos de agendamento — afinidade, anti‑afinidade, taints e tolerations — ajuda a manter as aplicações rodando de forma correta e a maximizar o uso do cluster sem introduzir riscos desnecessários.
Requests vs Limits (CPU e Memória)
Ao criar containers dentro de pods, é boa prática definir quanto recurso o container solicita (request) e qual o limite máximo (limit) que ele pode consumir.
| Tipo | O que significa | Exemplo |
|---|---|---|
| Request | Quantidade garantida ao container; o scheduler usa esse valor para escolher o node onde o pod será colocado. | cpu: 500m (0,5 CPU) |
| Limit | Teto máximo que o container pode usar durante a execução. | memory: 512Mi |
- O scheduler considera apenas requests ao decidir o node, assegurando que a quantidade solicitada esteja disponível.
- Limits evitam que um container consuma recursos em excesso, protegendo os demais workloads.
- Se o container ultrapassar o limite, pode sofrer throttling (CPU) ou ser finalizado pelo kernel por falta de memória (OOMKilled).
Como declarar no manifesto YAML
resources:
requests:
cpu: "250m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
250m equivale a 0,25 CPU (millicores). Quando o limit não é informado, o container pode usar tudo que o node tiver disponível, o que pode gerar problemas de estabilidade.
Classes de QoS e efeitos práticos
Kubernetes classifica os pods em Quality of Service (QoS) com base nos requests e limits definidos. Essa classificação influencia a prioridade de sobrevivência em situações de escassez de recursos.
| Classe QoS | Quando ocorre |
|---|---|
| Guaranteed | Requests e limits são idênticos para todos os containers do pod. |
| Burstable | Pelo menos um container tem request menor que o limit (ou não tem limit). |
| BestEffort | Nenhum request nem limit foi especificado. |
Impactos práticos
- OOMKilled: o kernel encerra o processo que ultrapassou o limite de memória.
- CPU Throttling: o uso de CPU é restringido quando o container excede o limit.
- Pods Guaranteed têm a maior prioridade de sobrevivência, seguidos pelos Burstable e, por último, pelos BestEffort.
- Em caso de pressão de memória, o kubelet elimina pods começando pelos de menor QoS.
Afinidade, anti‑afinidade e agendamento básico
Afinidade e anti‑afinidade
A afinidade permite influenciar onde um pod será colocado em relação a outros pods ou nodes.
- Pod affinity: o pod prefere ser agendado em um node que já possua pods com determinadas labels (ex.: para reduzir latência de comunicação).
- Pod anti‑affinity: o pod evita nodes que já tenham pods com certas labels (ex.: para melhorar a disponibilidade distribuindo réplicas).
Exemplo de pod affinity:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- frontend
topologyKey: "kubernetes.io/hostname"
Esse pod será agendado no mesmo host onde existir outro pod com app=frontend.
Taints e tolerations
Enquanto afinidades são preferências, taints e tolerations funcionam como barreiras que impedem ou permitem a colocação de pods em determinados nodes.
- Taint: aplica‑se ao node e repele pods que não possuam a toleration correspondente.
- Toleration: declarada no pod, permite que ele seja agendado em nodes com o taint especificado.
Exemplo de criação de taint:
kubectl taint nodes node1 key=value:NoSchedule
Pod com toleration correspondente:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
Sem a toleration, o pod será impedido de ser agendado naquele node.
Comandos úteis
- Definir requests e limits: incluídos na seção
resourcesdo spec do container.
Aplicar um taint:
kubectl taint nodes node1 key=value:NoSchedule
Ver taints de um node:
kubectl describe node node1 | grep Taints
Listar pods com informações de recursos:
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[0].resources}{"\n"}{end}'
Conclusão
Configurar corretamente requests e limits evita que containers consumam recursos de forma descontrolada, reduzindo falhas e aumentando a estabilidade do cluster. Conhecer as classes de QoS permite priorizar workloads críticos e definir o comportamento esperado em situações de pressão de recursos. Por fim, afinidades, anti‑afinidades, taints e tolerations dão ao administrador controle fino sobre o agendamento, possibilitando a distribuição inteligente de workloads conforme requisitos de desempenho, disponibilidade ou isolamento.
Dominar esses conceitos é a base para construir clusters resilientes, escaláveis e eficientes. Nos próximos artigos, abordaremos autoescalamento e estratégias avançadas para garantir alta disponibilidade e uso otimizado do Kubernetes.