Limites Reais de Kubernetes: Por Que 1M de Nodes é Impossível

Descubra os gargalos arquiteturais que impedem Kubernetes de escalar para 1 milhão de nodes: limitações do etcd, API server watchers e por que a indústria escolhe federation.

Os Limites Reais de Kubernetes: Por Que 1 Milhão de Nodes é Teoricamente Impossível

Kubernetes domina a orquestração de containers há anos, mas poucos desenvolvedores enfrentam os limites arquiteturais que aparecem quando você escala além de alguns milhares de nodes. A discussão sobre escalar K8s para 1 milhão de nodes expõe gargalos fundamentais na arquitetura do sistema - gargalos que importam mesmo em clusters bem menores.

O limite oficial do Kubernetes é 5.000 nodes por cluster na versão 1.29, com restrições adicionais de 150.000 pods totais e 300.000 containers. Alibaba Cloud e ByteDance conseguiram clusters entre 10.000 e 15.000 nodes em produção, mas esses são outliers que exigiram modificações significativas. O que impede o crescimento para ordens de magnitude maiores? Não são detalhes de implementação corrigíveis - são limitações arquiteturais no próprio design do control plane.

Vamos dissecar onde exatamente o Kubernetes quebra em escala extrema e por que a indústria converge para federação de clusters ao invés de tentar construir mega-clusters únicos.

O Calcanhar de Aquiles: etcd e o Custo da Consistência Forte

O etcd funciona como o único source of truth no Kubernetes, armazenando todo o estado do cluster em um banco de dados distribuído. Essa escolha arquitetural traz consistência forte através do algoritmo Raft, mas cria o primeiro gargalo fundamental em escala.

A documentação oficial recomenda manter o banco de dados do etcd abaixo de 8GB para operação estável. Em um cluster de 5.000 nodes com configuração típica, você já está próximo desse limite considerando apenas os objetos core: nodes, pods, services, configmaps, secrets. Cada watch stream aberto contra o etcd consome memória adicional (aproximadamente 1GB de RAM para cada 10.000 watchers ativos). Controllers, operators customizados e ferramentas de observabilidade abrem watches constantemente.

O bottleneck real não é capacidade de armazenamento, mas latência de escrita. O etcd precisa garantir que escritas sejam persistidas em disco através de fsync antes de confirmar a transação. O objetivo é manter essa latência abaixo de 10ms no percentil 99, mas isso depende diretamente da performance de I/O do disco. Com SSD NVMe em condições ideais, o etcd processa cerca de 10.000 escritas por segundo. Parece muito até você calcular o que acontece com 100.000 pods sendo criados ou atualizados simultaneamente.

A fragmentação no etcd agrava o problema. Conforme objetos são criados e deletados, o banco pode crescer para 3-4x o tamanho real dos dados. Compactação automática precisa rodar a cada 30 minutos para evitar degradação de performance, mas o processo em si adiciona overhead adicional. Network round-trip entre members do cluster etcd também impacta diretamente write latency - razão pela qual clusters acima de 1.000 nodes precisam de um cluster etcd dedicado em hardware separado.

Escalar para 1 milhão de nodes significa lidar com bilhões de objetos no etcd. Não existe solução conhecida para manter consistência forte com latências aceitáveis nessa escala usando a arquitetura atual. Mesmo distribuindo o etcd através de sharding, você perde a semântica de transação atômica que controllers do Kubernetes assumem.

API Server: Broadcast Storm e o Problema dos Watchers

O kube-apiserver age como gateway para todo acesso ao etcd, mas também como hub de notificações através do mecanismo de watch. Cada controller, kubelet, e ferramenta externa abre watch streams para ser notificado de mudanças relevantes. Em um cluster de 5.000 nodes, existem no mínimo 5.000 kubelets assistindo seus próprios pods, além de dezenas de controllers builtin e potencialmente centenas de operators customizados.

Quando um objeto muda, o API server precisa notificar todos os watchers interessados. Uma única escrita pode gerar milhares de notificações simultâneas. O watch cache do API server consome até 12GB de RAM em clusters de 5.000 nodes apenas para manter cópias em memória e distribuir updates eficientemente.

Os defaults do API server são conservadores por necessidade: --max-requests-inflight=400 para leituras e --max-mutating-requests-inflight=200 para escritas. Esses limites protegem contra overload, mas também criam enfileiramento sob carga pesada. A implementação de Priority and Fairness (APF) ajuda a priorizar requisições críticas, mas não resolve o problema fundamental de broadcast scalability.

