Déployer des GPU pour des charges de travail par lot avec le planificateur de charges de travail dynamique


Cette page explique comment optimiser l'obtention de GPU via le planificateur de charge de travail dynamique. Nous recommandons le planificateur de charges de travail dynamique pour les charges de travail par lot à grande échelle pouvant s'exécuter pendant les heures creuses avec des conditions définies pour la gestion de la capacité des GPU. Ces charges de travail peuvent être dédiées à l'entraînement de modèles de deep learning ou à une simulation nécessitant de grandes quantités de GPU avec un modèle de provisionnement atomique, ce qui signifie que toutes les ressources sont créées en même temps.

Pour exécuter des charges de travail GPU dans Google Kubernetes Engine (GKE) sans le planificateur de charges de travail dynamique, consultez la page Exécuter des GPU dans des pools de nœuds GKE Standard.

Quand utiliser le planificateur de charges de travail dynamique ?

Nous vous recommandons d'utiliser le planificateur de charges de travail dynamique si vos charges de travail répondent à toutes les conditions suivantes :

  • Vous demandez des GPU pour exécuter vos charges de travail.
  • Vous disposez d'une capacité de GPU réservée limitée ou inexistante, et vous souhaitez améliorer l'obtention des ressources GPU.
  • Votre charge de travail est flexible en termes d'horaires et votre cas d'utilisation peut tolérer d'attendre pour obtenir toute la capacité demandée, par exemple lorsque GKE alloue les ressources GPU en dehors des heures de pointe.
  • Votre charge de travail nécessite plusieurs nœuds et ne peut pas commencer à s'exécuter tant que tous les nœuds GPU ne sont pas provisionnés et prêts en même temps (par exemple, entraînement de machine learning distribué).

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.

Utiliser des pools de nœuds avec le planificateur de charges de travail dynamique

Vous pouvez utiliser l'une des trois méthodes suivantes pour indiquer que le planificateur de charges de travail dynamique peut fonctionner avec des pools de nœuds spécifiques dans votre cluster :

Créer un pool de nœuds

Créez un pool de nœuds avec le planificateur de charges de travail dynamique activé à l'aide de la gcloud CLI :

gcloud beta 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 \
    --enable-autoscaling  \
    --num-nodes=0   \
    --total-max-nodes TOTAL_MAX_NODES  \
    --location-policy=ANY  \
    --reservation-affinity=none  \
    --no-enable-autorepair

Remplacez les éléments suivants :

  • NODEPOOL_NAME : nom que vous avez choisi pour le pool de nœuds.
  • CLUSTER_NAME : nom du cluster.
  • LOCATION : région Compute Engine du cluster, telle que us-central1.
  • GPU_TYPE : type de GPU.
  • AMOUNT : nombre de GPU à associer aux nœuds du pool.
  • DRIVER_VERSION : version du pilote NVIDIA à installer. La valeur peut être l'une des suivantes :
    • default : installe la version de pilote par défaut pour votre version de GKE.
    • latest : installe la dernière version de pilote disponible pour votre version de GKE. Disponible seulement pour les nœuds qui utilisent Container-Optimized OS.
  • TOTAL_MAX_NODES : nombre maximal de nœuds pour effectuer le scaling automatique du pool de nœuds entier.
  • MACHINE_TYPE : type de machine Compute Engine pour vos nœuds. Nous vous recommandons de sélectionner un type de machine optimisé pour les accélérateurs.

Vous pouvez éventuellement utiliser les options suivantes :

  • --no-enable-autoupgrade : recommandé. Désactive les mises à niveau automatiques des nœuds. Compatible uniquement avec les clusters GKE non enregistrés dans une version disponible. Pour en savoir plus, consultez la section Désactiver les mises à niveau automatiques des nœuds pour un pool de nœuds existant.
  • --node-locations=COMPUTE_ZONES : liste d'une ou de plusieurs zones, séparées par une virgule, dans lesquelles GKE crée les nœuds GPU. Ces zones doivent se trouver dans la même région que le cluster. Choisissez des zones disposant de GPU disponibles.
  • --enable-gvnic : cette option permet à gVNIC sur les pools de nœuds GPU d'augmenter la vitesse du trafic réseau.

