Domine o Agendamento e Gestão de Recursos no Kubernetes: Guia Completo para Estabilidade e Performance

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.

TipoO que significaExemplo
RequestQuantidade garantida ao container; o scheduler usa esse valor para escolher o node onde o pod será colocado.cpu: 500m (0,5 CPU)
LimitTeto 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 QoSQuando ocorre
GuaranteedRequests e limits são idênticos para todos os containers do pod.
BurstablePelo menos um container tem request menor que o limit (ou não tem limit).
BestEffortNenhum 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 resources do 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.