Execute uma carga de trabalho em grande escala com início flexível com aprovisionamento em fila


Esta página mostra como otimizar a obtenção de GPUs para cargas de trabalho de IA e em lote de grande escala com GPUs usando o início flexível com aprovisionamento em fila, com tecnologia do Dynamic Workload Scheduler.

Antes de ler esta página, certifique-se de que conhece o seguinte:

Este guia destina-se a engenheiros de aprendizagem automática (ML), administradores e operadores de plataformas, bem como a especialistas em dados e IA interessados em usar capacidades de orquestração de contentores do Kubernetes para executar cargas de trabalho em lote. Para mais informações sobre as funções comuns e exemplos de tarefas que referimos no Google Cloud conteúdo, consulte Funções e tarefas comuns de utilizadores do GKE.

Como funciona o início flexível com aprovisionamento em fila

Com o início flexível com aprovisionamento em fila, o GKE atribui todos os recursos pedidos ao mesmo tempo. O início flexível com aprovisionamento em fila usa as seguintes ferramentas:

  • O início flexível com aprovisionamento em fila baseia-se no Dynamic Workload Scheduler combinado com a definição de recursos personalizados (CRD) do pedido de aprovisionamento. Estas ferramentas gerem a capacidade atribuída com base nos recursos disponíveis e nos requisitos da carga de trabalho.
  • (Opcional) O Kueue automatiza o ciclo de vida do início flexível com pedidos de aprovisionamento em fila. O Kueue implementa o enfileiramento de tarefas e processa automaticamente o ciclo de vida do pedido de aprovisionamento.

Para usar o início flexível com aprovisionamento em fila, tem de adicionar os flags --flex-start e --enable-queued-provisioning quando criar o conjunto de nós.

Prática recomendada:

Use o flex-start com aprovisionamento em fila para cargas de trabalho de IA e em lote de grande escala quando as suas cargas de trabalho cumprirem os seguintes critérios:

  • As suas cargas de trabalho têm horas de início flexíveis.
  • As suas cargas de trabalho têm de ser executadas em vários nós em simultâneo.

Para cargas de trabalho mais pequenas que podem ser executadas num único nó, use flex-start. Para mais informações sobre o aprovisionamento de GPUs no GKE, consulte o artigo Obtenha aceleradores para cargas de trabalho de IA.

Antes de começar

Antes de começar, certifique-se de que realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ative a API Google Kubernetes Engine
  • Se quiser usar a CLI gcloud para esta tarefa, instale-a e, em seguida, inicialize-a. Se instalou anteriormente a CLI gcloud, execute gcloud components update para obter a versão mais recente.

Use node pools com início flexível com aprovisionamento em fila

Esta secção aplica-se apenas a clusters padrão.

Pode usar qualquer um dos seguintes métodos para designar que o início flexível com aprovisionamento em fila pode funcionar com pools de nós específicos no seu cluster:

Crie um node pool

Crie um node pool com início flexível e aprovisionamento em fila ativado através da CLI gcloud:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --enable-queued-provisioning \
    --accelerator type=GPU_TYPE,count=AMOUNT,gpu-driver-version=DRIVER_VERSION \
    --machine-type=MACHINE_TYPE \
    --flex-start \
    --enable-autoscaling  \
    --num-nodes=0   \
    --total-max-nodes TOTAL_MAX_NODES  \
    --location-policy=ANY  \
    --reservation-affinity=none  \
    --no-enable-autorepair

