Como resolver OOMKilled no Kubernetes
OOMKilled quer dizer que o container usou mais memória do que o limite dele e o kernel matou o processo. O pod reinicia, às vezes entra em CrashLoopBackOff, e o log da aplicação não mostra erro nenhum, porque ela não teve tempo de escrever.
1. Confirme o OOMKilled
Em Last State, o describe mostra Reason: OOMKilled e Exit Code: 137:
kubectl describe pod <pod> -n <namespace>
kubectl get pod <pod> -n <namespace> \
-o jsonpath='{.status.containerStatuses[*].lastState.terminated.reason}' 2. Compare o consumo com o limite
O kubectl top precisa do metrics-server no cluster:
kubectl top pod <pod> -n <namespace> --containers
kubectl get pod <pod> -n <namespace> \
-o jsonpath='{.spec.containers[*].resources}' Limite do container ou memória do nó
- Se o container passou do próprio limits.memory, o OOMKilled é dele: o limite está baixo para o que a aplicação usa, ou a aplicação está vazando memória.
- Se o nó ficou sem memória, o kubelet despeja pods (status Evicted, evento de pressão de memória), começando pelos que mais passaram do request. Request baixo demais deixa o scheduler colocar pods demais no mesmo nó.
Como corrigir
- Ponha limits.memory acima do pico real, com folga, e requests.memory perto do uso normal.
- Runtimes com heap próprio precisam respeitar o limite: na JVM, use -XX:MaxRAMPercentage; no Node.js, --max-old-space-size; o GC do .NET já lê o limite do container.
- Se o consumo cresce sem parar até o limite, aumentar só adia: é vazamento de memória na aplicação.
Sem terminal, no Kubepier
No Kubepier, o consumo de CPU e memória aparece por cluster, nó e namespace, com o metrics-server que o cluster já tem, e o pod que reiniciou por OOMKilled sobe para a lista de pods com problema, no navegador ou no celular.