Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Dépannage des problèmes liés à NGINX Ingress

Dernière mise à jour :Aug 25, 2026

Cette rubrique présente le flux de diagnostic, les méthodes de dépannage, les vérifications courantes et les solutions pour résoudre les problèmes liés à Nginx Ingress.

Sommaire

Catégorie

Contenu

Processus de diagnostic

Processus de diagnostic

Approches de dépannage

Approches de dépannage

Méthodes de dépannage courantes

Problèmes courants et solutions

Informations générales

La communauté Kubernetes maintient le contrôleur Ingress NGINX officiel. Le Nginx Ingress Controller dans ACK utilise la version communautaire et prend en charge toutes les annotations de la communauté.

Déployez un Nginx Ingress Controller dans le cluster pour analyser les règles de transfert Ingress. Le contrôleur reçoit les requêtes, les fait correspondre aux règles et les transfère vers les pods de service backend. Voici la relation entre un Service, un Nginx Ingress et le Nginx Ingress Controller :

  • Un Service abstraite un ou plusieurs services backend identiques.

  • Un Nginx Ingress définit des règles de proxy inverse qui acheminent les requêtes HTTP/HTTPS vers les pods de Service en fonction de l'hôte et du chemin URL.

  • Le Nginx Ingress Controller analyse les règles Nginx Ingress. Lorsqu'un Ingress change, le contrôleur met à jour ses règles de transfert et achemine les requêtes entrantes vers le pod de Service approprié.

Le Nginx Ingress Controller récupère les modifications Ingress depuis l'API Server, génère des fichiers de configuration d'équilibreur de charge (tels que nginx.conf), et recharge l'équilibreur de charge (par exemple, nginx -s reload) pour appliquer les nouvelles règles de routage.S2

Flux de dépannage

Diagnostic Ingress.png

  1. Suivez ces étapes pour isoler le problème au niveau de l'Ingress et vérifier la configuration de votre contrôleur Ingress.

    1. Dans le pod contrôleur, confirmez que l'accès fonctionne comme prévu. Pour plus d'informations, consultez la section Accès manuel à l'Ingress et aux pods backend dans le pod contrôleur.

    2. Vérifiez que vous utilisez correctement le NGINX Ingress Controller. Pour plus d'informations, consultez la documentation communautaire du NGINX Ingress Controller.

  2. Utilisez la fonctionnalité de diagnostic Ingress pour vérifier les configurations de l'Ingress et des composants, puis appliquez les modifications recommandées. Pour des instructions détaillées, consultez la section Utilisation de la fonctionnalité de diagnostic Ingress.

  3. Suivez le guide de dépannage pour diagnostiquer et résoudre le problème.

  4. Si les étapes précédentes ne résolvent pas le problème, effectuez les vérifications suivantes :

    • Pour les problèmes liés aux certificats TLS :

      1. Vérifiez si l'intégration WAF ou WAF transparent est activée pour le nom de domaine.

        • Si c'est le cas, assurez-vous qu'aucun certificat TLS n'est configuré pour l'intégration WAF ou WAF transparent.

        • Sinon, passez à l'étape suivante.

      2. Vérifiez si le SLB utilise un écouteur de couche 7.

        • Si c'est le cas, assurez-vous qu'aucun certificat TLS n'est configuré pour l'écouteur de couche 7.

        • Sinon, passez à l'étape suivante.

    • Pour les problèmes non liés aux certificats TLS, vérifiez le journal des erreurs dans le pod contrôleur. Pour plus d'informations, consultez la section Vérification du journal des erreurs dans le pod contrôleur.

  5. Si le problème persiste, effectuez une capture de paquets sur le pod contrôleur et les pods d'application correspondants pour identifier la cause racine. Pour plus d'informations, consultez la section Capture de paquets.

Dépannage

Zone du problème

Symptôme

Solution

Échec d'accès

Un pod à l'intérieur du cluster ne peut pas accéder à un Ingress.

Impossible d'accéder à l'adresse externe d'un LoadBalancer de cluster depuis l'intérieur du cluster

Un Ingress ne peut pas s'accéder lui-même.

Impossible d'accéder au contrôleur Ingress lui-même

Impossible d'accéder aux services TCP ou UDP.

Ajout de services TCP et UDP

Problèmes d'accès HTTPS

L'Ingress sert un certificat obsolète ou par défaut.

L'Ingress continue de servir le certificat TLS par défaut ou obsolète après l'ajout ou la mise à jour d'un nouveau certificat

Une erreur RX_RECORD_TOO_LONG/wrong version number se produit.

Une erreur « SSL_ERROR_RX_RECORD_TOO_LONG » se produit lors de l'accès HTTPS

Problèmes lors de la création d'une ressource Ingress

L'erreur « failed calling webhook... » se produit.

Une erreur « failed calling webhook » se produit lors de la création d'une ressource Ingress

Un Ingress est créé mais ne prend pas effet.

Les règles Ingress ne prennent pas effet

Comportement d'accès inattendu

Impossible d'obtenir l'IP source du client.

Les pods Ingress ne conservent pas l'adresse IP source

La liste d'autorisation IP ne prend pas effet ou ne fonctionne pas comme prévu.

Impossible de se connecter à un service gRPC exposé par un Ingress.

Impossible de se connecter à un service gRPC exposé par un Ingress

La version Canary n'a aucun effet.

Les règles Canary ne prennent pas effet

Des règles Canary incorrectes acheminent mal le trafic.

Le routage du trafic ne correspond pas aux règles Canary, ou du trafic non désiré est acheminé vers le service Canary

L'erreur The plain HTTP request was sent to HTTPS port se produit.

Impossible de se connecter à un service backend HTTPS

Des erreurs telles que 502, 503, 413 ou 499 se produisent.

L'Ingress renvoie des codes d'erreur HTTP courants

Certaines ressources ne se chargent pas sur une page.

Une erreur 404 se produit lors de l'accès aux ressources avec l'annotation rewrite-target.

Échec du chargement de certaines ressources ou affichage d'un écran blanc après la réécriture vers le répertoire racine

Les requêtes de ressources renvoient net::ERR_FAILED ou net::ERR_HTTP2_SERVER_REFUSED_STREAM.

L'erreur « net::ERR_HTTP2_SERVER_REFUSED_STREAM » se produit

Méthodes de dépannage courantes

Utilisation du diagnostic Ingress

  1. Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Sur la page Clusters, cliquez sur le nom de votre cluster. Dans le volet de navigation de gauche, cliquez sur Inspections and Diagnostics > Diagnostics.

  3. Sur la page Diagnostics, cliquez sur Ingress diagnostics.

  4. Dans le panneau Ingress diagnostics, cliquez sur Diagnose, saisissez l'URL où le problème se produit, par exemple https://www.example.com. Sélectionnez I have read and agree, puis cliquez sur Start Diagnosis.

    Une fois le diagnostic terminé, résolvez le problème en fonction des résultats.

Affichage des journaux des pods contrôleur dans Log Service

Le format des journaux d'accès pour le contrôleur Ingress est défini dans une ConfigMap. Par défaut, il s'agit de la ConfigMap nginx-configuration dans le namespace kube-system.

Par défaut, le contrôleur Ingress ACK utilise le format de journal suivant :

$remote_addr - [$remote_addr] - $remote_user [$time_local]
    "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length
    $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length
    $upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name]
