Com a chegada do Kubernetes v1.36, a comunidade entrega uma melhoria estratégica para quem lida com processamento de dados, batch jobs e modelos de machine learning: a capacidade de modificar os requests e limits de recursos (CPU, memória e GPUs) em Jobs que estão no estado de suspensão.
O desafio da imutabilidade em cargas de trabalho batch
Historicamente, uma vez que o pod template de um Job era definido, ele tornava-se imutável. Para empresas brasileiras que operam plataformas de dados ou esteiras de ML, isso criava um gargalo operacional. Se o seu controller (como o Kueue ou um scheduler customizado) detectasse uma mudança na disponibilidade de recursos do cluster, a única saída para ajustar o job era o delete-and-recreate. O resultado? Perda de histórico, metadados e toda a rastreabilidade da execução. Em cenários multicloud ou ambientes com alta volatilidade de custos (spot instances), essa rigidez impedia um planejamento de capacidade eficiente.
Ajustando a demanda dinamicamente
Imagine um cenário de treinamento de modelo que foi configurado inicialmente para 8 CPUs e 4 GPUs. Se, no momento da execução, o seu orquestrador identifica que há um gargalo de hardware e apenas 2 GPUs estão disponíveis, o cluster simplesmente ignoraria a fila ou causaria falhas constantes. Com o v1.36, o fluxo muda:
- O Job é criado com spec.suspend: true.
- O controller valida o cenário atual do cluster.
- O controller atualiza as especificações de recursos no pod template sem precisar recriar o objeto Job.
- Ao remover a suspensão (spec.suspend: false), o Job inicia com o novo "tamanho" ajustado.
Considerações técnicas para a operação
Para times de engenharia, é fundamental notar que esta funcionalidade, agora em beta e habilitada por padrão, exige cautela:
- Condições de mutação: A alteração só é aceita se o Job estiver suspenso e, caso ele já tenha rodado anteriormente, todos os pods ativos precisam obrigatoriamente estar terminados (status.active == 0). O API server rejeitará qualquer tentativa de modificação enquanto houver pods em execução para evitar inconsistências no scheduler.
- Política de substituição: Recomendamos fortemente o uso de podReplacementPolicy: Failed. Isso garante que o controle de lifecycle dos pods seja limpo e que o scheduler não se perca em uma eventual contenção de recursos entre pods antigos e novos.
- Limitações no DRA: Se você utiliza Dynamic Resource Allocation (DRA), atenção: as instâncias de resourceClaimTemplates permanecem imutáveis. O ajuste de hardware precisa, neste caso, de uma definição específica fora do template principal.
Para o tomador de decisão, este é um passo claro em direção a uma maior eficiência no consumo de recursos, reduzindo o desperdício computacional (tema central de FinOps) e aumentando a resiliência operacional das esteiras de dados que são o coração de muitas empresas tech aqui no Brasil.
Artigo originalmente publicado por Kevin Hannon em Kubernetes Blog.