Substitua o seguinte:

  • NODEPOOL_NAME: o nome que escolher para o node pool.
  • CLUSTER_NAME: o nome do cluster.
  • LOCATION: a região do Compute Engine do cluster, como us-central1.
  • GPU_TYPE: o tipo de GPU.
  • AMOUNT: o número de GPUs a associar aos nós no conjunto de nós.
  • DRIVER_VERSION: a versão do controlador NVIDIA a instalar. Pode ser uma das seguintes opções:
    • default: instale a versão predefinida do controlador para a sua versão do GKE.
    • latest: instale a versão mais recente do controlador disponível para a sua versão do GKE. Disponível apenas para nós que usam o SO otimizado para contentores.
  • TOTAL_MAX_NODES: o número máximo de nós a dimensionar automaticamente para todo o node pool.
  • MACHINE_TYPE: o tipo de máquina do Compute Engine para os seus nós.

    Prática recomendada:

    Use um tipo de máquina otimizado para aceleradores para melhorar o desempenho e a eficiência das cargas de trabalho de IA/ML.

Opcionalmente, pode usar as seguintes flags:

  • --node-locations=COMPUTE_ZONES: a lista separada por vírgulas de uma ou mais zonas onde o GKE cria os nós de GPU. As zonas têm de estar na mesma região que o cluster. Escolha zonas com GPUs disponíveis.
  • --enable-gvnic: esta flag ativa o gVNIC nos conjuntos de nós de GPU para aumentar a velocidade do tráfego de rede.

Este comando cria um node pool com a seguinte configuração:

  • A flag --flex-start combinada com a flag --enable-queued-provisioning indica ao GKE para criar um conjunto de nós com o início flexível com aprovisionamento em fila ativado e para adicionar a contaminação cloud.google.com/gke-queued ao conjunto de nós.
  • O GKE permite o aprovisionamento em fila e a escala automática de clusters.
  • Inicialmente, o conjunto de nós tem zero nós.
  • A flag --no-enable-autorepair desativa as reparações automáticas, o que pode interromper as cargas de trabalho executadas em nós reparados.

Ative a administração de contas automática de nós para criar pools de nós para o início flexível com administração de contas em fila

Pode usar o aprovisionamento automático de nós para gerir pools de nós para o início flexível com o aprovisionamento em fila para clusters que executam a versão 1.29.2-gke.1553000 ou posterior. Quando ativa o aprovisionamento automático de nós, o GKE cria pools de nós com os recursos necessários para a carga de trabalho associada.

Para ativar o aprovisionamento automático de nós, considere as seguintes definições e conclua os passos em Configurar limites de GPU:

  • Especifique os recursos necessários para o início flexível com aprovisionamento em fila quando ativa a funcionalidade. Para listar os resourceTypes disponíveis, execute o comando gcloud compute accelerator-types list.
  • Use a flag --no-enable-autoprovisioning-autorepair para desativar a reparação automática de nós.
  • Permita que o GKE instale automaticamente os controladores de GPU em nós de GPU aprovisionados automaticamente. Para mais informações, consulte o artigo Instalar controladores através do aprovisionamento automático de nós com GPUs.

Execute as suas cargas de trabalho de IA e em lote com o início flexível com aprovisionamento em fila

Para executar cargas de trabalho em lote com início flexível com aprovisionamento em fila, use qualquer uma das seguintes configurações:

Prática recomendada:

Use o Kueue para executar as suas cargas de trabalho de IA e em lote com início flexível com aprovisionamento em fila.

Início flexível com aprovisionamento em fila para trabalhos com o Kueue

As secções seguintes mostram como configurar o início flexível com aprovisionamento em fila para trabalhos com o Kueue:

  • Inicie de forma flexível com a configuração do conjunto de nós de aprovisionamento em fila.
  • Reserva e início flexível com configuração do conjunto de nós de aprovisionamento em fila.

Esta secção usa os exemplos no diretório dws-examples do repositório ai-on-gke. Publicámos os exemplos no diretório dws-examples ao abrigo da licença Apache2.

Tem de ter autorizações de administrador para instalar o Kueue. Para os obter, certifique-se de que lhe é atribuída a função de IAM roles/container.admin. Para saber mais sobre as funções de IAM do GKE, consulte o guia de criação de políticas de autorização de IAM.