Important

Si vous modifiez le format des journaux, vous devez également mettre à jour les règles de collecte des journaux dans Log Service. Sinon, les journaux ne pourront pas s'afficher correctement dans la console Log Service. Soyez prudent lorsque vous modifiez le format des journaux.

Les journaux du contrôleur Ingress sont disponibles dans la console Log Service. Pour plus de détails, consultez la section Collecte des journaux de conteneurs à partir d'un cluster ACK.

Dans l'onglet Raw Logs de la console Log Service, chaque entrée de journal du contrôleur Ingress est affichée sous forme de paire clé-valeur. En plus des champs d'accès HTTP, chaque entrée de journal inclut des champs de métadonnées Kubernetes tels que _container_name_, _namespace_ et _pod_name_.

Certains noms de champs dans la console Log Service diffèrent de ceux des journaux réels. Le tableau suivant répertorie les champs et leurs descriptions.

Champ

Description

remote_addr/client_ip

L'adresse IP réelle du client.

request/(method+url+version)

Les informations de la requête, y compris la méthode de requête, l'URL et la version HTTP.

request_time

Le temps total de la requête, mesuré depuis la réception du premier octet du client jusqu'à l'envoi du dernier octet de la réponse. Cette valeur peut être affectée par des facteurs tels que les conditions réseau du client et peut ne pas représenter la vitesse de traitement réelle de la requête.

upstream_addr

L'adresse du backend upstream. Ce champ est vide si la requête n'atteint pas un backend. Si la requête est retentée sur plusieurs upstreams, leurs adresses sont répertoriées, séparées par des virgules.

upstream_status

Le code d'état HTTP renvoyé par le backend upstream. Un code d'état HTTP standard indique que la réponse provient du backend upstream. Si aucun backend n'est disponible, la valeur est 502. Si la requête est retentée sur plusieurs upstreams, leurs codes d'état sont répertoriés, séparés par des virgules (,).

upstream_response_time

Le temps de réponse du backend upstream, en secondes.

proxy_upstream_name

Le nom du backend upstream. Le format de nommage est <namespace>-<service-name>-<port>.

proxy_alternative_upstream_name

Le nom de l'upstream alternatif. Ce champ n'est pas vide si la requête est acheminée vers un upstream alternatif, tel qu'un service Canary.

Par défaut, vous pouvez également afficher les journaux d'accès récents directement dans le conteneur en exécutant la commande suivante :

kubectl logs <controller-pod-name> -n <namespace> | less

Exemple de sortie :

42.11.**.** - [42.11.**.**]--[25/Nov/2021:11:40:30 +0800]"GET / HTTP/1.1" 200 615 "_" "curl/7.64.1" 76 0.001 [default-nginx-svc-80] 172.16.254.208:80 615 0.000 200 46b79dkahflhakjhdhfkah**** 47.11.**.**[]
42.11.**.** - [42.11.**.**]--[25/Nov/2021:11:40:31 +0800]"GET / HTTP/1.1" 200 615 "_" "curl/7.64.1" 76 0.001 [default-nginx-svc-80] 172.16.254.208:80 615 0.000 200 fadgrerthflhakjhdhfkah**** 47.11.**.**[]

Vérifier les journaux d'erreurs dans le pod du contrôleur

Examinez les journaux du pod du contrôleur Ingress afin de cerner l'origine du problème. Les journaux d'erreur d'un pod de contrôleur se divisent en deux catégories :

  • Journaux d'erreur du contrôleur : ces journaux sont généralement générés lorsqu'une erreur survient dans la configuration Ingress. Exécutez la commande suivante pour filtrer les journaux d'erreur du contrôleur :

    kubectl logs <controller-pod-name> -n <namespace> | grep -E ^[WE]
    Remarque

    Au démarrage du contrôleur Ingress, plusieurs entrées de journal de type avertissement (W) peuvent apparaître. Ce comportement est normal. Par exemple, les avertissements relatifs à un kubeConfig manquant ou à une classe Ingress non spécifiée n'affectent pas le fonctionnement normal du contrôleur Ingress et peuvent être ignorés.

  • Journaux d'erreur Nginx : ces journaux sont générés lorsqu'une erreur se produit lors du traitement des requêtes. Exécutez la commande suivante pour filtrer les journaux d'erreur Nginx :

    kubectl logs <controller-pod-name> -n <namespace> | grep error

Accéder au contrôleur Ingress et aux pods backend

  1. Exécutez la commande suivante pour obtenir un shell dans le pod du contrôleur :

    kubectl exec <controller-pod-name> -n <namespace> -it -- bash
  2. Des outils tels que curl et OpenSSL sont préinstallés dans le pod. Utilisez-les pour tester la connectivité et vérifier les configurations de certificat.

    • Exécutez les commandes suivantes pour tester l'accès au backend via l'Ingress :

      # Replace your.domain.com with the domain name that you want to test.
      curl -H "Host: your.domain.com" http://127.0.0.1/ # for http
      curl --resolve your.domain.com:443:127.0.0.1 https://127.0.0.1/ # for https
    • Exécutez la commande suivante pour vérifier les informations du certificat :

      openssl s_client -servername your.domain.com -connect 127.0.0.1:443
    • Accédez au pod backend pour vérifier son comportement.

      Remarque

      Le contrôleur Ingress n'accède pas aux pods backend via l'IP de cluster du service. Il accède directement aux adresses IP des pods.

      1. Exécutez la commande suivante pour obtenir l'adresse IP du pod backend :

        kubectl get pod -n <namespace> <pod-name> -o wide

        Exemple de sortie :

        NAME                      READY    STATUS    RESTARTS   AGE    IP            NODE                        NOMINATED NODE    READINESS GATES
        nginx-dp-7f5fcc7f-****    1/1      Running   0          23h    10.71.0.146   cn-beijing.192.168.**.**    <none>            <none>

        La sortie indique que l'adresse IP du pod backend est 10.71.0.146.

      2. Exécutez la commande suivante dans le pod du contrôleur pour accéder au pod backend et confirmer que la connexion fonctionne :

        curl http://<your-pod-ip>:<port>/path

