1
resposta

Depois que criei os ambientes separados de configmap, ao tentar subir os pods, dão erro.

Estou enfrentando um problema ao rodar um ambiente Kubernetes local usando:

  • WSL2
  • Ubuntu
  • Docker Desktop
  • KIND (Kubernetes in Docker)

Cenário

Estou fazendo um projeto da Alura com 3 pods:

  • portal-noticias
  • sistema-noticias
  • db-noticias (MySQL)

Também criei ConfigMaps separados para injetar variáveis de ambiente:

  • db-configmap
  • sistema-configmap

Os pods portal-noticias e sistema-noticias sobem normalmente, mas o pod do banco (db-noticias) sempre entra em:

OOMKilled
CrashLoopBackOff

Sintomas

Ao subir o pod:

kubectl get pods

Resultado:

db-noticias   0/1   OOMKilled

Mesmo aumentando memória para 2Gi, o problema continua.


Investigação feita

  1. Testei imagem original da Alura:
aluracursos/mysql-db:1
  1. Testei imagem oficial:
mysql:5.7

Mesmo problema.


  1. Testei pod mínimo (sem ConfigMap, só MYSQL_ROOT_PASSWORD)

Mesmo problema:

OOMKilled

  1. kubectl describe pod mostra:
Reason: OOMKilled
Exit Code: 137
QoS Class: Burstable

  1. dmesg mostra:
Memory cgroup out of memory: Killed process (mysqld)
anon-rss: ~521MB
constraint=CONSTRAINT_MEMCG

Ambiente host

No WSL:

free -h

Mostra:

  • ~11Gi RAM total
  • bastante memória livre

No Docker:

docker inspect devops-lab-control-plane | grep -i memory

Sem limite configurado (Memory: 0).


Estranho

Mesmo com:

limits:
  memory: "2048Mi"

o MySQL inicia por 1–2 segundos e logo morre com:

OOMKilled

Perguntas

  1. Alguém já viu esse comportamento com:
WSL2 + Ubuntu + Docker Desktop + KIND + MySQL
  1. Pode ser algum problema de:
  • cgroup v2?
  • KIND dentro do WSL?
  • containerd?
  • incompatibilidade do MySQL 5.7 nesse ambiente?
  1. Existe alguma configuração extra necessária no KIND/WSL para bancos como MySQL?

  2. Vale mais a pena usar:

  • Deployment em vez de Pod?
  • outro runtime?
  • Minikube / k3d em vez de KIND?

Qualquer sugestão é bem-vinda porque já testei imagem limpa, ConfigMap mínimo, aumento de memória e o erro continua.

1 resposta

Olá, Fabio. Como vai?

Esse é um dos problemas mais intrigantes e frustrantes que podem acontecer ao rodar Kubernetes localmente via KIND no ecossistema Windows/WSL2. O seu relato de investigação está impecável: você já isolou o ConfigMap, testou diferentes imagens (Alura e oficial) e validou que o host possui memória física livre.

O xis da questão aqui está no Exit Code: 137 e no log do dmesg: Memory cgroup out of memory: Killed process (mysqld). Quando o KIND roda dentro do WSL2 com cgroups v2, existe um comportamento muito específico de como o Kernel do WSL e o Docker Desktop gerenciam os limites de memória que costuma quebrar o MySQL 5.7.

Abaixo, apresento o diagnóstico do que está acontecendo e as soluções práticas para você destravar o seu banco de dados:

O Diagnóstico: A Armadilha do cgroup v2 + WSL2 + MySQL 5.7

O MySQL 5.7 possui um mecanismo interno que tenta detectar a memória total disponível no host para dimensionar suas estruturas internas (como o InnoDB Buffer Pool).
Quando você usa o KIND (Kubernetes in Docker), seus nós do Kubernetes são, na verdade, containers Docker rodando dentro da máquina virtual do WSL2.

Em ambientes modernos com cgroups v2, se o container do nó do KIND não tiver um limite explícito definido no Docker, o MySQL dentro do Pod tenta ler a memória total do host (os seus 11Gi do WSL). Ele tenta alocar estruturas mapeando essa memória, mas esbarra no limite do cgroup que o Kubernetes (KIND) impôs ao Pod (os seus 2Gi). O Kernel do Linux detecta essa tentativa de alocação que estoura o cgroup do Pod e envia o sinal SIGKILL (137), gerando o OOMKilled.


Como Resolver: Soluções Práticas

Aqui estão as três abordagens mais eficazes para resolver esse problema, da mais simples para a mais estruturada:

1. Limitar a memória diretamente no arquivo de configuração do KIND (Recomendado)

A melhor forma de alinhar o que o Docker e o KIND enxergam de memória é limitar o nó do KIND na criação do cluster. Crie um arquivo chamado kind-config.yaml:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000 # Caso precise expor o portal depois
    hostPort: 30000
# Força o container do KIND a respeitar os limites do cgroup de forma amigável

Ao recriar o cluster, você pode limitar o container do nó via linha de comando do Docker ou configurar o arquivo .wslconfig na sua conta de usuário do Windows para limitar a memória máxima do WSL2 como um todo (ex: memory=4GB). Isolar a memória do WSL2 força o MySQL a enxergar um ambiente menor.

2. Passar parâmetros de otimização para o MySQL no Pod

Você pode instruir o MySQL a não tentar adivinhar a memória do sistema e trabalhar de forma extremamente enxuta. No manifesto YAML do seu Pod db-noticias, adicione o argumento args para limitar o uso de memória do InnoDB:

apiVersion: v1
kind: Pod
metadata:
  name: db-noticias
  labels:
    app: db-noticias
spec:
  containers:
  - name: mysql
    image: aluracursos/mysql-db:1
    args:
    - "--innodb-buffer-pool-size=64M"
    - "--innodb-log-buffer-size=8M"
    envFrom:
    - configMapRef:
        name: db-configmap
    resources:
      requests:
        memory: "256Mi"
        cpu: "100m"
      limits:
        memory: "512Mi" # 512Mi será mais que suficiente com os argumentos acima

3. Migrar para o Minikube (Alternativa de Runtime)

Respondendo à sua pergunta sobre mudar de ferramenta: Sim, o Minikube costuma ser mais estável com bancos de dados no WSL2. O KIND é excelente e ultra-rápido, mas como ele roda "Docker dentro de Docker", o aninhamento de cgroups v2 no WSL2 gera esse tipo de efeito colateral com o MySQL. O Minikube, quando configurado com o driver do docker (minikube start --driver=docker), gerencia o mapeamento de recursos de uma forma ligeiramente diferente que evita o falso dimensionamento do MySQL.

Respondendo suas outras dúvidas:

  • Vale a pena usar Deployment em vez de Pod? Para o erro de OOMKilled não mudará o resultado (o Deployment criará um ReplicaSet que criará um Pod que continuará morrendo). Porém, como boa prática de Kubernetes, sim, sempre use Deployments em vez de Pods isolados para garantir alta disponibilidade e autorregeneração.
  • Incompatibilidade do MySQL 5.7? Sim, o MySQL 5.7 é conhecido por ter problemas de leitura de limites em cgroups v2. O MySQL 8.0 possui correções nativas muito melhores para rodar dentro de containers sem estourar o OOM.

Resumo do plano de ação: Altere o manifesto do seu Pod do banco adicionando os args do InnoDB listados na Solução 2. Essa é a forma mais rápida de fazer o MySQL inicializar sem tentar "engolir" a memória do seu WSL2!

Espero que possa ter lhe ajudado!