Résoudre les problèmes liés aux pools de nœuds GKE Standard


Cette page explique comment résoudre les problèmes liés aux pools de nœuds en mode GKE Standard.

Si vous avez besoin d'aide supplémentaire, contactez l'assistance Cloud Customer Care.

Problèmes liés à la création de pools de nœuds

Cette section liste les problèmes qui peuvent survenir lors de la création de pools de nœuds dans des clusters exécutant GKE Standard et fournit des suggestions sur la façon de les résoudre.

Problème : la création du pool de nœuds échoue en raison d'une insuffisance de ressources

Le problème suivant se produit lorsque vous créez un pool de nœuds avec du matériel spécifique dans une zone Google Cloud qui ne dispose pas de suffisamment de ressources matérielles pour répondre à vos besoins.

Pour vérifier que la création du pool de nœuds a échoué en raison d'un manque de ressources dans une zone, recherchez les messages d'erreur pertinents dans vos journaux.

  1. Accédez à l'explorateur de journaux dans la console Google Cloud :

    Accéder à l'explorateur de journaux

  2. Dans le champ Requête, saisissez la requête suivante :

    log_id(cloudaudit.googleapis.com/activity)
    resource.labels.cluster_name="CLUSTER_NAME"
    protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")
    

    Remplacez CLUSTER_NAME par le nom de votre cluster GKE.

  3. Cliquez sur Exécuter la requête.

Un des messages d'erreur suivants peut s'afficher :

  • resource pool exhausted
  • The zone does not have enough resources available to fulfill the request. Try a different zone, or try again later.
  • ZONE_RESOURCE_POOL_EXHAUSTED
  • ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS
  • Machine type with name 'MACHINE_NAME' does not exist in zone 'ZONE_NAME'

Essayez les solutions suivantes pour résoudre ce problème :

  • Assurez-vous que la région ou la zone Google Cloud sélectionnée dispose du matériel spécifique dont vous avez besoin. Utilisez le tableau de disponibilité Compute Engine pour vérifier si des zones spécifiques acceptent le matériel spécifique que vous souhaitez. Choisissez pour vos nœuds une région ou une zone Google Cloud pouvant offrir une meilleure disponibilité pour le matériel dont vous avez besoin.
  • Créez le pool de nœuds avec des types de machines plus petits. Augmentez le nombre de nœuds dans le pool de nœuds afin que la capacité de calcul totale reste identique.
  • Utilisez la réservation de capacité Compute Engine pour réserver les ressources à l'avance.
  • Utilisez le provisionnement optimal, décrit dans la section suivante, pour vous assurer de pouvoir créer le pool de nœuds s'il peut provisionner un nombre minimal de nœuds spécifié, par rapport au nombre demandé.

Provisionnement optimal

Vous pouvez utiliser le provisionnement optimal pour certains matériels, qui indique à GKE de valider la création du pool de nœuds s'il peut provisionner un nombre minimal de nœuds spécifié. GKE va tenter en continu de provisionner les nœuds restants, afin de satisfaire à la requête d'origine. Exécutez la commande suivante pour indiquer à GKE d'utiliser le provisionnement optimal :

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --node-locations=ZONE1,ZONE2,... \
    --machine-type=MACHINE_TYPE
    --best-effort-provision \
    --min-provision-nodes=MINIMUM_NODES

Remplacez les éléments suivants :

  • NODE_POOL_NAME : nom du nouveau pool de nœuds.
  • ZONE1,ZONE2,... : zones Compute Engine pour les nœuds. Ces zones doivent être compatibles avec le matériel sélectionné.
  • MACHINE_TYPE : type de machine Compute Engine pour les nœuds. Par exemple, a2-highgpu-1g.
  • MINIMUM_NODES : nombre minimal de nœuds pour que GKE puisse provisionner et créer le pool de nœuds. Si aucune valeur n'est spécifiée, la valeur par défaut est 1.

Par exemple, considérons un scénario dans lequel vous avez besoin de 10 nœuds avec des GPU NVIDIA A100 40 Go associés dans la zone us-central1-c. Selon le tableau de disponibilité des régions et des zones GPU, cette zone est compatible avec les GPU A100. Pour éviter l'échec de la création du pool de nœuds, si moins de 10 machines basées sur ces GPU sont disponibles, utilisez le provisionnement optimal.

gcloud container node-pools create a100-nodes \
    --cluster=ml-cluster \
    --node-locations=us-central1-c \
    --num-nodes=10 \
    --machine-type=a2-highgpu-1g \
    --accelerator=type=nvidia-tesla-a100,count=1 \
    --best-effort-provision \
    --min-provision-nodes=5

GKE crée le pool de nœuds même s'il n'y a que cinq GPU disponibles dans la zone us-central1-c. GKE va tenter en continu de provisionner d'autres nœuds, jusqu'à ce que le pool de nœuds contienne 10 nœuds.

Erreur : l'instance ne contient pas les métadonnées "instance-template"

L'erreur suivante peut s'afficher en tant qu'état d'un pool de nœuds qui ne parvient pas à mettre à niveau, à évoluer ou à effectuer une réparation automatique de nœuds :

Instance INSTANCE_NAME does not contain 'instance-template' metadata

Ce message indique que les métadonnées des instances de VM, allouées par GKE, ont été corrompues. Cela se produit généralement lorsque des opérations de création d'automatisation ou de scripts personnalisés tentent d'ajouter des métadonnées d'instance (telles que block-project-ssh-keys). Au lieu d'ajouter ou de mettre à jour des valeurs, elle supprime également les métadonnées existantes. Pour en savoir plus sur les métadonnées d'instance de VM, consultez la page Définir des métadonnées personnalisées.