Commandes de dépannage Nginx Ingress

  • kubectl-plugin

    Le contrôleur Ingress Kubernetes officiel était initialement basé sur Nginx, mais il est passé à OpenResty à partir de la version 0.25.0. Le contrôleur surveille les modifications apportées aux ressources Ingress sur le serveur API, génère automatiquement la configuration Nginx correspondante, puis recharge Nginx pour appliquer les changements. Pour plus d'informations, consultez la documentation officielle.

    À mesure que le nombre de ressources Ingress augmente, toutes les configurations sont consolidées dans un seul fichier nginx.conf volumineux, ce qui rend le débogage difficile. Depuis la version 0.14.0, la section upstream est générée dynamiquement à l'aide de lua-resty-balancer, ce qui accroît encore la complexité du débogage. Pour résoudre ce problème, la communauté a contribué un plugin kubectl, ingress-nginx, afin de simplifier le processus de débogage des configurations ingress-nginx. Pour plus d'informations, voir kubectl-plugin.

    Exécutez la commande suivante pour récupérer les informations sur les services backend actuellement connus du contrôleur ingress-nginx :

    kubectl ingress-nginx backends -n ingress-nginx
  • Commande dbg

    Outre le plugin kubectl, vous pouvez utiliser la commande dbg pour afficher des informations et effectuer des diagnostics.

    1. Exécutez la commande suivante pour obtenir un shell dans le conteneur Nginx Ingress :

      kubectl exec -it -n kube-system <nginx-ingress-pod-name> -- bash
    2. Exécutez /dbg pour afficher une sortie similaire à la suivante :

      nginx-ingress-controller-69f46d8b7-qmt25:/$ /dbg
      dbg is a tool for quickly inspecting the state of the nginx instance
      Usage:
        dbg [command]
      Available Commands:
        backends    Inspect the dynamically-loaded backends information
        certs       Inspect dynamic SSL certificates
        completion  Generate the autocompletion script for the specified shell
        conf        Dump the contents of /etc/nginx/nginx.conf
        general     Output the general dynamic lua state
        help        Help about any command
      Flags:
        -h, --help              help for dbg
            --status-port int   Port to use for the lua HTTP endpoint configuration. (default 10246)
      Use "dbg [command] --help" for more information about a command.

    Vérifiez si un certificat existe pour un nom de domaine spécifique.

    /dbg certs get <hostname>

    Répertoriez toutes les informations des services backend.

    /dbg backends all 

Statut Nginx Ingress

Nginx fournit un endpoint de statut intégré qui affiche des statistiques d'exécution. Dans le conteneur Nginx Ingress, utilisez curl pour accéder à l'endpoint nginx_status sur le port 10246 afin de consulter les statistiques de requêtes et de connexions.

  1. Exécutez la commande suivante pour obtenir un shell dans le conteneur Nginx Ingress :

    kubectl exec -itn kube-system  <nginx-ingress-pod-name>  bash
  2. Exécutez la commande suivante pour afficher les statistiques actuelles de requêtes et de connexions pour Nginx :

    nginx-ingress-controller-79c5b4d87f-xxx:/etc/nginx$ curl localhost:10246/nginx_status
    Active connections: 12818 
    server accepts handled requests
     22717127 22717127 823821421 
    Reading: 0 Writing: 382 Waiting: 12483 

    Depuis son démarrage, Nginx a géré 22 717 127 connexions et traité 823 821 421 requêtes, soit une moyenne d'environ 36,2 requêtes par connexion.

    • Active connections : nombre total de connexions actives. Dans cet exemple, la valeur est 12 818.

    • Reading : nombre de connexions pour lesquelles Nginx lit actuellement les en-têtes de requête. Dans cet exemple, la valeur est 0.

    • Writing : nombre de connexions pour lesquelles Nginx envoie actuellement des réponses. Dans cet exemple, la valeur est 382.

    • Waiting : nombre de connexions keep-alive. Dans cet exemple, la valeur est 12 483.

Capture de paquets

Si vous ne parvenez pas à déterminer la cause d'un problème, effectuez une capture de paquets.

  1. Sur la base de vos premières constatations, déterminez si le problème réseau se situe au niveau du pod Ingress ou du pod d'application. Si vous ne disposez pas de suffisamment d'informations, vous pouvez capturer les paquets sur les deux pods.

  2. Connectez-vous au nœud qui héberge le pod d'application ou le pod Ingress concerné.

  3. Sur l'instance ECS (et non à l'intérieur d'un conteneur), exécutez la commande suivante pour capturer le trafic lié à un pod spécifique et l'enregistrer dans un fichier :

    tcpdump -i any host <Ingress-pod-IP-or-application-pod-IP> -C 20 -W 200 -w /tmp/ingress.pcap
  4. Surveillez les journaux. Lorsque l'erreur attendue se produit, arrêtez la capture de paquets.

  5. Mettez en corrélation les informations des paquets capturés avec les journaux d'erreur de l'application pour identifier précisément le problème.

    Remarque
    • Dans des conditions normales, la capture de paquets n'affecte pas vos services. Elle ajoute uniquement une charge CPU et des E/S disque mineures.

    • La commande précédente effectue une rotation des fichiers de capture. Elle peut générer un maximum de 200 fichiers .pcap de 20 Mo chacun.

Échec de l'accès intra-cluster à l'adresse de l'équilibreur de charge externe

Symptôme

Dans un cluster, les pods situés sur certains nœuds ne parviennent pas à accéder aux pods backend via l'adresse externe du contrôleur Nginx Ingress (l'adresse IP de l'instance d'équilibreur de charge), tandis que les pods situés sur d'autres nœuds y parviennent.

Cause

Ce problème est causé par le paramètre externalTrafficPolicy du service du contrôleur, qui détermine la manière dont le trafic externe est géré. Lorsqu'il est défini sur Local, seuls les pods backend situés sur le même nœud qu'un pod de contrôleur peuvent recevoir des requêtes. Lorsqu'il est défini sur Cluster, tous les pods backend sont accessibles normalement. Lorsque des ressources au sein du cluster utilisent l'adresse externe d'un service d'équilibreur de charge, les requêtes sont également traitées comme du trafic externe.

Solution

  • (Recommandé) Accédez au service depuis l'intérieur du cluster Kubernetes en utilisant son ClusterIP ou son nom de service. Le nom de service pour l'ingress est nginx-ingress-lb.kube-system.

  • Exécutez la commande kubectl edit svc nginx-ingress-lb -n kube-system pour modifier le service ingress. Modifiez la valeur externalTrafficPolicy du service d'équilibreur de charge en Cluster. Si le plugin de réseau de conteneurs du cluster est Flannel, l'adresse IP source du client est perdue. Si vous utilisez Terway, l'adresse IP source du client est conservée.

  • Pour plus d'informations sur les annotations de service, consultez Configurer Classic Load Balancer (CLB) à l'aide d'annotations.

    Exemple :

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/backend-type: eni   # Direct to ENI.
      labels:
        app: nginx-ingress-lb
      name: nginx-ingress-lb
      namespace: kube-system
    spec:
      externalTrafficPolicy: Cluster

Impossible d'accéder au contrôleur Ingress

Symptôme

Dans un cluster Flannel, lorsque vous accédez à l'Ingress depuis un pod Ingress via son nom de domaine, l'IP SLB ou le ClusterIP, certaines ou toutes les requêtes échouent.

Cause

La configuration Flannel par défaut désactive le hairpinning.

Solution

  • (Recommandé) Recréez le cluster avec le plugin réseau Terway et migrez vos charges de travail vers le nouveau cluster.

  • Si vous ne pouvez pas recréer le cluster, modifiez la configuration Flannel pour activer hairpinMode. Après avoir modifié la configuration, recréez les pods Flannel pour appliquer les changements.

    1. Exécutez la commande suivante pour modifier la configuration Flannel :

      kubectl edit cm kube-flannel-cfg -n kube-system
    2. Dans la section cni-conf.json de la sortie, ajoutez "hairpinMode": true à l'objet delegate.

      Exemple :

      cni-conf.json: |
          {
            "name": "cb0",
            "cniVersion":"0.3.1",
            "type": "flannel",
            "delegate": {
              "isDefaultGateway": true,
              "hairpinMode": true
            }
          }
    3. Exécutez la commande suivante pour supprimer les pods Flannel. Le système les recrée automatiquement avec la nouvelle configuration.

      kubectl delete pod -n kube-system -l app=flannel   

