View a markdown version of this page

Otimização de custos no Modo Automático do EKS - Amazon EKS

Ajudar a melhorar esta página

Para contribuir com este guia de usuário, escolha o link Editar esta página no GitHub, disponível no painel direito de cada página.

Otimização de custos no Modo Automático do EKS

O Modo Automático do EKS otimiza continuamente os custos de computação por meio de consolidação, bin-packing e dimensionamento correto. Porém, certas configurações da workload podem impedir essas otimizações. Este tópico explica como funciona a otimização de custos, o que pode bloqueá-la e como configurar o cluster para manter a eficiência de custos.

Como o Modo Automático do EKS otimiza custos

O Modo Automático do EKS reduz os custos de computação por meio dos seguintes mecanismos:

  • Bin-packing: ao agendar pods em nós, o Modo Automático do EKS seleciona os tipos de instância que melhor correspondam às solicitações de recursos agregadas, minimizando a capacidade não utilizada.

  • Consolidação: o Modo Automático do EKS avalia periodicamente os nós em execução e os substitui ou remove quando as workloads podem ser executadas em menos instâncias ou em instâncias menos dispendiosas.

  • Dimensionamento correto: à medida que a escala vertical de workloads diminui, o Modo Automático do EKS consolida os pods em nós menores e encerra as instâncias subutilizadas.

Essas otimizações podem ser executadas continuamente, sem intervenção manual. Porém, certas anotações de pod e configurações de NodePool podem impedir que a consolidação ocorra.

Pools de nós incorporados e barreiras de proteção de custo

Os pools de nós de general-purpose e de system incorporados aplicam vários padrões de proteção de custos:

  • Famílias de instâncias restritas a C, M e R: não são permitidos tipos de instância acelerados (P, G, Inf, Trn) ou exóticos.

  • Capacidade somente sob demanda: nenhuma instância spot, o que evita a rotatividade causada por interrupções, mas também significa que não a economia gerada pelas instâncias spot não ocorre.

  • Geração 5 ou mais recente: as gerações de instância mais antigas e menos econômicas foram excluídas.

Se você usar apenas pools de nós incorporados, já terá os benefícios dessas barreiras de proteção. A orientação neste tópico sobre a exclusão das famílias de instâncias e a restrição do tamanho das instâncias é mais relevante quando você cria NodePools personalizados, que não herdam essas restrições.

Porém, mesmo com pools de nós incorporados, as seções a seguir continuam se aplicar:

  • O que bloqueia a consolidação: a anotação do-not-disrupt e os PDBs restritivos bloqueiam a consolidação, não importando qual foi o NodePool que provisionou o nó.

  • Use os limites de NodePool como teto de custo: os pools de nós Incorporados não têm limits de recursos configurados. Se o tamanho das workloads puder aumentar significativamente, pense em criar um NodePool personalizado com limites em vez de usar pools incorporados ilimitados.

  • Ciclo de vida e custo do nó: a sobreposição de substituição de nós se aplica a todos os nós, incluindo os provisionados por pools incorporados.

Barreira de proteção Pools de nós incorporados NodePools personalizados

Exclusão de instâncias aceleradas

Impostas

Você deve configurar

Limites de tamanho das instâncias

Não definido

Você deve configurar

limits de recursos (limite máximo de CPU/memória)

Não definido

Você deve configurar

Sob demanda apenas

Impostas

Você escolhe (spot/sob demanda)

Proteção por consolidação (do-not-disrupt/PDB)

Sua responsabilidade

Sua responsabilidade

O que bloqueia a consolidação

A consolidação é bloqueada quando o Modo Automático do EKS determina que interromper um nó violaria os requisitos de disponibilidade de uma workload. As seguintes configurações impedem a consolidação:

A anotação do-not-disrupt

A anotação karpenter.sh/do-not-disrupt instrui o Modo Automático do EKS a preservar um nó enquanto o pod anotado estiver sendo executado nele. Isso evita que o nó seja consolidado, substituído ou encerrado, mesmo que seja subutilizado.

metadata: annotations: karpenter.sh/do-not-disrupt: "true"
Importante

Implicação para custos: quando um pod tem a anotação do-not-disrupt, o nó em que ele é executado fica isento da consolidação. Isso significa que:

  • O nó continua sendo executado em seu tamanho de instância atual, qualquer que seja a utilização real.

  • O uso da vCPU e da memória nesse nó pode permanecer elevado mesmo com a diminuição de demanda da workload.

  • Se vários pods em muitos nós tiverem essa anotação, a consolidação em todo o cluster será significativamente reduzida, resultando em custos mais altos sustentados.