Prepare o seu ambiente

  1. No Cloud Shell, execute o seguinte comando:

    git clone https://github.com/GoogleCloudPlatform/ai-on-gke
    cd ai-on-gke/tutorials-and-examples/workflow-orchestration/dws-examples
    
  2. Instale a versão mais recente do Kueue no seu cluster:

    VERSION=KUEUE_VERSION
    kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    

    Substitua KUEUE_VERSION pela versão mais recente do Kueue.

Se usar o Kueue numa versão anterior à 0.7.0, altere a configuração do Feature Gate do Kueue definindo o Feature Gate ProvisioningACC como true. Consulte os feature gates do Kueue para uma explicação mais detalhada e valores de gates predefinidos. Para mais informações sobre a instalação do Kueue, consulte Instalação.

Crie os recursos do Kueue para a configuração apenas do conjunto de nós do Dynamic Workload Scheduler

Com o seguinte manifesto, cria uma fila ao nível do cluster denominada dws-cluster-queue e o espaço de nomes LocalQueue denominado dws-local-queue. Os trabalhos que fazem referência à fila dws-cluster-queue neste espaço de nomes usam o início flexível com aprovisionamento em fila para obter os recursos de GPU.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "default-flavor"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: AdmissionCheck
metadata:
  name: dws-prov
spec:
  controllerName: kueue.x-k8s.io/provisioning-request
  parameters:
    apiGroup: kueue.x-k8s.io
    kind: ProvisioningRequestConfig
    name: dws-config
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ProvisioningRequestConfig
metadata:
  name: dws-config
spec:
  provisioningClassName: queued-provisioning.gke.io
  managedResources:
    - nvidia.com/gpu
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "dws-cluster-queue"
spec:
  namespaceSelector: {}
  resourceGroups:
    - coveredResources: ["cpu", "memory", "nvidia.com/gpu", "ephemeral-storage"]
      flavors:
        - name: "default-flavor"
          resources:
            - name: "cpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "memory"
              nominalQuota: 1000000000Gi # "Infinite" quota
            - name: "nvidia.com/gpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "ephemeral-storage"
              nominalQuota: 1000000000Ti # "Infinite" quota
  admissionChecks:
    - dws-prov
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: "default"
  name: "dws-local-queue"
spec:
  clusterQueue: "dws-cluster-queue"
---
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  labels:
    control-plane: controller-manager
  name: controller-manager-metrics-monitor
  namespace: kueue-system
spec:
  endpoints:
    - path: /metrics
      port: 8080
      scheme: http
      interval: 30s
  selector:
    matchLabels:
      control-plane: controller-manager
---

A fila deste cluster tem limites de quota elevados e apenas a integração de aprovisionamento flexível com início flexível está ativada. Para mais informações sobre as APIs Kueue e como configurar limites, consulte o artigo Conceitos do Kueue.

Implemente a LocalQueue:

kubectl create -f ./dws-queues.yaml

O resultado é semelhante ao seguinte:

resourceflavor.kueue.x-k8s.io/default-flavor created
admissioncheck.kueue.x-k8s.io/dws-prov created
provisioningrequestconfig.kueue.x-k8s.io/dws-config created
clusterqueue.kueue.x-k8s.io/dws-cluster-queue created
localqueue.kueue.x-k8s.io/dws-local-queue created

Se quiser executar tarefas que usem o início flexível com aprovisionamento em fila noutros espaços de nomes, pode criar LocalQueues adicionais através do modelo anterior.

Execute a tarefa

No manifesto seguinte, a tarefa de exemplo usa o início flexível com aprovisionamento em fila:

apiVersion: batch/v1
kind: Job
metadata:
  name: sample-job
  namespace: default
  labels:
    kueue.x-k8s.io/queue-name: dws-local-queue
  annotations:
    provreq.kueue.x-k8s.io/maxRunDurationSeconds: "600"
