Pular para o conteúdo
Abrir o Kubepier

Kubernetes · guia

Requests e limits sem chute: dimensionar a partir de métricas

Equipe IA4CODE
engenharia de plataforma e SRE
publicado em 25 set 2026 8 min de leitura throttling e QoS medidos num cluster k3s 1.35 de teste em 25 set 2026

TL;DR

Request e limit fazem coisas diferentes. O request é o que o scheduler reserva para o pod ao escolher o nó; o limit é o teto que o kernel aplica ao container. Em CPU, passar do limit não mata: o container é limitado (throttling). Medimos um container com limit de 200m tentando usar tudo: ficou em 201m e foi limitado em 809 de 810 períodos de 100 ms. Em memória, passar do limit é OOMKilled. Dimensione o request pelo uso típico e o limit de memória acima do pico, ambos medidos por pelo menos uma semana, e confira a classe de QoS que resulta.

Quem usa o quê

RequestLimit
Quem usascheduler, na escolha do nókernel (cgroup), no container rodando
CPU acima delepermitido, se o nó tiver folgathrottling: o container espera
Memória acima delepermitido; entra na conta da evictionOOMKilled, exit 137
Sem valorse houver limit, copia o limitsem teto: pode usar o nó inteiro

Fonte: documentação do Kubernetes, "Resource Management for Pods and Containers". A soma dos requests do nó é o que decide se um pod novo cabe; um nó ocioso com requests esgotados deixa o pod em Pending.

CPU: o limit segura, mesmo com o nó livre

Um container em loop infinito, com request de 100m e limit de 200m, num nó de 10 CPUs praticamente ocioso:

saída real
kubectl -n loja top pod cpu-limitada --containers
POD            NAME   CPU(cores)   MEMORY(bytes)
cpu-limitada   app    201m         0Mi

O limit vira uma cota no cgroup: 20 ms de CPU a cada período de 100 ms.

saída real, cpu.stat resumido
kubectl -n loja exec cpu-limitada -- cat /sys/fs/cgroup/cpu.max
kubectl -n loja exec cpu-limitada -- cat /sys/fs/cgroup/cpu.stat
20000 100000

usage_usec 16198471
nr_periods 810
nr_throttled 809
throttled_usec 35571023

Em 810 períodos, o container foi limitado em 809, e passou 35,6 s esperando. Para um loop de teste isso não importa; para uma API, é latência: a requisição que chega no fim da cota espera o próximo período. Se as métricas mostram container_cpu_cfs_throttled_periods_total subindo e a latência junto, o limit de CPU está baixo.

Memória: o limit mata

Memória não se comprime. Passou do limit, o kernel mata o processo com SIGKILL e o container registra OOMKilled com exit 137. Reproduzimos com um container que tenta alocar 150M com limit de 128Mi: três reinícios em 75 s. O passo a passo está em OOMKilled.

Sem limit de memória, o container pode crescer até o nó ficar sem memória, e aí quem age é o kubelet, despejando pods (Evicted). Os primeiros a sair são os que passam do próprio request.

Do uso medido ao manifesto

  1. Colete uma semana de uso normal, incluindo o pico do dia e os jobs noturnos.
  2. Request de CPU: perto do uso típico (por exemplo, o percentil 90 da taxa de uso). É o que garante espaço no nó.
  3. Request de memória: perto do uso típico da memória de trabalho.
  4. Limit de memória: acima do pico da semana, com folga para crescimento. Escreva o critério no manifesto.
  5. Limit de CPU: decida se quer (veja o throttling acima). Sem ele, o request continua garantindo a parte do container.
consultas no Prometheus, por container
# pico de memória em 7 dias
max_over_time(container_memory_working_set_bytes{namespace="loja", container="checkout"}[7d])

# percentil 90 do uso de CPU em 7 dias (núcleos)
quantile_over_time(0.9, rate(container_cpu_usage_seconds_total{namespace="loja", container="checkout"}[5m])[7d:5m])
deployment.yaml · valores do exemplo, a partir das consultas
resources:
  requests:
    cpu: 300m         # p90 de 7 dias: 0,28 núcleo
    memory: 512Mi     # uso típico: 470Mi
  limits:
    memory: 896Mi     # pico de 7 dias: 700Mi, mais 25% de folga

A classe de QoS que sai disso

Os valores definem a classe de QoS do pod, que decide a ordem de despejo quando o nó aperta. Request igual a limit em CPU e memória, em todos os containers, dá Guaranteed; sem nada, BestEffort; o resto é Burstable (documentação do Kubernetes, "Pod Quality of Service Classes"). O container do teste de CPU, com request 100m e limit 200m, ficou Burstable:

saída real
kubectl -n loja get pod cpu-limitada -o jsonpath='{.status.qosClass}'
Burstable

Para conferir antes de aplicar, use a calculadora de QoS.

Perguntas frequentes

Devo colocar limit de CPU?

Depende do que você prefere perder. Com limit, o container nunca passa dele e é limitado mesmo com o nó ocioso: no nosso teste, um limit de 200m segurou o container em 201m e ele ficou limitado em 809 de 810 períodos. Sem limit, ele usa a folga do nó, e o request continua garantindo a parte dele. Muitos times deixam CPU sem limit e memória com limit.

Request de memória protege contra OOMKilled?

Não. O request serve ao scheduler; quem mata por memória é o limit. Um container com request 64Mi e limit 128Mi morre ao passar de 128Mi.

Como descubro o uso real?

kubectl top mostra o instante (precisa do metrics-server). Para dimensionar, use o histórico: no Prometheus, max_over_time e quantis de container_memory_working_set_bytes e da taxa de container_cpu_usage_seconds_total, por pelo menos uma semana de uso normal.

Existe um fator certo de folga?

A documentação do Kubernetes não prescreve nenhum. Escolha um critério (por exemplo, limite de memória acima do pico de 7 dias com margem para crescimento), escreva o motivo no manifesto e revise quando o pico mudar.

Leia em seguida

Todos os guias →