Résoudre les problèmes liés à GKE Ingress

Les problèmes liés à Ingress dans Google Kubernetes Engine (GKE) peuvent empêcher le trafic externe ou interne d'atteindre vos services.

Utilisez ce document pour trouver des solutions aux erreurs liées à la classe Ingress, aux annotations d'adresses IP statiques, aux tailles de clés de certificat et aux interactions avec les niveaux de réseau.

Ces informations sont destinées aux administrateurs et opérateurs de plate-forme, ainsi qu'aux développeurs d'applications qui déploient et gèrent des applications exposées à l'aide d'Ingress dans GKE. Pour en savoir plus sur les rôles courants et les exemples de tâches que nous citons dans le contenu Google Cloud , consultez Rôles utilisateur et tâches courantes de GKE.

Annotation incorrecte pour la classe Ingress

Problème constaté

Lorsque vous créez un Ingress, l'erreur suivante peut s'afficher :

Missing one or more resources. If resource creation takes longer than expected, you might have an invalid configuration.

Causes probables

Lorsque vous créez l'entrée, il est possible que vous ayez mal configuré la classe Ingress dans le fichier manifeste.

Solution

Pour spécifier une classe Ingress, vous devez utiliser l'annotation kubernetes.io/ingress.class. Vous ne pouvez pas spécifier un objet GKE Ingress en utilisant spec.ingressClassName.

  • Pour déployer un équilibreur de charge d'application interne, utilisez l'annotation kubernetes.io/ingress.class: gce-internal.
  • Pour déployer un équilibreur de charge d'application externe, utilisez l'annotation kubernetes.io/ingress.class: gce.

Annotation incorrecte pour l'adresse IP statique

Problème constaté

Lorsque vous configurez un Ingress externe pour qu'il utilise une adresse IP statique, l'erreur suivante peut s'afficher :

Error syncing to GCP: error running load balancer syncing routine: loadbalancer <Name of load balancer> does not exist: the given static IP name <Static IP> doesn't translate to an existing static IP.

Causes probables

  • Vous n'avez pas créé d'adresse IP externe statique avant de déployer l&#Ingress.
  • Vous n'utilisez pas la bonne annotation pour votre type d'équilibreur de charge.

Solution

Si vous configurez un Ingress externe :

Si vous configurez un Ingress interne :

  • Réservez une adresse IP interne statique régionale avant de déployer lIngress.
  • Utilisez l'annotation kubernetes.io/ingress.regional-static-ip-name sur votre ressource Ingress.

L'adresse IP statique est déjà utilisée

Problème constaté

L'erreur suivante peut s'afficher lorsque vous spécifiez une adresse IP statique pour provisionner votre ressource d&#Ingress;entrée interne ou externe :

Error syncing to GCP: error running load balancer syncing
routine: loadbalancer <LB name> does not exist:
googleapi: Error 409: IP_IN_USE_BY_ANOTHER_RESOURCE - IP ''<IP address>'' is already being used by another resource.

Causes probables

L'adresse IP statique est déjà utilisée par une autre ressource.

Erreur lors de la désactivation du protocole HTTP et de l'utilisation d'un certificat géré par Google

Problème constaté

Si vous configurez un certificat SSL géré par Google et que vous désactivez le trafic HTTP sur votre Ingress, l'erreur suivante s'affiche :

Error syncing to GCP: error running load balancer syncing
routine: loadbalancer <Load Balancer name> does not exist:
googleapi: Error 404: The resource ''projects/<Project>/global/sslPolicies/<Policy name>' was not found, notFound

Causes probables

Vous ne pouvez pas utiliser les annotations suivantes ensemble lorsque vous configurez l'Ingress :

  • networking.gke.io/managed-certificates (pour associer le certificat géré par Google à un objet Ingress)
  • kubernetes.io/ingress.allow-http: false (pour désactiver le trafic HTTP)

Solution

Ne désactivez le trafic HTTP qu'une fois que l'équilibreur de charge d'application externe a été entièrement programmé. Vous pouvez mettre à jour l'Ingress et ajouter l'annotation kubernetes.io/ingress.allow-http: false au fichier manifeste.

Absence de sous-réseau proxy réservé pour un Ingress interne

Problème constaté

Lorsque vous déployez un Ingress pour un équilibreur de charge d'application interne, l'erreur suivante peut s'afficher :

