Kubernetes 1.36 erro IPVS pod Java derrubar - Meu Universo Nerd

Você ainda usa IPVS no seu kube-proxy? Ele foi removido no Kubernetes 1.36. E se você usa APIs deprecated que foram aposentadas nessa versão, seus CronJobs Java podem parar de funcionar silenciosamente. É exatamente o tipo de erro que só aparece em produção, nunca em staging.

O Kubernetes 1.36 ("Haru") foi lançado em abril de 2026 com 70 enhancements, e hoje saiu o patch 1.36.1. Tem mudanças que quebram pipelines Java se você atualizar sem checar. Aqui está o checklist completo antes de você apertar o botão de upgrade.

Você ainda usa IPVS no seu kube-proxy? Ele foi removido no Kubernetes 1.36. E se você usa APIs deprecated que foram aposentadas nessa versão, seus CronJobs Java podem parar de funcionar silenciosamente. É exatamente o tipo de erro que só aparece em produção, nunca em staging.

O Kubernetes 1.36 ("Haru") foi lançado em abril de 2026 com 70 enhancements, e hoje saiu o patch 1.36.1. Tem mudanças que quebram pipelines Java se você atualizar sem checar. Aqui está o checklist completo antes de você apertar o botão de upgrade.

O que é o Kubernetes 1.36 e por que você precisa checar antes de atualizar

O Kubernetes segue um ciclo de releases de três meses. A versão 1.36 "Haru" (primavera em japonês) foi a liberação de abril de 2026, e o patch 1.36.1 saiu em 13 de maio de 2026, o que significa que os clusters gerenciados (EKS, GKE, AKS) vão começar a oferecer essa versão nas próximas semanas.

Para times que rodam microserviços Java no Kubernetes corporativo, a atualização de versão principal sempre carrega riscos de breaking change. O problema real não é o que foi adicionado (features novas não quebram nada), mas o que foi removido. No 1.36, tem duas remoções críticas que afetam diretamente aplicações Java em produção.

Pensa assim: atualizar o Kubernetes sem checar as remoções é como trocar o motor do carro sem verificar se o novo parafuso é compatível com a carroceria antiga. A nova versão roda, mas algo pode não encaixar direito.

Remoção 1: IPVS no kube-proxy foi aposentado

O kube-proxy é o componente do Kubernetes responsável por gerenciar as regras de rede que direcionam o tráfego para os pods certos. Historicamente, ele suportava três modos: iptables (padrão), IPVS (alta performance para clusters com muitos Services) e userspace (legado).

No Kubernetes 1.36, o modo IPVS foi marcado como removido. Se o seu kube-proxy está configurado com mode: ipvs, o comportamento após o upgrade depende do provedor, mas o resultado esperado é queda na resolução de Service.

Como verificar se você usa IPVS no seu cluster:

// Não é código Java aqui — é o comando kubectl para checar
// Execute no terminal antes de atualizar:
// kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode

// Você vai ver algo como:
// mode: "ipvs"    ← PROBLEMA: remover antes do upgrade para 1.36
// mode: "iptables" ← OK: padrão e ainda suportado

