Entenda como fazer a manutenção do host no GKE

Durante o ciclo de vida de um cluster do GKE de longa duração, as interrupções nas cargas de trabalho devidos a interrupções na infraestrutura que o Cloud de Confiance by S3NS emite. Esses eventos automáticos podem ocorrer para responder a decisões de programação (eventos de preempção) ou atualizações de nós, que incluem upgrades automáticos de nós do GKE (eventos de manutenção) ou correção de problemas detectados (eventos de encerramento).

Neste documento, explicamos o que significa interrupção de nós no GKE e como minimizar o impacto dela nos nós do GKE.

Para detalhes sobre como monitorar notificações e eventos de manutenção, consulte Monitorar eventos de manutenção.

Este documento se aplica aos seguintes tipos de máquina:

Este documento é destinado a administradores e operadores de plataforma que gerenciam o ciclo de vida da infraestrutura técnica subjacente. Para saber mais sobre papéis comuns e tarefas de exemplo mencionados no conteúdo do Cloud de Confiance by S3NS , consulte Tarefas e papéis de usuário comuns do GKE.

O que significa interrupção de infraestrutura no GKE?

Seus clusters do GKE gerenciam o ciclo de vida dos nós do GKE. Esses nós são provisionados em VMs do Compute Engine, que periodicamente passam pelas seguintes interrupções:

  • Correção de problemas detectados (TerminationEvent): esses eventos ocorrem porque o Cloud de Confiance by S3NS detecta um problema e interrompe a infraestrutura do cluster. TerminationEvent eventos não são compatíveis com o encerramento completo. Os eventos TerminationEvent são acionados pelos seguintes problemas:

    • O reparo automático ocorre quando o GKE repara um nó após repetidas falhas nas verificações de integridade.
    • HostError ocorre quando um erro de hardware ou software na máquina física faz com que a VM seja interrompida.
  • Eventos de manutenção ou upgrade (MaintenanceEvent): esses eventos ocorrem quando o Cloud de Confiance by S3NS precisa interromper uma VM para realizar a manutenção. Esses eventos são acionados pelas seguintes tarefas de manutenção:

    Para mais informações sobre como você e o GKE gerenciam mudanças durante o ciclo de vida de um cluster, consulte Tipos de mudanças.

  • Resposta a decisões de programação (PreemptionEvent): esses eventos ocorrem quando o Cloud de Confiance by S3NS precisa interromper VMs para disponibilizar capacidade para recursos de maior prioridade. Os eventos PreemptionEvent podem ser:

    • Remoção:ocorre quando a infraestrutura preemptiva ou Spot é interrompida para acomodar uma VM de prioridade mais alta.
    • Desfragmentação:ocorre quando o GKE interrompe uma fração de TPU menor para acomodar uma maior. A desfragmentação só ocorre em frações de TPU.

Durante o ciclo de vida de um cluster do GKE de longa duração, os nós podem sofrer interrupções periódicas nas cargas de trabalho. Quando essas interrupções afetam os nós do GKE que executam suas cargas de trabalho, o GKE precisa reiniciar as cargas de trabalho em execução e o nó subjacente.

Por que os nós que não são compatíveis com a migração em tempo real exigem gerenciamento de interrupções

Com algumas exceções, a maioria das VMs do Compute Engine tem política de manutenção do host definida como migração em tempo real, ou seja, há pouca ou nenhuma interrupção das cargas de trabalho em execução. No entanto, algumas classes de VMs não aceitam migração em tempo real, incluindo os seguintes tipos de máquina:

  • Tipos de máquina com GPUs e TPUs anexadas.
  • Tipos de máquina H4D.
  • O tipo de máquina c4a-highmem-96-metal.
  • Tipos de máquina Z3 com mais de 18 TiB de SSD Titanium anexado.
  • Tipos de máquina Z4D com mais de 42 TiB de SSD Titanium anexado.
  • Tipos de máquina Z4M com mais de 48 TiB de SSD Titanium anexado ou qualquer instância Z4M que use o Cloud RDMA.