spec:
  parallelism: 1
  completions: 1
  suspend: true
  template:
    spec:
      nodeSelector:
        cloud.google.com/gke-nodepool: NODEPOOL_NAME
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: dummy-job
          image: gcr.io/k8s-staging-perf-tests/sleep:v0.0.3
          args: ["120s"]
          resources:
            requests:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
            limits:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
      restartPolicy: Never

Este manifesto inclui os seguintes campos relevantes para a configuração de aprovisionamento flexível com filas:

  • A etiqueta kueue.x-k8s.io/queue-name: dws-local-queue indica ao GKE que o Kueue é responsável pela orquestração desse trabalho. Esta etiqueta também define a fila onde o trabalho é colocado em fila.
  • A flag suspend: true indica ao GKE para criar o recurso Job, mas para não agendar os pods ainda. O Kueue altera essa flag para false quando os nós estão prontos para a execução do trabalho.
  • nodeSelector indica ao GKE para agendar o trabalho apenas no conjunto de nós especificado. O valor deve corresponder a NODEPOOL_NAME, o nome do conjunto de nós com o aprovisionamento em fila ativado.
  1. Execute a tarefa:

    kubectl create -f ./job.yaml
    

    O resultado é semelhante ao seguinte:

    job.batch/sample-job created
    
  2. Verifique o estado da tarefa:

    kubectl describe job sample-job
    

    O resultado é semelhante ao seguinte:

    Events:
      Type    Reason            Age    From                        Message
      ----    ------            ----   ----                        -------
      Normal  Suspended         5m17s  job-controller              Job suspended
      Normal  CreatedWorkload   5m17s  batch/job-kueue-controller  Created Workload: default/job-sample-job-7f173
      Normal  Started           3m27s  batch/job-kueue-controller  Admitted by clusterQueue dws-cluster-queue
      Normal  SuccessfulCreate  3m27s  job-controller              Created pod: sample-job-9qsfd
      Normal  Resumed           3m27s  job-controller              Job resumed
      Normal  Completed         12s    job-controller              Job completed
    

O início flexível com aprovisionamento em fila com integração do Kueue também suporta outros tipos de carga de trabalho disponíveis no ecossistema de código aberto, como os seguintes:

  • RayJob
  • JobSet v0.5.2 ou posterior
  • Kubeflow MPIJob, TFJob e PyTorchJob.
  • Pods do Kubernetes usados frequentemente por orquestradores de fluxos de trabalho
  • Flux mini cluster

Para mais informações sobre este apoio técnico, consulte o utilizador em lote do Kueue.

Crie os recursos do Kueue para a configuração do Reservation e do Dynamic Workload Scheduler do conjunto de nós

Com o seguinte manifesto, cria dois ResourceFlavors associados a dois conjuntos de nós diferentes: reservation-nodepool e dws-nodepool. Os nomes destes conjuntos de nós são apenas exemplos. Modifique estes nomes de acordo com a configuração do conjunto de nós. Além disso, com a configuração ClusterQueue, as tarefas recebidas tentam usar reservation-nodepool e, se não houver capacidade, estas tarefas usam o programador de carga de trabalho dinâmico para obter os recursos da GPU.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "reservation"
spec:
  nodeLabels:
    cloud.google.com/gke-nodepool: "reservation-nodepool" # placeholder value
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "dws"
spec:
  nodeLabels:
    cloud.google.com/gke-nodepool: "dws-nodepool" # placeholder value
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "cluster-queue"
spec:
  namespaceSelector: {} # match all.
  resourceGroups:
    - coveredResources: ["cpu", "memory", "nvidia.com/gpu"]
      flavors:
        - name: "reservation" # first we try reservation
          resources:
            - name: "cpu"
              nominalQuota: 9
            - name: "memory"
              nominalQuota: 36Gi
            - name: "nvidia.com/gpu"
              nominalQuota: 9
        - name: "dws" # if reservation is saturated we try dws
          resources:
            - name: "cpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "memory"
              nominalQuota: 1000000000Gi # "Infinite" quota
            - name: "nvidia.com/gpu"
              nominalQuota: 1000000000 # "Infinite" quota
  admissionChecksStrategy:
    admissionChecks:
      - name: "dws-prov"
        onFlavors: [dws]
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: "default"
  name: "user-queue"
