Kubernetes vai impedir kubelet de iniciar em nós com cgroup v1 a partir da versão 1.35
Post do blog oficial do Kubernetes, publicado em 6 de outubro, detalha o calendário de depreciação do cgroup v1: a partir da versão 1.35 o kubelet simplesmente não sobe em nós que ainda usam o modelo antigo, a menos que alguém force um override temporário.

Depreciar um recurso do Kubernetes↳Kubernetes18 conteúdosGerenciamento de infraestrutura multicloud com Kubernetes proporciona otimização e economiaDevSecOps · set 2021Azure Kubernetes Services – AKS: referências gratuitas e dicas para solução de problemas comunsDevSecOps · abr 2019Kubernetes em produção: o que ninguém te conta e você aprende tarde demaisDev (Back & Front) · abr 2026Ver tudo em DevSecOps → raramente é evento único: é um processo que se arrasta por várias minor releases até virar bloqueio de verdade. É o caso do cgroup v1. Um post do blog oficial do Kubernetes, assinado por Paco Xu (DaoCloud) e publicado nesta terça-feira (6 de outubro), reúne o estado atual dessa transição, e o ponto que merece atenção de quem opera cluster em produção é concreto: a partir da versão 1.35, o kubelet não inicia em um nó Linux que ainda rode cgroup v1, a menos que alguém configure explicitamente um override.
A linha do tempo que já está em curso
cgroup v2 não é novidade: tornou-se suporte estável no Kubernetes desde a versão 1.25. O que mudou foi o tratamento dado ao v1. Na versão 1.31, o suporte a cgroup v1 entrou em modo de manutenção, o que na prática significa que o projeto para de investir em melhorias e passa a tratar o v1 como legado. A partir da versão 1.35 (já lançada), a flag failCgroupV1 passa a valer true por padrão, e é aqui que o breaking change aparece de fato: sem esse nó estar em cgroup v2, o kubelet falha ao subir.
Quem opera via kubeadm sente o bloqueio ainda mais cedo. A partir da 1.35, o preflight check SystemVerification (do pacote k8s.io/system-validators) passa a retornar erro, não apenas aviso, quando detecta cgroup v1 combinado com kubelet 1.35 ou mais recente, durante kubeadm init, kubeadm join e kubeadm upgrade. Com um kubelet mais antigo, o check continua sendo só um aviso. A remoção completa do fallback está marcada para a versão 1.38 e é acompanhada pela KEP-5573.
Em resumo: se seu cluster roda hoje numa versão anterior à 1.35, a migração dos nós Linux para cgroup v2 precisa acontecer antes do upgrade, ou alguém vai ter que setar failCgroupV1: false no arquivo de configuração do kubelet como paliativo temporário, sabendo que esse paliativo também tem prazo de validade.
O que realmente precisa estar no lugar
Migrar para cgroup v2 não é só uma flag de kernel. O post detalha os requisitos de infraestrutura que precisam estar alinhados antes de qualquer upgrade:
| Componente | Requisito mínimo |
|---|---|
| Kernel Linux | 5.8 ou mais recente (5.9+ recomendado se for usar Memory QoS) |
| Kubernetes | Qualquer versão suportada atualmente (v2 estável desde 1.25) |
| containerd | v1.4+ suporta cgroup v2; v2.0+ traz detecção automática do cgroup driver |
| CRI-O | v1.20 ou mais recente |
| cAdvisor | v0.43.0 ou mais recente, para quem lê o filesystem de cgroup diretamente |
Faltar qualquer linha dessa tabela não derruba o cluster na hora, mas cria inconsistência silenciosa: ferramentas de monitoramento que leem /sys/fs/cgroup diretamente, por exemplo, podem simplesmente parar de encontrar os arquivos que esperavam, porque a hierarquia do v2 é unificada e diferente da do v1.
Cgroup driver: o detalhe que quebra silenciosamente
O ponto mais sutil do artigo, e provavelmente o que mais gera incidente em produção, é o alinhamento entre o cgroup driver do kubelet e o do container runtime. Os dois precisam combinar; se não combinam, o comportamento de isolamento de recursos fica inconsistente entre o que o Kubernetes pensa que está aplicando e o que o kernel de fato aplica.
A recomendação do próprio autor do post é direta:
Se você pode escolher qualquer uma das opções, eu recomendo usar o driver systemd.
If you can pick either option, I recommend using the systemd driver.Paco Xu, DaoCloud
A boa notícia é que a KEP-4033, que trata da descoberta automática do cgroup driver via CRI, graduou para estável na versão 1.34. Com um runtime que implementa o RPC RuntimeConfig (containerd 2.0+ ou CRI-O 1.28+), o kubelet passa a usar o valor reportado pelo próprio runtime em vez de depender da configuração manual cgroupDriver: systemd no arquivo do kubelet. Quem ainda roda runtime mais antigo continua precisando configurar isso à mão, e esquecer esse passo é a causa mais comum de nó que sobe mas aplica limite errado.
Memória, OOM e PSI: o que muda no comportamento observado
A parte que interessa direto a quem faz plantão de SRE é o que muda no comportamento de runtime, não só na configuração. Três pontos do post merecem destaque:
- Memory QoS (alpha, atualizado na 1.36): depende do controlador de memória do cgroup v2.
memory.highfaz throttling, enquantomemory.minememory.lowdão proteção tiered quandomemoryReservationPolicy: TieredReservationestá habilitada. Isso simplesmente não existe em cgroup v1. O detalhe de risco: em kernel anterior ao 5.9, o reclaim dememory.highpode travar em livelock conhecido, e a 1.36 passou a logar aviso quando detecta essa combinação. - OOM por container, não por processo: em nós cgroup v2, o kubelet passa a usar
memory.oom.grouppor padrão (viasingleProcessOOMKill: false), então um evento de OOM mata todos os processos daquele container juntos, em vez de derrubar um processo isolado e deixar o container funcionando pela metade. Quem depende do comportamento antigo precisa setarsingleProcessOOMKill: trueexplicitamente. - PSI (Pressure Stall Information) em GA: a feature
KubeletPSIestá estável e ligada por padrão em clusters que atendem aos requisitos (cgroup v2, kernel 4.20+,CONFIG_PSI=y, sem boot compsi=0). É dado exposto via Summary API e/metrics/cadvisor, útil para distinguir contenção real de CPU/memória/IO de simples uso alto.
Nenhum desses três recursos funciona em cgroup v1. É o argumento mais forte a favor de migrar além do prazo imposto: ficar no v1 não é só manter o status quo, é abrir mão de visibilidade que já está disponível e que ajuda a diagnosticar throttling e contenção sem instrumentação extra.
Como auditar o cluster antes de atualizar
O post traz um roteiro de verificação ponta a ponta que vale reproduzir em qualquer pipeline de pré-upgrade. No nível do SO, stat -fc %T /sys/fs/cgroup/ retorna cgroup2fs quando o nó já está em v2. Para inspecionar a árvore de unidades geridas pelo systemd, systemctl list-units 'kube*' --type=slice lista as slices do Kubernetes; tree -L 2 -d /sys/fs/cgroup/kubepods.slice mostra a estrutura de diretórios dos Pods.
Para confirmar que um limite de CPU ou memória realmente chegou até o cgroup, o caminho documentado é descer camada por camada: comparar spec.containers[*].resources com status.containerStatuses[*].resources via kubectl, localizar o container com crictl inspect, extrair o PID e então ler cpu.weight, cpu.max e memory.max diretamente no cgroup correspondente. É trabalho manual, mas é o único jeito confiável de confirmar que um resize in-place (estável desde a 1.35, com suporte a recursos em nível de Pod em beta na 1.36) realmente convergiu, já que o status pode ficar temporariamente fora de sincronia com o spec durante o ajuste.
O que isso custa, na prática
A migração em si não tem custo de licença nem reescrita de workload: aplicações não precisam saber se rodam sobre v1 ou v2. O custo real é operacional e se concentra em três frentes: atualizar kernel para 5.8+ em frotas de nós que ainda rodam distribuições antigas, validar que todo o parque de containerd/CRI-O está nas versões mínimas, e auditar qualquer ferramenta de terceiros (monitoramento, policy engine, exporter customizado) que leia o filesystem de cgroup diretamente, porque a hierarquia mudou de estrutura.
Para quem já está em kernel recente e runtime atualizado, a janela até a versão 1.38 dá tempo de sobra. Para quem ainda carrega nó legado em produção, essa é a depreciação que vale colocar no radar do próximo ciclo de upgrade, não deixar para o dia em que o kubelet simplesmente recusa subir.
Fonte: Kubernetes Blog
Este artigo foi escrito por Rafael Oliveira, colunista de DevOps. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.
User Namespaces no Kubernetes: guia para rodar pods sem root sem quebrar o cluster
O isolamento de UID/GID entre container e host já é estável desde o 1.36. Veja os pré-requisitos de kernel, filesystem e runtime, e o checklist do que quebra em volumes e políticas de segurança antes de ligar hostUsers: false.