Le certificat TLS par défaut ou ancien est toujours servi

Symptôme

Après avoir ajouté ou modifié un Secret dans le cluster et spécifié le secretName dans un Ingress, les requêtes sont toujours servies avec le certificat par défaut (Kubernetes Ingress Controller Fake Certificate) ou un ancien certificat.

Cause

  • Le certificat n'est pas renvoyé par le contrôleur ingress dans le cluster.

  • Le contrôleur n'a pas chargé correctement le certificat car il est invalide.

  • Le contrôleur ingress utilise Server Name Indication (SNI) pour servir le certificat correct, mais le handshake TLS peut ne pas inclure l'extension SNI.

Solution

  • Vérifiez que le handshake TLS inclut l'extension SNI en utilisant l'une des méthodes suivantes :

    • Utilisez un navigateur moderne qui prend en charge SNI.

    • Lorsque vous testez le certificat avec la commande openssl s_client, incluez le paramètre -servername.

    • Lorsque vous utilisez curl, mappez le nom de domaine avec le paramètre --resolve ou en modifiant votre fichier hosts, plutôt que d'envoyer une requête à une adresse IP avec un en-tête Host.

  • Confirmez qu'aucun certificat TLS n'est configuré sur WAF, l'accès transparent WAF ou un écouteur de couche 7 SLB. Le certificat TLS doit être renvoyé par le contrôleur ingress dans le cluster.

  • Exécutez les diagnostics Ingress dans la console Intelligent Operations pour vérifier les problèmes de configuration et les journaux d'erreur. Pour plus d'informations, consultez Utiliser les diagnostics Ingress.

  • Exécutez la commande suivante pour vérifier manuellement les journaux d'erreur du pod Ingress et apportez des modifications en fonction des suggestions contenues dans les journaux.

    kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]

Impossible de se connecter à gRPC via Ingress

Symptôme

Vous ne pouvez pas accéder à un service gRPC via un Ingress.

Cause

  • Il manque l'annotation pour le protocole backend dans la ressource Ingress.

  • Les services gRPC nécessitent une connexion TLS lorsqu'ils sont exposés via un Ingress.

Solution

  • Ajoutez l'annotation suivante à la ressource Ingress : nginx.ingress.kubernetes.io/backend-protocol: "GRPC".

  • Assurez-vous que le client envoie du trafic chiffré sur le port TLS.

Impossible de se connecter au service HTTPS backend

Symptômes

  • Impossible d'accéder au service HTTPS situé derrière l'Ingress.

  • Les requêtes peuvent renvoyer un code d'état 400 avec le message The plain HTTP request was sent to HTTPS port.

Cause

Par défaut, le contrôleur Ingress envoie des requêtes HTTP au pod backend.

Solution

Définissez l'annotation suivante dans votre ressource Ingress : nginx.ingress.kubernetes.io/backend-protocol:"HTTPS".

Impossible de conserver l'adresse IP source dans les pods Ingress

Symptôme

L'adresse IP source du client n'est pas conservée dans le pod Ingress. L'application reçoit plutôt une adresse IP interne, telle que l'IP du nœud ou une adresse de la plage 100.XX.XX.XX.

Cause

  • La valeur externalTrafficPolicy du service qui expose l'Ingress est définie sur Cluster.

  • L'instance Server Load Balancer (SLB) est configurée comme un proxy de couche 7.

  • Un pare-feu d'applications web (WAF) ou un service WAF transparent est utilisé.

Solution

  • Si votre service a externalTrafficPolicy défini sur Cluster et est exposé par une instance SLB de couche 4 :

    Modifiez externalTrafficPolicy en Local. Cette modification peut empêcher les pods à l'intérieur du cluster d'accéder à l'Ingress via l'adresse IP SLB. Pour une solution, consultez Impossible d'accéder à l'adresse externe d'un LoadBalancer de cluster depuis l'intérieur du cluster.

  • Si vous utilisez un proxy de couche 7, tel qu'une instance SLB de couche 7, WAF ou WAF transparent, suivez ces étapes :

    1. Assurez-vous que votre proxy de couche 7 est configuré pour ajouter l'en-tête de requête X-Forwarded-For.

    2. Dans le ConfigMap du contrôleur Ingress (nginx-configuration dans le namespace kube-system par défaut), ajoutez enable-real-ip: "true".

    3. Vérifiez les journaux pour confirmer que l'adresse IP source est conservée.

  • Si votre chemin de trafic implique plusieurs étapes de transfert, telles qu'un service de proxy inverse supplémentaire devant le contrôleur Ingress, activez enable-real-ip et vérifiez la valeur du champ remote_addr dans les journaux. Cela vous aide à déterminer si le conteneur Ingress reçoit l'adresse IP source du client dans l'en-tête de requête X-Forwarded-For. Si ce n'est pas le cas, assurez-vous que l'adresse IP source est ajoutée à la requête, par exemple dans l'en-tête X-Forwarded-For, avant que la requête n'atteigne le contrôleur Ingress.

La règle Canary ne prend pas effet

Symptômes

Vous avez configuré une version Canary dans votre cluster, mais la règle Canary ne s'applique pas.

Cause

  • Lors de l'utilisation des annotations canary-*, l'annotation nginx.ingress.kubernetes.io/canary: "true" n'est pas définie.

  • Pour les versions du contrôleur Nginx Ingress antérieures à la 0.47.0, le champ Host de votre règle Ingress doit contenir le nom de domaine de votre service et ne peut pas être vide.

Solution

Un trafic inattendu est acheminé vers le service Canary

Symptôme

Vous avez configuré une règle Canary, mais le trafic n'est pas distribué comme spécifié. Il se peut également que le trafic provenant d'autres Ingress standard soit redirigé vers le service Canary.

Cause

Le contrôleur Nginx Ingress applique une règle Canary non pas à un seul Ingress, mais à tous les Ingress qui partagent le même service.

Pour plus d'informations sur ce comportement, consultez la page Un Ingress avec une règle Canary affecte tous les Ingress partageant le même service.

Solution

Pour activer une version Canary pour un Ingress (y compris ceux utilisant la correspondance de service et les annotations connexes canary-*), créez des services dédiés (un service stable et un service Canary) pointant vers les pods existants. Activez ensuite la règle Canary sur cet Ingress spécifique. Pour plus d'informations, consultez la rubrique Mettre en œuvre des versions Canary et des déploiements bleu-vert à l'aide de Nginx Ingress.

Erreur lors de la création d'un Ingress : « failed calling webhook »

Symptômes

Lorsque vous créez une ressource Ingress, vous recevez une erreur « Internal error occurred: failed calling webhook... ».

Le code d'erreur complet est APISERVER_500. Le message détaillé est Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.kube-system.svc:443/networking/v1beta1/ingresses?timeout=10s: context deadline exceeded. L'expression « context deadline exceeded » indique la cause racine : un délai d'expiration de l'appel webhook.

Cause

Lors de la création d'une ressource Ingress, un Service — par défaut, ingress-nginx-controller-admission — doit valider sa configuration. Si un composant de la chaîne d'appel est indisponible (par exemple, si le Service ou le contrôleur Ingress est supprimé), la validation échoue et le serveur API rejette la ressource Ingress.