Error syncing to GCP: error running load balancer syncing routine:
loadbalancer <LB name> does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/<Region>/targetHttpsProxies/<Target proxy>'.
An active proxy-only subnetwork is required in the same region and VPC as
the forwarding rule.

Causes probables

Vous n'avez pas créé de sous-réseau proxy réservé avant de créer la ressource Ingress. Un sous-réseau proxy réservé est requis pour les équilibreurs de charge d'application internes.

Solution

Créez un sous-réseau proxy réservé avant de déployer l'Ingress interne.

La clé du certificat SSL est trop grande

Problème constaté

Si la taille de la clé du certificat SSL de votre équilibreur de charge est trop grande, l'erreur suivante peut s'afficher :

Error syncing to GCP: error running load balancer syncing routine: loadbalancer gky76k70-load-test-trillian-api-ingress-fliismmb does not exist: Cert creation failures - k8s2-cr-gky76k70-znz6o1pfu3tfrguy-f9be3a4abbe573f7 Error:googleapi: Error 400: The SSL key is too large., sslCertificateKeyTooLarge

Causes probables

Google Cloud est limité à 2 048 bits pour les clés de certificat SSL.

Solution

Réduisez la taille de la clé du certificat SSL à 2 048 bits ou moins.

Erreur lors de la création d'un Ingress au niveau Standard

Problème constaté

Si vous déployez un Ingress dans un projet avec le niveau de réseau par défaut du projet défini sur Standard, le message d'erreur suivant s'affiche :

Error syncing to GCP: error running load balancer syncing routine: load balancer <LB Name> does not exist: googleapi: Error 400: STANDARD network tier (the project''s default network tier) is not supported: STANDARD network tier is not supported for global forwarding rule., badRequest

Solution

Configurez le niveau de réseau par défaut du projet sur "Premium".

Erreur "Introuvable" attendue pour k8s-ingress-svc-acct-permission-check-probe

Le contrôleur d'entrée effectue régulièrement des vérifications périodiques des autorisations du compte de service en extrayant une ressource de test à partir de votre projet Google Cloud . Vous verrez s'afficher cela comme un GET du BackendService global (non inexistant) sous le nom k8s-ingress-svc-acct-permission-check-probe. Comme cette ressource ne doit normalement pas exister, la requête GET renvoie "not found" (introuvable). Ce comportement est normal. Le contrôleur vérifie que l'appel d'API n'est pas refusé en raison de problèmes d'autorisation. Si vous créez un objet BackendService avec le même nom, le GET réussit au lieu de renvoyer "not found" (introuvable).

Erreurs lors de l'utilisation de l'équilibrage de charge natif en conteneurs

Utilisez les techniques suivantes pour valider votre configuration réseau. Dans les sections suivantes, nous expliquons comment résoudre des problèmes spécifiques liés à l'équilibrage de charge natif en conteneurs.

  • Consultez la documentation sur l'équilibrage de charge pour savoir comment répertorier vos groupes de points de terminaison réseau.

  • Vous pouvez trouver le nom et les zones du NEG correspondant à un service donné dans l'annotation neg-status de ce service. Vous pouvez obtenir les spécifications du service avec la commande :

    kubectl get svc SVC_NAME -o yaml
    

    L'annotation metadata:annotations:cloud.google.com/neg-status contient le nom du NEG correspondant au service et les zones de ce groupe.

  • Vous pouvez vérifier l'état du service de backend correspondant à un NEG à l'aide de la commande suivante :

    gcloud compute backend-services --project PROJECT_NAME \
        get-health BACKEND_SERVICE_NAME --global
    

    Le service de backend porte le même nom que le NEG associé.

  • Pour imprimer les journaux d'événements d'un service, utilisez la commande :

    kubectl describe svc SERVICE_NAME
    

    La chaîne de caractères du nom du service inclut le nom et l'espace de noms du service GKE correspondant.

Impossible de créer un cluster avec des adresses IP d'alias

Symptômes

Lorsque vous tentez de créer un cluster à l'aide d'adresses IP d'alias, vous pouvez rencontrer le message d'erreur suivant :

ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
Causes probables

Cette erreur se produit lorsque vous tentez de créer un cluster doté d'adresses IP d'alias qui utilise également un réseau ancien.

Solution

Assurez-vous de ne pas créer de cluster utilisant simultanément des adresses IP d'alias et un ancien réseau. Pour en savoir plus sur l'utilisation d'adresses IP d'alias, consultez la page Créer un cluster de VPC natif.

Le trafic n'atteint pas les points de terminaison