Cette commande crée un pool de nœuds avec la configuration suivante :

  • GKE active le provisionnement en file d'attente et l'autoscaling des clusters.
  • Le pool de nœuds ne contient initialement aucun nœud.
  • L'option --enable-queued-provisioning active le planificateur de charges de travail dynamique et ajoute le rejet cloud.google.com/gke-queued au pool de nœuds.
  • Les options --no-enable-autorepair et --no-enable-autoupgrade désactivent la réparation et la mise à niveau automatiques des nœuds, ce qui peut perturber les charges de travail s'exécutant sur des nœuds réparés ou mis à niveau. Vous ne pouvez désactiver la mise à niveau automatique des nœuds que sur les clusters qui ne sont pas enregistrés dans un canal de publication.

Mettre à jour le pool de nœuds existant et activer le planificateur de charges de travail dynamique

Activez le planificateur de charges de travail dynamique pour un pool de nœuds existant. Passez en revue les conditions préalables pour configurer correctement le pool de nœuds.

Prérequis

  • Assurez-vous de créer un pool de nœuds avec l'option --reservation-affinity=none. Cette option est requise pour activer ultérieurement le planificateur de charges de travail dynamique, car vous ne pouvez pas modifier l'affinité de réservation après la création du pool de nœuds.

  • Assurez-vous de maintenir au moins un pool de nœuds sans la gestion du planificateur de charges de travail dynamique pour que le cluster fonctionne correctement.

  • Assurez-vous que le pool de nœuds est vide. Vous pouvez redimensionner le pool de nœuds afin qu'il ne contienne aucun nœud.

  • Assurez-vous que l'autoscaling est activé et correctement configuré.

  • Assurez-vous que la réparation automatique est désactivée.

Activer le planificateur de charges de travail dynamique pour un pool de nœuds existant

Vous pouvez activer le planificateur de charges de travail dynamique pour un pool de nœuds existant à l'aide de la gcloud CLI :

gcloud beta container node-pools update NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
     --enable-queued-provisioning

Remplacez les éléments suivants :

  • NODEPOOL_NAME : nom du pool de nœuds choisi
  • CLUSTER_NAME : nom du cluster
  • LOCATION : région Compute Engine du cluster, telle que us-central1

Cette commande de mise à jour du pool de nœuds entraîne les modifications de configuration suivantes :

  • L'option --enable-queued-provisioning active le planificateur de charges de travail dynamique et ajoute le rejet cloud.google.com/gke-queued au pool de nœuds.

Vous pouvez également mettre à jour les paramètres de pool de nœuds suivants :

  • Désactiver les mises à niveau automatiques des nœuds : nous vous recommandons de désactiver les mises à niveau automatiques des nœuds, car les mises à niveau du pool de nœuds ne sont pas compatibles avec l'utilisation du planificateur de charges de travail dynamique. Pour désactiver les mises à niveau automatiques des nœuds, assurez-vous que votre cluster GKE n'est pas inscrit dans un canal de publication.
  • Activez gVNIC sur les pools de nœuds GPU : la carte d'interface réseau virtuelle Google (gVNIC) augmente la vitesse du trafic réseau pour les nœuds GPU.

Activer le provisionnement automatique des nœuds afin de créer des pools de nœuds pour le planificateur de charges de travail dynamique

Vous pouvez utiliser le provisionnement automatique des nœuds pour gérer les pools de nœuds du planificateur de charges de travail dynamique pour les clusters exécutant la version 1.29.2-gke.1553000 ou ultérieure. Lorsque vous activez le provisionnement automatique des nœuds et le planificateur de charges de travail dynamique, GKE crée des pools de nœuds avec les ressources requises pour la charge de travail associée.

Pour activer le provisionnement automatique des nœuds, examinez les paramètres suivants et effectuez les étapes décrites dans la section Configurer les limites de GPU :

Exécuter vos charges de travail par lot avec le planificateur de charges de travail dynamique

Pour utiliser le planificateur de charges de travail dynamique, nous vous recommandons d'utiliser Kueue. Kueue met en œuvre la mise en file d'attente des jobs, en déterminant quand les Jobs doivent attendre et quand ils doivent démarrer, en fonction des quotas et d'une hiérarchie de partage équitable des ressources entre les équipes. Cela simplifie la configuration nécessaire pour utiliser des VM en file d'attente.