Por exemplo, quando um evento de host acontece com a VM em uma fração de TPU, toda a fração é interrompida e reprogramada porque todos os eventos de manutenção são coordenados no nível da fração. Portanto, se você criar uma fração de TPU com centenas de VMs, todas elas vão receber a mesma programação de eventos de manutenção.

Quando um evento de host ocorre, o GKE encerra o nó e os pods dele. Se os pods forem implantados como parte de uma carga de trabalho maior, como um job ou uma implantação, o GKE reinicia os pods no nó afetado.

Gerenciar eventos de manutenção

O restante deste documento descreve como gerenciar as interrupções do MaintenanceEvent.

O gerenciamento de interrupções de nós durante eventos de manutenção do host segue um fluxo de trabalho de três etapas:

  1. Detectar manutenção programada do host: use rótulos de nós do GKE, endpoints de metadados ou registros.
  2. Agir de acordo com a manutenção detectada: se a manutenção estiver programada, avalie sua infraestrutura e cargas de trabalho e determine a melhor ação para seu caso de uso. Tome as medidas adequadas, como permitir que o sistema processe o evento de manutenção automaticamente, iniciar manualmente a manutenção do host ou organizar estratégias de manutenção.
  3. Verifique o resultado do evento de manutenção: verifique se o evento de manutenção foi iniciado corretamente, seja quando o Compute Engine inicia o evento de manutenção conforme programado ou quando você o inicia manualmente.

Detectar manutenção programada do host

Para monitorar e detectar os próximos eventos de manutenção, confira as notificações do GKE e do Compute Engine.

Para detalhes sobre como monitorar notificações e eventos de manutenção, consulte Monitorar eventos de manutenção.

Agir de acordo com a manutenção detectada

Se você receber uma notificação de manutenção programada para um ou mais nós no cluster, use a árvore de decisão a seguir para determinar a melhor maneira de lidar com a interrupção:

  1. Manutenção automática:permite que o Compute Engine inicie o evento de manutenção no horário programado. As VMs vão migrar em tempo real automaticamente em segundo plano com interrupção mínima ou nenhuma.

    1. Se a VM host for compatível com a migração em tempo real, recomendamos que você permita que o evento de manutenção aconteça automaticamente.
    2. Se as cargas de trabalho forem executadas em nós flexíveis para inatividade, será possível otimizar o tempo de manutenção automaticamente configurando a manutenção oportunista. Isso aciona as atualizações necessárias apenas durante períodos de inatividade natural.
  2. Iniciar manualmente um evento de manutenção de host:avalie as seguintes perguntas para determinar a melhor maneira de lidar manualmente com a interrupção:

    1. Os nós afetados são VMs únicas ou isoladas?

      • Sim (estou executando uma VM única ou isolada):
        • Se você não precisar de controles de tempo precisos, permita que o Compute Engine inicie o evento de manutenção conforme programado (automático por padrão).
        • Se você precisar evitar a preempção inesperada, inicie manualmente o evento de manutenção do host no nó individual em um momento conveniente, por exemplo, durante janelas de tráfego menores.
      • Não (estou executando um pool de nós de aceleradores): escolha uma das opções na próxima etapa.
    2. Escolha uma das seguintes opções com base no seu caso de uso:

      • Se o pool de aceleradores executar tarefas de treinamento de IA/ML acopladas:implemente a estratégia paralela. Salve o estado de treinamento em um checkpoint, encerre o pool de maneira adequada e faça atualizações de host e de cluster do GKE simultaneamente antes de reiniciar.

      • Se o pool de aceleradores executar endpoints de inferência ou exibição de IA/ML de alta disponibilidade:implemente a estratégia contínua. Coordene a manutenção programada do host e os upgrades de versão em lotes contínuos dentro dos limites da zona ou do pool, usando réplicas ativas para proteger os SLAs.

Iniciar manualmente um evento de manutenção de host em VMs únicas ou isoladas