Para aplicações Java com Spring Boot, o impacto prático é na resolução de Service: suas chamadas REST para outros microserviços via Kubernetes Service (ex: http://pagamento-service/api/pagamento) podem começar a falhar com timeout ou connection refused após o upgrade, se o IPVS for o modo ativo.

// Exemplo de cliente Spring Boot que chama outro microservice via Service K8s
@Service
public class PagamentoClient {

    private final RestClient restClient;

    public PagamentoClient(RestClient.Builder builder) {
        // Resolve "pagamento-service" via DNS do K8s (kube-proxy por baixo)
        this.restClient = builder
            .baseUrl("http://pagamento-service")
            .build();
    }

    public PagamentoResponse processar(PagamentoRequest request) {
        // Se kube-proxy IPVS foi removido e nao foi migrado para iptables,
        // essa chamada vai dar timeout silencioso em producao
        return restClient.post()
            .uri("/api/v1/pagamento")
            .body(request)
            .retrieve()
            .body(PagamentoResponse.class);
    }
}

A solução é migrar o modo antes do upgrade. Se você usa EKS, a AWS oferece o Amazon VPC CNI como alternativa mais robusta que IPVS para clusters de produção.

Remoção 2: APIs deprecated que afetam seus CronJobs e Deployments

Essa é a remoção mais perigosa porque é silenciosa. O Kubernetes 1.36 removeu APIs que foram marcadas como deprecated em versões anteriores. Se seus manifestos YAML ainda usam essas versões, o apply vai continuar funcionando em algumas situações, mas o comportamento pode ser imprevisível em clusters novos.

Como Tech Leader, já acompanhei um incidente em que um time migrou de cluster e os CronJobs de geração de relatório pararam silenciosamente. A causa? Os manifestos usavam batch/v1beta1 que havia sido aposentado. O erro aparecia apenas no log do controller manager, não no kubectl get cronjob.

Verifique suas versões de API antes do upgrade (consulte o guia oficial de deprecations do Kubernetes):

// Não é Java — são os comandos para auditoria de API antes do upgrade

// 1. Verificar quais APIs deprecated voce usa agora:
// kubectl get --raw /apis | jq '.groups[].versions[].groupVersion'

// 2. Listar todos os recursos com API version especifica:
// kubectl get cronjobs --all-namespaces -o json | jq '.items[].apiVersion'

// 3. Ferramenta oficial para auditoria: pluto — github.com/FairwindsOps/pluto
// pluto detect-all-in-cluster

// Exemplo de output do pluto:
// NAME                    KIND       VERSION        REPLACEMENT
// relatorio-diario        CronJob    batch/v1beta1  batch/v1
// relatorio-semanal       CronJob    batch/v1beta1  batch/v1

A correção é direta: atualize seus manifestos YAML de batch/v1beta1 para batch/v1 (disponível desde K8s 1.21) antes de atualizar o cluster. O mesmo vale para outras APIs deprecated que seu time possa usar.

// Exemplo de CronJob Java no manifesto correto para K8s 1.36
// Arquivo: kubernetes/relatorio-diario.yaml

/*
apiVersion: batch/v1           ← CORRETO para K8s 1.36+
kind: CronJob
metadata:
  name: relatorio-diario
  namespace: producao
spec:
  schedule: "0 6 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: relatorio
            image: minha-app/relatorio:1.5.0
            command: ["/app/generate-report.sh"]
            env:
            - name: SPRING_PROFILES_ACTIVE
              value: "producao"
          restartPolicy: OnFailure
*/

// ERRADO para K8s 1.36 (vai ser rejeitado pelo apiserver):
// apiVersion: batch/v1beta1  ← REMOVIDO no 1.36

O que foi adicionado no 1.36 que vale o upgrade

Agora que cobrimos os riscos, vale entender por que atualizar é importante além de manter a versão suportada. O Kubernetes 1.36 trouxe três features que impactam diretamente times Java.

User Namespaces estável (security grade para containers Java): Essa feature permite que seus containers Java rodem como root internamente sem ser root no host. Na prática, você pode rodar a JVM com as permissões que ela precisa dentro do container, enquanto o isolamento real acontece no kernel do host. Isso elimina a necessidade de soluções de contorno com securityContext.runAsNonRoot em apps legadas que esperam rodar como root.

// Manifesto de Pod com User Namespaces habilitado (K8s 1.36 stable)
// A JVM roda como UID 0 dentro do container
// mas mapeia para UID nao-privilegiado no host

/*
apiVersion: v1
kind: Pod
spec:
  hostUsers: false   ← habilita User Namespaces
  containers:
  - name: api-java
    image: minha-api:2.0
    securityContext:
      runAsUser: 0    ← root no container, nao-privilegiado no host
*/

Mutating Admission Policies em GA: Antes do 1.36, para injetar variáveis de ambiente ou modificar manifests automaticamente (sidecar de observabilidade, agentes de APM), você precisava de um webhook de admission customizado rodando. Agora, com Mutating Admission Policies, você faz isso via configuração declarativa do próprio K8s, sem precisar manter um servidor webhook. Para times Java que usam agentes de APM (Dynatrace, Datadog), isso simplifica muito a operação.

Resize in-place de PersistentVolume no EBS (alpha): Se seus microserviços Java usam volumes EBS para armazenar arquivos temporários, logs ou dados de processamento batch, o resize agora pode ser feito sem recriar o pod. Ainda é alpha no 1.36, mas é o caminho para operações mais suaves em produção.

Checklist completo antes de atualizar para Kubernetes 1.36

Aqui está o checklist que uso com times Java antes de qualquer upgrade de Kubernetes em produção:

// Checklist de upgrade — Kubernetes 1.36
// Execute cada verificacao antes de atualizar o cluster de producao

// 1. CHECAR MODO DO KUBE-PROXY
// kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode
// Se "ipvs": migrar para "iptables" antes do upgrade

// 2. AUDITAR APIS DEPRECATED
// pluto detect-all-in-cluster --target-versions k8s=v1.36.0
// Corrigir todos os manifestos com versoes antigas antes de prosseguir

// 3. VERIFICAR COMPATIBILIDADE DO HELM CHARTS
// helm list --all-namespaces
// Checar se os charts do seu Spring Boot usam APIs deprecated
// Atualizar os charts para versoes compatíveis com 1.36

// 4. TESTAR EM NAMESPACE ISOLADO
// kubectl create namespace k8s-136-teste
// Aplicar todos os manifestos no namespace de teste primeiro
// Validar que todos os Deployments, Services e CronJobs funcionam

// 5. UPGRADE CANARY
// Atualizar 1 node primeiro (se managed: via node group)
// Deixar 15 minutos rodando antes de atualizar o restante
// Monitorar metricas de erro (HTTP 5xx, latencia, pod restarts)

Perguntas Frequentes sobre Kubernetes 1.36 e Java

O Kubernetes 1.36 quebra o Spring Boot diretamente?
Não diretamente. O Spring Boot roda dentro do container e não interage com a API do Kubernetes em produção normal. O impacto chega pela remoção do IPVS (resolução de Service pode falhar) e APIs deprecated (manifestos rejeitados pelo apiserver). Apps Spring Boot sem essas situações não sofrem impacto.

Preciso atualizar agora ou posso esperar?
O Kubernetes mantém suporte ativo para as três últimas versões minor. Se você ainda roda 1.33 ou 1.34, tem tempo. Mas 1.32 e abaixo perdem suporte nos próximos meses. Planejar o upgrade agora, quando há tempo para testes, é melhor do que fazer sob pressão de fim de suporte.

Como o EKS gerencia o upgrade para 1.36?
A AWS lança o suporte a novas versões do K8s normalmente 1-2 meses após o release upstream. Para o 1.36 (lançado em abril de 2026), espere disponibilidade no EKS entre junho e julho de 2026. A AWS envia notificação no console quando a versão fica disponível. O upgrade do control plane é feito primeiro, depois os node groups.

User Namespaces funciona com containers Java existentes sem mudanças?
Sim, mas requer hostUsers: false no spec do Pod. A JVM não precisa de nenhuma alteração. A mudança é só no manifesto. O comportamento do app Java dentro do container não muda.

Mutating Admission Policies substitui meu webhook de admission atual?
Para casos simples de mutação (injetar variável de ambiente, adicionar label), sim. Para lógica complexa com chamadas externas, o webhook customizado ainda é necessário. O 1.36 não deprecou os webhooks existentes.

Conclusão: o upgrade seguro é o upgrade planejado

O Kubernetes 1.36 é uma versão sólida com melhorias reais de segurança e operação. Os 70 enhancements incluem trabalho importante para times Java: User Namespaces estável para isolamento real de containers, Mutating Admission Policies que simplificam injeção de configurações, e o início do caminho para resize dinâmico de volumes EBS.

Mas como em qualquer upgrade de infraestrutura, o risco não está no que foi adicionado. Está no que foi removido sem que ninguém no time tenha checado os manifestos ou a configuração do kube-proxy.

Os três pontos que ficam desse artigo:

  • Cheque o modo do kube-proxy antes de atualizar. Se for IPVS, migre para iptables primeiro.
  • Audite as APIs deprecated com o Pluto antes de qualquer upgrade. CronJobs em batch/v1beta1 param silenciosamente.
  • Faça o upgrade canary: 1 node por 15 minutos antes de atualizar o cluster inteiro.

Você já atualizou para Kubernetes 1.35 ou está planejando ir direto para o 1.36? Seu cluster usa IPVS? Conta nos comentários como está sendo a gestão de versões do K8s no seu time.

Na próxima semana vou entrar em detalhe no User Namespaces: como configurar corretamente para apps Java legadas que precisam de permissões específicas dentro do container sem comprometer a segurança do host.