spec:
  clusterQueue: "cluster-queue"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: AdmissionCheck
metadata:
  name: dws-prov
spec:
  controllerName: kueue.x-k8s.io/provisioning-request
  parameters:
    apiGroup: kueue.x-k8s.io
    kind: ProvisioningRequestConfig
    name: dws-config
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ProvisioningRequestConfig
metadata:
  name: dws-config
spec:
  provisioningClassName: queued-provisioning.gke.io
  managedResources:
    - nvidia.com/gpu

A fila deste cluster tem limites de quota elevados e apenas a integração de aprovisionamento flexível com início flexível está ativada. Para mais informações sobre as APIs Kueue e como configurar limites, consulte o artigo Conceitos do Kueue.

Implemente o manifesto através do seguinte comando:

kubectl create -f ./dws_and_reservation.yaml

O resultado é semelhante ao seguinte:

resourceflavor.kueue.x-k8s.io/reservation created
resourceflavor.kueue.x-k8s.io/dws created
clusterqueue.kueue.x-k8s.io/cluster-queue created
localqueue.kueue.x-k8s.io/user-queue created
admissioncheck.kueue.x-k8s.io/dws-prov created
provisioningrequestconfig.kueue.x-k8s.io/dws-config created

Execute a tarefa

Ao contrário da configuração anterior, este manifesto não inclui o campo nodeSelector porque é preenchido pelo Kueue, consoante a capacidade livre no ClusterQueue.

apiVersion: batch/v1
kind: Job
metadata:
  generateName: sample-job-
  namespace: default
  labels:
    kueue.x-k8s.io/queue-name: user-queue
  annotations:
    provreq.kueue.x-k8s.io/maxRunDurationSeconds: "600"
spec:
  parallelism: 1
  completions: 1
  suspend: true
  template:
    spec:
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: dummy-job
          image: gcr.io/k8s-staging-perf-tests/sleep:v0.0.3
          args: ["120s"]
          resources:
            requests:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
            limits:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
      restartPolicy: Never
  1. Execute a tarefa:

    kubectl create -f ./job-without-node-selector.yaml
    

    O resultado é semelhante ao seguinte:

    job.batch/sample-job-v8xwm created
    

Para identificar que conjunto de nós a sua tarefa usa, tem de saber que ResourceFlavor a sua tarefa usa.

Resolução de problemas

Para mais informações sobre a resolução de problemas do Kueue, consulte o artigo Resolva problemas de pedidos de aprovisionamento no Kueue.

Início flexível com aprovisionamento em fila para trabalhos sem Kueue

Defina um objeto ProvisioningRequest