É possível iniciar manualmente a manutenção reprogramável quando ela se adequar à sua programação, como em períodos de baixa atividade. Para isso, aplique o rótulo cloud.google.com/perform-maintenance=true se as seguintes condições forem atendidas:

  • O Compute Engine emite uma notificação sobre um evento de manutenção programada.
  • O evento de manutenção do Compute Engine pode ser reprogramado. Para verificar se o evento pode ser reprogramado, procure a notificação can_reschedule=TRUE nos metadados do evento. Se o evento não puder ser reprogramado, a definição do rótulo cloud.google.com/perform-maintenance=true não terá efeito, e a manutenção vai acontecer no horário originalmente programado.

Se as condições anteriores forem atendidas, em um nó no pool de nós, defina o rótulo do nó cloud.google.com/perform-maintenance como true. Exemplo:

kubectl label nodes <node-name> cloud.google.com/perform-maintenance=true

Se você iniciar um evento de manutenção, o GKE vai executar as seguintes operações:

  1. Aplica um taint ao nó.
  2. Remove pods sem problemas.
  3. Solicita que o Compute Engine inicie o evento de manutenção imediatamente, em vez de aguardar o horário programado.

Verificar o resultado do evento de manutenção

Depois de detectar um evento de manutenção futuro e decidir o melhor curso de ação, verifique o resultado do evento de manutenção.

O Compute Engine inicia o evento de manutenção conforme programado

Quando o evento de manutenção começa, um nó pode ser encerrado uma ou mais vezes com um curto período de notificação antes do encerramento iminente. Nesses casos, o GKE faz o possível para encerrar as cargas de trabalho e remover os pods de maneira adequada.

Início da manutenção programada

Quando a manutenção programada começa, o Compute Engine atualiza os metadados no diretório http://metadata.google.internal/computeMetadata/v1/instance/attributes/. O Compute Engine atualiza os rótulos de metadados da seguinte maneira:

  • Define maintenance-event como TERMINATE_ON_HOST_MAINTENANCE.
  • Em upcoming-maintenance, define maintenance_status como ONGOING.

O GKE detecta e processa o evento de manutenção programada do host, seja acionado manualmente ou de forma automática.

A seguinte métrica do sistema do GKE informa a contagem de interrupções de um nó do GKE desde a última amostra (a métrica é amostrada a cada 60 segundos):

  • kubernetes.io/node/interruption_count

Os campos interruption_type (como TerminationEvent, MaintenanceEvent ou PreemptionEvent) e interruption_reason (como HostError, Eviction ou AutoRepair) podem ajudar a fornecer o motivo pelo qual um nó foi interrompido.

Para ver um detalhamento das interrupções e as causas delas nos nós de TPU nos clusters do seu projeto, use a seguinte consulta PromQL:

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node"}[${__interval}]))

Para ver apenas os eventos de manutenção do host, atualize a consulta para filtrar o valor HW/SW Maintenance para interruption_reason. Use a seguinte consulta PromQL:

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node", interruption_reason="HW/SW Maintenance"}[${__interval}]))

Para ver a contagem de interrupções agregada por pool de nós, use a seguinte consulta PromQL:

  sum by (node_pool_name,interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_pool_interruption_count{monitored_resource="k8s_node_pool", interruption_reason="HW/SW Maintenance", node_pool_name=NODE_POOL_NAME }[${__interval}]))

Configurações avançadas para minimizar interrupções

Nesta seção, descrevemos outras ferramentas para configurar o cluster e as cargas de trabalho para minimizar as interrupções.

Ativar o tratamento de interrupções

apiVersion: v1
kind: ConfigMap
metadata:
  name: gke-disruption-handling
  namespace: kube-system
data:
  maintenance-experience.yaml: |
    gracefulTermination: true

Para ativar o tratamento de interrupções, crie um arquivo chamado maintenance-config.yaml com este ConfigMap. Aplique o ConfigMap ao cluster com o seguinte comando:

kubectl apply -f my-configmap.yaml

Configure o GKE para encerrar as cargas de trabalho normalmente

Nesta seção, você configura o GKE para gerenciar o ciclo de vida do seu aplicativo e minimizar a interrupção da carga de trabalho. Se você não configurar uma período de carência, o período de carência é de 30 segundos por padrão.

