Résoudre les problèmes liés aux clusters Autopilot


Cette page explique comment résoudre les problèmes liés aux clusters Autopilot de Google Kubernetes Engine (GKE).

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

Problèmes liés aux clusters

Impossible de créer un cluster : 0 nœud enregistré

Le problème suivant se produit lorsque vous essayez de créer un cluster Autopilot avec un compte de service IAM désactivé ou ne disposant pas des autorisations requises. La création du cluster échoue avec le message d'erreur suivant :

All cluster resources were brought up, but: only 0 nodes out of 2 have registered.

Pour identifier le problème, procédez comme suit :

  1. Vérifiez si le compte de service Compute Engine par défaut ou le compte de service IAM personnalisé que vous souhaitez utiliser est désactivé :

    gcloud iam service-accounts describe SERVICE_ACCOUNT
    

    Remplacez SERVICE_ACCOUNT par l'adresse e-mail du compte de service (par exemple, my-iam-account@my-first-project.iam.gserviceaccount.com).

    Si le compte de service est désactivé, le résultat ressemble à ce qui suit :

    disabled: true
    displayName: my-service-account
    email: my-service-account@my-project.iam.gserviceaccount.com
    ...
    
  2. Si le compte de service est désactivé, activez-le :

    gcloud iam service-accounts enable SERVICE_ACCOUNT
    

Si le compte de service est activé et que l'erreur persiste, accordez-lui les autorisations minimales requises pour GKE :

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:SERVICE_ACCOUNT" \
    --role roles/container.nodeServiceAccount

Espace de noms bloqué à l'état de fin lorsque le cluster contient 0 nœud

Le problème suivant se produit lorsque vous supprimez un espace de noms dans un cluster après son scaling à la baisse à 0 nœud. Le composant metrics-server ne peut pas accepter la demande de suppression d'espace de noms, car il ne possède aucune instance répliquée.

Pour diagnostiquer ce problème, exécutez la commande suivante :

kubectl describe ns/NAMESPACE_NAME

Remplacez NAMESPACE_NAME par le nom de l'espace de noms.

Le résultat est le suivant :

Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request

Pour résoudre ce problème, effectuez le scaling à la hausse de n'importe quelle charge de travail afin de déclencher la création d'un nœud par GKE. Lorsque le nœud est prêt, la demande de suppression d'espace de noms s'arrête automatiquement. Une fois que GKE a supprimé l'espace de noms, effectuez le scaling à la baisse de la charge de travail.

Problèmes de scaling

Échec du scaling à la hausse du nœud : le pod risque d'être planifié

Le problème suivant se produit lorsque la journalisation du port série est désactivée dans votre projet Google Cloud. Les clusters GKE Autopilot nécessitent la journalisation du port série pour déboguer efficacement les problèmes de nœuds. Si la journalisation du port série est désactivée, Autopilot ne peut pas provisionner les nœuds pour exécuter vos charges de travail.

Le message d'erreur dans votre journal des événements Kubernetes est semblable à celui-ci :

LAST SEEN   TYPE      REASON          OBJECT                          MESSAGE
12s         Warning   FailedScaleUp   pod/pod-test-5b97f7c978-h9lvl   Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled

La journalisation du port série peut être désactivée au niveau de l'organisation via une règle d'administration qui applique la contrainte compute.disableSerialPortLogging. La journalisation du port série peut également être désactivée au niveau du projet ou de l'instance de machine virtuelle (VM).

Pour résoudre ce problème, procédez comme suit :

  1. Demandez à votre administrateur des règles d'administration Google Cloud de supprimer la contrainte compute.disableSerialPortLogging du projet avec votre cluster Autopilot.
  2. Si aucune règle d'administration n'applique cette contrainte, essayez d'activer la journalisation du port série dans vos métadonnées de projet. Cette action nécessite l'autorisation IAM compute.projects.setCommonInstanceMetadata.

Échec du scaling à la hausse du nœud : GCE manque de ressources