Symptômes
Erreurs 502/503 ou connexions refusées
.
Causes probables

Les nouveaux points de terminaison sont généralement accessibles une fois qu'ils sont reliés à l'équilibreur de charge, à condition qu'ils répondent aux vérifications d'état. Vous pouvez rencontrer des erreurs 502 ou des connexions refusées si le trafic ne peut pas atteindre les points de terminaison.

Les erreurs 502 et les connexions refusées peuvent également être causées par un conteneur qui ne gère pas le signal SIGTERM. Si un conteneur ne gère pas explicitement le signal SIGTERM, il s'interrompt immédiatement et cesse de traiter les requêtes. L'équilibreur de charge continue d'envoyer du trafic entrant à destination du conteneur arrêté, ce qui entraîne des erreurs.

L'équilibreur de charge natif du conteneur ne comporte qu'un seul point de terminaison backend. Lors d'une mise à jour progressive, l'ancien point de terminaison est automatiquement déprogrammé avant la programmation du nouveau point de terminaison.

Le ou les pods de backend sont déployés dans une nouvelle zone pour la première fois après le provisionnement d'un équilibreur de charge natif en conteneurs. L'infrastructure de l'équilibreur de charge est programmée dans une zone lorsqu'elle comporte au moins un point de terminaison. Lorsqu'un nouveau point de terminaison est ajouté à une zone, l'infrastructure de l'équilibreur de charge est programmée et entraîne des interruptions de service.

Solution

Configurez les conteneurs afin qu'ils puissent gérer le signal SIGTERM et continuer à répondre aux requêtes tout au long du délai de grâce pour la résiliation (par défaut, 30 secondes). Configurez les pods afin qu'ils se mettent à échouer aux vérifications d'état lorsqu'ils reçoivent un signal SIGTERM. Cela indique à l'équilibreur de charge qu'il doit arrêter d'envoyer du trafic vers le pod lorsque la déprogrammation du point de terminaison est en cours.

Si votre application ne se ferme pas correctement et cesse de répondre aux requêtes lors de la réception d'un SIGTERM, le hook d'arrêt préalable peut servir à gérer SIGTERM et continuer à diffuser le trafic pendant la déprogrammation du point de terminaison.

lifecycle:
  preStop:
    exec:
      # if SIGTERM triggers a quick exit; keep serving traffic instead
      command: ["sleep","60"]

Consultez la documentation sur l'arrêt d'un pod.

Si le backend de votre équilibreur de charge ne comporte qu'une seule instance, configurez la stratégie de déploiement pour éviter de supprimer la seule instance avant que la nouvelle instance ne soit complètement programmée. Pour les pods d'application gérés par la charge de travail Deployment, cette opération peut être effectuée en configurant la stratégie de déploiement avec le paramètre maxUnavailable égal à 0.

strategy:
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

Pour résoudre les cas où le trafic n'atteint pas les points de terminaison, vérifiez que les règles de pare-feu autorisent le trafic TCP entrant vers vos points de terminaison sur les plages 130.211.0.0/22 et 35.191.0.0/16. Pour en savoir plus, consultez la page Ajouter des vérifications d'état dans la documentation Cloud Load Balancing.

Affichez les services de backend dans votre projet. La chaîne de caractères du nom du service de backend concerné inclut le nom et l'espace de noms du service GKE correspondant :

gcloud compute backend-services list

Retrouvez l'état de santé du service de backend :

gcloud compute backend-services get-health BACKEND_SERVICE_NAME

Si aucun des services de backend n'est opérationnel, il se peut que votre pare-feu, votre entrée ou votre service soient mal configurés.

Si certains services de backend ne sont pas opérationnels pendant une courte période, cela peut s'expliquer par la latence de la programmation réseau.

Si certains services de backend ne figurent pas dans la liste, cela peut s'expliquer par la latence de la programmation. Vous pouvez vous en assurer en exécutant la commande suivante, où NEG_NAME est le nom du service de backend (les NEG et les services de backend portent le même nom) :

gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME

Vérifiez que tous les points de terminaison prévus se trouvent dans le NEG.

Si vous avez un petit nombre de backends (par exemple, 1 Pod) sélectionnés par un équilibreur de charge natif en conteneurs, envisagez d'augmenter le nombre d'instances dupliquées et de répartir les pods de backend sur toutes les zones couvertes par le cluster GKE. Cela garantit que l'infrastructure de l'équilibreur de charge sous-jacent est entièrement programmée. Sinon, envisagez de limiter les pods de backend à une seule zone.