Solution

  • Vérifiez la chaîne d'appel du webhook pour vous assurer que toutes les ressources requises fonctionnent correctement. La chaîne est la suivante : ValidatingWebhookConfiguration → Service → Pod.

  • Vérifiez que le Pod du contrôleur Ingress dispose de la fonctionnalité d'admission activée et qu'il est accessible depuis l'extérieur.

  • Si le contrôleur Ingress est supprimé ou si vous n'avez pas besoin de la fonctionnalité webhook, supprimez la ressource ValidatingWebhookConfiguration.

Erreur SSL_ERROR_RX_RECORD_TOO_LONG lors de l'accès HTTPS

Symptôme

Vous recevez une erreur lors de l'accès HTTPS : SSL_ERROR_RX_RECORD_TOO_LONG ou routines:CONNECT_CR_SRVR_HELLO:wrong version number.

Cause

La requête HTTPS est envoyée vers un port non HTTPS, tel qu'un port HTTP.

Les causes courantes incluent :

  • Le port 443 sur le SLB est mappé au port 80 sur le Pod Ingress.

  • Le port 443 dans le Service du contrôleur Ingress est mappé au port 80 sur le Pod Ingress.

Solution

Modifiez les paramètres du SLB ou du Service pour acheminer le trafic HTTPS vers le port correct.

Codes d'erreur HTTP courants

Symptôme

Les requêtes renvoient des erreurs autres que 2xx ou 3xx, telles que 502, 503, 413 ou 499.

Causes et solutions

Examinez le journal d'accès pour déterminer si l'erreur est renvoyée par le contrôleur Ingress. Pour plus d'informations, consultez la rubrique Utiliser Log Service pour afficher les journaux d'accès d'un contrôleur NGINX Ingress. Si c'est le cas, appliquez les solutions suivantes :

  • Erreur 413

    • Cause : Le contrôleur Nginx Ingress fonctionne correctement, mais la taille des données de la requête dépasse la limite autorisée.

    • Solution : Exécutez kubectl edit cm -n kube-system nginx-configuration pour modifier la configuration du contrôleur. Ajustez les valeurs de nginx.ingress.kubernetes.io/client-max-body-size et nginx.ingress.kubernetes.io/proxy-body-size selon vos besoins (valeur par défaut : 20m).

  • Erreur 499

    • Cause : Le client s'est déconnecté prématurément. Cela n'indique pas nécessairement un problème avec le composant ou le service backend.

    • Solution :

      • Un petit nombre d'erreurs 499 peut être normal et ignoré, selon votre application.

      • Si un grand nombre d'erreurs 499 se produit, vérifiez si le temps de traitement de votre service backend et le délai d'expiration des requêtes côté client sont configurés comme prévu.

  • Erreur 502

    • Cause : Le contrôleur Nginx Ingress fonctionne correctement, mais le Pod du contrôleur ne peut pas se connecter au Pod backend cible.

    • Solution :

      • Si l'erreur se produit systématiquement :

        • Des configurations incorrectes pour le Service backend ou les pods peuvent provoquer cette erreur. Vérifiez la configuration du port du Service backend et le code de l'application dans le conteneur.

      • Si l'erreur se produit de manière intermittente :

        • Une charge élevée sur le Pod du contrôleur Nginx Ingress peut provoquer cette erreur. Vous pouvez évaluer la charge en vérifiant le nombre de requêtes et de connexions sur l'instance d'équilibreur de charge associée au contrôleur. Consultez la rubrique Configurer un contrôleur NGINX Ingress pour les scénarios à forte charge afin d'allouer plus de ressources au contrôleur.

        • Cette erreur peut survenir si le Pod backend ferme activement la session. Le contrôleur Nginx Ingress active les connexions persistantes par défaut. Assurez-vous que le délai d'inactivité pour les connexions persistantes du backend est supérieur au délai d'inactivité du contrôleur (par défaut : 900 secondes).

      • Si vous ne parvenez pas à identifier le problème à l'aide des méthodes précédentes, effectuez une capture de paquets pour analyse.

  • Erreur 503

    • Cause : Le contrôleur Ingress ne trouve aucun Pod backend ou tous les Pods backend sont inaccessibles.

    • Solution :

      • Si l'erreur se produit de manière intermittente :

        • Consultez les solutions pour l'erreur 502.

        • Vérifiez l'état de readiness du service backend et configurez des contrôles d'intégrité appropriés.

      • Si l'erreur se produit systématiquement :

        Vérifiez si le Service backend est correctement configuré et s'il possède un endpoint.

L'erreur net::ERR_HTTP2_SERVER_REFUSED_STREAM

Symptômes

Certaines ressources ne parviennent pas à se charger et la console de développement du navigateur affiche l'erreur net::ERR_HTTP2_SERVER_REFUSED_STREAM ou net::ERR_FAILED.

Cause

Le nombre de requêtes de ressources simultanées dépasse la limite maximale de flux pour une connexion HTTP/2.

Solution

  • (Recommandé) Dans le ConfigMap, augmentez la valeur de http2-max-concurrent-streams (par défaut : 128) à une valeur adaptée à votre charge de travail. Pour plus de détails, consultez la page http2-max-concurrent-streams.

  • Sinon, désactivez la prise en charge d'HTTP/2 dans le ConfigMap en définissant use-http2 sur false. Pour plus de détails, consultez la page use-http2.

Erreur : « The param of ServerGroupName is illegal »

Cause

ServerGroupName utilise le format namespace+svcName+port. Un nom de groupe de serveurs doit comporter entre 2 et 128 caractères, commencer par une lettre ou un caractère chinois, et peut contenir des chiffres, des points (.), des traits de soulignement (_) et des tirets (-).

Solution

Modifiez le nom du groupe de serveurs pour qu'il respecte les exigences de nommage.

Erreur de création d'Ingress : « certificate signed by unknown authority »

Lorsque vous créez un Ingress, le cluster renvoie une erreur avec le code APISERVER_500 et le message suivant : Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.kube-system.svc:443/networking/v1beta1/ingresses?timeout=10s: x509: certificate signed by unknown authority.

Cause

Cette erreur se produit si plusieurs déploiements Ingress dans votre cluster partagent des ressources telles que des Secrets, des services ou des configurations Webhook. Ce chevauchement de ressources provoque une incompatibilité de certificat SSL lorsque le Webhook d'admission communique avec son service backend, entraînant un échec de validation.

Solution

Redéployez vos Ingress et assurez-vous que chaque déploiement utilise un ensemble unique de ressources. Pour plus d'informations sur les ressources d'un déploiement Ingress, consultez la rubrique Quelles mises à jour sont effectuées lors de la mise à niveau du contrôleur Nginx Ingress dans la gestion des composants ACK ?.

Redémarrage du Pod Ingress dû à l'échec des contrôles d'intégrité

Symptôme

L'échec des contrôles d'intégrité entraîne le redémarrage du Pod du contrôleur.

Cause

  • Les contrôles d'intégrité peuvent échouer si le Pod Ingress ou son nœud subit une charge élevée.

  • Les contrôles d'intégrité peuvent échouer si le paramètre de noyau tcp_tw_reuse ou tcp_timestamps est défini sur les nœuds du cluster.