Le problème suivant se produit lorsque vos charges de travail demandent plus de ressources que celles disponibles dans cette région ou cette zone Compute Engine. Vos pods peuvent rester à l'état Pending.

  • Vérifiez les événements du pod :

    kubectl events --for='pod/POD_NAME' --types=Warning
    

    Remplacez RESOURCE_NAME par le nom de la ressource Kubernetes en attente. Par exemple, pod/example-pod.

    Le résultat ressemble à ce qui suit :

    LAST SEEN         TYPE            REASON                  OBJECT                   Message
    19m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    14m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    12m (x2 over 18m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    34s (x3 over 17m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    

Pour résoudre ce problème, procédez comme suit :

  • Déployez le pod dans une région ou une zone différente. Si votre pod est soumis à une restriction zonale telle qu'un sélecteur de topologie, supprimez-la si possible. Pour obtenir des instructions, consultez la section Placer les pods GKE dans des zones spécifiques.
  • Créez un cluster dans une autre région et relancez le déploiement.
  • Essayez d'utiliser une autre classe de calcul. Les classes de calcul qui s'appuient sur des types de machines Compute Engine plus petits sont plus susceptibles de disposer de ressources disponibles. Par exemple, le type de machine par défaut pour Autopilot offre la plus haute disponibilité. Pour obtenir la liste des classes de calcul et des types de machines correspondants, consultez la section Quand utiliser des classes de calcul spécifiques.
  • Si vous exécutez des charges de travail GPU, le GPU demandé peut ne pas être disponible à l'emplacement de votre nœud. Essayez de déployer votre charge de travail dans un autre emplacement ou de demander un autre type de GPU.

Pour éviter les problèmes de scaling à la hausse causés par la disponibilité des ressources à l'avenir, envisagez les approches suivantes :

Échec du scaling à la hausse des nœuds : ressources zonales de pod dépassées

Le problème suivant se produit lorsqu'Autopilot ne provisionne pas de nouveaux nœuds pour un pod dans une zone spécifique, car cela enfreindrait les limites de ressources.

Le message d'erreur dans vos journaux est semblable à celui-ci :

    "napFailureReasons": [
            {
              "messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
              ...

Cette erreur fait référence à un événement noScaleUp, dans lequel le provisionnement automatique des nœuds n'a provisionné aucun groupe de nœuds pour le pod de la zone.

Si vous rencontrez cette erreur, vérifiez les points suivants :

Problèmes liés aux charges de travail

Charges de travail bloquées avec une erreur de stockage éphémère

GKE ne crée pas de pods si vos requêtes de stockage éphémère de pods dépassent le maximum Autopilot de 10 Gio dans GKE 1.28.6-gke.1317000 et versions ultérieures.

Pour diagnostiquer ce problème, décrivez le contrôleur de charge de travail, tel que le déploiement ou la tâche :

kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME

Remplacez les éléments suivants :

  • CONTROLLER_TYPE : type de contrôleur de charge de travail, tel que replicaset ou daemonset. Pour obtenir la liste des types de contrôleurs, consultez la section Gestion des charges de travail.
  • CONTROLLER_NAME : nom de la charge de travail bloquée.

Si le pod n'est pas créé parce que la demande de stockage éphémère dépasse la valeur maximale, le résultat ressemble à ce qui suit :

# lines omitted for clarity

Events:

{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}

Pour résoudre ce problème, mettez à jour vos demandes de stockage éphémère de sorte que la quantité de stockage éphémère totale demandée par les conteneurs de charge de travail et les conteneurs injectés par des webhooks soit inférieure ou égale au maximum autorisé. Pour en savoir plus sur la valeur maximale, consultez la section Demandes de ressources dans Autopilot pour la configuration de la charge de travail.

Pods bloqués à l'état "Pending"

Un pod peut rester bloqué à l'état Pending dans le cas où vous sélectionnez un nœud spécifique à utiliser pour le pod, mais la somme des demandes de ressources dans le pod et dans les objets DaemonSet devant être exécutés sur le nœud dépasse la capacité maximale pouvant être allouée au nœud : Il se peut alors que votre pod affiche l'état Pending et ne soit pas planifié.

Pour éviter ce problème, évaluez les tailles de vos charges de travail déployées afin de vous assurer qu'elles correspondent aux demandes de ressources maximales autorisées pour Autopilot.

Vous pouvez également essayer de planifier vos DaemonSets avant de programmer vos pods de charge de travail standards.

Pods bloqués lors de l'arrêt ou de la création

Un problème connu entraîne parfois le blocage des pods dans l'un des états suivants :

  • Terminating
  • CreateContainerError

Ce problème peut survenir lorsque vous utilisez des pods extensibles dans des environnements GKE qui répondent à toutes les conditions suivantes :

  1. Vos nœuds exécutent les versions de GKE de la version 1.29.2-gke.1060000 jusqu'à la version 1.30.2-gke.1394000, non incluse.
  2. Votre pod utilise l'une des classes de calcul suivantes :
    • Classe de calcul à usage général par défaut
    • Classe de calcul Balanced
    • Classe de calcul Scale-Out

Pour résoudre ce problème, mettez à niveau votre plan de contrôle vers GKE version 1.30.2-gke.1394000 ou ultérieure. Les pods déjà bloqués dans l'état Terminating ou CreateContainerError seront déployés correctement après que GKE recrée les pods sur les nœuds qui exécutent une version corrigée.

Lorsque vous mettez à niveau un cluster Autopilot, GKE met à niveau les nœuds de calcul pour qu'ils correspondent à la version du plan de contrôle au fil du temps. Un redémarrage du plan de contrôle est nécessaire pour activer l'utilisation intensive et doit se produire une fois que tous les nœuds exécutent une version compatible. Le plan de contrôle redémarre automatiquement environ une fois par semaine lors d'opérations telles que le scaling, les mises à niveau ou la maintenance.

Pour déclencher manuellement un redémarrage du plan de contrôle, procédez comme suit :

  1. Vérifiez si tous vos nœuds exécutent la version 1.30.2-gke.1349000 ou ultérieure :

    kubectl get nodes
    

    Le résultat ressemble à ce qui suit :

    NAME                                          STATUS   ROLES    AGE     VERSION
    gk3-ap-cluster-1-default-pool-18092e49-mllk   Ready    <none>   4m26s   v1.30.2-gke.1349000
    

    Tous les nœuds de la sortie doivent afficher la version requise ou une version ultérieure.

  2. Démarrez manuellement une mise à niveau du plan de contrôle vers la même version que celle utilisée par le cluster. Pour obtenir des instructions, consultez la page Mettre à jour manuellement le plan de contrôle.

Performances des charges de travail systématiquement peu fiables sur un nœud spécifique

Dans la version 1.24 ou ultérieure de GKE, si vos charges de travail sur un nœud spécifique subissent systématiquement des perturbations, des plantages ou un comportement peu fiable similaire, vous pouvez signaler le nœud problématique à GKE en l'ordonnançant à l'aide de la commande suivante :

kubectl drain NODE_NAME --ignore-daemonsets

Remplacez NODE_NAME par le nom du nœud problématique. Vous pouvez trouver le nom du nœud en exécutant la commande kubectl get nodes.

GKE effectue les opérations suivantes :

  • Il supprime les charges de travail existantes du nœud et arrête la planification des charges de travail sur ce nœud.
  • Il recrée automatiquement toutes les charges de travail évincées qui sont gérées par un contrôleur, tel qu'un objet Deployment ou StatefulSet, sur d'autres nœuds.
  • Il arrête toutes les charges de travail qui restent sur le nœud et répare ou recrée le nœud au fil du temps.
  • Si vous utilisez Autopilot, GKE s'arrête et remplace le nœud immédiatement et ignore tous les PodDisruptionBudgets configurés.

La programmation des pods prend plus de temps que prévu sur des clusters vides

Cet événement se produit lorsque vous déployez une charge de travail sur un cluster Autopilot qui n'a aucune autre charge de travail. Les clusters Autopilot démarrent avec zéro nœud utilisable et le scaling à zéro nœud si le cluster est vide pour éviter d'avoir des ressources de calcul non utilisées dans le cluster. Le déploiement d'une charge de travail dans un cluster ne comportant aucun nœud déclenche un événement de scaling à la hausse.

Si vous rencontrez ce problème, Autopilot fonctionne comme prévu et aucune action n'est nécessaire. Votre charge de travail sera déployée comme prévu après le démarrage des nouveaux nœuds.

Vérifiez si vos pods attendent de nouveaux nœuds :

  1. Décrivez votre pod en attente :

    kubectl describe pod POD_NAME
    

    Remplacez POD_NAME par le nom de votre pod en attente.

  2. Vérifiez la section Events du résultat. Si le pod attend de nouveaux nœuds, le résultat ressemble à ce qui suit :

    Events:
      Type     Reason            Age   From                                   Message
      ----     ------            ----  ----                                   -------
      Warning  FailedScheduling  11s   gke.io/optimize-utilization-scheduler  no nodes available to schedule pods
      Normal   TriggeredScaleUp  4s    cluster-autoscaler                     pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]
    

    L'événement TriggeredScaleUp indique que votre cluster effectue un scaling à partir de zéro nœud vers autant de nœuds nécessaires pour exécuter la charge de travail déployée.

L'accès aux nœuds sous-jacents est interdit dans un cluster GKE Autopilot. Par conséquent, il est nécessaire d'exécuter l'utilitaire tcpdump depuis un pod, puis de le copier à l'aide de la commande "kubectl cp". Si vous exécutez généralement l'utilitaire tcpdump à partir d'un pod d'un cluster GKE Autopilot, l'erreur suivante peut s'afficher :

    tcpdump: eth0: You don't have permission to perform this capture on that device
    (socket: Operation not permitted)

En effet, GKE Autopilot, par défaut, applique un contexte de sécurité à tous les pods qui supprime la capacité NET_RAW pour atténuer les failles potentielles. Exemple :

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: tcpdump
  name: tcpdump
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW

Pour remédier à ce problème, si votre charge de travail nécessite la fonctionnalité NET_RAW, vous pouvez la réactiver comme suit :

  1. Ajoutez la fonctionnalité NET_RAW à la section securityContext de la spécification YAML de votre pod :

    securityContext:
      capabilities:
        add:
        - NET_RAW
    
  2. Exécutez tcpdump à partir d'un pod :

    tcpdump port 53 -w packetcap.pcap
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    
  3. Utilisez la commande kubectl cp pour effectuer une copie sur votre ordinateur local afin de procéder à une analyse plus approfondie :

    kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAME
    
  4. Utilisez kubectl exec pour exécuter la commande tcpdump afin d'effectuer une capture de paquets réseau et de rediriger la sortie :

    kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap
    

Étape suivante

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