Práticas recomendadas para ComputeClasses

Os engenheiros de plataforma podem usar ComputeClasses personalizadas para configurar declarativamente as definições de nós e as prioridades de fallback que o Google Kubernetes Engine (GKE) usa para criar nós durante o escalonamento automático. É possível criar ComputeClasses com base em estratégias específicas e requisitos de carga de trabalho. Este documento apresenta as práticas recomendadas para projetar e implementar ComputeClasses nos clusters. Você já deve estar familiarizado com as ComputeClasses personalizadas. Para uma visão geral consolidada de todas as práticas recomendadas do GKE, consulte Práticas recomendadas para o GKE.

Design da ComputeClass

As seções a seguir apresentam práticas recomendadas para projetar e implementar ComputeClasses nos clusters com base em metas como maximizar a capacidade de recebimento de recursos e o desempenho. As ComputeClasses funcionam com pools de nós criados manualmente e automaticamente.

Projetar cada ComputeClass com base em uma estratégia

Projete cada ComputeClass para atender a um objetivo específico para suas cargas de trabalho, equipes ou organização. Use o comportamento de fallback das ComputeClasses e a capacidade de selecionar pools de nós criados manualmente e automaticamente para priorizar determinados resultados, como reduzir a sobrecarga manual ou melhorar o desempenho do agendamento. As seções a seguir descrevem estratégias comuns.

Melhorar a capacidade de recebimento de recursos e reduzir a sobrecarga manual

Para delegar a criação de pool de nós ao GKE, use apenas pools de nós criados automaticamente na ComputeClass. O escalonador automático configura nós com base na disponibilidade de hardware, nos requisitos de recursos do pod e na capacidade zonal. Essa estratégia elimina a necessidade de criar e ajustar manualmente os pools de nós e pode reduzir os custos associados à capacidade de nós ociosa e não utilizada.

Melhorar o desempenho do agendamento e ajustar os nós

Para ajustar os nós de maior prioridade e reduzir a latência de agendamento, use uma combinação de pools de nós criados manualmente e automaticamente na ComputeClass. Essa estratégia híbrida reduz a frequência com que os pods aguardam a criação de novos pools de nós pelo GKE. Como os pools de nós de maior prioridade são criados manualmente, é possível ajustar o hardware para atender aos requisitos exatos dos pods.

A estratégia híbrida envolve os seguintes tipos de pools de nós em ordem de prioridade na ComputeClass:

  1. Pools de nós criados manualmente: esses pools de nós têm as especificações exatas em que você quer que a maioria dos pods seja executada. Configure esses pools de nós com rótulos de nós específicos, taints de nós, reservas de capacidade ou configurações especiais, como parâmetros kubelet. Crie esses pools de nós com quantos nós você estima que os pods vão precisar. Na ComputeClass, atribua a maior prioridade a esses pools de nós.
  2. Pools de nós criados automaticamente: como uma medida de fallback, use a ComputeClass para solicitar pools de nós adicionais que ainda estejam otimizados para os pods. Atribua uma prioridade menor a esses pools de nós criados automaticamente do que aos pools de nós criados manualmente.

A ComputeClass de exemplo a seguir usa essa estratégia híbrida:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: hybrid-class
spec:
  nodePoolAutoCreation:
    enabled: true
  priorities:
  - nodepools: ['manual-pool1']
  - machineFamily: n4
    minCores: 16
    minMemoryGb: 64
  whenUnsatisfiable: DoNotScaleUp

Ao implantar uma carga de trabalho que usa essa ComputeClass, o GKE coloca pods em nós disponíveis em manual-pool1. O GKE cria novos pools de nós somente quando o pool de nós criado manualmente não tem capacidade disponível. A latência de agendamento diminui quando o número de nós atuais no pool de nós criado manualmente aumenta, porque o GKE não precisa criar novos nós com frequência.

Definir explicitamente o comportamento de escalonamento de último recurso