O GKE se esforça para encerrar esses pods da melhor maneira possível e executar a ação de encerramento definida por você, por exemplo, salvando um estado de treinamento. O GKE envia um sinal SIGTERM para os pods no início do período de carência. Se os pods não forem encerrados até o final do período de carência, o GKE envia um sinal SIGKILL de acompanhamento para os processos que ainda estão em execução contêiner no pod.

Para configurar o período de encerramento completo, defina o período de carência de encerramento (segundos) no campo spec.terminationGracePeriodSeconds do manifesto do pod. Por exemplo, para receber um tempo de notificação de 10 minutos, defina o campo spec.terminationGracePeriodSeconds no manifesto do pod como 600 segundos, da seguinte maneira:

    spec:
      terminationGracePeriodSeconds: 600

Recomendamos que você defina um período de carência de rescisão longo o suficiente para que todas as tarefas em andamento sejam concluídas dentro do período de notificação. Se a carga de trabalho usar um framework de ML, como MaxText, Pax ou JAX com o Orbax, as cargas de trabalho vão poder capturar o sinal SIGTERM e iniciar um processo de checkpoint. Para saber mais, consulte Checkpoint automático da TPU.

Processo de encerramento sem dificuldades

Quando um evento de manutenção iniciado manualmente começa, o Compute Engine sinaliza o encerramento iminente da máquina atualizando a chave de metadados maintenance-event. O GKE inicia o encerramento suave.

O fluxo de trabalho a seguir mostra como o GKE executa o encerramento otimizado de nós quando há um encerramento iminente de nós:

  1. Em 60 segundos, ocorre o seguinte:
    1. Os componentes do sistema aplicam o rótulo de nó cloud.google.com/active-node-maintenance definido como ONGOING para indicar que as cargas de trabalho estão sendo interrompidas.
    2. O GKE aplica o taint do nó para evitar que novos pods sejam programados no nó. O taint tem a chave cloud.google.com/impending-node-termination:NoSchedule. Recomendamos que você não modifique as cargas de trabalho para tolerar esse taint devido ao encerramento conhecido que ocorre.
  2. O componente maintenance-handler começa a remover pods, primeiro os de carga de trabalho e depois os do sistema (por exemplo, kube-system).
  3. O GKE envia um sinal de encerramento SIGTERM para os pods de carga de trabalho que estão em execução no nó para alertá-los sobre um encerramento iminente. Os pods podem usar esse alerta para concluir quaisquer tarefas em andamento. O GKE faz o possível para encerrar esses pods normalmente.
  4. Depois que a remoção é concluída, o GKE atualiza o valor do rótulo cloud.google.com/active-node-maintenance para terminating para indicar que o nó está pronto para ser encerrado.

Em seguida, o nó é encerrado e um substituto é alocado. O GKE limpa os rótulos e as contaminações quando o processo é concluído. Para aumentar a janela de encerramento para suas cargas de trabalho usando GPUs ou TPUs, conclua as etapas na seção Iniciar manualmente um evento de manutenção do host.

Verificar o progresso de uma finalização suave ativa

É possível filtrar os registros do GKE pelos seguintes eventos de encerramento suave:

  • Quando a VM detecta uma interrupção devido a um encerramento de nó iminente, como um evento de manutenção do host do Compute Engine, o GKE define o cloud.google.com/active-node-maintenance como ONGOING quando as cargas de trabalho estão sendo interrompidas e como terminating quando as cargas de trabalho são concluídas e o nó está pronto para ser encerrado.
  • Ao restringir a programação de novas cargas de trabalho, o GKE aplica o taint cloud.google.com/impending-node-termination:NoSchedule.

Minimizar a interrupção das cargas de trabalho em execução com a manutenção oportunista

É possível minimizar a interrupção das cargas de trabalho em execução acionando automaticamente a manutenção quando o GKE detecta que os nós com GPUs ou TPUs estão inativos. Para ativar esse recurso, crie um novo pool de nós. Não é possível ativar a manutenção oportunista em um pool de nós atual.

Criar um pool de nós com manutenção oportunista

O comando a seguir demonstra como criar um pool de nós com a manutenção oportunista ativada:

gcloud beta container node-pools create NODE_POOL_NAME \
    --cluster CLUSTER_NAME \
    --accelerator ACCELERATOR_ARG \
    --machine-type MACHINE_TYPE \
    --num-nodes NODE_COUNT \
    --zone ZONE \
    --project=PROJECT_ID \
    --opportunistic-maintenance=node-idle-time=NODE_IDLE_TIME,min-nodes=MIN_NODES,window=WINDOW

Substitua os seguintes valores:

  • NODE_POOL_NAME: o nome do pool de nós do GKE.
  • CLUSTER_NAME : o nome do cluster do GKE.
  • NODE_IDLE_TIME : o tempo que um nó pode permanecer inativo (ou seja, nenhuma carga de trabalho que consome aceleradores está em execução) antes que a manutenção seja acionada. O valor representa a duração em segundos, com até nove dígitos fracionários, e termina com o caractere s, por exemplo: 80000s.
  • MIN_NODES : o número mínimo de nós que precisam estar disponíveis em um pool de nós. Essa opção bloqueia a manutenção se ela fizer com que o número de nós em execução fique abaixo desse valor, por exemplo: 10.
  • WINDOW : a janela de tempo, em segundos, em que a manutenção oportunista pode ser executada. O valor termina com um caractere s. Por exemplo, um valor de 14 dias, ou 1209600s, implica que a manutenção oportunista só pode ser executada nas duas semanas anteriores à data de manutenção programada. Um valor de 28 dias, ou 2419200s, permite que a manutenção oportunista seja executada a qualquer momento durante a janela de manutenção programada. Essa janela para manutenção de host do Compute Engine é diferente das janelas de manutenção do GKE, que determinam quando a manutenção do cluster do GKE pode ocorrer e são configuradas separadamente.

Exemplo de configuração para manutenção oportunista

Veja o exemplo a seguir. Você tem um pool de nós com quatro nós, e a configuração de manutenção oportunista está definida como --opportunistic-maintenance=node-idle-time=600s,window=2419200s,min-nodes=3. Nesse cenário, ocorre o seguinte:

  • node1 tem uma carga de trabalho de GPU em execução. Esse nó não está inativo, então é pulado.
  • node2 está inativo há 60 segundos. Esse nó não ficou inativo por tempo suficiente, então foi ignorado.
  • node3 está inativo há 600 segundos. Esse nó atende ao requisito de inatividade.
  • node4 está inativo há 600 segundos. Esse nó atende ao requisito de inatividade.

node3 e node4 atendem ao requisito de inatividade. No entanto, apenas um desses nós vai acionar a manutenção oportunista porque o valor da opção min-nodes está definido como 3.

Verificar a configuração e o estado dos nós com manutenção oportunista

Verifique se a manutenção oportunista está configurada para um nó executando o seguinte comando:

kubectl describe node NODE_NAME | grep node.gke.io/opportunistic-config

Substitua NODE_NAME pelo nome do nó que você quer verificar.

Verifique se um nó configurado com manutenção oportunista está passando por manutenção:

kubectl describe node NODE_NAME | grep node.gke.io/maintenance-state

Se o nó for acionado por manutenção oportunista, a anotação maintenance-state vai mostrar opportunistic-triggered como true.

Limitações

Esteja ciente das seguintes limitações da manutenção oportunista:

  • Esse recurso só pode ser usado com pools de nós de GPU e TPU.
  • A manutenção oportunista não é compatível com o escalonamento automático de clusters porque o escalonador automático de clusters já reduz a escala vertical de nós inativos.
  • Para pools de nós de TPU de vários hosts, o valor da configuração min-nodes-per-pool precisa ser 0, porque esses pools de nós são atômicos.
  • A versão mínima do GKE com suporte é a 1.33.3-gke.1118000.
  • Somente a manutenção planejada que inclui a notificação can_reschedule=TRUE é compatível.
  • Para desativar esse recurso, recrie o pool de nós sem as respectivas flags. Ou é possível desativar manualmente o recurso em nós específicos com cloud.google.com/opportunistic-disable=true.
  • Em casos raros, a manutenção pode levar mais tempo para ser concluída em um nó. Os clientes que usam esse recurso podem ter menos nós disponíveis, até o valor da configuração min-nodes-per-pool, por um período.

A seguir