Práticas recomendadas para ComputeClasses

Os engenheiros de plataforma podem usar ComputeClasses personalizadas para configurar de forma declarativa as configurações de nós e as prioridades de substituição 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 e requisitos de carga de trabalho específicos. Neste documento, apresentamos as práticas recomendadas para projetar e implementar ComputeClasses nos clusters. Você já deve conhecer 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 mostram as práticas recomendadas para projetar e implementar ComputeClasses nos clusters com base em metas como maximizar a flexibilidade, a eficiência, a disponibilidade e o desempenho da capacidade de computação. 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 uma meta específica das suas cargas de trabalho, equipes ou organização. Use o comportamento substituto de ComputeClasses e a capacidade de selecionar pools de nós criados manualmente e de criação automática para priorizar determinados resultados, como reduzir o overhead manual ou melhorar o desempenho do escalonamento. As seções a seguir descrevem estratégias comuns.

Melhorar a disponibilidade 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 sua ComputeClass. O escalonador automático configura nós com base na disponibilidade de hardware, nos requisitos de recursos de pods 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 ociosos e não utilizados.

Melhorar o desempenho da programação e ajustar os nós

Para ajustar os nós de maior prioridade e reduzir a latência de programação, 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 o GKE criar novos pools de nós. 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 o número de nós que você estima que os pods vão precisar. Na sua ComputeClass, atribua a prioridade mais alta a esses pools de nós.
  2. Pools de nós criados automaticamente: como medida de fallback, use a ComputeClass para solicitar outros pools de nós que ainda estejam otimizados para seus pods. Atribua uma prioridade menor a esses pools de nós criados automaticamente do que aos pools de nós criados manualmente.

O exemplo de ComputeClass 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

Quando você implanta uma carga de trabalho que usa essa ComputeClass, o GKE coloca os pods nos 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 programação diminui quando o número de nós no pool de nós criado manualmente aumenta, porque o GKE não precisa criar novos nós com tanta frequência.

Definir explicitamente o comportamento de escalonamento de último recurso

O campo whenUnsatisfiable controla o que acontece se o GKE não puder atender aos requisitos de qualquer uma 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. Definir 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, da seguinte maneira:

  • 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 alto desempenho 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 em um 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, configure uma ComputeClass padrão para o cluster. O GKE aplica a ComputeClass padrão a todas as 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 ou 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ó para outras ComputeClasses aos pools de nós atuais no cluster. Durante a programação 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ó 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 evitar 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 que você tenha um cluster Standard. 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 GKE Autopilot. Para mais informações, consulte Sobre as cargas de trabalho do modo Autopilot no GKE Standard.

Cargas de trabalho com estado

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

Desativar migração ativa

A migração ativa move automaticamente os pods para novos nós que têm uma prioridade mais alta na ComputeClass ou que 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 prioridade mais alta. Se você tiver cargas de trabalho que dependem de dados no armazenamento permanente local, mover os pods para novos nós poderá causar interrupções porque os pods perderão o acesso aos dados permanentes. Para evitar esse problema, desative a migração ativa para ComputeClasses destinadas a cargas de trabalho com estado.

Melhorar a confiabilidade da programação usando StorageClasses

Use StorageClasses para melhorar a confiabilidade da programação 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 campo volumeBindingMode em um 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.
  • Use StorageClasses com reconhecimento de topologia:se a ComputeClass abranger várias gerações de séries de máquinas, use uma StorageClass que tenha a seleção automática de tipo de disco (parameters.type: dynamic) ativada e que programe apenas em nós compatíveis com os tipos de disco especificados. Por exemplo, sua ComputeClass volta de séries somente de Hyperdisk, como C4, C4D ou N4, para séries Persistent Disk, como N2 ou N2D, durante restrições de capacidade zonal. É possível usar o StorageClass dynamic-rwo integrado ou um StorageClass personalizado. Suas cargas de trabalho com estado podem, então, fazer failover em várias gerações de instâncias do Compute Engine, porque o escalonador automático de clusters escolhe dinamicamente um tipo de disco compatível (hyperdisk-balanced ou pd-balanced) para qualquer nó de fallback provisionado.

Projetar sua infraestrutura para flexibilidade, eficiência e disponibilidade de capacidade de computação

As seções a seguir mostram as práticas recomendadas para melhorar a flexibilidade, a eficiência e a disponibilidade da capacidade de computação em ComputeClasses, para que os pods passem menos tempo em um 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áquina específicos nas regras de prioridade do 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 campo machineFamily. Durante uma operação de escalonamento, o GKE pode criar nós que usam qualquer tipo de máquina viável nessa série de máquinas, o que aumenta a probabilidade de os pods serem executados na configuração de nó de sua preferência.

Usar reservas de capacidade para hardware em alta demanda

Se as cargas de trabalho dependem de hardware sob demanda, como TPUs ou GPUs de alto desempenho, crie reservas de capacidade do Compute Engine para o hardware e consuma essas reservas nas ComputeClasses. As reservas de capacidade melhoram a probabilidade de o hardware estar disponível na sua região ou zona, o que ajuda a aumentar a flexibilidade, a eficiência e a disponibilidade da capacidade de computação. Para consumir uma reserva em uma ComputeClass sem afetar o comportamento de substituição, 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 do ComputeClass e usar 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 clusters armazena informações sobre reservas de capacidade em um cache. Quando você cria uma 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 use 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 mostram as 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 na carga de trabalho, cobranças não planejadas pelo uso de recursos e esgotamento de cotas.

Restringir o acesso da API às configurações do 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 costumam separar equipes ou tipos de carga de trabalho diferentes 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 de front-end da Web possam selecionar ComputeClasses que criam aceleradores. Verifique se as ValidatingAdmissionPolicies verificam as seguintes configurações comuns:

  • Verifique 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 de ComputeClass, verifique todos esses campos nas expressões ValidatingAdmissionPolicy.
  • Verifique se há desvios de tolerância de caracteres curinga:bloqueie ou valide explicitamente as tolerâncias de caracteres curinga (por exemplo, a tolerância operator: Exists sem chave). Esses seletores de caracteres curinga podem abranger a maioria dos taints de nó, incluindo os taints de ComputeClass.
  • Verifique todos os controladores de carga de trabalho:configure o 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 as 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 mostram as 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 travados.

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, talvez o GKE não programe os pods.

Por exemplo, considere uma ComputeClass que solicita apenas instâncias por demanda. Se um pod selecionar essa ComputeClass e 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 preferido e consolidar nós subutilizados. Modificações nessas configurações em uma ComputeClass atual podem resultar em interrupções inesperadas na carga de trabalho. Antes de aplicar qualquer modificação 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 as atualizações de CRD do ComputeClass antes de fazer upgrade do cluster

O GKE atualiza regularmente a CustomResourceDefinition (CRD) do ComputeClass para adicionar campos, modificar o comportamento dos campos 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 na CRD causam problemas de carga de trabalho usando as seguintes diretrizes:

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 os PodDisruptionBudgets configurados. Por exemplo, é possível configurar uma implantação de inferência para ter um PodDisruptionBudget que exija 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 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 use PodDisruptionBudgets para proteger cargas de trabalho que precisam ser executadas até a conclusão, que têm apenas uma instância ou que dependem de dados permanentes 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 toleram 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 tem as seguintes práticas recomendadas para ComputeClasses:

A seguir