A anotação do-not-disrupt é um mecanismo de disponibilidade. Não leva em conta o preço. Use-a somente para workloads em que a interrupção durante a execução cause perda de dados ou retrabalho significativo, por exemplo, trabalhos em lotes de longa execução ou processos com estado sem pontos de verificação.

Alternativas a serem consideradas:

  • Orçamentos de interrupção de pod (PDBs): use PDBs para controlar a taxa de interrupção em vez do seu bloqueio total. Os PDBs permitem que a consolidação continue e, ao mesmo tempo, garantem que um número mínimo de réplicas permaneça disponível.

  • Workloads mais breves: para executores de CI/CD e agentes de compilação, permita interrupções e use a lógica de repetição incorporada do sistema de CI em vez de usar do-not-disrupt.

  • Anotações com limite de tempo: aplique do-not-disrupt somente durante uma operação crítica, depois remova a anotação programaticamente quando a operação for concluída.

Orçamentos de interrupção de pod (PDBs)

PDBs que definem maxUnavailable: 0 ou minAvailable como a contagem de réplicas atuais bloqueiam efetivamente qualquer consolidação dos pods afetados. Revise os PDBs para garantir que eles permitam que pelo menos um pod seja interrompido de cada vez.

Use os limites de NodePool como teto de custo

Os limits de NodePool estabelecem um teto rígido para o total de recursos computacionais que um NodePool pode provisionar. Quando o limite é atingido, o Modo Automático do EKS impede a inicialização de novos nós para esse NodePool. Isso acontece mesmo que haja pods pendentes.

Use limits como uma barreira de proteção de custo, especialmente para NodePools que atendem a workloads não de produção, teste ou com picos, nos quais a escalação ilimitada não é apropriada.

apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: ci-runners spec: template: spec: nodeClassRef: group: eks.amazonaws.com kind: NodeClass name: default requirements: - key: "eks.amazonaws.com/instance-category" operator: In values: ["c", "m"] limits: cpu: "500" memory: 1000Gi

Neste exemplo, o NodePool de ci-runners não podem exceder 500 vCPUs ou 1.000 GiB de memória total em todos os nós que ele provisiona. Os pods que excedem esse limite permanecem no estado Pending até que capacidade seja liberada.

dica

Defina limits com base no tamanho máximo de pico esperado mais uma reserva para substituição de nós. Revise sua utilização do NodePool regularmente e ajuste os limites à medida que os padrões de workload mudarem.

Excluir famílias de instâncias para controle de custos

Por padrão, o Modo Automático do EKS seleciona entre muitos tipos de instância para maximizar a flexibilidade de agendamento. Para workloads que não exigem hardware especializado, restrinja as famílias de instâncias para evitar que tipos de instância dispendiosos sejam iniciados.

Excluir instâncias aceleradas

Se as workloads não precisam de recursos de GPU ou acelerador, exclua as famílias de instâncias aceleradas do NodePool. Isso evita cenários em que instâncias aceleradas são selecionadas durante restrições de capacidade.

spec: template: spec: requirements: - key: "eks.amazonaws.com/instance-category" operator: In values: ["c", "m", "r"]

Especificando apenas as categorias de instâncias otimizadas para computação, de uso geral e otimizadas para memória, você exclui da seleção as famílias de instâncias aceleradas (P, G, Inf, Trn) e outras famílias de instâncias especializadas.

Como a seleção de instâncias interage com as restrições de capacidade

O Modo Automático do EKS desprioriza os tipos de instância aceleradas e exóticas durante a seleção normal de instâncias. Porém, quando ocorrerem falhas de inicialização sustentadas, o Modo Automático do EKS é iniciado a partir de qualquer tipo de instância disponível restante para priorizar a disponibilidade para a workload. Por exemplo, isso acontece quando as cotas de serviço do EC2 se esgotam temporariamente para todos os tipos de instância preferenciais.

Para evitar esse comportamento de fallback, restrinja explicitamente os requisitos do NodePool apenas às categorias de instâncias de que a workload precisa. Quando os tipos preferenciais não estão disponíveis e nenhum outro tipo é permitido pela configuração do NodePool, os pods permanecem no estado Pending em vez de serem agendados em instâncias caras.