Crie um pedido através do Pedido de aprovisionamento para cada tarefa. O início flexível com aprovisionamento em fila não inicia os pods, apenas aprovisiona os nós.

  1. Crie o seguinte manifesto provisioning-request.yaml:

    Standard

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
      labels:
        cloud.google.com/apply-warden-policies: "true"
    template:
      spec:
        nodeSelector:
          cloud.google.com/gke-nodepool: NODEPOOL_NAME
          cloud.google.com/gke-flex-start: "true"
        tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
        containers:
          - name: pi
            image: perl
            command: ["/bin/sh"]
            resources:
              limits:
                cpu: "700m"
                nvidia.com/gpu: 1
              requests:
                cpu: "700m"
                nvidia.com/gpu: 1
        restartPolicy: Never
    ---
    apiVersion: autoscaling.x-k8s.io/API_VERSION
    kind: ProvisioningRequest
    metadata:
      name: PROVISIONING_REQUEST_NAME
      namespace: NAMESPACE_NAME
    spec:
      provisioningClassName: queued-provisioning.gke.io
      parameters:
        maxRunDurationSeconds: "MAX_RUN_DURATION_SECONDS"
      podSets:
      - count: COUNT
        podTemplateRef:
          name: POD_TEMPLATE_NAME
    

    Substitua o seguinte:

    • API_VERSION: a versão da API, v1 ou v1beta1. Recomendamos que use o v1 para ter estabilidade e acesso às funcionalidades mais recentes.
    • NAMESPACE_NAME: o nome do seu namespace do Kubernetes. O espaço de nomes tem de ser igual ao espaço de nomes dos pods.
    • PROVISIONING_REQUEST_NAME: o nome do ProvisioningRequest. Vai fazer referência a este nome na anotação do pod.
    • MAX_RUN_DURATION_SECONDS: opcionalmente, o tempo de execução máximo de um nó em segundos, até ao valor predefinido de sete dias. Para saber mais, consulte o artigo Como funciona o início flexível com aprovisionamento em fila. Não pode alterar este valor após a criação do pedido. Este campo está disponível na versão 1.28.5-gke.1355000 ou posterior do GKE.
    • COUNT: número de agrupamentos pedidos. Os nós são agendados atomicamente numa zona.
    • POD_TEMPLATE_NAME: o nome do PodTemplate.
    • NODEPOOL_NAME: o nome que escolher para o node pool. Remova-o se quiser usar um node pool aprovisionado automaticamente.

    O GKE pode aplicar validações e mutações aos pods durante a respetiva criação. A etiqueta cloud.google.com/apply-warden-policies permite que o GKE aplique as mesmas validações e mutações a objetos PodTemplate. Esta etiqueta é necessária para o GKE calcular os requisitos de recursos dos nós para os seus pods. A integração de início flexível com aprovisionamento em fila suporta apenas uma especificação PodSet. Se quiser misturar diferentes modelos de Pod, use o modelo que pede mais recursos. A combinação de diferentes tipos de máquinas, como VMs com diferentes tipos de GPUs, não é suportada.

    Aprovisionamento automático de nós

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
      labels:
        cloud.google.com/apply-warden-policies: "true"
    template:
      spec:
        nodeSelector:
          cloud.google.com/gke-accelerator: GPU_TYPE
          cloud.google.com/gke-flex-start: "true"
        tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
        containers:
          - name: pi
            image: perl
            command: ["/bin/sh"]
            resources:
              limits:
                cpu: "700m"
                nvidia.com/gpu: 1
              requests:
                cpu: "700m"
                nvidia.com/gpu: 1
        restartPolicy: Never
    ---
    apiVersion: autoscaling.x-k8s.io/API_VERSION
    kind: ProvisioningRequest
    metadata:
      name: PROVISIONING_REQUEST_NAME
      namespace: NAMESPACE_NAME
    spec:
      provisioningClassName: queued-provisioning.gke.io
      parameters:
        maxRunDurationSeconds: "MAX_RUN_DURATION_SECONDS"
      podSets:
      - count: COUNT
        podTemplateRef:
          name: POD_TEMPLATE_NAME
    

    Substitua o seguinte:

    • API_VERSION: a versão da API, v1 ou v1beta1. Recomendamos que use o v1 para ter estabilidade e acesso às funcionalidades mais recentes.
    • NAMESPACE_NAME: o nome do seu namespace do Kubernetes. O espaço de nomes tem de ser igual ao espaço de nomes dos pods.
    • PROVISIONING_REQUEST_NAME: o nome do ProvisioningRequest. Vai fazer referência a este nome na anotação do pod.
    • MAX_RUN_DURATION_SECONDS: opcionalmente, o tempo de execução máximo de um nó em segundos, até ao valor predefinido de sete dias. Para saber mais, consulte o artigo Como funciona o início flexível com aprovisionamento em fila. Não pode alterar este valor após a criação do pedido. Este campo está disponível na versão 1.28.5-gke.1355000 ou posterior do GKE.
    • COUNT: número de agrupamentos pedidos. Os nós são agendados atomicamente numa zona.
    • POD_TEMPLATE_NAME: o nome do PodTemplate.
    • GPU_TYPE: o tipo de hardware da GPU.

    O GKE pode aplicar validações e mutações aos pods durante a respetiva criação. A etiqueta cloud.google.com/apply-warden-policies permite que o GKE aplique as mesmas validações e mutações a objetos PodTemplate. Esta etiqueta é necessária para o GKE calcular os requisitos de recursos dos nós para os seus pods.

  2. Aplique o manifesto:

    kubectl apply -f provisioning-request.yaml
    