Solution

  • Augmentez le nombre de Pods Ingress (scale out) et vérifiez que le problème est résolu. Pour plus de détails, consultez la rubrique Déploiement du contrôleur Nginx Ingress pour une haute disponibilité.

  • Désactivez le paramètre de noyau tcp_tw_reuse ou définissez-le sur 2, et désactivez le paramètre de noyau tcp_timestamps. Vérifiez ensuite que le problème est résolu.

Ajouter des services TCP et UDP

  1. Ajoutez une entrée au ConfigMap tcp-services ou udp-services. Par défaut, ces ConfigMaps se trouvent dans le namespace ingress-nginx.

    Par exemple, pour mapper le port externe 9000 au port 8080 du service example-go dans le namespace default :

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tcp-services
      namespace: ingress-nginx
    data:
      9000: "default/example-go:8080"  # Maps port 9000 to port 8080 of the service.
  2. Ajoutez le port mappé à la définition du conteneur dans le déploiement Ingress. Par défaut, il s'agit du déploiement nginx-ingress-controller dans le namespace ingress-nginx.

  3. Ajoutez le port mappé au Service qui expose le contrôleur Ingress.

    Exemple de code

    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      type: LoadBalancer
      ports:
        - name: http
          port: 80
          targetPort: 80
          protocol: TCP
        - name: https
          port: 443
          targetPort: 443
          protocol: TCP
        - name: proxied-tcp-9000
          port: 9000
          targetPort: 9000
          protocol: TCP
      selector:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx

    Pour plus d'informations, consultez la page Exposing TCP and UDP services.

Les règles Ingress ne prennent pas effet

Symptôme

Vous ajoutez ou modifiez une règle Ingress, mais elle ne prend pas effet.

Causes possibles

  • Une erreur dans la configuration Ingress empêche le chargement correct de la nouvelle règle Ingress.

  • La ressource Ingress est mal configurée.

  • Le contrôleur Ingress ne dispose pas des permissions requises pour surveiller les modifications des ressources Ingress.

  • Un Ingress existant utilise server-alias pour un nom de domaine, ce qui entre en conflit avec le nouvel Ingress et entraîne l'ignorance de la règle.

Solutions

  • Utilisez l'outil de diagnostic Ingress dans la console Intelligent O&M pour diagnostiquer le problème et suivez les instructions affichées à l'écran. Pour plus d'informations, consultez la rubrique Utiliser la fonctionnalité de diagnostic Ingress.

  • Vérifiez les ressources Ingress existantes pour détecter des erreurs de configuration ou des conflits :

    • Si vous utilisez une expression régulière dans un chemin qui ne possède pas l'annotation rewrite-target, assurez-vous que l'annotation nginx.ingress.kubernetes.io/use-regex: "true" est configurée.

    • Vérifiez que PathType est défini comme prévu. Par défaut, ImplementationSpecific fonctionne de manière identique à Prefix.

  • Assurez-vous que ClusterRole, ClusterRoleBinding, Role, RoleBinding et ServiceAccount associés au contrôleur Ingress existent. Par défaut, ils sont tous nommés ingress-nginx.

  • Accédez au conteneur du pod du contrôleur et inspectez les règles ajoutées dans le fichier nginx.conf.

  • Exécutez la commande suivante pour vérifier manuellement les journaux du conteneur et identifier le problème.

    kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]

La réécriture de chemin entraîne un échec de chargement ou un écran blanc

Symptôme

Après avoir utilisé l'annotation Ingress rewrite-target pour réécrire un chemin d'accès, certaines ressources ne parviennent pas à se charger ou un écran blanc apparaît.

Cause

  • L'annotation rewrite-target n'est pas configurée avec une expression régulière.

  • L'application utilise des chemins absolus codés en dur pour demander des ressources.

Solution

  • Configurez l'annotation rewrite-target avec une expression régulière et un groupe de capture. Pour plus d'informations, consultez la page Rewrite.

  • Vérifiez que les requêtes frontend utilisent le chemin correct.

Corriger l'analyse des journaux SLS après une mise à niveau

Symptôme

Le composant ingress-nginx-controller existe en deux versions principales : 0,20 et 0,30. Après avoir mis à niveau le composant de la version 0.20 à la 0.30 à l'aide de Add-ons dans la console, le tableau de bord Ingress affiche incorrectement les informations de trafic pour le service backend lorsque vous utilisez une version Canary ou un déploiement bleu-vert.

Cause

Les versions 0.20 et 0.30 utilisent des formats de journal par défaut différents. Par conséquent, le tableau de bord Ingress analyse incorrectement les journaux lorsque vous utilisez une version Canary ou un déploiement bleu-vert.

Solution

Pour résoudre ce problème, mettez à jour le nginx-configuration configmap et la configuration k8s-nginx-ingress.

  1. Mettez à jour le nginx-configuration configmap.

    • Si vous n'avez pas modifié le nginx-configuration configmap, enregistrez le contenu suivant sous le nom nginx-configuration.yaml et exécutez kubectl apply -f nginx-configuration.yaml.

      apiVersion: v1
      kind: ConfigMap
      data:
        allow-backend-server-header: "true"
        enable-underscores-in-headers: "true"
        generate-request-id: "true"
        ignore-invalid-headers: "true"
        log-format-upstream: $remote_addr - [$remote_addr] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name]
        max-worker-connections: "65536"
        proxy-body-size: 20m
        proxy-connect-timeout: "10"
        reuse-port: "true"
        server-tokens: "false"
        ssl-redirect: "false"
        upstream-keepalive-timeout: "900"
        worker-cpu-affinity: auto
      metadata:
        labels:
          app: ingress-nginx
        name: nginx-configuration
        namespace: kube-system
    • Si vous avez modifié le nginx-configuration configmap, exécutez la commande suivante pour corriger le problème sans écraser votre configuration :

      kubectl edit configmap nginx-configuration -n kube-system

    À la fin du champ log-format-upstream, ajoutez [$proxy_alternative_upstream_name], puis enregistrez et quittez.

  2. Mettez à jour la configuration k8s-nginx-ingress.

    Enregistrez le contenu suivant dans un fichier nommé k8s-nginx-ingress.yaml, puis exécutez la commande kubectl apply -f k8s-nginx-ingress.yaml pour appliquer la configuration.

    Contenu YAML

    apiVersion: log.alibabacloud.com/v1alpha1
    kind: AliyunLogConfig
    metadata:
      namespace: kube-system
      # your config name, must be unique in you k8s cluster
      name: k8s-nginx-ingress
    spec:
      # logstore name to upload log
      logstore: nginx-ingress
      # product code, only for k8s nginx ingress
      productCode: k8s-nginx-ingress
      # logtail config detail
      logtailConfig:
        inputType: plugin
        # logtail config name, should be same with [metadata.name]
        configName: k8s-nginx-ingress
        inputDetail:
          plugin:
            inputs:
            - type: service_docker_stdout
              detail:
                IncludeLabel:
                  io.kubernetes.container.name: nginx-ingress-controller
                Stderr: false
                Stdout: true
            processors:
            - type: processor_regex
              detail:
                KeepSource: false
                Keys:
                - client_ip
                - x_forward_for
                - remote_user
                - time
                - method
                - url
                - version
                - status
                - body_bytes_sent
                - http_referer
                - http_user_agent
                - request_length
                - request_time
                - proxy_upstream_name
                - upstream_addr
                - upstream_response_length
                - upstream_response_time
                - upstream_status
                - req_id
                - host
                - proxy_alternative_upstream_name
                NoKeyError: true
                NoMatchError: true
                Regex: ^(\S+)\s-\s\[([^]]+)]\s-\s(\S+)\s\[(\S+)\s\S+\s"(\w+)\s(\S+)\s([^"]+)"\s(\d+)\s(\d+)\s"([^"]*)"\s"([^"]*)"\s(\S+)\s(\S+)+\s\[([^]]*)]\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s*(\S*)\s*\[*([^]]*)\]*.*
                SourceKey: content

