Definir requests e limits sem chutar
requests é o que o scheduler reserva para o Pod; limits é o teto que o runtime impõe.
Chutar os dois produz os dois piores resultados ao mesmo tempo: nó cheio de Pods ociosos e
aplicação sendo freada no pico. Este guia dimensiona com dado.
1. Colete o uso real
Seção intitulada “1. Colete o uso real”Você precisa de pelo menos uma semana de dados, cobrindo o pico do negócio.
kubectl top pods -n loja --containers # instantâneo, para uma primeira noção# CPU: percentil 95 dos últimos 7 dias, por containerquantile_over_time(0.95, rate(container_cpu_usage_seconds_total{namespace="loja", container!=""}[5m])[7d:5m])
# Memória: o MÁXIMO, não o percentil — memória não se comprimemax_over_time( container_memory_working_set_bytes{namespace="loja", container!=""}[7d])Sem Prometheus, o metrics-server com kubectl top amostrado ao longo do dia já dá uma
base melhor que o chute.
2. Defina requests pelo percentil
Seção intitulada “2. Defina requests pelo percentil”- CPU request = p95 do uso, com uma folga de 20% a 30%.
- Memória request = pico observado, com folga de 20% a 30%.
resources: requests: cpu: 200m # p95 medido: ~150m memory: 512Mi # pico medido: ~400Mi limits: memory: 512Mi # igual ao request: veja o passo 3 # cpu: intencionalmente ausenteRequest muito acima do uso desperdiça nó inteiro; muito abaixo faz o scheduler superlotar o nó e todo mundo sofre no pico.
3. Trate CPU e memória com regras diferentes
Seção intitulada “3. Trate CPU e memória com regras diferentes”Esta é a parte que mais gera dúvida, e as duas se comportam de formas opostas:
- CPU é compressível. Passar do limite não mata o processo: ele é freado (throttling), o que aparece como latência alta sem nenhum erro. Por isso, para a maioria dos serviços em produção, não definir limite de CPU é a escolha mais defensável — o request já garante a fatia mínima, e a folga do nó fica disponível no pico.
- Memória não é compressível. Passar do limite significa OOMKill, imediato e sem
aviso. Limite de memória é obrigatório, e a prática segura é
limits.memoryigual arequests.memory.
# está havendo throttling? Se sim, o limite de CPU está atrapalhando.sum by (pod) (rate(container_cpu_cfs_throttled_seconds_total{namespace="loja"}[5m]))# houve OOMKill?kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}A exceção ao “sem limite de CPU”: ambientes multi-inquilino onde um vizinho barulhento prejudica os outros, ou quando você precisa de comportamento previsível para testes. Nesses casos, use limite generoso e monitore o throttling.
4. Entenda a classe de QoS que você acabou de escolher
Seção intitulada “4. Entenda a classe de QoS que você acabou de escolher”A combinação de requests e limits define quem é despejado primeiro quando o nó fica sem memória:
| Classe | Como se obtém | Despejo |
|---|---|---|
| Guaranteed | requests == limits, para CPU e memória, em todos os containers | por último |
| Burstable | requests definidos, limits diferentes ou ausentes | no meio |
| BestEffort | nada definido | primeiro |
Nunca deixe um serviço de produção sem requests: além de virar BestEffort e ser o
primeiro a morrer, ele impede qualquer decisão correta do scheduler e do autoscaler.
5. Aplique um padrão no namespace
Seção intitulada “5. Aplique um padrão no namespace”Para não depender de disciplina, force um mínimo:
apiVersion: v1kind: LimitRangemetadata: { name: padroes, namespace: loja }spec: limits: - type: Container default: { memory: 512Mi } # limits, se não declarado defaultRequest: { cpu: 100m, memory: 256Mi } max: { memory: 4Gi }---apiVersion: v1kind: ResourceQuotametadata: { name: cota, namespace: loja }spec: hard: requests.cpu: "40" requests.memory: 80Gi limits.memory: 80GiE complete com política de admissão exigindo requests declarados — veja política como código.
6. Revise periodicamente
Seção intitulada “6. Revise periodicamente”Uso muda com versão, tráfego e feature nova. Coloque na rotina trimestral:
# quem pede muito mais do que usa (candidatos a redução)sum by (namespace, pod) (kube_pod_container_resource_requests{resource="cpu"}) / sum by (namespace, pod) (rate(container_cpu_usage_seconds_total[7d]))Ferramentas ajudam: o VPA em modo Off gera recomendações sem aplicar nada — é a forma
mais segura de usá-lo, e evita o conflito com o HPA descrito em
escala automática.
Checklist de pronto
Seção intitulada “Checklist de pronto”- Requests baseados em 7 dias de dados, não em chute.
-
limits.memorydefinido e igual ao request. - Limite de CPU ausente (ou justificado e monitorado por throttling).
- Nenhum Pod de produção em
BestEffort. -
LimitRangeeResourceQuotano namespace. - Alerta de OOMKill e de throttling ativo.
- Revisão agendada.