5 min de leitura

Kubernetes v1.36: Pod-Level Resource Managers – O fim do trade-off entre isolamento e eficiência

Server room and cabling
Photo by Kier in Sight Archives on Unsplash

Por anos, a orquestração de containers empurrou times de infraestrutura para uma escolha dolorosa: eficiência ou isolamento. O Kubernetes v1.36 finalmente rasga essa página com os Pod-Level Resource Managers — um modelo híbrido que entrega os dois mundos, no mesmo pod, sem concessões.

Pod-Level Resource Managers no Kubernetes v1.36: modelo híbrido com alinhamento NUMA, pool compartilhado e fatias exclusivas

O velho pesadelo dos clusters de missão crítica

Quem opera bancos de dados, motores de inferência ou sistemas de trading sabe: latência não é métrica, é contrato. E o Kubernetes, até a versão 1.35, forçava uma decisão que machucava qualquer bolso de cloud.

Um pod típico de PostgreSQL com sidecars de observabilidade ilustra bem o drama: o banco precisa de CPUs dedicadas para manter o p99 estável, mas os sidecars consomem migalhas. No entanto, alocar recursos iguais para todos os containers criava um rombo de capacidade. Reduzir os limites do sidecar, por outro lado, quebrava a classe Guaranteed QoS e abria a porta para contenção.

As três estratégias que falhavam (cada uma do seu jeito)

  • Requests/limits simétricos: containers ociosos drenavam recursos caros. Um sidecar de logs com 4 CPUs garantidas que jamais usaria 5% disso.
  • Assimetria com Burstable QoS: o banco podia ser expulso do isolamento real. Picos de tráfego transformavam o nó em uma roleta russa de latência.
  • CPU Manager static isolado: a fatia exclusiva ia para o container principal, mas os sidecars competiam em um pool sem qualquer proteção — a contenção apenas mudava de lugar.
O resultado era uma equação cruel: nós superdimensionados, custos cloud inflados e a constante dúvida "será que hoje o p99 explode?"

Pod-Level Resource Managers: a arquitetura que dissolve o trade-off

A ideia central é quase óbvia depois de explicada: recursos definidos no nível do pod, com fatias exclusivas para containers críticos e um pool compartilhado para o restante. Mas a execução — com alinhamento NUMA e CFS quota global — é o que torna a mágica possível.

Três engrenagens que movem o modelo híbrido: recursos totais declarados no pod, containers marcados como exclusivos com CFS quota desabilitado e sidecars unidos por um pool comum com quota única no nível do grupo.

O que muda na prática

  1. Você define podResources.shared com o total de CPU e memória do pool de sidecars.
  2. Containers com recursos declarados da forma tradicional (e limites iguais a requests) recebem fatias NUMA exclusivas, sem CFS throttle.
  3. Os demais containers compartilham o pool, com um teto coletivo — se um sidecar tentar monopolizar, a quota global o freia.

Essa abordagem preserva a QoS Guaranteed para o pod como um todo, porque o total de recursos está devidamente reservado no nó. O scheduler não enxerga mais cada container isoladamente, mas o bloco coeso.

Feature gates e pré-requisitos de configuração

Nada funciona se as bases não estiverem corretas. A ativação é simples, mas exige alinhamento fino de componentes clássicos do kubelet.

Checklist obrigatório para o nó

  • Kubernetes 1.36 (a API não existe em versões anteriores).
  • Feature gates: PodLevelResources=true e PodLevelResourceManagers=true.
  • Topology Manager com política diferente de nonesingle-numa-node ou best-effort são as recomendadas.
  • CPU Manager em modo static.
  • Memory Manager em modo static (recomendado para alinhamento completo NUMA).

Exemplo de manifesto funcional

apiVersion: v1
kind: Pod
metadata:
name: db-ml-pod
spec:
containers:
- name: database
image: postgres:15
resources:
requests:
cpu: "4"
memory: "8Gi"
limits:
cpu: "4"
memory: "8Gi"
- name: sidecar-logs
image: fluentd:latest
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
- name: sidecar-metrics
image: prometheus-exporter:latest
resources: {}
podResources:
shared:
cpu: "2"
memory: "4Gi"

O container database recebe 4 CPUs exclusivas alinhadas à NUMA; os sidecars competem dentro do pool de 2 CPUs. Sem desperdício, sem surpresas.

Dois escopos de alinhamento NUMA: pod vs. container

A Topology Manager ganha granularidade extra. A decisão de escopo impacta diretamente latência de memória e escalabilidade.