O campo whenUnsatisfiable controla o que acontece se o GKE não atender aos requisitos de nenhuma das regras de prioridade em uma ComputeClass. Para evitar comportamentos inesperados após um upgrade de versão, especifique explicitamente um valor para esse campo em cada ComputeClass. A definição de um valor ajuda os usuários da ComputeClass a saber o que esperar ao selecionar essa ComputeClass em uma carga de trabalho. O valor recomendado para esse campo depende do tipo de carga de trabalho, conforme descrito abaixo:

  • Cargas de trabalho de uso geral: se as cargas de trabalho puderem ser executadas em qualquer série de máquinas, especifique um valor de ScaleUpAnyway. Se os nós que correspondem a uma regra de prioridade na ComputeClass não estiverem disponíveis, o GKE vai escalonar verticalmente os nós que usam a série de máquinas padrão do cluster.
  • Cargas de trabalho que precisam de hardware especializado: para aceleradores ou cargas de trabalho de computação de alta performance que dependem de hardware específico, como GPUs ou determinadas séries de máquinas do Compute Engine, especifique um valor de DoNotScaleUp. Se os nós que correspondem a uma regra de prioridade na ComputeClass não estiverem disponíveis, os pods vão permanecer no estado Pending até que os recursos fiquem disponíveis. Essa abordagem impede que os pods sejam executados em hardware incompatível.

Para mais informações, consulte Definir o comportamento de escalonamento quando nenhuma regra de prioridade se aplica.

Definir uma ComputeClass padrão no nível do cluster para a maioria das cargas de trabalho

Se a maioria das cargas de trabalho tiver os mesmos requisitos de hardware, então configure uma ComputeClass padrão para o cluster. O GKE aplica a ComputeClass padrão a cargas de trabalho que não selecionam explicitamente uma ComputeClass. Ao definir uma ComputeClass padrão, os operadores de aplicativos não precisam mudar os seletores de nós nem solicitar manualmente pools de nós e hardware específicos em pods individuais. Se você definir uma ComputeClass padrão no nível do cluster, não adicione rótulos e taints de nós para outras ComputeClasses aos pools de nós atuais no cluster. Durante o agendamento da ComputeClass padrão no nível do cluster, o GKE ignora todos os pools de nós que têm rótulos ou taints de nós para outras ComputeClasses.

Definir ComputeClasses padrão para namespaces para separar locatários

Além de uma ComputeClass padrão no nível do cluster, é possível definir uma ComputeClass padrão para namespaces específicos. Se você tiver ambientes multilocatários ou quiser separar cargas de trabalho executadas em hardware especializado, configure ComputeClasses padrão para esses namespaces. Para impedir que os pods do sistema sejam executados em hardware especializado, como nós de GPU, adicione uma ComputeClass de uso geral como a ComputeClass padrão para namespaces do sistema.

Executar cargas de trabalho de baixa interação no modo Autopilot

Se você tiver cargas de trabalho que não exigem interação ou gerenciamento manual, execute-as no modo Autopilot usando ComputeClasses. É possível ativar o modo Autopilot em qualquer ComputeClass, mesmo quando você tem um cluster padrão. O GKE executa as cargas de trabalho que selecionam uma ComputeClass do Autopilot em nós totalmente gerenciados que implementam os recursos de segurança, escalonamento e faturamento do Autopilot do GKE. Para mais informações, consulte Sobre cargas de trabalho do modo Autopilot no GKE Standard.

Cargas de trabalho com estado

As seções a seguir apresentam práticas recomendadas para reduzir interrupções ou comportamentos inesperados em cargas de trabalho com estado que dependem de dados persistentes.

Desativar a migração ativa

A migração ativa move automaticamente os pods para novos nós que têm uma prioridade maior na ComputeClass ou têm capacidade para executar pods do DaemonSet não programados. Durante a migração ativa, o GKE encerra os pods nos nós atuais e cria novos pods em nós de maior prioridade. Se você tiver cargas de trabalho que dependem de dados no armazenamento persistente local, a movimentação dos pods para novos nós poderá causar interrupções, porque os pods perdem o acesso aos dados persistentes. Para evitar esse problema, desative a migração ativa para ComputeClasses destinadas a cargas de trabalho com estado.

Melhorar a confiabilidade do agendamento usando StorageClasses

Use StorageClasses para melhorar a confiabilidade do agendamento de cargas de trabalho com estado das seguintes maneiras:

  • Criar volumes somente após a criação do pod: se você usar o provisionamento dinâmico de volume, especifique um valor de WaitForFirstConsumer no volumeBindingMode campo em uma StorageClass. Esse modo de vinculação de volume impede a criação de um PersistentVolume até que o GKE crie um pod que use o PersistentVolumeClaim correspondente. O GKE provisiona o PersistentVolume na mesma zona que o nó que executa o pod.
  • Usar StorageClasses com reconhecimento de topologia:se a ComputeClass abranger várias gerações de uma série de máquinas (por exemplo, C4 e C3), use uma StorageClass que tenha a seleção automática de tipo de disco ativada e que programe apenas em nós que ofereçam suporte aos tipos de disco especificados. É possível usar a StorageClass dynamic-rwo integrada ou uma StorageClass personalizada. As cargas de trabalho com estado podem ser executadas em várias gerações de instâncias do Compute Engine, porque o escalonador automático de cluster escolhe dinamicamente um tipo de disco compatível.

