Limites de recursos e OOM em containers
Sem limite de memória, um container com vazamento não derruba só ele mesmo — pode derrubar a VM inteira.
Por padrão, um container pode consumir toda a memória e CPU disponíveis na máquina onde ele roda — não existe limite nenhum a menos que você configure um. Isso é inofensivo enquanto tudo funciona bem; é um desastre no dia em que um serviço tem um vazamento de memória (memory leak) e ninguém colocou um teto nele.
O que é o OOM killer
Quando o Linux fica sem memória disponível, o kernel não trava — ele aciona o OOM killer ("out of memory killer"), um mecanismo que escolhe um processo (com base em heurísticas de quanto memória ele usa e sua importância estimada) e o mata à força, liberando memória pra manter o resto do sistema de pé. Isso vale tanto no nível do host quanto, com cgroups, no nível de cada container individualmente.
mem_limit e cpus no compose
services:
api:
build: .
mem_limit: 512m # o container não pode passar de 512MB de RAM
cpus: "0.5" # o container não pode usar mais que meio núcleo de CPUIsso não é uma sugestão — é um limite rígido imposto via cgroups do Linux (o mesmo mecanismo do kernel que dá isolamento de recursos a um container). Se o processo dentro do container tentar alocar mais memória do que mem_limit permite, o kernel aciona o OOM killer só dentro do cgroup daquele container — não do host inteiro.
O que acontece quando o container estoura o limite
docker ps -aCódigo de saída 137 (128 + 9, o número do sinal SIGKILL) é a marca registrada de um processo morto à força — geralmente pelo OOM killer. docker inspect confirma a causa especificamente:
docker inspect api --format '{{json .State}}'Por que isolar isso importa: sem limite, um container derruba a VM inteira
Sem mem_limit, um container com vazamento de memória não tem teto — ele consome RAM até o host inteiro ficar sem memória disponível. Nesse ponto, é o OOM killer do host que entra em ação, e ele pode escolher matar qualquer processo do sistema, incluindo outros containers saudáveis, ou até serviços essenciais como o próprio daemon do Docker ou o SSH — derrubando a VPS inteira por causa de um único serviço mal comportado. Com mem_limit configurado, o dano fica contido: só aquele container é morto, o resto do sistema continua de pé.
Exercício
Um worker de processamento de imagens tem histórico de picos de uso de memória durante conversões grandes, mas nunca deveria ultrapassar 1GB em uso normal. Configure mem_limit pra esse serviço no compose de um jeito que dê alguma margem pros picos sem deixar o serviço sem limite nenhum.