Escopo Mecanismo Indicado para
pod Todos os recursos do pod (exclusivos + pool) são alocados em uma única zona NUMA. Cargas com exigência absoluta de localidade de memória — bancos de dados grandes, inferência em batch.
container Cada container exclusivo ocupa sua própria zona NUMA; o pool compartilhado pode abranger múltiplas zonas. Sidecars de rede ou observabilidade que não dependem de acesso local à memória.

O escopo pod é mais restritivo e pode impedir o scheduling de pods grandes. Já o container oferece flexibilidade, mas exige atenção extra para não introduzir latência cruzada entre zonas.

Casos reais e impacto mensurável

Resultados de testes em ambientes de homologação mostram que o modelo híbrido não é apenas elegante no papel. Ele muda números.

PostgreSQL + sidecars de observabilidade

Cluster com 3 sidecars (logs, métricas, backup). A migração de Burstable para Pod-Level Resources, com 4 CPUs exclusivas para o banco e 1 CPU compartilhada no pool, reduziu o p99 de latência em 35% mesmo sob rajadas de ingestão de logs.

Inferência de ML + Envoy

Modelo de deep learning com 8 CPUs exclusivas e um pool de 1 CPU para Envoy e monitoramento. A taxa de inferência permaneceu estável enquanto o proxy absorvia 10 mil requisições por segundo sem disputa por recursos.

Trading de alta frequência

Engine de matching em C++ com escopo pod e 6 CPUs dedicadas. O jitter médio caiu para menos de 5 microssegundos, mesmo em cenários de pico de mercado.

O isolamento real chegou onde antes só existiam apostas.

Observabilidade: novas métricas do kubelet

Para acompanhar o comportamento das fatias e do pool compartilhado, três métricas fundamentais entram em cena:

  • resource_manager_allocations_total — alocações completas de fatias exclusivas e shared pools.
  • resource_manager_allocation_errors_total — falhas por insuficiência de recursos no nó.
  • resource_manager_container_assignments — mapeamento container→fatia ou pool, essencial para debugging.

Dica prática: grave dashboards com essas métricas antes de ativar o recurso em produção. Elas contam histórias que logs não mostram.

Limitações e cuidados no estágio Alpha

Como toda funcionalidade Alpha, o Pod-Level Resource Manager exige respeito a algumas arestas ainda não aparadas.

O que exige atenção redobrada

  • API instável: a estrutura do YAML pode mudar até a GA. Prepare-se para reaplicar manifestos em upgrades.
  • Complexidade de configuração: interação entre Topology Manager, CPU Manager e Memory Manager gera combinações que nem sempre falham de forma clara — um erro silencioso pode degradar performance sem alarmes óbvios.
  • Convivência entre sidecars no pool: sidecars não isolados competem entre si. Um vazamento de recursos ou pico anormal em um deles afeta todos os outros do mesmo pool.
  • Escalabilidade restrita no escopo pod: pods com muitos containers podem não caber em uma única zona NUMA, exigindo fallback para container ou redução do escopo.

Testes em clusters de homologação são mandatórios. Comece com workloads não críticos, monitore as novas métricas e escale gradualmente.

O que vem depois: a estrada para além do híbrido estático

O Pod-Level Resource Manager é o primeiro passo de uma direção clara. As próximas iterações devem incorporar inteligência dinâmica à divisão de recursos.

Três movimentos esperados no roadmap

  • Pools adaptativos: ajuste automático do tamanho do pool compartilhado com base em telemetria de uso — sidecars ganham mais fôlego sob picos e encolhem na calmaria.
  • Observabilidade com eBPF: inspeção de contenção dentro do pool sem overhead de instrumentação tradicional.
  • Perfis históricos e auto-tuning: o scheduler aprenderá a proporção ideal exclusivo/compartilhado para cada workload ao longo do tempo.

A era do "um tamanho serve para todos" na alocação de recursos está com os dias contados. O caminho é a granularidade dinâmica, onde cada container recebe exatamente o tratamento que seu papel na carga de trabalho exige.

Resumo prático: O Kubernetes v1.36 entrega, pela primeira vez, isolamento rígido para containers críticos e eficiência para sidecars no mesmo pod — sem concessões, sem QoS rebaixada, sem contas de cloud assustadoras.

O trade-off morreu. Comece a testar o modelo híbrido no seu cluster de homologação hoje. A próxima geração de workloads críticos já tem um lugar garantido no Kubernetes — e ele não desperdiça um único ciclo de CPU.