Erreur : « cannot list/get/update resource »

Symptôme

Lorsque vous vérifiez les erreurs dans un pod du contrôleur comme décrit dans la section Vérification des journaux d'erreurs dans un pod de contrôleur, vous pouvez rencontrer un journal d'erreur similaire à celui-ci :

User "system:serviceaccount:kube-system:ingress-nginx" cannot list/get/update resource "xxx" in API group "xxx" at the cluster scope/ in the namespace "kube-system"

Cause

Le Nginx Ingress Controller ne dispose pas des permissions nécessaires pour mettre à jour les ressources concernées.

Solution

  • Examinez le journal pour déterminer si le problème provient d'un ClusterRole ou d'un Role.

    • Si le journal contient l'expression at the cluster scope, le problème est causé par le ClusterRole (ingress-nginx).

    • Si le journal contient l'expression in the namespace "kube-system", cela indique que le problème est causé par le Role (kube-system/ingress-nginx).

  • Vérifiez que les permissions et les liaisons requises existent bien.

    • Pour un ClusterRole :

      • Assurez-vous que le ClusterRole ingress-nginx et le ClusterRoleBinding ingress-nginx existent. S'ils n'existent pas, créez-les, restaurez-les à partir d'une sauvegarde ou désinstallez et réinstallez le composant.

      • Vérifiez que le ClusterRole ingress-nginx inclut la permission indiquée dans le journal (dans l'exemple ci-dessous, la permission de list la ressource ingresses dans le groupe d'API networking.k8s.io). Si la permission est manquante, ajoutez-la manuellement au ClusterRole.

        E0629 17:26:22.916137       8 reflector.go:138] k8s.io/client-go@v0.23.6/tools/cache/reflector.go:167: Failed to watch *v1.Ingress: failed to list *v1.Ingress: ingresses.networking.k8s.io is forbidden: User "system:serviceaccount:kube-system:ingress-nginx" cannot list resource "ingresses" in API group "networking.k8s.io" at the cluster scope
    • Pour un Role :

      • Assurez-vous que le Role kube-system/ingress-nginx et le RoleBinding kube-system/ingress-nginx existent. S'ils n'existent pas, créez-les, restaurez-les à partir d'une sauvegarde ou désinstallez et réinstallez le composant.

      • Vérifiez que le Role ingress-nginx inclut la permission indiquée dans le journal (dans l'exemple ci-dessous, la permission update pour la ConfigMap ingress-controller-leader-nginx). Si la permission est manquante, ajoutez-la manuellement au Role.

        E0629 17:07:09.111640       9 leaderelection.go:367] Failed to update lock: configmaps "ingress-controller-leader-nginx" is forbidden: User "system:serviceaccount:kube-system:ingress-nginx" cannot update resource "configmaps" in API group "" in the namespace "kube-system"

Échec du test du fichier de configuration

Symptôme

Lorsque vous consultez les journaux du contrôleur dans le pod comme décrit dans la section Vérification des journaux d'erreurs dans un pod de contrôleur, vous pouvez trouver un journal d'erreur semblable au suivant :

requeuing……nginx: configuration file xxx test failed (multiple lines)

Cause

Une erreur de configuration empêche Nginx de recharger sa configuration. La cause est généralement une erreur de syntaxe dans une règle ingress ou dans un extrait de code injecté dans la ConfigMap.

Solution

  • Analysez les messages d'erreur dans les journaux pour identifier le problème. Vous pouvez ignorer les messages de niveau warn. Si un message d'erreur n'est pas clair, utilisez le nom de fichier et le numéro de ligne indiqués dans le journal pour inspecter le fichier dans le pod. Par exemple, le journal suivant montre une erreur dans le fichier /tmp/nginx/nginx-cfg2825306115 à la ligne 449.

    E0629 19:54:09.340338       8 queue.go:130] "requeuing" err=<
    -----------------------------------------------------------------------
          Error: exit status 1
          2022/06/29 19:54:09 [warn] 179#179: the "http2_max_field_size" directive is obsolete, use the "large_client_header_buffers" directive instead in /tmp/nginx/nginx-cfg2825306115:146
            nginx: [warn] the "http2_max_field_size" directive is obsolete, use the "large_client_header_buffers" directive instead in /tmp/nginx/nginx-cfg2825306115:146
          2022/06/29 19:54:09 [warn] 179#179: the "http2_max_header_size" directive is obsolete, use the "large_client_header_buffers" directive instead in /tmp/nginx/nginx-cfg2825306115:147
            nginx: [warn] the "http2_max_header_size" directive is obsolete, use the "large_client_header_buffers" directive instead in /tmp/nginx/nginx-cfg2825306115:147
          2022/06/29 19:54:09 [warn] 179#179: the "http2_max_requests" directive is obsolete, use the "keepalive_requests" directive instead in /tmp/nginx/nginx-cfg2825306115:148
            nginx: [warn] the "http2_max_requests" directive is obsolete, use the "keepalive_requests" directive instead in /tmp/nginx/nginx-cfg2825306115:148
          2022/06/29 19:54:09 [emerg] 179#179: unexpected "}" in /tmp/nginx/nginx-cfg2825306115:449
            nginx: [emerg] unexpected "}" in /tmp/nginx/nginx-cfg2825306115:449
          nginx: configuration file /tmp/nginx/nginx-cfg2825306115 test failed

    Exécutez les commandes suivantes pour vérifier la configuration autour de la ligne spécifiée et détecter les erreurs.

    # Log in to the pod.
    kubectl exec -n <namespace> <controller pod name> -it -- bash
    # View the file with line numbers to inspect the configuration around the error.
    cat -n /tmp/nginx/nginx-cfg2825306115
  • Utilisez le message d'erreur et le fichier de configuration pour identifier et corriger la mauvaise configuration.

Erreur : « Unexpected error validating SSL certificate »

Symptôme

Lorsque vous consultez les journaux du pod Controller comme décrit dans la section Vérification des journaux d'erreurs dans un pod de contrôleur, vous pouvez trouver des journaux d'erreur du contrôleur similaires aux suivants :

Unexpected error validating SSL certificate "xxx" for server "xxx"
W0629 20:39:10.993206    7 controller.go:1364] Unexpected error validating SSL certificate "default/tls-secret" for server "test.example.com": x509: certificate is not valid for any names, but wanted to match test.example.com
W0629 20:39:10.993238    7 controller.go:1365] Validating certificate against DNS names. This will be deprecated in a future version
W0629 20:39:10.993252    7 controller.go:1370] SSL certificate "default/tls-secret" does not contain a Common Name or Subject Alternative Name for server "test.example.com": x509: certificate is not valid for any names, but wanted to match test.example.com

Cause