Vous pouvez utiliser le planificateur de charges de travail dynamique sans Kueue si vous utilisez vos propres outils ou plateformes de planification par lot internes. Pour configurer le planificateur de charges de travail dynamique pour les jobs sans Kueue, consultez la page Planificateur de charges de travail dynamique pour les jobs sans Kueue.

Planificateur de charges de travail dynamique pour les jobs avec Kueue

La section suivante explique comment configurer le planificateur de charges de travail dynamique pour les jobs avec Kueue. Cette section utilise les exemples du dépôt dws-examples. Nous avons publié les exemples dans le dépôt dws-examples sous la licence Apache2.

Préparer votre environnement

  1. Dans Cloud Shell, exécutez la commande suivante :

    git clone https://github.com/GoogleCloudPlatform/ai-on-gke
    cd ai-on-gke/tutorials-and-examples/workflow-orchestration/dws-examples
    
  2. Installez Kueue dans votre cluster avec la configuration nécessaire pour activer l'intégration des requêtes de provisionnement :

    kubectl apply --server-side -f ./kueue-manifests.yaml
    

Pour en savoir plus sur l'installation de Kueue, consultez la section Installation.

Créer les ressources Kueue

Avec le fichier manifeste suivant, vous créez une file d'attente au niveau du cluster nommée dws-cluster-queue et l'espace de noms LocalQueue nommé dws-local-queue. Les jobs qui font référence à la file d'attente dws-cluster-queue dans cet espace de noms utilisent le planificateur de charges de travail dynamique pour obtenir les ressources 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"]
    flavors:
    - name: "default-flavor"
      resources:
      - name: "cpu"
        nominalQuota: 10000  # Infinite quota.
      - name: "memory"
        nominalQuota: 10000Gi # Infinite quota.
      - name: "nvidia.com/gpu"
        nominalQuota: 10000  # 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"
---

Déployez la file d'attente locale :

kubectl create -f ./dws-queues.yaml

Le résultat ressemble à ce qui suit :

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

Si vous souhaitez exécuter des jobs qui utilisent le planificateur de charges de travail dynamique dans d'autres espaces de noms, vous pouvez créer des LocalQueues supplémentaires à l'aide du modèle précédent.

Exécuter votre tâche

Dans le fichier manifeste suivant, l'exemple de job utilise le planificateur de charges de travail dynamique :

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

Ce fichier manifeste inclut les champs suivants qui sont pertinents pour la configuration du planificateur de charges de travail dynamique :

  • Le libellé kueue.x-k8s.io/queue-name: dws-local-queue indique à GKE que Kueue est responsable de l'orchestration de ce job. Ce libellé définit également la file d'attente dans laquelle le job est mis en file d'attente.
  • L'option suspend: true indique à GKE de créer la ressource de job, mais de ne pas encore planifier les pods. Kueue remplace cette option par false lorsque les nœuds sont prêts pour l'exécution du job.
  • nodeSelector indique à GKE de ne planifier le job que sur le pool de nœuds spécifié. La valeur doit correspondre à NODEPOOL_NAME, le nom du pool de nœuds avec le provisionnement en file d'attente activé.
  1. Exécutez votre tâche :

    kubectl create -f ./job.yaml
    

    Le résultat ressemble à ce qui suit :

    job.batch/sample-job created
    
  2. Vérifiez l'état de votre job :

    kubectl describe job sample-job
    

    Le résultat ressemble à ce qui suit :

    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
    

L'intégration du planificateur de charges de travail dynamique avec Kueue est également compatible avec d'autres types de charges de travail disponibles dans l'écosystème Open Source, comme par exemple :

  • RayJob
  • JobSet
  • Kubeflow MPIJob, TFJob, PyTorchJob.
  • Pods Kubernetes fréquemment utilisés par les orchestrateurs de workflows
  • Mini-cluster de flux

Pour en savoir plus sur cette compatibilité, consultez la section Utilisateur par lots de Kueue.

Planificateur de charges de travail dynamique pour les jobs sans Kueue