Capacidade de receber recursos

As seções a seguir apresentam práticas recomendadas para melhorar a capacidade de recebimento de recursos em ComputeClasses, para que os pods passem menos tempo no estado Pending.

Solicitar séries de máquinas em vez de tipos de máquinas

É possível solicitar uma série de máquinas do Compute Engine ou tipos de máquinas específicos nas regras de prioridade da ComputeClass. A menos que você tenha uma dependência estrita de um tipo de máquina específico, selecione uma série de máquinas usando o machineFamily campo. Durante uma operação de escalonamento, o GKE pode criar nós que usam qualquer tipo de máquina viável nessa série, o que melhora a probabilidade de os pods serem executados na configuração de nó preferida.

Usar reservas de capacidade para hardware sob demanda

Se as cargas de trabalho dependem de hardware sob demanda, como TPUs ou GPUs de alta performance, crie reservas de capacidade do Compute Engine para o hardware e consuma essas reservas nas ComputeClasses. As reservas de capacidade melhoram a probabilidade de hardware estar disponível na região ou zona, o que ajuda a aumentar a capacidade de recebimento de recursos. Para consumir uma reserva em uma ComputeClass sem afetar o comportamento de fallback, use a afinidade de reserva Specific ou AnyThenFail. Se você usar a afinidade AnyBestEffort ou Automatic e não houver capacidade reservada disponível, o Compute Engine poderá ignorar as regras de prioridade da ComputeClass e fazer fallback para o hardware sob demanda. Para mais informações, consulte Como consumir recursos zonais reservados.

Não consumir novas reservas por pelo menos uma hora

O escalonador automático de cluster armazena informações sobre reservas de capacidade em um cache. Ao criar uma nova reserva de capacidade, o escalonador automático pode levar até uma hora para descobrir essa reserva. Depois de criar uma reserva, aguarde pelo menos uma hora antes de consumi-la em uma carga de trabalho. Se você implantar uma carga de trabalho que usa a reserva antes que o escalonador automático a armazene no cache, a operação de escalonamento automático poderá falhar.

Segurança

As seções a seguir apresentam práticas recomendadas para melhorar a segurança das ComputeClasses nos clusters. Essas medidas são importantes porque as ComputeClasses podem ser usadas para criar e configurar nós que usam hardware caro ou com disponibilidade limitada. O uso indevido intencional ou acidental pode resultar em interrupções de carga de trabalho, cobranças de uso de recursos não planejadas e esgotamento de cota.

Restringir o acesso à API para configurações de ComputeClass

As cargas de trabalho podem usar ComputeClasses para criar nós que executam hardware especializado, incluindo GPUs e TPUs. Restrinja o acesso para criar, modificar e excluir ComputeClasses aos mesmos principais que podem criar, modificar e excluir nós nos clusters. Para controlar o acesso às ComputeClasses, use políticas de RBAC.

Restringir a disponibilidade da ComputeClass por namespace

Os clientes do GKE geralmente separam diferentes equipes ou tipos de carga de trabalho por namespace do Kubernetes. As ComputeClasses são um recurso com escopo de cluster, o que significa que qualquer carga de trabalho em qualquer namespace pode selecionar qualquer ComputeClass por padrão. Para evitar o uso indevido intencional ou acidental, use ValidatingAdmissionPolicies para controlar o conjunto de ComputeClasses que as cargas de trabalho em cada namespace podem selecionar. Por exemplo, é possível impedir que os pods no namespace do front-end da Web selecionem ComputeClasses que criam aceleradores. Verifique se as ValidatingAdmissionPolicies verificam as seguintes configurações comuns:

  • Verificar todos os campos de seleção:uma carga de trabalho pode selecionar uma ComputeClass usando o campo nodeSelector, nodeAffinity ou tolerations na especificação do pod. Para evitar a seleção não intencional da ComputeClass, verifique todos esses campos nas expressões ValidatingAdmissionPolicy.
  • Verificar se há tolerâncias de curinga ignoradas:bloqueie ou valide explicitamente as tolerâncias de curinga (por exemplo, a tolerância operator: Exists sem chave). Esses seletores de curinga podem abranger a maioria dos taints de nós, incluindo taints de ComputeClass.
  • Verificar todos os controladores de carga de trabalho: configure matchConstraints da política para abranger todos os recursos do controlador de carga de trabalho (como Deployment, StatefulSet, DaemonSet, Job e CronJob). Não limite suas verificações apenas aos recursos Pod.

