← Todos os posts
11 de ago. de 2026

Por Que Seu Nó Kubernetes Trava: Três Modos de Falha de Storage

TL;DR: “O nó travou” é um sintoma, não um diagnóstico — nesse cluster teve três causas-raiz sem relação entre si em três incidentes separados: sessões iSCSI do Longhorn caindo sob pressão de NVMe/memória, mounts CIFS bloqueando em estado D não-interruptível quando o NAS sumia, e kubelet evictando pods porque media ephemeral-storage no disco errado. Cada um precisou de um fix diferente e nenhum dos três se sobrepõe. Este post é o índice: como cada modo de falha se parece de fora, como diferenciá-los rápido, e links pro postmortem completo de cada um.

Um nó Kubernetes travado não te diz quase nada sobre o motivo do travamento. Sem SSH, sem ping, kubectl get nodes mostrando NotReady — é a mesma saída seja a causa um driver de storage, um travamento em estado D do kernel, ou uma cascata de eviction longe de onde a pressão real está. Três incidentes no mesmo cluster homelab produziram o mesmo sintoma de topo por três motivos sem relação causal entre si. Este post existe pra encurtar a próxima rodada de “qual desses é esse” — uma árvore de decisão, não uma repetição das investigações individuais.

Três vezes, no mesmo cluster, a resposta pra “por que esse nó não responde” acabou sendo um subsistema completamente diferente. Toda vez, a primeira hora de debug parecia idêntica: sem SSH, sem ping, às vezes sem SysRq, journald mostrando o efeito mas não a causa. Toda vez, a causa-raiz real estava duas ou três camadas longe de onde a investigação começou.

Este post é pra quem roda k3s (ou qualquer distribuição Kubernetes) com Longhorn, mounts CIFS/SMB, ou um data directory dividido entre discos, e já bateu num nó que não responde sem saber qual desses modos de falha está vendo. Pressupõe que você já leu — ou está prestes a ler — pelo menos um dos três postmortems linkados; isso aqui é o mapa, não o território.

Sumário

Os três modos de falha, lado a lado

Longhorn iSCSI + pressão de memóriaTravamento de mount CIFSEviction por root-dir do kubelet
SintomaTravamento total do nó, reboot no botãoPods presos em Terminating, panic eventual do nóPod evictado apesar de usar quase nada de disco
GatilhoStall de fdatasync do NVMe ou sobrecomprometimento de memória em cascata até a liveness do engine LonghornNAS fica offline enquanto um pod está no meio de I/O num mount CIFSkubelet --root-dir e o disco de dados real são filesystems diferentes
Estado do kernelhung_task_panic disparando (ou falhando em disparar)Processos em TASK_UNINTERRUPTIBLE (estado D), imunes a SIGKILLSem travamento em nível de kernel — esse é decisão do scheduler, não travamento
Primeiro sinal pra checardmesg / kdump pra quedas de sessão iSCSI e pressão de memóriaps aux procurando processos em estado D (D) no nó afetadoMensagem do evento de eviction citando thresholds de ephemeral-storage
Categoria do fixFirmware + ajuste de timeout do Longhorn + swapSidecar de liveness probe em nível de rede, não um ajuste de opção de mountBind-mount do disco real no caminho convencional do kubelet

Comece aqui: o que a mensagem de eviction (ou a falta dela) te diz

Se tem um evento de eviction do Kubernetes com nome de pod específico e um threshold de recurso citado (ephemeral-storage, memory), comece por eviction por root-dir do kubelet — isso é decisão de scheduler, não travamento, e é o único dos três onde o nó em si continua totalmente responsivo. Se o nó não responde a SSH e SysRq sem nenhum evento de eviction, é um dos outros dois, e o próximo passo é checar se a carga de trabalho toca um mount CIFS/SMB ou um PVC baseado em Longhorn.

Se for CIFS/SMB: checa estado D primeiro

ps aux | grep ' D ' no nó afetado antes de fazer qualquer outra coisa. Processos em estado D ignoram SIGKILL — essa é a impressão digital do travamento de mount CIFS, e significa que o fix não é ajustar timeout de liveness probe, é substituir qualquer probe que toque o mount por uma que não toque. Opções estilo NFS (timeo/retrans) não se aplicam ao módulo CIFS; não perca tempo com elas.

Se for Longhorn: checa kdump antes de assumir que é o disco

O postmortem de Longhorn/memória cobre dois gatilhos distintos que terminam na mesma queda de sessão iSCSI — um stall de fdatasync do NVMe em cascata pelo etcd até um timeout de liveness probe do Longhorn, e, separadamente, sobrecomprometimento de memória travando o kswapd num flush de inode ext4 antes que um crash dump pudesse sequer ser escrito. journald sozinho não distingue os dois; a saída do kdump distingue. Se o cluster ainda não tem crashkernel configurado, esse é o primeiro buraco pra fechar — a variante de sobrecomprometimento de memória dessa falha não deixa nenhum outro registro.

Por que eles não compartilham um fix

É tentador tratar “o nó travou” como um problema só com um checklist de hardening só. Não é, nesse cluster: o fix do Longhorn é ajuste de firmware e de replica-timeout, o fix do CIFS é uma mudança arquitetural em como a liveness é sondada, e o fix do kubelet é um bind-mount que não tem nada a ver com nenhum dos dois. Tratar o fix de um incidente como política geral — por exemplo, assumir que todo travamento é pressão de memória e só adicionar swap — vai deixar passar os outros dois inteiros e queimar uma janela de incidente confirmando uma hipótese que já estava errada desde o início.

A única coisa genuinamente compartilhada entre os três: nenhum deles foi diagnosticável só com journald. Cada um precisou de kdump, checagem de estado de processo (ps aux pra estado D), ou ler a mensagem de eviction ao pé da letra em vez de assumir que ela apontava pro culpado óbvio.

Referências


Breno Zanato Detomini
Breno Zanato Detomini

Engenheiro de sistemas embarcados e redes, baseado no Brasil.

← Todos os posts