Dans le cas où une des valeurs de métadonnées critiques (entre autres :instance-template ,kube-labels ,kubelet-config ,kubeconfig ,cluster-name ,configure-sh ,cluster-uid) a été supprimée, le nœud ou le pool de nœuds entier peut s'afficher dans un état instable, car ces valeurs sont essentielles aux opérations GKE.

Si les métadonnées d'instance ont été corrompues, nous vous recommandons de les récupérer en recréant le pool de nœuds contenant les instances de VM corrompues. Vous devez ajouter un pool de nœuds à votre cluster et augmenter le nombre de nœuds du nouveau pool de nœuds, tout en marquant les nœuds comme non programmables et en supprimant les nœuds d'un autre. Consultez les instructions pour migrer des charges de travail entre des pools de nœuds.

Pour déterminer par qui et quand les métadonnées d'instance ont été modifiées, vous pouvez consulter les informations sur les journaux d'audit Compute Engine ou rechercher des journaux à l'aide de l'explorateur de journaux en utilisant une requête semblable à celle-ci :

resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"

Dans les journaux, vous pouvez trouver l'adresse IP de l'utilisateur d'origine de la requête et le user-agent : Exemple :

requestMetadata: {
  callerIp: "REDACTED"
  callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}

Migrer des charges de travail entre des pools de nœuds

Suivez les instructions ci-dessous pour migrer des charges de travail d'un pool de nœuds vers un autre. Si vous souhaitez modifier les attributs de machine des nœuds de votre pool de nœuds, consultez la section Scaling vertical en modifiant les attributs de machine de nœud.

Migrer des pods vers un nouveau pool de nœuds

Pour migrer des pods vers un nouveau pool de nœuds, procédez comme suit :

  1. Appliquez la commande "cordon" aux nœuds du pool de nœuds existant : cette opération a pour effet de marquer les nœuds du pool existant comme non programmables. Kubernetes arrête de planifier de nouveaux pods sur ces nœuds lorsque vous les marquez comme non ordonnançables.

  2. Drainez les nœuds du pool de nœuds existant : cette opération supprime de manière optimale les charges de travail s'exécutant sur les nœuds du pool de nœuds existant.

Ces étapes, effectuées individuellement pour chaque nœud, entraînent la fermeture des pods exécutés dans votre pool de nœuds existants. Kubernetes les replanifie sur d'autres nœuds disponibles.

Pour vous assurer que Kubernetes arrête correctement vos applications, vos conteneurs doivent gérer le signal SIGTERM. Utilisez cette approche pour fermer les connexions actives aux clients et valider ou effectuer un rollback des transactions de base de données de manière claire. Dans le fichier manifeste de votre pod, vous pouvez utiliser le champ spec.terminationGracePeriodSeconds pour spécifier la durée pendant laquelle Kubernetes doit attendre avant d'arrêter les conteneurs du pod. La durée par défaut est de 30 secondes. Pour en savoir plus sur l'arrêt de pods, consultez la documentation de Kubernetes.

Vous pouvez marquer les nœuds comme non programmables et les drainer à l'aide des commandes kubectl cordon et kubectl drain.

Créer un pool de nœuds et migrer des charges de travail

Pour migrer vos charges de travail vers un nouveau pool de nœuds, créez le pool de nœuds, puis marquez et drainez les nœuds dans le pool existant :

  1. Ajoutez un pool de nœuds au cluster.

    Vérifiez que le nouveau pool de nœuds a été créé en exécutant la commande suivante :

    gcloud container node-pools list --cluster CLUSTER_NAME
    
  2. Exécutez la commande suivante pour voir sur quel nœud les pods sont exécutés (consultez la colonne NODE) :

    kubectl get pods -o=wide
    
  3. Obtenez la liste des nœuds du pool existant, en remplaçant EXISTING_NODE_POOL_NAME par le nom :

    kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME
    
  4. Exécutez la commande kubectl cordon NODE (remplacez NODE par les noms issus de la commande précédente). La commande d'interface système suivante parcourt chaque nœud du pool existant et les marque comme non programmables :

    for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do
      kubectl cordon "$node";
    done
    
  5. Vous pouvez également mettre à jour vos charges de travail exécutées sur le pool de nœuds existant pour ajouter un sélecteur de nœuds pour le libellé cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME, où NEW_NODE_POOL_NAME est le nom du nouveau pool de nœuds. Cela garantit que GKE place ces charges de travail sur les nœuds du nouveau pool de nœuds.

  6. Drainez chaque nœud en expulsant les pods avec un délai de grâce attribué de 10 secondes :

    for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do
      kubectl drain --force --ignore-daemonsets --delete-emptydir-data --grace-period=GRACEFUL_TERMINATION_SECONDS  "$node";
    done
    

    Remplacez GRACEFUL_TERMINATION_PERIOD_SECONDS par le délai requis pour l'arrêt optimal.

  7. Exécutez la commande suivante pour vérifier que les nœuds du pool existant ont l'état SchedulingDisabled dans la liste des nœuds :

    kubectl get nodes
    

    En outre, vous devriez voir que les pods s'exécutent maintenant sur les nœuds du nouveau pool de nœuds :

    kubectl get pods -o=wide
    
  8. Supprimez le pool de nœuds existant si vous n'en avez plus besoin :

    gcloud container node-pools delete default-pool --cluster CLUSTER_NAME
    

Étapes suivantes

Si vous avez besoin d'une aide supplémentaire, contactez Cloud Customer Care.