Cette erreur est due à une mauvaise configuration du certificate. Une cause fréquente est une inadéquation entre les domain name configurés dans la ressource ingress et les domain name inclus dans le certificate. Certains journaux de niveau avertissement, tels qu'un subject alternative name manquant, peuvent ne pas affecter le fonctionnement du certificate. Déterminez si cela constitue un problème réel pour votre cas d'utilisation.

Solution

Utilisez le message d'erreur pour vérifier les problèmes suivants liés au certificate dans votre cluster.

  • Vérifiez que le format et le contenu du fichier de certificate (.crt) et du fichier de clé privée (.key) sont corrects.

  • Assurez-vous que les domain name du certificate, tels que le common name ou un subject alternative name, correspondent au domain name configuré dans la ressource ingress.

  • Vérifiez si le certificate a expiré.

Fichiers de configuration résiduels dans le contrôleur

Symptôme

Les versions du Nginx Ingress Controller antérieures à la 1,10 présentent un bogue connu. Normalement, le contrôleur nettoie rapidement les fichiers nginx-cfg générés. Toutefois, si une erreur dans une configuration Ingress invalide le fichier nginx.conf rendu, le contrôleur ne parvient pas à supprimer ces fichiers de configuration défectueux. Cette accumulation progressive de fichiers nginx-cfgxxx consomme un espace disque important.

1.6M	nginx-cfg1093913015
1.6M	nginx-cfg1093943092
1.6M	nginx-cfg1093985057
1.6M	nginx-cfg1093989258
1.6M	nginx-cfg1094101515
1.6M	nginx-cfg1094200269
1.6M	nginx-cfg1094291268
1.6M	nginx-cfg1094298834
1.6M	nginx-cfg1094398542
0	nginx-cfg1094455202
1.6M	nginx-cfg1094500903
1.6M	nginx-cfg1094513787
1.6M	nginx-cfg1094539327
1.6M	nginx-cfg1094651267
0	nginx-cfg1094749495
0	nginx-cfg1094766605
1.6M	nginx-cfg1094774347
1.6M	nginx-cfg1094799028
1.6M	nginx-cfg109483858
1.6M	nginx-cfg1094903817
1.6M	...

Cause

Ce problème est dû à un défaut dans la logique de nettoyage. Le mécanisme de nettoyage supprime les fichiers de configuration générés correctement, mais échoue à supprimer les fichiers invalides, qui restent ainsi sur le système. Pour plus de détails, consultez le problème GitHub #11568 de la communauté.

Solution

Pour résoudre ce problème, appliquez l'une des solutions suivantes.

  • Mettez à niveau le Nginx Ingress Controller vers la version 1.10 ou ultérieure. Pour plus de détails, consultez la section Mise à niveau des composants Nginx Ingress Controller.

  • Supprimez périodiquement les fichiers nginx-cfgxxx résiduels. Vous pouvez écrire un script pour automatiser ce processus et réduire les efforts manuels.

  • Validez les nouvelles configurations Ingress avant de les appliquer afin d'éviter la génération de fichiers de configuration invalides.

Pods bloqués en état Pending après la mise à niveau du contrôleur

Symptôme

Lors de la mise à niveau du Nginx Ingress Controller, il se peut que les pods ne puissent pas être planifiés et restent en état Pending pendant une longue période.

Cause

Pendant la mise à niveau du Nginx Ingress Controller, les règles d'affinité de nœud et d'anti-affinité de pod par défaut peuvent empêcher la planification des nouveaux pods. Vous devez vous assurer que le cluster dispose de ressources disponibles suffisantes.

Exécutez les commandes suivantes pour investiguer la cause racine :

kubectl -n kube-system describe pod <pending-pod-name>
kubectl -n kube-system get events

Solution

Essayez l'une des solutions suivantes.

  • Augmentez les ressources du cluster : ajoutez de nouveaux nœuds pour répondre aux exigences d'affinité. Pour plus d'informations, consultez la section Mise à l'échelle manuelle d'un pool de nœuds.

  • Ajustez l'affinité : si les ressources sont limitées, assouplissez l'exigence d'anti-affinité de pod en exécutant la commande kubectl edit deploy nginx-ingress-controller -n kube-system. Cela permet de planifier les pods sur le même nœud, mais cette approche peut réduire la haute disponibilité.

    Exemple de configuration

          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:   ## Replace with preferredDuringSchedulingIgnoredDuringExecution.
                - labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - ingress-nginx
                  topologyKey: "kubernetes.io/hostname"
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  # virtual nodes have this label
                  - key: type
                    operator: NotIn
                    values:
                    - virtual-kubelet
              preferredDuringSchedulingIgnoredDuringExecution:
              - preference:
                  matchExpressions:
                  # autoscaled nodes have this label
                  - key: k8s.aliyun.com
                    operator: NotIn
                    values:
                    - "true"
                weight: 100

Confusion de flux TCP avec plusieurs CLB pour Nginx Ingress

Symptômes

Dans un cluster Container Service for Kubernetes (ACK) utilisant le CNI Flannel et le mode réseau IPVS, une confusion de flux TCP peut survenir sous forte concurrence si le Nginx Ingress Controller est lié à plusieurs Classic Load Balancers (CLB). Les captures de paquets peuvent révéler les anomalies suivantes.

  • Retransmission de paquets

  • Réinitialisation de connexion TCP

Dans les captures de paquets du ingress pod, le filtrage par TCP stream dans Wireshark révèle des retransmissions de paquets et des signaux de réinitialisation. Voici un exemple de sortie d'analyse de protocole :

Filter: tcp.stream eq 7517
Frame 197967: 2582 bytes on wire (20656 bits), 2582 bytes captured (20656 bits)
Ethernet II, Src: 66:4b:c1:20:9a:0a (66:4b:c1:20:9a:0a), Dst: d6:79:26:1b:14:4d (d6:79:26:1b:14:4d)
Internet Protocol Version 4, Src: 172.30.3.183, Dst: xxx
Transmission Control Protocol, Src Port: 80, Dst Port: 1458, Seq: 1284522488, Ack: 173965101, Len: 2516
Selected packet (Frame 197967):
Src: 172.30.3.183 -> Dst: xxx
TCP Seq: 2516
Sequence number: 1284522488
Acknowledgement: 173965101
Timestamp value: 1789595929
Hex dump (partial):
0000  d6 79 26 1b 14 4d 66 4b  c1 20 9a 0a 08 45 b0
0010  ...
Info column shows multiple entries including:
[ACK] Seq=xxx Ack=xxx
[TCP Window Full]
[TCP Retransmission]
[RST]

Cause

Dans un cluster ACK configuré avec le plugin réseau Flannel, les CLB transfèrent le trafic vers le NodePort sur le node où s'exécute le Nginx Ingress Controller. Cependant, lorsque plusieurs Services utilisent différents NodePorts, des conflits de session peuvent survenir dans IPVS sous forte concurrence.

Solution

  • Utilisez un seul équilibreur de charge : créez un seul LoadBalancer Service pour le Nginx Ingress Controller. Liez manuellement les autres CLB au NodePort du nœud pour réduire la probabilité de conflits.

  • Évitez les NodePorts actifs multiples : sur un seul node, évitez d'avoir plusieurs NodePorts actifs simultanément pour réduire le risque de conflits de session IPVS.