Créez une requête via l'API ProvisioningRequest pour chaque job. Le planificateur de charges de travail dynamique ne démarre pas les pods. Il provisionne uniquement les nœuds.

  1. Créez le fichier manifeste provisioning-request.yaml suivant :

    apiVersion: v10
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
    template:
      spec:
        nodeSelector:
            cloud.google.com/gke-nodepool: NODEPOOL_NAME
        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/v1beta1
    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
    

    Remplacez les éléments suivants :

    • NAMESPACE_NAME : nom de votre espace de noms Kubernetes. L'espace de noms doit être identique à celui des pods.
    • PROVISIONING_REQUEST_NAME : le nom du ProvisioningRequest. Vous ferez référence à ce nom dans l'annotation de pod.
    • MAX_RUN_DURATION_SECONDS (facultatif) : durée d'exécution maximale d'un nœud en secondes, jusqu'à la valeur par défaut de sept jours. Pour en savoir plus, consultez la section Fonctionnement du planificateur de charges de travail dynamique. Vous ne pouvez pas modifier cette valeur après la création de la requête. Ce champ est disponible en version preview dans GKE version 1.28.5-gke.1355000 ou ultérieure.
    • COUNT : nombre de pods demandés. Les nœuds sont programmés de manière atomique dans une zone.
    • POD_TEMPLATE_NAME : nom standard de Kubernetes. GKE fait référence à cette valeur dans le PodSet ProvisioningRequest.
    • NODEPOOL_NAME : nom que vous avez choisi pour le pool de nœuds.
  2. Appliquez le fichier manifeste :

    kubectl apply -f provisioning-request.yaml
    

Configurer les pods

Dans la spécification de job, associez les pods à ProvisioningRequest à l'aide des annotations suivantes :

apiVersion: batch/v1
kind: Job
spec:
  template:
    metadata:
      annotations:
        cluster-autoscaler.kubernetes.io/consume-provisioning-request: PROVISIONING_REQUEST_NAME
        cluster-autoscaler.kubernetes.io/provisioning-class-name: "queued-provisioning.gke.io"
    spec:
      ...

La clé d'annotation de pod cluster-autoscaler.kubernetes.io/consume-provisioning-request définit la ProvisioningRequest à utiliser. GKE utilise les annotations consume-provisioning-request et provisioning-class-name pour effectuer les opérations suivantes :

  • Programmer les pods uniquement dans les nœuds provisionnés par le planificateur de charges de travail dynamique.
  • Éviter de comptabiliser deux fois les demandes de ressources entre les pods et le planificateur de charges de travail dynamique dans l'autoscaler de cluster.
  • Injecter une annotation safe-to-evict: false afin d'empêcher l'autoscaler de cluster de déplacer des pods entre les nœuds et d'interrompre les calculs par lot. Vous pouvez modifier ce comportement en spécifiant safe-to-evict: true dans les annotations de pod.

Observer l'état du planificateur de charges de travail dynamique

L'état d'un programmeur de charge de travail dynamique indique si un pod peut être planifié ou non. Vous pouvez utiliser les requêtes watch Kubernetes pour observer les modifications efficacement ou d'autres outils que vous utilisez déjà pour suivre l'état des objets Kubernetes. Le tableau suivant décrit l'état possible d'un programmeur de charge de travail dynamique et chaque résultat possible :

État du programmeur de charge de travail dynamique Description Résultat possible
En attente La requête n'a pas encore été consultée et traitée. Après le traitement, la requête passe à l'état Accepted ou Failed.
Accepted=true La requête est acceptée et attend que des ressources soient disponibles. La requête doit passer à l'état Provisioned si des ressources ont été trouvées et que les nœuds ont été provisionnés, ou à l'état Failed si cela n'est pas possible.
Provisioned=true Les nœuds sont prêts. Vous avez 10 minutes pour démarrer les pods et utiliser les ressources provisionnées. Passé ce délai, l'autoscaler de cluster considère les nœuds comme non nécessaires et les supprime.
Failed=true Les nœuds ne peuvent pas être provisionnés en raison d'erreurs. Failed=true correspond à un état final. Résolvez la condition en fonction des informations spécifiées dans ses champs Reason et Message. Créez et relancez une requête du planificateur de charges de travail dynamique.
Provisioned=false Les nœuds n'ont pas encore été provisionnés.

Si la valeur est Reason=NotProvisioned, il s'agit d'un état temporaire avant que toutes les ressources ne soient disponibles.

