PerfectScale
Kubernetes v1.35: o que há de novo e o que melhorou?
Kubernetes v1.35: 'Timbernetes' chega com 60 melhorias, avançando em escalabilidade, segurança, gerenciamento de dispositivos, agendamento e mais.
Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.
O Kubernetes v1.35, também conhecido como "Timbernetes (The World Tree Release)", traz diversos recursos novos que tornam o Kubernetes mais robusto e mais preparado para lidar com workloads modernos em escala. São 60 novos recursos nesta versão: 17 deles agora são Estáveis (GA), 19 estão em Beta e 22 em Alpha. O tema "World Tree" (Árvore do Mundo) mostra como esta versão fortalece o Kubernetes em todos os níveis, das fundações aos sistemas centrais e pontos de extensão. Isso permite lidar com uma ampla variedade de workloads, de AI/ML a workloads stateful e de edge.
Estes são alguns dos recursos que mais nos empolgam no Kubernetes v1.35: suporte a gang scheduling, atualização in-place de recursos de Pods, batching oportunista no scheduler e muito mais. Essas melhorias tornam o Kubernetes muito melhor em otimizar performance, escalar bem e gerenciar recursos com eficiência.
Vamos falar sobre as principais melhorias do Kubernetes v1.35:
Recursos Estáveis do Kubernetes v1.35
1. Atualização in-place de recursos de Pods****
Feature Group: SIG Node | KEP: #1287
No Kubernetes v1.35, as atualizações in-place de recursos de CPU e memória de Pods chegaram à Disponibilidade Geral (GA).
Antes desse recurso, era preciso recriar o Pod toda vez que você alterava .spec.resources.requests ou .spec.resources.limits. O Kubernetes tratava mudanças de recursos como campos imutáveis, então até um pequeno ajuste de CPU ou memória causava um reinício completo. Isso era disruptivo para serviços stateful, batch jobs de longa duração e aplicações sensíveis à latência. Além disso, causava downtime.
Com a v1.35, o Kubernetes permite alterar os requests ou limits de CPU e memória de um Pod em execução sem precisar reiniciar o Pod ou seus contêineres. Agora você pode aplicar mudanças de recursos diretamente no contêiner em execução quando o runtime e a configuração do nó oferecem suporte. O kubelet atualiza as configurações de cgroup in-place, e o Pod continua rodando. Se uma mudança de recurso não puder ser aplicada com segurança, o Kubernetes ainda recorre à recriação do Pod, preservando a compatibilidade retroativa. Isso torna o escalonamento vertical mais fácil, seguro e eficaz.
2. Distribuição de tráfego PreferSameNode
Feature Group: SIG Network | KEP:#3015
No Kubernetes v1.35, a distribuição de tráfego PreferSameNode alcançou a Disponibilidade Geral (GA).
Antes dessa mudança, o Kubernetes tinha a opção PreferClose no campo trafficDistribution. Ela era útil, mas pouco clara. PreferClose significava implicitamente "preferir endpoints próximos", o que na prática significava proximidade no nível da zona, não do nó. Não havia uma forma clara de os usuários indicarem que queriam preferência estrita por endpoints locais ao nó, e a API não comunicava com clareza a diferença entre o comportamento de roteamento no nível do nó e no nível da zona.
Com a v1.35, o Kubernetes permite escolher para onde vai o tráfego do Service. Ele pode preferir fortemente endpoints que estão no mesmo nó do Pod cliente e usar endpoints remotos apenas quando não houver endpoints locais disponíveis. Uma nova opção, PreferSameNode, foi introduzida para priorizar endpoints no mesmo nó. Ao mesmo tempo, PreferClose foi renomeada para PreferSameZone, tornando a API autodescritiva e mais clara. PreferClose continua sendo suportada por compatibilidade retroativa, mas PreferSameZone agora é a opção preferida e explícita para roteamento zonal. Juntas, essas mudanças separam claramente as preferências de tráfego no nível do nó e no nível da zona. Isso é útil para workloads focados em performance que querem reduzir a latência e o tráfego entre nós.
apiVersion: v1kind: Servicemetadata: name: node-local-servicespec: selector: app: web ports: - port: 80 targetPort: 8080 trafficDistribution: PreferSameNodeCom essa configuração, se um Pod cliente e um Pod de backend correspondente rodarem no mesmo nó, o Kubernetes roteará o tráfego localmente. Somente quando não existirem endpoints locais o tráfego será enviado para Pods em outros nós.
3. Limite configurável de nós NUMA para o Topology Manager
Feature Group: SIG Node | KEP:#4622
No Kubernetes v1.35, o limite configurável de nós NUMA do Topology Manager chegou à Disponibilidade Geral (GA).
NUMA (Non-Uniform Memory Access) é uma arquitetura de hardware em que um servidor é dividido em várias regiões de memória (nós NUMA), cada uma diretamente conectada a um conjunto específico de CPUs. O Topology Manager é um componente do kubelet que alinha as alocações de CPU, memória e dispositivos para que os workloads rodem em hardware fisicamente próximo.
Antes desse recurso, o Kubernetes impunha um limite rígido de 8 nós NUMA sempre que o Topology Manager estava habilitado. Essa medida de segurança existia para evitar a explosão de estados durante os cálculos de afinidade NUMA. Como resultado, o kubelet desabilitava completamente o Topology Manager em nós com mais de 8 nós NUMA. Essa limitação significava que o Kubernetes não conseguia aproveitar servidores grandes multi-socket, em que a localidade precisa de CPU, memória e dispositivos é crítica para a performance.
Com a v1.35, a opção de política max-allowable-numa-nodes agora é estável. O Kubernetes permite que administradores de cluster executem o Topology Manager em máquinas com mais de 8 nós NUMA. Isso remove o teto artificial e permite que o Kubernetes coordene o posicionamento de CPU, memória e dispositivos mesmo em máquinas muito grandes. Embora ainda existam desafios de performance para sistemas NUMA extremamente grandes, o Kubernetes agora dá aos operadores o controle para habilitar o recurso de acordo com seu hardware e suas necessidades de workload.
Assim, esse recurso permite que o Kubernetes aproveite melhor os servidores modernos de alto desempenho, comumente usados em HPC, AI/ML, telecom e workloads de baixa latência.
apiVersion: kubelet.config.k8s.io/v1kind: KubeletConfigurationtopologyManagerPolicy: restrictedtopologyManagerScope: podtopologyManagerPolicyOptions: max-allowable-numa-nodes: "true"4. Nova opção de política do CPUManager para restringir reservedSystemCPUs
Feature Group: SIG Node | KEP: #4540
Antes desse recurso, o Kubernetes permitia que administradores reservassem CPUs específicas para o sistema usando reservedSystemCPUs. No entanto, essa reserva era aplicada apenas para Pods Guaranteed com requisições inteiras de CPU. Pods Burstable e BestEffort, assim como Pods Guaranteed com requisições fracionárias de CPU, ainda podiam consumir tempo de CPU desses núcleos reservados. Em clusters do mundo real, isso levava a problemas de "vizinho barulhento", em que workloads de aplicação interferiam nos processos do sistema, causando instabilidade do nó, atrasos no agendamento ou degradação de performance sob carga.
Com o Kubernetes v1.35, a opção strict-cpu-reservation da política static do CPUManager agora está em Disponibilidade Geral (GA). Quando habilitada, o Kubernetes impede estritamente que todos os Pods, independentemente da classe de QoS, rodem nas CPUs listadas em reservedSystemCPUs. Isso torna o isolamento de CPU previsível e confiável, garantindo que os daemons do sistema sempre tenham capacidade de CPU dedicada. O resultado são nós mais estáveis e melhor performance para workloads sensíveis à latência e de alto throughput que rodam ao lado de componentes críticos do sistema.
apiVersion: kubelet.config.k8s.io/v1kind: KubeletConfigurationcpuManagerPolicy: staticreservedSystemCPUs: "0-1"cpuManagerPolicyOptions: strict-cpu-reservation: "true"Com essa configuração, as CPUs 0-1 ficam reservadas exclusivamente para o SO e os daemons de sistema do Kubernetes. Nenhum Pod de aplicação, seja BestEffort, Burstable ou Guaranteed, pode rodar nessas CPUs.
5. Limite do kubelet para pulls paralelos de imagens
Feature Group: SIG Node | KEP: #3673
O limite de pulls paralelos de imagens do kubelet controla quantas imagens de contêiner um nó pode baixar ao mesmo tempo. O pull de imagens é uma operação intensiva em rede e disco.
Antes desse recurso, o comportamento do kubelet era efetivamente binário. Quando serializeImagePulls estava definido como true, as imagens eram baixadas uma de cada vez, o que evitava a disputa por recursos, mas atrasava significativamente a inicialização de pods durante scale-ups ou reinícios de nós. Quando serializeImagePulls estava definido como false, não havia limite superior para pulls paralelos de imagens. Em nós ocupados, isso podia inundar a rede, saturar os discos e atrasar outras operações críticas no nó.
Com o Kubernetes v1.35, a configuração maxParallelImagePulls agora está em Disponibilidade Geral (GA). Isso permite que administradores definam um limite superior explícito para pulls simultâneos de imagens. O Kubernetes agora pode baixar várias imagens em paralelo, mas apenas até um limite seguro definido pelo operador. Pulls adicionais entram em fila até que um pull em andamento seja concluído, oferecendo concorrência controlada em vez de um comportamento tudo ou nada.
apiVersion: kubelet.config.k8s.io/v1kind: KubeletConfigurationserializeImagePulls: falsemaxParallelImagePulls: 3Com essa configuração, o kubelet permite que até três imagens sejam baixadas simultaneamente em um nó.
6. Coleta de lixo de imagens do kubelet após uma idade máxima
Feature Group: SIG Node | KEP:#4210
Antes desse recurso, a coleta de lixo de imagens do kubelet era guiada principalmente por limiares de uso de disco. As imagens eram removidas apenas quando o uso de disco ultrapassava HighThresholdPercent, e a limpeza continuava até o uso cair abaixo de LowThresholdPercent. Embora eficaz para evitar o esgotamento do disco, isso significava que imagens raramente usadas ou desatualizadas podiam permanecer no disco indefinidamente, desde que o nó não estivesse sob pressão de disco. Com o tempo, isso levava a caches de imagens inchados e a um uso ineficiente do disco.
Com o Kubernetes v1.35, a configuração imageMaximumGCAge agora é estável, permitindo que o kubelet colete imagens que não foram usadas por um período especificado, independentemente do uso de disco. Administradores podem definir uma idade máxima para imagens não utilizadas, expressa como uma duração. Quando uma imagem excede essa idade sem ser usada, ela se torna elegível para exclusão. Isso complementa a coleta baseada em disco existente e torna a limpeza de imagens proativa em vez de reativa.
apiVersion: kubelet.config.k8s.io/v1kind: KubeletConfigurationimageMaximumGCAge: 24himageGCHighThresholdPercent: 85imageGCLowThresholdPercent: 70Com essa configuração, qualquer imagem de contêiner que não tenha sido usada por 24 horas pode ser removida pelo kubelet, mesmo que o uso de disco esteja abaixo do limiar superior.
7. Mecanismo managedBy na API de Job
Feature Group: SIG Apps | KEP:#4368
Antes desse recurso, todo objeto Job era sempre reconciliado pelo controlador de Job embutido. Mesmo que um sistema externo (como um controlador customizado ou um scheduler multi-cluster) quisesse gerenciar a execução ou o status, o Kubernetes ainda criava Pods, atualizava as condições do Job, repetia tentativas em falhas e aplicava a semântica de conclusão. Isso fazia com que casos de uso avançados, como espelhar Jobs entre clusters, exigissem annotations, workarounds em controladores ou lógica de supressão para evitar conflitos.
Com o Kubernetes v1.35, o campo managedBy agora está em Disponibilidade Geral (GA). Quando definido, o Kubernetes trata o Job como gerenciado externamente e não reconcilia seus Pods nem seu status. Isso viabiliza sistemas como o MultiKueue, em que um Job é criado em um cluster de gerenciamento, executado em um cluster worker e o status é sincronizado de volta sem interferência do controlador nativo de Job. O recurso é intencionalmente limitado: ele permite delegar o gerenciamento do Job, mas não muda a semântica do Job, o comportamento de CronJob nem passa configuração para o controlador externo.
apiVersion: batch/v1kind: Jobmetadata: name: delegated-jobspec: managedBy: kueue.x-k8s.io/multikueue ........8. Pod Generation (rastreamento confiável de atualizações de Pods)
Feature Group: SIG Node | KEP: #5067
Antes desse recurso, os Pods não tinham um campo metadata.generation como objetos de nível mais alto, como Deployments ou StatefulSets. Embora controladores pudessem atualizar o spec de um Pod, não havia uma forma nativa e monotônica de saber se o kubelet já havia processado uma determinada mudança. Isso dificultava detectar com confiabilidade se uma atualização de Pod ainda estava pendente, parcialmente aplicada ou totalmente refletida no status — especialmente para atualizações in-place e mudanças rápidas e sucessivas.
Com o Kubernetes v1.35, o rastreamento de generation de Pods agora está em Disponibilidade Geral (GA). Cada Pod começa com metadata.generation: 1, e toda atualização em um campo mutável do spec do Pod incrementa esse valor. O kubelet registra a generation sobre a qual atuou em status.observedGeneration. Isso torna explícito se o status atual do Pod reflete o spec desejado mais recente ou uma versão anterior. Controladores externos podem comparar esses dois campos com segurança para determinar se a reconciliação foi concluída, sem depender de timing ou suposições.
Recursos Beta do Kubernetes v1.35
9. Tolerância configurável para HorizontalPodAutoscalers
Feature Group: SIG Autoscaling | KEP: #4951
O Horizontal Pod Autoscaler (HPA) ajusta automaticamente o número de réplicas de Pods em um workload com base em métricas observadas, como uso de CPU ou memória.
Antes desse recurso, o HPA usava uma tolerância fixa de 10%, válida para todo o cluster, ao decidir se deveria escalar. Esse valor não era configurável por workload. Como resultado, aplicações altamente sensíveis podiam deixar de escalar quando precisavam reagir a pequenos aumentos de carga, enquanto outros workloads podiam sofrer escalonamentos desnecessários ou oscilações. Ajustar esse comportamento exigia mudar uma flag global do controlador, impactando todos os HPAs do cluster.
Com o Kubernetes v1.35, a tolerância configurável avançou para Beta e está habilitada por padrão. Agora você pode definir valores de tolerância por HPA e por direção de escalonamento usando o campo behavior. Isso oferece controle refinado sobre a sensibilidade do autoscaling sem afetar outros workloads. Operadores podem ajustar serviços críticos para escalarem de forma agressiva, mantendo estáveis os workloads menos sensíveis.
apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: web-hpaspec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60 behavior: scaleUp: tolerance: 0.05Com essa configuração, o HPA só faz scale-up quando a utilização de CPU ultrapassa 65% (5% acima do alvo).
10. Limites mutáveis de anexação de volumes
Feature Group: SIG Storage | KEP:#4876
Os limites de anexação de volumes definem quantos volumes de armazenamento podem ser anexados a um nó em um dado momento. O Kubernetes usa essa informação para decidir onde agendar Pods que usam volumes persistentes. Os drivers CSI reportam esses limites por meio do objeto CSINode.
Antes desse recurso, a capacidade de anexação de volumes reportada em CSINode.spec.drivers[*].allocatable.count era estática. Depois que um driver CSI registrava seu limite de anexação na inicialização, o Kubernetes assumia que esse valor era sempre preciso. Se slots de volume fossem consumidos depois — por operações externas, reinícios de nós ou falhas transitórias — o scheduler ainda podia alocar Pods em nós que não tinham mais capacidade. Isso resultava em Pods presos em ContainerCreating porque o volume, na prática, não podia ser anexado.
Com o Kubernetes v1.35, o limite alocável de anexação de volumes agora é mutável e o recurso está em Beta, habilitado por padrão. Os drivers CSI podem atualizar dinamicamente a capacidade de anexação disponível de um nó em tempo de execução. O Kubernetes também introduz um intervalo de atualização configurável via objeto CSIDriver, permitindo que os drivers controlem com que frequência as contagens alocáveis são recalculadas. Além disso, o Kubernetes atualiza automaticamente a contagem alocável quando detecta falhas de anexação causadas por capacidade insuficiente. Isso torna as decisões de agendamento mais precisas e reduz significativamente as inicializações de Pods travadas ou com falha.
apiVersion: storage.k8s.io/v1kind: CSIDrivermetadata: name: example.csi.storagespec: attachRequired: true nodeAllocatableUpdatePeriodSeconds: 30 # Note: minimum is 10 secondsIsso configura chamadas periódicas do kubelet ao endpoint NodeGetInfo do driver CSI a cada 30 segundos para atualizar CSINode.spec.drivers[].allocatable.count
11. Batching oportunista
Feature Group: SIG Scheduling | KEP: #5598
O batching oportunista é uma otimização do scheduler que melhora a performance quando o Kubernetes agenda muitos Pods com requisitos de agendamento idênticos ou equivalentes.
Antes desse recurso, o kube-scheduler processava os Pods um a um, com complexidade de agendamento proporcional ao número de Pods multiplicado pelo número de nós. Mesmo quando vários Pods eram idênticos do ponto de vista do agendamento — mesmas requisições de recursos, afinidades e restrições — o scheduler repetia os mesmos cálculos de filtragem e pontuação para cada Pod. Isso gerava trabalho redundante e agendamento lento, especialmente para batch jobs, workloads de ML e criação de réplicas em larga escala.
Com o Kubernetes v1.35, o batching oportunista é introduzido como um recurso Beta, habilitado por padrão. O scheduler agora calcula uma assinatura de agendamento do pod, que captura todos os aspectos relevantes para o agendamento de um Pod, incluindo specs do pod, atributos do nó e estado do cluster. Quando Pods com a mesma assinatura chegam em sequência na fila de agendamento, o scheduler os agrupa em lote. Ele armazena em cache os resultados do agendamento do primeiro Pod e os reutiliza para os Pods seguintes com a mesma assinatura, evitando cálculos repetidos. O cache tem vida curta e é atualizado automaticamente para garantir a correção conforme o estado do cluster muda.
Essa otimização funciona de forma transparente — nenhuma configuração do usuário é necessária — e beneficia principalmente workloads com muitos Pods idênticos, como Jobs, workers paralelos de ML e deployments em larga escala. Ao reduzir o trabalho redundante de agendamento, o Kubernetes consegue posicionar Pods mais rápido e escalar workloads com mais eficiência sob alta carga.
12. maxUnavailable para StatefulSets
Feature Group: SIG Apps | KEP: #961
Um StatefulSet gerencia um conjunto de Pods que exigem identidades estáveis, inicialização e término ordenados e armazenamento persistente.
Antes desse recurso, StatefulSets que usavam a estratégia RollingUpdate atualizavam os Pods estritamente um de cada vez, começando pelo maior ordinal. Não havia como controlar quantos Pods podiam ficar indisponíveis durante uma atualização. Mesmo que uma aplicação stateful pudesse tolerar vários Pods temporariamente fora do ar, o Kubernetes ainda impunha atualizações serializadas, resultando em longos tempos de rollout para StatefulSets grandes.
Com o Kubernetes v1.35, o campo maxUnavailable para atualizações contínuas de StatefulSets agora está em Beta e habilitado por padrão. Isso permite que operadores especifiquem quantos Pods podem ficar indisponíveis durante uma atualização, seja como um número absoluto ou como uma porcentagem das réplicas. Quando combinado com podManagementPolicy: Parallel, o Kubernetes pode atualizar vários Pods de uma vez, ainda respeitando as restrições de disponibilidade. Se não for definido, o padrão continua sendo 1, preservando o comportamento anterior.
apiVersion: apps/v1kind: StatefulSetmetadata: name: databasespec: replicas: 10 podManagementPolicy: Parallel updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 20% ........13. Status do Deployment: contagem de réplicas em terminação
Feature Group: SIG Apps | KEP: #3973
Um Deployment gerencia atualizações contínuas e o escalonamento de Pods, e seu status é usado por operadores e automações para entender o progresso do rollout.
Antes desse recurso, o status do Deployment reportava apenas campos como replicas, updatedReplicas, readyReplicas e availableReplicas. Pods em terminação não ficavam explicitamente visíveis no status do Deployment. Isso dificultava saber se um Deployment estava realmente estável ou se ainda havia Pods sendo finalizados em segundo plano. Operadores e controladores precisavam listar Pods manualmente e filtrar por deletionTimestamp, o que era propenso a erros e ineficiente.
Com o Kubernetes v1.35, o campo status.terminatingReplicas foi promovido a Beta e está habilitado por padrão (com o feature gate DeploymentReplicaSetTerminatingReplicas habilitado no API server e no controller manager). Esse campo reporta o número de Pods que estão em terminação, mas ainda não foram totalmente removidos. Ele melhora a observabilidade durante rollouts e eventos de scale-down e cria a base para melhorias futuras no comportamento dos Deployments, como políticas mais inteligentes de substituição de Pods que levam em conta o progresso do desligamento.
apiVersion: apps/v1kind: Deploymentmetadata: name: webstatus: replicas: 5 updatedReplicas: 5 readyReplicas: 4 availableReplicas: 4 terminatingReplicas: 1 ........14. Exposição de labels de topologia do nó via Downward API
Feature Group: SIG Node | KEP:#4742
As labels de topologia do nó descrevem onde um Pod está rodando na infraestrutura, como a região ou a zona de disponibilidade do nó.
Antes desse recurso, os Pods não podiam acessar diretamente informações de topologia do nó. Workloads que precisavam de dados de zona ou região tinham que consultar o API server do Kubernetes, depender de sidecars ou receber permissões adicionais de RBAC. Isso aumentava a complexidade operacional e introduzia riscos de segurança ao expandir as permissões dos Pods de aplicação além do que eles realmente precisavam.
Com o Kubernetes v1.35, as labels de topologia do nó agora são injetadas nos Pods e expostas por meio da Downward API, com o recurso em Beta e habilitado por padrão. O kubelet propaga labels padrão, como topology.kubernetes.io/zone e topology.kubernetes.io/region, do nó para o Pod, disponibilizando-as como variáveis de ambiente ou arquivos projetados. Isso permite que workloads se tornem cientes da topologia sem acesso à API, simplificando a configuração e respeitando o princípio do menor privilégio.
apiVersion: v1kind: Podmetadata: name: topology-aware-podspec: containers: - name: app image: busybox command: ["sh", "-c", "env"] env: - name: ZONE valueFrom: fieldRef: fieldPath: metadata.labels['topology.kubernetes.io/zone'] - name: REGION valueFrom: fieldRef: fieldPath: metadata.labels['topology.kubernetes.io/region']Com essa configuração, o Pod recebe automaticamente a zona e a região do nó em que está rodando.
Recursos Alpha do Kubernetes v1.35
15. Suporte a gang scheduling no Kubernetes
Feature Group: SIG Scheduling | KEP: #4671
Antes desse recurso, o Kubernetes agendava os Pods individualmente. Para workloads fortemente acoplados, isso resultava em agendamento parcial: alguns Pods começavam a rodar enquanto outros ficavam pendentes por falta de recursos. Esses jobs parcialmente agendados podiam entrar em deadlock, desperdiçar recursos do cluster e bloquear outros workloads, forçando os usuários a recorrer a schedulers externos ou controladores customizados para impor a semântica de gang.
Com o Kubernetes v1.35, o gang scheduling nativo é introduzido como um recurso Alpha, usando a nova Workload API e políticas de grupos de pods. Os usuários definem um Workload que agrupa os Pods e especifica um requisito de minCount. O scheduler retém os Pods até que o grupo esteja completo e então tenta posicioná-los juntos. Se não conseguir agendar pelo menos o número exigido de Pods dentro de um timeout, nenhum é vinculado, e os Pods aguardam até que haja recursos suficientes disponíveis. Isso traz suporte de primeira classe, no nível do scheduler, à semântica de gang diretamente no Kubernetes.
Exemplo:
Workload definindo um gang de Pods
apiVersion: scheduling.k8s.io/v1alpha1kind: Workloadmetadata: name: ml-trainingspec: podGroups: - name: workers policy: gang: minCount: 4Pod vinculado ao Workload:
apiVersion: v1kind: Podmetadata: name: worker-0spec: workloadRef: name: ml-training podGroup: workers containers: - name: trainer image: <your-image>Com essa configuração, o Kubernetes agenda os Pods apenas quando pelo menos quatro workers podem rodar juntos. Se o cluster não puder atender a esse requisito, nenhum dos Pods é iniciado.
16. Operadores estendidos de toleration para posicionamento baseado em limiares
Feature Group: SIG Scheduling | KEP: #5471
Taints e tolerations são usados no Kubernetes para controlar onde os Pods podem rodar. Os nós usam taints para dizer "não coloque Pods aqui", e os Pods usam tolerations para dizer "eu posso rodar neste nó".
Antes desse recurso, as tolerations suportavam apenas operadores básicos, como Exists e Equal. Isso significava que os Pods podiam tolerar um taint ou não, mas não podiam expressar graus de tolerância. Por exemplo, um workload não podia dizer "rode apenas em nós com SLA ≥ 99,9" ou "evite nós com confiabilidade abaixo de um certo limiar". Como resultado, clusters que queriam posicionamento sensível a SLA precisavam recorrer a schedulers customizados, múltiplos node pools ou lógicas de admissão complexas.
Com o Kubernetes v1.35, as tolerations ganham operadores de comparação numérica (como semântica de maior-que ou menor-que) e avançam como parte do agendamento estendido. Os nós podem expor taints orientados a SLA (por exemplo, pontuações de confiabilidade ou qualidade do domínio de falha), e os Pods podem especificar tolerations que só correspondem se o valor do taint do nó satisfizer uma condição numérica. Isso permite que workloads críticos tenham como alvo nós de alto SLA, enquanto workloads best-effort podem rodar intencionalmente em infraestrutura de menor custo e menor SLA, melhorando a utilização sem sacrificar a confiabilidade.
Taint de nó expressando um nível de SLA:
kubectl taint nodes node-aservicelevel.org.example/agreed-service-level=800:NoSchedulePod tolerando apenas nós com SLA suficiente:
apiVersion: v1kind: Podmetadata: name: sla-tolerant-podspec: tolerations: - key: servicelevel.org.example/agreed-service-level operator: LessThan value: "900" effect: NoSchedule containers: - name: app image: busybox command: ["sh", "-c", "echo running on lower-SLA node"]Com essa configuração, o Pod só será agendado em nós cujo valor do taint de SLA seja inferior a 900.
17. Recursos de contêiner mutáveis quando um Job está suspenso
Feature Group: SIG Apps | KEP: #5440
Um Job do Kubernetes executa uma tarefa até que ela termine com sucesso e garante sua conclusão.
Antes desse recurso, o template de Pod dentro de um Job era efetivamente imutável. Se um Job falhasse por falta de CPU ou memória (por exemplo, OOM kills repetidos), os usuários não tinham como ajustar os valores de recursos no Job existente. A única opção era excluir o Job e criar um novo com recursos atualizados, o que significava perder o histórico e o status do Job, além de qualquer ferramenta que rastreasse o progresso ou as tentativas.
Com o Kubernetes v1.35, Jobs em estado suspenso podem ter as requisições e os limites de recursos de seus contêineres modificados, quando o feature gate MutableJobPodResourcesForSuspendedJobs está habilitado. Os usuários podem suspender um Job com falha, atualizar o template de Pod com valores de recursos apropriados e então retomar o Job. O Kubernetes continua a execução usando a configuração atualizada, preservando a identidade e o estado do ciclo de vida do Job, o que torna a recuperação de recursos mal configurados muito mais tranquila.
apiVersion: batch/v1kind: Jobmetadata: name: data-processorspec: suspend: true template: spec: restartPolicy: OnFailure containers: - name: worker image: busybox command: ["sh", "-c", "echo processing && sleep 30"] resources: requests: cpu: "1" memory: "1Gi" limits: cpu: "2" memory: "2Gi"Após atualizar os recursos, o Job pode ser retomado definindo spec.suspend como false. O Job continua com os novos valores de CPU e memória, sem excluir ou recriar o Job.
18. Recursos declarados pelo nó antes do agendamento
Feature Group: SIG Node | KEP: #5328
Antes desse recurso, o Kubernetes assumia que os nós eram amplamente compatíveis com o control plane, dentro do desvio de versões suportado. Quando novos recursos eram habilitados no nível do control plane, o scheduler ainda podia alocar Pods que usavam esses recursos em nós mais antigos que ainda não os suportavam. Isso resultava em falhas em tempo de execução, comportamentos sutilmente incorretos ou Pods travados após o agendamento, mesmo que a decisão de posicionamento em si parecesse válida.
Com o Kubernetes v1.35, um recurso Alpha introduz um mecanismo formal para que os nós declarem os recursos que suportam por meio de um novo campo status.declaredFeatures no objeto Node. Quando habilitado, os nós publicam o conjunto de recursos do Kubernetes que eles entendem. O scheduler, os controladores de admissão e componentes externos podem então usar essa informação para validar Pods e restringir o agendamento a nós compatíveis, evitando problemas de desvio de recursos antes de os Pods serem vinculados.
Dynamic Resource Allocation (DRA) - Trabalho em andamento
Feature Group: SIG Node / SIG Scheduling
A Dynamic Resource Allocation (DRA) é o framework nativo do Kubernetes para gerenciar recursos de hardware especializados (como GPUs, aceleradores e dispositivos) de forma integrada ao scheduler e segura para o ciclo de vida. Ela substitui muitas limitações dos device plugins tradicionais ao integrar a alocação de dispositivos diretamente ao processo de agendamento e vinculação do Kubernetes.
Antes do Kubernetes v1.35, a funcionalidade central da DRA já havia alcançado o status estável na v1.34.
Com o Kubernetes v1.35, a DRA está sempre habilitada e vários recursos alpha importantes amadureceram significativamente. O foco na v1.35 não são novas APIs, mas tornar os conceitos existentes da DRA mais completos, confiáveis e observáveis.
Vamos aos detalhes:
Requisições de recursos estendidos via DRA
As requisições de recursos estendidos permitem que Pods solicitem dispositivos com semântica mais rica, incluindo reutilização entre init containers e melhor pontuação durante o agendamento.****
****Antes do Kubernetes v1.35, a DRA ficava atrás dos device plugins em alguns cenários. Por exemplo, dispositivos não podiam ser reutilizados de forma limpa entre init containers e contêineres de aplicação, e as decisões de agendamento careciam de sinais adequados de pontuação para certos tipos de dispositivo.
Agora, com o Kubernetes v1.35, essas lacunas foram resolvidas. A reutilização de dispositivos entre init containers funciona corretamente, e a lógica de agendamento avalia melhor o posicionamento dos dispositivos. Isso torna a DRA viável para ciclos de vida de Pods mais complexos e workloads multiestágio.
Taints e tolerations de dispositivos
Taints de dispositivos permitem que dispositivos individuais — e não nós inteiros — expressem condições que afetam o agendamento e a remoção (eviction), de forma semelhante aos taints de nós.
Antes do Kubernetes v1.35, os taints de dispositivos eram limitados e careciam de formas seguras de avaliar seu impacto antes de aplicar evictions. Qualquer taint com NoExecute removia imediatamente os Pods que usavam o dispositivo.
Agora, com o Kubernetes v1.35, foi introduzido um novo efeito: None. Isso permite que operadores façam um dry run. Você pode inspecionar quantos pods seriam afetados e mudar para NoExecute apenas quando estiver pronto.
Além disso, o DeviceTaintRule agora reporta informações de status, tornando as evictions observáveis e mais seguras de operar.
Dispositivos particionáveis
Dispositivos particionáveis são dispositivos físicos que podem ser divididos em unidades lógicas menores (por exemplo, fatias de GPU).
Antes**,** todas as partições de um dispositivo tinham que ser definidas em um único ResourceSlice, limitando a flexibilidade na forma de modelar e divulgar os dispositivos.
Agora, com o Kubernetes v1.35, dispositivos pertencentes ao mesmo dispositivo particionável podem ser definidos em múltiplos ResourceSlices. Isso melhora a flexibilidade de modelagem e se alinha melhor à forma como o hardware moderno expõe recursos particionados.
Capacidade consumível
A capacidade consumível rastreia recursos de dispositivos que são esgotados gradualmente, em vez de alocados de forma exclusiva (por exemplo, largura de banda de memória ou aceleradores de uso limitado).
As primeiras implementações tinham problemas de corretude e cobertura de testes incompleta, limitando a confiança no comportamento de agendamento e contabilização.
Agora (v1.35), vários bugs foram corrigidos e a cobertura de testes foi ampliada. O comportamento de consumo e liberação de capacidade agora é mais confiável, tornando esse recurso mais seguro para experimentação.
Condições de vinculação de dispositivos
As condições de vinculação definem quando e como a alocação de um dispositivo se torna definitiva durante o agendamento e a admissão do Pod.
Antes, existiam casos extremos em que o comportamento de vinculação podia ser ambíguo ou tratado incorretamente em cenários de falha.
Agora (v1.35), várias correções e validações melhoram a corretude. As decisões de vinculação são mais previsíveis e resilientes, especialmente durante novas tentativas e falhas parciais.
Semântica comparável de versões de recursos
As versões de recursos permitem que clientes e controladores acompanhem mudanças em objetos do Kubernetes ao longo do tempo.
Antes do Kubernetes v1.35, as versões de recursos só podiam ser comparadas por igualdade, não por ordem. Os clientes não conseguiam determinar de forma confiável se uma versão era mais recente que outra sem ajuda do lado do servidor.
Agora, com o Kubernetes v1.35, todas as versões de recursos in-tree seguem um formato numérico estrito e comparável. Os clientes podem comparar versões por conta própria com segurança. Isso permite melhor performance dos informers e controladores mais confiáveis. Essa mudança é fundamental e habilita várias melhorias de nível mais alto em todo o Kubernetes.
Descontinuações / Remoções
Remoção do suporte a cgroup v1
Os cgroups são usados pelo Kubernetes para gerenciar CPU e memória dos contêineres. Versões anteriores suportavam tanto cgroup v1 quanto v2, principalmente por compatibilidade retroativa.
Na v1.35, o suporte a cgroup v1 foi totalmente removido, e o cgroup v2 passa a ser obrigatório.
Descontinuação do modo IPVS no kube-proxy
O kube-proxy roteia o tráfego de Services para os Pods usando diferentes modos de backend. O modo IPVS foi descontinuado na v1.35 devido à complexidade operacional e à sobreposição com dataplanes modernos.
O Kubernetes agora incentiva o uso do modo iptables ou de CNIs baseados em eBPF para redes escaláveis.
Isso reduz a sobrecarga de manutenção e melhora a confiabilidade da rede no longo prazo.
Última chamada para o containerd v1.x
O containerd é o runtime de contêineres padrão usado pelo Kubernetes.
As versões mais antigas do containerd v1.x estão se aproximando do fim do suporte.
O Kubernetes v1.35 sinaliza a última chamada para atualizar para versões mais recentes do containerd.
O Kubernetes 1.35 traz um total de 60 Kubernetes Enhancement Proposals (KEPs). Essas melhorias abrangem funcionalidades do Kubernetes, flexibilidade, gerenciamento de recursos, observabilidade e mais.
Além das principais mudanças que discutimos, há outros recursos adicionados pelo time do k8s. Recomendamos que você dê uma olhada nas notas de lançamento do Kubernetes v1.35 e confira este link para mais detalhes.