Para mais informações, consulte Restringir o acesso para modificar e selecionar ComputeClasses.

Confiabilidade

As seções a seguir apresentam práticas recomendadas para melhorar a confiabilidade do escalonamento automático e da migração de pods para ComputeClasses, o que reduz o risco de interrupções ou pods presos.

Impedir o uso de seletores de nós conflitantes

Os seletores de nós nos pods afetam onde o GKE coloca esses pods e, no modo Autopilot ou com a criação automática de pool de nós, podem acionar a criação de novos pools de nós no cluster. Se você tiver pods que selecionam uma ComputeClass e usam seletores de nós para solicitar nós que entram em conflito com a configuração da ComputeClass, o GKE poderá não programar os pods.

Por exemplo, considere uma ComputeClass que solicita apenas instâncias sob demanda. Se um pod selecionar essa ComputeClass e selecionar VMs spot em um seletor de nós, o GKE não poderá programar o pod porque a ComputeClass e o seletor de nós entram em conflito. Para evitar esse problema, use métodos como ValidatingAdmissionPolicies para impedir que os pods que selecionam ComputeClasses também selecionem rótulos de nós do sistema. Para mais informações, consulte Seletores de nós para rótulos de nós do sistema.

Testar todas as mudanças nas configurações de migração ativa e escalonamento automático

As configurações de migração ativa e escalonamento automático em uma ComputeClass afetam diretamente a frequência com que o GKE encerra os pods para realizar tarefas como mover pods para hardware mais preferencial e consolidar nós subutilizados. As modificações dessas configurações em uma ComputeClass atual podem resultar em interrupções inesperadas na carga de trabalho. Antes de aplicar modificações a essas configurações em ComputeClasses atuais, teste as mudanças em um ambiente de preparo. Também é possível usar anotações para proteger cargas de trabalho críticas contra remoção durante o escalonamento.

Testar atualizações do CRD da ComputeClass antes dos upgrades do cluster

O GKE atualiza regularmente a definição de recurso personalizado (CRD, na sigla em inglês) da ComputeClass para adicionar campos, modificar o comportamento do campo e corrigir problemas. As adições e modificações de campo normalmente entram em vigor em versões específicas do GKE. Antes de fazer upgrade dos clusters de produção para novas versões secundárias ou de patch, verifique se as mudanças no CRD causam problemas de carga de trabalho usando as diretrizes a seguir:

Usar PodDisruptionBudgets para melhorar a disponibilidade da carga de trabalho

As operações da ComputeClass que causam remoções de pods, como a migração ativa, respeitam todos os PodDisruptionBudgets configurados. Por exemplo, é possível configurar uma implantação de inferência para ter um PodDisruptionBudget que exige que mais de 70% dos pods estejam disponíveis. Durante a migração ativa, se uma remoção de pod violar esse orçamento, o GKE não vai remover o pod. Especifique PodDisruptionBudgets para cargas de trabalho como as seguintes:

  • Cargas de trabalho sem estado, como implantações de inferência.
  • Cargas de trabalho com estado replicadas, como aplicativos de banco de dados de alta disponibilidade.

Não dependa de PodDisruptionBudgets para proteger cargas de trabalho que precisam ser executadas até a conclusão, ter apenas uma instância ou depender de dados persistentes locais. Especifique um orçamento que equilibre a disponibilidade da carga de trabalho e permita que funções como upgrades sejam concluídas.

Proteger cargas de trabalho críticas contra remoção

Se você tiver cargas de trabalho em que cada pod precisa ser executado até a conclusão antes de ser encerrado, adicione a anotação cluster-autoscaler.kubernetes.io/safe-to-evict: "false" à especificação do pod. Essa anotação impede que o GKE remova pods durante operações de escalonamento automático. Use essa anotação para proteger pods que não podem tolerar interrupções, como cargas de trabalho com estado de instância única e jobs em lote de longa duração.

Resumo das práticas recomendadas

Este documento apresenta as seguintes práticas recomendadas para ComputeClasses:

A seguir