Limitar os tamanhos das instâncias

Além de restringir as famílias de instâncias, você pode limitar o tamanho máximo das instâncias do NodePool. A restrição do tamanho das instâncias limita a exposição ao risco de custo de qualquer nó individual que não possa ser consolidado. Por exemplo, um nó bloqueado por uma anotação do-not-disrupt não pode ser reduzido mesmo que sua workload seja pequena.

Use o rótulo eks.amazonaws.com/instance-cpu para limitar os tamanhos máximos das instâncias nos requisitos do NodePool:

requirements: - key: "eks.amazonaws.com/instance-cpu" operator: Lte values: ["32"]

Essa configuração impede que o Modo Automático do EKS inicie instâncias com mais de 32 vCPUs nesse NodePool.

Para identificar oportunidades de otimização em um cluster existente, analise as maiores instâncias em execução. Se a consolidação de nós grandes for consistentemente bloqueada, o custo por nó dessa capacidade ociosa será proporcionalmente maior.

Pipelines de CI/CD, trabalhos em lote e executores efêmeros criam padrões de picos e ociosidade que exigem configuração específica para manter a eficiência de custos.

Configuração Recomendação

do-not-disrupt

Não use executores de CI/CD. Em vez disso, use os mecanismos de repetição e de fila do sistema de CI.

limits de NodePool

Defina um limite máximo de CPU/memória com base na simultaneidade máxima esperada mais um buffer para a sobreposição de substituição de nós.

Categorias de instância

Restringir às famílias c e m. Exclua as famílias de instâncias aceleradas (P, G, Inf, Trn) para workloads não GPU.

Tamanhos de instância

Considere restringir o uso aos tamanhos médios (por exemplo, de 4 a 32 vCPUs) para limitar a exposição ao risco de custo de qualquer nó que não possa ser consolidado.

Tempos de consolidação

Use a configuração consolidateAfter padrão. Evite definir demoras longas que mantêm a capacidade de expansão online após a conclusão dos executores.

Tipo de capacidade

Use instâncias spot para executores tolerantes a falhas. Combine com instâncias sob demanda para criar agentes que mantêm o estado durante a execução.

Exemplo: NodePool executor de CI

apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: ci-runners spec: template: spec: nodeClassRef: group: eks.amazonaws.com kind: NodeClass name: default requirements: - key: "eks.amazonaws.com/instance-category" operator: In values: ["c", "m"] - key: "eks.amazonaws.com/instance-cpu" operator: Lte values: ["32"] - key: "karpenter.sh/capacity-type" operator: In values: ["spot", "on-demand"] limits: cpu: "500" memory: 1000Gi disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 30s

Esta configuração:

  • Restringe às famílias de instâncias econômicas

  • Limita a capacidade total do NodePool a 500 vCPUs

  • Permite uma consolidação drástica (30 segundos após a remoção dos pods)

  • Permite configurar capacidade spot e sob demanda

Ciclo de vida e custo do nó

O Modo Automático do EKS substitui nós por meio de interrupções graduais quando eles se desviam da especificação desejada (por exemplo, após a liberação de uma nova AMI do Modo Automático) ou quando o vida útil do nó está chegando ao fim. Durante uma substituição gradual:

  • Um novo nó substituto é iniciado e fica pronto.

  • Os pods são drenados do nó antigo, respeitando os orçamentos de interrupção de pods.

  • Por um breve período, ambos, o nós antigo e o nó substituto, permanecem em execução.

Para clusters com nós grandes ou com muitos nós, essa sobreposição pode criar aumentos de custo periódicos. Para minimizar o impacto:

  • Revise os orçamentos de interrupção: garanta que os orçamentos de interrupção permitam a drenagem na hora certa. Orçamentos restritivos estendem o período de sobreposição durante o qual o nó antigo e o nó permanecem em execução.

  • Instâncias do tamanho certo: instâncias menores reduzem o custo absoluto da janela de sobreposição.

  • Reduza a vida útil máxima do nó: valores de expiração mais curtos (por exemplo, 7 dias) criam eventos de substituição mais frequentes, porém menores. Isso distribui o custo de maneira mais uniforme ao longo do tempo, em vez de concentrá-lo.

Para obter mais informações sobre o ciclo de vida do nós, consulte Saiba mais sobre as instâncias gerenciadas do Modo Automático do Amazon EKS.