Configure os pods

Esta secção usa tarefas do Kubernetes para configurar os pods. No entanto, também pode usar um JobSet do Kubernetes ou qualquer outra framework como o Kubeflow, o Ray ou controladores personalizados. Na especificação do Job, associe os pods ao ProvisioningRequest através das seguintes anotações:

apiVersion: batch/v1
kind: Job
spec:
  template:
    metadata:
      annotations:
        autoscaling.x-k8s.io/consume-provisioning-request: PROVISIONING_REQUEST_NAME
        autoscaling.x-k8s.io/provisioning-class-name: "queued-provisioning.gke.io"
    spec:
      ...

A chave de anotação do agrupamento consume-provisioning-request define que ProvisioningRequest consumir. O GKE usa as anotações consume-provisioning-request e provisioning-class-name para fazer o seguinte:

  • Para agendar os pods apenas nos nós aprovisionados pelo início flexível com aprovisionamento em fila.
  • Para evitar a contabilização dupla de pedidos de recursos entre pods e o início flexível com o aprovisionamento em fila no escalador automático de clusters.
  • Para injetar a anotação safe-to-evict: false, para impedir que o escalador automático de clusters mova pods entre nós e interrompa os cálculos em lote. Pode alterar este comportamento especificando safe-to-evict: true nas anotações do pod.

Observe o estado de um pedido de aprovisionamento

O estado de um pedido de aprovisionamento define se um agrupamento pode ser agendado ou não. Pode usar monitorizações do Kubernetes para observar as alterações de forma eficiente ou outras ferramentas que já usa para acompanhar os estados dos objetos do Kubernetes. A tabela seguinte descreve o estado possível de um pedido de aprovisionamento e cada resultado possível:

Estado do pedido de aprovisionamento Descrição Resultado possível
Pendente O pedido ainda não foi visto nem processado. Após o processamento, o pedido passa para o estado Accepted ou Failed.
Accepted=true O pedido é aceite e está a aguardar que os recursos fiquem disponíveis. O pedido deve transitar para o estado Provisioned se tiverem sido encontrados recursos e os nós tiverem sido aprovisionados ou para o estado Failed se isso não tiver sido possível.
Provisioned=true Os nós estão prontos. Tem 10 minutos para iniciar os pods para consumir recursos aprovisionados. Após este período, o redimensionador automático de clusters considera que os nós não são necessários e remove-os.
Failed=true Não é possível aprovisionar os nós devido a erros. Failed=true é um estado terminal. Resolva problemas da condição com base nas informações nos campos Reason e Message da condição. Crie e tente novamente um novo pedido de solicitação de aprovisionamento.
Provisioned=false Os nós ainda não foram aprovisionados.

Se Reason=NotProvisioned, este é um estado temporário antes de todos os recursos estarem disponíveis.

Se Reason=QuotaExceeded, resolva o problema da condição com base neste motivo e nas informações no campo Message da condição. Pode ter de pedir mais quota. Para mais detalhes, consulte a secção Verifique se o pedido de aprovisionamento está limitado pela quota. Esta Reason só está disponível com a versão 1.29.2-gke.1181000 ou posterior do GKE.