Si la valeur est Reason=QuotaExceeded, corrigez la condition en fonction de ce motif et des informations contenues dans le champ Message de la condition. Vous devrez peut-être demander plus de quota. Pour en savoir plus, consultez la section Vérifier si le planificateur de charges de travail dynamique est limité par un quota. Ce Reason n'est disponible qu'avec GKE version 1.29.2-gke.1181000 ou ultérieure.

Démarrer les pods

Lorsque la requête du planificateur de charges de travail dynamique atteint l'état Provisioned=true, vous pouvez exécuter votre job pour démarrer les pods. Cela évite la prolifération des pods non programmables pour les requêtes en attente ou ayant échoué, ce qui peut affecter les performances de kube-scheduler et de l'autoscaler de cluster.

Si vous n'avez pas besoin de pods non programmables, vous pouvez également créer des pods en parallèle avec le planificateur de charges de travail dynamique.

Annuler la requête du planificateur de charges de travail dynamique

Pour annuler la requête avant son provisionnement, vous pouvez supprimer ProvisioningRequest :

kubectl delete provreq PROVISIONING_REQUEST_NAME -n NAMESPACE

Dans la plupart des cas, la suppression de ProvisioningRequest empêche la création de nœuds. Toutefois, selon la planification, par exemple si des nœuds étaient déjà provisionnés, ils peuvent quand même être créés. Dans ce cas, l'autoscaler de cluster supprime les nœuds au bout de 10 minutes si aucun pod n'est créé.

Fonctionnement du planificateur de charges de travail dynamique

Avec ProvisioningRequest API, le planificateur de charges de travail dynamique effectue les opérations suivantes :

  1. Vous indiquez à GKE que votre charge de travail peut attendre, pendant une durée indéterminée, jusqu'à ce que tous les nœuds requis soient prêts à être utilisés simultanément.
  2. L'autoscaler de cluster accepte votre requête et calcule le nombre de nœuds nécessaires, en les traitant comme une seule unité.
  3. La requête attend que toutes les ressources nécessaires soient disponibles dans une seule zone.
  4. L'autoscaler de cluster provisionne tous les nœuds nécessaires en même temps.
  5. Tous les pods de la charge de travail peuvent s'exécuter ensemble sur des nœuds qui viennent d'être provisionnés.
  6. Les nœuds provisionnés sont limités à sept jours d'exécution, ou moins si vous définissez le paramètre maxRunDurationSeconds pour indiquer que les charges de travail nécessitent moins de temps pour s'exécuter. Pour en savoir plus, consultez la section Limiter l'environnement d'exécution d'une VM (bêta). Cette fonctionnalité est disponible avec GKE version 1.28.5-gke.1355000 ou ultérieure. Passé ce délai, les nœuds et les pods qui y sont exécutés sont préemptés. Si les pods terminent plus tôt et que les nœuds ne sont pas utilisés, l'autoscaler de cluster les supprime conformément au profil d'autoscaling.
  7. Les nœuds ne sont pas réutilisés entre le planificateur de charges de travail dynamique. Chaque ProvisioningRequest ordonne la création de nœuds avec une durée d'exécution actualisée de sept jours.

Quota

Le nombre de requêtes ProvisioningRequests à l'état Accepted est limité par un quota dédié, configuré par projet, indépendamment pour chaque région.

Vérifier le quota dans la console Google Cloud

Pour vérifier le nom de la limite de quota et l'utilisation actuelle dans la console Google Cloud, procédez comme suit :

  1. Accédez à la page Quotas de la console Google Cloud.

    Accéder à la section "Quotas"

  2. Dans la zone Filtre , sélectionnez la propriété Métrique, saisissez active_resize_requests, puis appuyez sur Entrée.

La valeur par défaut est 100. Pour augmenter le quota, suivez les étapes répertoriées dans la section Demander un guide de limite de quota supérieure.

Vérifier si le planificateur de charges de travail dynamique est limité par le quota

Si le traitement de votre requête du planificateur de charges de travail dynamique prend plus de temps que prévu, vérifiez que la requête n'est pas limitée par le quota. Vous devrez peut-être demander une augmentation de quota.

Pour les clusters exécutant la version 1.29.2-gke.1181000 ou ultérieure, vérifiez si des limites de quota spécifiques empêchent le traitement de votre requête :