A recomendação oficial é adicionar uma instância de API server para cada 1.000-3.000 nodes. Isso ajuda com CPU e latência de requests individuais, mas não resolve o problema de memória dos watch caches nem o overhead de sincronização com etcd. Múltiplas instâncias de API server competem pelos mesmos recursos do etcd.

O KEP-2185 propõe sharding do API server como solução experimental, onde diferentes instâncias gerenciam subsets de objetos. A implementação está em andamento, mas introduz complexidade significativa para roteamento de requisições e manutenção de consistência entre shards. Não existem comparações públicas detalhadas dos trade-offs específicos entre diferentes estratégias de sharding.

Scheduler: O Dilema NP-Completo em Escala

O default scheduler do Kubernetes processa entre 100-300 pods por segundo em hardware típico. Deployments largos precisam agendar milhares de pods simultaneamente. A arquitetura do scheduler é inerentemente sequencial para a maior parte do pipeline - cada pod precisa passar por filtering, scoring e binding phases.

O problema fundamental é que scheduling ótimo é NP-completo. O scheduler usa heurísticas e aproximações, mas mesmo assim precisa avaliar cada node candidato contra múltiplos predicates (filtros) e priorities (scores). Quanto mais nodes existem, mais caras essas operações ficam. Performance profiles podem reduzir latência em 40-60% desabilitando certos checks, mas às custas de qualidade das decisões de placement.

A SchedulingQueue pode se tornar bottleneck com mais de 10.000 pods pendentes. Informer caches e SharedInformers - mecanismos que controllers usam para manter estado local atualizado - foram identificados como limitadores críticos de memória no control plane em escala. Cada informer mantém uma cópia completa dos objetos que assiste.

Escalar o scheduler horizontalmente é teoricamente possível através de sharding por namespace ou label selectors, mas a maioria dos workloads assume um scheduler centralizado que pode fazer decisões globalmente ótimas considerando todo o cluster. Múltiplos schedulers independentes podem levar a distribuição subótima e race conditions.

Por Que a Indústria Escolheu Federation ao Invés de Mega-Clusters

A resposta pragmática para limites de escala não é tentar construir clusters cada vez maiores, mas federar múltiplos clusters de tamanho médio. ByteDance, por exemplo, gerencia múltiplos clusters com 5.000+ nodes cada ao invés de um único mega-cluster.

Blast radius é a razão mais óbvia. Um bug no control plane ou problema de rede em um cluster de 1 milhão de nodes afetaria operações inteiras. Com federation, problemas ficam isolados a clusters individuais. Você também ganha flexibilidade para heterogeneidade - diferentes clusters podem rodar versões diferentes do Kubernetes, ter configurações de networking distintas, ou ser otimizados para workloads específicos.

O pattern comum envolve um control plane federado leve que gerencia routing de workloads para clusters apropriados, com cada cluster operando independentemente dentro dos limites suportados. Tools como Cluster API e KubeFed fornecem abstrações para gerenciar múltiplos clusters, embora a experiência de desenvolvedor ainda não seja tão transparente quanto um cluster único.

Não existe roadmap oficial ou KEPs aprovados para escalar Kubernetes a 1 milhão de nodes em cluster único. O SIG Scalability menciona objetivo de alcançar 10.000+ nodes, mas não há metas para ordens de magnitude além disso. A lacuna entre 10.000 e 1.000.000 não é linear - são mudanças arquiteturais fundamentais que quebrariam garantias que o ecossistema Kubernetes assume.

O Que Isso Significa Para Sua Arquitetura

Se você está operando clusters acima de 1.000 nodes, você já deveria estar pensando em limites de escala. Monitorar latência do etcd (objetivo: <10ms p99 para writes) e utilização de memória do API server é crucial. Configurar compactação automática correta e manter watch streams sob controle previne problemas antes que causem outages.

Para clusters acima de 5.000 nodes, aceite que você está no território de customizações. Você precisará hardware dedicado para o control plane, tuning agressivo de configurações, e possivelmente modificações no código. A documentação oficial não especifica detalhes para essa escala porque cada caso se torna único.

Escalar Kubernetes não é apenas sobre adicionar mais máquinas. É sobre reconciliar as garantias de consistência forte que tornam K8s previsível com as realidades físicas de sistemas distribuídos em larga escala. Essas limitações não são bugs a serem corrigidos - são trade-offs fundamentais da arquitetura escolhida. Reconhecer isso cedo influencia decisões de design que serão muito mais caras de mudar depois.


← Voltar para home