Si vous configurez une règle de réseau pour le point de terminaison, assurez-vous que le trafic entrant provenant du sous-réseau proxy réservé est autorisé.

Blocage du déploiement

Symptômes
Le déploiement d'une mise à jour se bloque et le nombre d'instances répliquées à jour ne correspond pas au nombre d'instances répliquées choisi.
Causes probables

Les vérifications d'état du déploiement échouent. Il est possible que l'image du conteneur soit incorrecte ou que la vérification d'état soit mal configurée. Le remplacement progressif des pods attend jusqu'à ce qu'un pod qui vient d'être lancé passe sa porte de disponibilité de pod. Cela se produit uniquement si le pod répond aux vérifications d'état de l'équilibreur de charge. Si le pod ne répond pas ou si la vérification d'état est mal configurée, les conditions de la porte de disponibilité ne peuvent pas être remplies et le déploiement ne peut pas se poursuivre.

Si vous utilisez kubectl 1.13 ou une version ultérieure, vous pouvez vérifier l'état des portes de disponibilité d'un pod à l'aide de la commande suivante :

kubectl get pod POD_NAME -o wide

Vérifiez le contenu de la colonne READINESS GATES.

Cette colonne n'existe pas dans les versions 1.12 et antérieures de kubectl. Un pod identifié comme étant dans l'état READY (prêt) peut néanmoins présenter une porte de disponibilité en échec. Pour le vérifier, exécutez la commande suivante :

kubectl get pod POD_NAME -o yaml

Les portes de disponibilité et leur état sont répertoriés dans le résultat.

Solution

Vérifiez que l'image du conteneur référencée dans la spécification de déploiement de pod fonctionne correctement et qu'elle est en mesure de répondre aux vérifications d'état. Assurez-vous que les vérifications d'état sont correctement configurées.

Erreurs en mode dégradé

Symptômes

À partir de la version 1.29.2-gke.1643000 de GKE, vous pouvez recevoir les avertissements suivants sur votre service dans l'explorateur de journaux lorsque des NEG sont mis à jour :

Entering degraded mode for NEG <service-namespace>/<service-name>-<neg-name>... due to sync err: endpoint has missing nodeName field
Causes probables

Ces avertissements indiquent que GKE a détecté des erreurs de configuration des points de terminaison lors d'une mise à jour du NEG basée sur des objets EndpointSlice, ce qui déclenche un processus de calcul plus approfondi appelé "mode dégradé". GKE continue de mettre à jour les NEG au mieux, en corrigeant l'erreur de configuration ou en excluant les points de terminaison non valides des mises à jour de NEG.

Voici quelques erreurs courantes :

  • endpoint has missing pod/nodeName field
  • endpoint corresponds to an non-existing pod/node
  • endpoint information for attach/detach operation is incorrect
Solution

En règle générale, les états transitoires sont à l'origine de ces événements, et ils se résolvent d'eux-mêmes. Toutefois, les événements causés par des erreurs de configuration dans les objets EndpointSlice personnalisés restent non résolus. Pour comprendre l'erreur de configuration, examinez les objets EndpointSlice correspondant au service :

kubectl get endpointslice -l kubernetes.io/service-name=<service-name>

Validez chaque point de terminaison en fonction de l'erreur dans l'événement.

Pour résoudre le problème, vous devez modifier manuellement les objets EndpointSlice. La mise à jour déclenche une nouvelle mise à jour des NEG. Une fois que l'erreur de configuration n'existe plus, le résultat ressemble à ce qui suit :

NEG <service-namespace>/<service-name>-<neg-name>... is no longer in degraded mode

Erreurs lors de l'utilisation de certificats SSL gérés par Google

Cette section explique comment résoudre les problèmes liés aux certificats gérés par Google.

Vérifier les événements sur les ressources ManagedCertificate et Ingress

Si vous dépassez le nombre de certificats autorisés, un événement avec le motif TooManyCertificates est ajouté à ManagedCertificate. Vous pouvez vérifier les événements d'un objet ManagedCertificate à l'aide de la commande suivante :

kubectl describe managedcertificate CERTIFICATE_NAME

Remplacez CERTIFICATE_NAME par le nom de votre ManagedCertificate.

Si vous associez un ManagedCertificate non existant à un objet Ingress, un événement avec le motif MissingCertificate est ajouté à l'objet Ingress. Vous pouvez vérifier les événements d'une ressource Ingress à l'aide de la commande suivante :

