Aprenda / Infraestrutura — Docker

IntermediárioAula 12 de 1615 min0% da trilha

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

docker-compose.yml (trecho)
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 CPU

Isso 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

terminal
docker ps -a

Có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:

terminal
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.

Quiz rápido

O que o OOM killer do Linux faz quando o sistema fica sem memória?
Por que definir mem_limit num serviço do compose é importante mesmo se ele nunca deveria vazar memória?