kubectl describe provreq PROVISIONING_REQUEST_NAME \
    --namespace NAMESPACE

Le résultat ressemble à ce qui suit :

…
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
…

Dans cet exemple, GKE ne peut pas déployer les nœuds, car le quota est insuffisant dans la région europe-west4.

Configurer les paramètres de perturbation pour les pools de nœuds avec des charges de travail à l'aide du planificateur de charges de travail dynamique

Les charges de travail nécessitant la disponibilité de tous les nœuds ou de la plupart des nœuds d'un pool de nœuds sont sensibles aux évictions. La réparation ou la mise à niveau automatique d'un nœud provisionné à l'aide de ProvisioningRequest API n'est pas possible, car ces opérations évincent toutes les charges de travail exécutées sur ce nœud et rendent les charges de travail non programmables.

Pour minimiser les perturbations de l'exécution des charges de travail à l'aide du planificateur de charges de travail dynamique, nous vous recommandons les mesures suivantes :

  • En fonction de l'inscription à un canal de publication de votre cluster, suivez les bonnes pratiques ci-dessous pour empêcher les mises à niveau automatiques des nœuds d'interrompre vos charges de travail :
  • Désactivez la réparation automatique de nœuds.
  • Utilisez des intervalles de maintenance et des exclusions afin de minimiser les perturbations pour l'exécution des charges de travail, tout en garantissant qu'il existe un intervalle de temps pendant lequel GKE peut perturber le pool de nœuds pour la maintenance automatique. Si vous utilisez ces outils de maintenance, vous devez définir une période spécifique pendant laquelle GKE peut perturber le pool de nœuds. Nous vous recommandons donc de définir cette période lorsqu'aucune charge de travail n'est en cours d'exécution.
  • Pour vous assurer que votre pool de nœuds reste à jour, nous vous recommandons de mettre à niveau manuellement votre pool de nœuds lorsqu'il n'y a aucune requête du planificateur de charges de travail dynamique active et que le pool de nœuds est vide.

Limites

  • L'anti-affinité entre les pods n'est pas prise en charge. L'autoscaler de cluster ne prend pas en compte les règles d'anti-affinité entre les pods lors du provisionnement des nœuds, ce qui peut entraîner des charges de travail non programmables. Cela peut se produire lorsque deux nœuds ou plus sont provisionnés dans le même pool de nœuds.
  • Seuls les nœuds GPU sont compatibles.
  • Les réservations ne sont pas compatibles avec le planificateur de charges de travail dynamique. Vous devez spécifier --reservation-affinity=none lors de la création du pool de nœuds. Le planificateur de charges de travail dynamique ne nécessite et n'accepte que la règle d'emplacement ANY pour l'autoscaling de cluster.
  • Une seule requête du planificateur de charges de travail dynamique peut créer jusqu'à 1 000 VM, ce qui correspond au nombre maximal de nœuds par zone pour un seul pool de nœuds.
  • GKE utilise le quota Compute Engine ACTIVE_RESIZE_REQUESTS pour contrôler le nombre de requêtes du planificateur de charges de travail dynamique en attente dans une file d'attente. Par défaut, ce quota est limité à 100 au niveau du projet Google Cloud. Si vous essayez de créer une requête du planificateur de charges de travail dynamique supérieure à ce quota, la nouvelle requête échoue.
  • Les pools de nœuds utilisant le planificateur de charges de travail dynamique sont sensibles aux perturbations, car les nœuds sont provisionnés ensemble. Pour en savoir plus, consultez la section Configurer les paramètres d'interruption pour les pools de nœuds avec des charges de travail à l'aide du planificateur de charges de travail dynamique.
  • Il est possible que la console Google Cloud liste des VM supplémentaires de courte durée. Ce comportement est intentionnel, car Compute Engine peut créer et supprimer rapidement des VM jusqu'à être en mesure de provisionner toutes les machines requises.
  • L'intégration du planificateur de charges de travail dynamique n'accepte qu'un seul PodSet. Si vous souhaitez combiner différents modèles de pods, utilisez celui qui présente le plus grand nombre de demandes de ressources. Il n'est pas possible de combiner différents types de machines tels que des VM avec différents types de GPU.

Étapes suivantes