kubectl describe ingress INGRESS_NAME

Remplacez INGRESS_NAME par le nom de votre ressource Ingress.

Certificat géré non provisionné lorsque le domaine est associé aux adresses IP de plusieurs équilibreurs de charge

Lorsque votre domaine est associé aux adresses IP de plusieurs équilibreurs de charge (plusieurs objets Ingress), vous devez créer un seul objet ManagedCertificate et l'associer à tous les objets Ingress. Si vous créez plusieurs objets ManagedCertificate et que vous associez chacun d'entre eux à un objet Ingress distinct, l'autorité de certification risque de ne pas pouvoir valider la propriété de votre domaine et certains de vos certificats risquent de ne pas être provisionnés. Pour que la validation aboutisse, le certificat doit être visible sous toutes les adresses IP auxquelles votre domaine est associé.

En particulier, lorsque votre domaine est associé à une adresse IPv4 et une adresse IPv6 configurées avec différents objets Ingress, vous devez créer un seul objet ManagedCertificate et l'associer aux deux objets Ingress.

Perturbations de la communication entre les certificats gérés par Google et l'objet Ingress

Les certificats gérés communiquent avec l'objet Ingress à l'aide de l'annotation ingress.gcp.kubernetes.io/pre-shared-cert. Vous pouvez perturber cette communication, par exemple si vous :

  • exécutez un processus automatisé supprimant l'annotation ingress.gcp.kubernetes.io/pre-shared-cert ;
  • stockez un instantané de l'objet Ingress, puis supprimez et restaurez l'Ingress à partir de l'instantané. Dans l'intervalle, la ressource SslCertificate répertoriée dans l'annotation ingress.gcp.kubernetes.io/pre-shared-cert a peut-être été supprimée. L'objet Ingress ne fonctionne pas si des certificats associés sont manquants.

Si la communication entre des certificats gérés par Google et l'objet Ingress est interrompue, supprimez le contenu de l'annotation ingress.gcp.kubernetes.io/pre-shared-cert et attendez que le système effectue le rapprochement. Pour éviter que le problème ne se reproduise, assurez-vous que l'annotation n'est pas modifiée ni supprimée par inadvertance.

Erreurs de validation lors de la création d'un certificat géré par Google

Les définitions ManagedCertificate sont validées avant la création de l'objet ManagedCertificate. Si la validation échoue, l'objet ManagedCertificate n'est pas créé et un message d'erreur s'affiche. Vous trouverez ci-dessous les différents messages d'erreur ainsi que les raisons pour lesquelles ils apparaissent :

spec.domains in body should have at most 100 items

Votre fichier manifeste ManagedCertificate regroupe plus de 100 domaines dans le champ spec.domains. Les certificats gérés par Google n'acceptent que 100 domaines au maximum.

spec.domains in body should match '^(([a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)+[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\.?$'

Vous avez spécifié un nom de domaine non valide ou un nom de domaine avec des caractères génériques dans le champ spec.domains. L'objet ManagedCertificate n'est pas compatible avec les domaines comportant des caractères génériques (par exemple, *.example.com).

spec.domains in body should be at most 63 chars long

Vous avez spécifié un nom de domaine trop long. Les certificats gérés par Google n'acceptent pas les noms de domaine dépassant 63 caractères.

Mettre à jour manuellement un certificat géré par Google

Pour mettre à jour manuellement le certificat afin que le certificat de l'ancien domaine continue de fonctionner jusqu'à ce que le certificat du nouveau domaine soit provisionné, procédez comme suit :

  1. Créez un certificat ManagedCertificate pour le nouveau domaine.
  2. Ajoutez le nom de l'élément ManagedCertificate à l'annotation networking.gke.io/managed-certificates dans l'objet Ingress à l'aide d'une liste d'éléments séparés par une virgule. Ne supprimez pas l'ancien nom du certificat.
  3. Attendez que le certificat ManagedCertificate devienne actif.
  4. Dissociez l'ancien certificat de l'objet Ingress et supprimez-le.

Lorsque vous créez un ManagedCertificate, Google Cloud crée un certificat SSL géré par Google. Vous ne pouvez pas mettre à jour ce certificat. Si vous mettez à jour ManagedCertificate, Google Cloud supprime et recrée le certificat SSL géré par Google.

Pour fournir un objet Ingress chiffré HTTPS sécurisé pour vos clusters GKE, consultez l'exemple Entrée sécurisée.

Étapes suivantes