Se Reason=ResourcePoolExhausted e Message contiver Expected time is indefinite, selecione uma zona ou uma região diferente, ou ajuste os recursos pedidos.

Inicie os Pods

Quando o pedido de aprovisionamento atinge o estado Provisioned=true, pode executar a tarefa para iniciar os pods. Isto evita a proliferação de pods não agendáveis para pedidos pendentes ou com falhas, o que pode afetar o desempenho do kube-scheduler e do redimensionador automático de clusters.

Em alternativa, se não se importar de ter agrupamentos não agendáveis, pode criar agrupamentos em paralelo com o pedido de solicitação de aprovisionamento.

Cancele o pedido de aprovisionamento

Para cancelar o pedido antes de o serviço ser aprovisionado, pode eliminar o ProvisioningRequest:

kubectl delete provreq PROVISIONING_REQUEST_NAME -n NAMESPACE

Na maioria dos casos, a eliminação de ProvisioningRequest impede a criação de nós. No entanto, dependendo do momento, por exemplo, se os nós já estivessem a ser aprovisionados, podem acabar por ser criados. Nestes casos, o escalador automático de clusters remove os nós após 10 minutos se não forem criados pods.

Resolva problemas de quota

Todas as VMs aprovisionadas por pedidos de aprovisionamento usam quotas de interrupção.

O número de ProvisioningRequests no estado Accepted é limitado por uma quota dedicada. Configura a quota para cada projeto, uma configuração de quota por região.

Verifique a quota na Google Cloud consola

Para verificar o nome do limite de quota e a utilização atual na Google Cloud consola, siga estes passos:

  1. Aceda à página Quotas na Google Cloud consola:

    Aceder a Quotas

  2. Na caixa Filtrar, selecione a propriedade Métrica, introduza active_resize_requests e prima Enter.

O valor predefinido é 100. Para aumentar a quota, siga os passos indicados em Peça um ajuste de quota.

Verifique se o pedido de aprovisionamento está limitado por quota

Se o seu pedido de aprovisionamento estiver a demorar mais do que o esperado a ser cumprido, verifique se o pedido não está limitado pela quota. Pode ter de pedir mais quota.

Para clusters com a versão 1.29.2-gke.1181000 ou posterior, verifique se as limitações de quota específicas estão a impedir o processamento do seu pedido:

kubectl describe provreq PROVISIONING_REQUEST_NAME \
    --namespace NAMESPACE

O resultado é semelhante ao seguinte:

…
Last Transition Time:  2024-01-03T13:56:08Z
    Message:               Quota 'NVIDIA_P4_GPUS' exceeded. Limit: 1.0 in region europe-west4.
    Observed Generation:   1
    Reason:                QuotaExceeded
    Status:                False
    Type:                  Provisioned
…

Neste exemplo, o GKE não consegue implementar nós porque não existe quota suficiente na região de europe-west4.

Migre node pools do aprovisionamento em fila para o início flexível

Para migrar pools de nós existentes que foram criados com a flag --enable-queued-provisioning para o início flexível, siga os passos abaixo:

  1. Certifique-se de que o conjunto de nós está vazio:

    kubectl get nodes -l cloud.google.com/gke-nodepool=NODEPOOL_NAME
    
  2. Atualize o node pool para flex-start:

    gcloud container node-pools update NODEPOOL_NAME \
      --cluster=CLUSTER_NAME --flex-start
    

Esta operação faz o seguinte:

  • Atualize o node pool para um node pool de início flexível.
  • Aplique os preços dos nós de início flexível.

Todos os nós em clusters executados na versão 1.32.2-gke.1652000 ou posterior, a versão mínima para nós de início flexível, usam atualizações de curta duração.

O que se segue?