L'Ingress Kubernetes constitue la passerelle principale pour le trafic externe entrant dans un cluster, ce qui en fait un composant critique pour la disponibilité des applications. Lorsqu'un Ingress échoue, les symptômes vont des erreurs 502 Bad Gateway et des échecs de négociation TLS à l'indisponibilité complète du service. Ce guide propose une approche structurée et consciente des versions pour diagnostiquer et résoudre les problèmes de réseau Ingress, en se concentrant sur le contrôleur NGINX Ingress Controller comme implémentation la plus largement déployée. Le flux de travail met l'accent sur l'observation avant l'intervention, les changements à rayon d'impact minimal et la vérification à chaque étape.
Inventaire des versions et de l'environnement
Un dépannage efficace commence par un inventaire précis des composants en cours d'exécution. Le comportement de l'Ingress varie considérablement entre les versions de Kubernetes, les versions du contrôleur Ingress et l'intégration avec l'équilibreur de charge du fournisseur cloud sous-jacent.
Vérifications des versions principales Exécutez les commandes suivantes pour établir une base de référence. Enregistrez la sortie et les horodatages avant d'apporter des modifications.
# Version du plan de contrôle Kubernetes
kubectl version --short
# Image et version du contrôleur Ingress (ajuster l'espace de noms/le label selon les besoins)
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
# Statut IngressClass et contrôleur par défaut
kubectl get ingressclass
Connaissance de la matrice de compatibilité
- Kubernetes 1.19+ : l'API Ingress
networking.k8s.io/v1est stable. Les anciennes versionsextensions/v1beta1etnetworking.k8s.io/v1beta1sont supprimées. - NGINX Ingress Controller v1.0+ : nécessite Kubernetes 1.19+. Abandonne la prise en charge des API v1beta1.
- Équilibreurs de charge cloud : AWS ALB, Google Cloud External HTTP(S) LB et Azure Application Gateway ont chacun des exigences d'annotation et des comportements de vérification de santé spécifiques qui diffèrent du contrôleur NGINX.
Vérification des prérequis Confirmez que le pod du contrôleur Ingress est Running et Ready. Vérifiez ses journaux pour les erreurs de démarrage :
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=100
Recherchez les messages concernant le chargement des certificats TLS, les échecs de rechargement de configuration ou les erreurs du webhook d'admission. Vérifiez que le contrôleur dispose des permissions RBAC pour surveiller les ressources Ingress, Service, Secret et Endpoint dans les espaces de noms cibles.
Chemin de configuration sécurisé
Les modifications de configuration des ressources Ingress, des secrets TLS ou des ConfigMaps du contrôleur doivent suivre un processus de validation par étapes. N'éditez jamais un Ingress de production directement sans plan de retour arrière.
1. Valider les manifestes localement Utilisez kubectl apply --dry-run=client -f <manifeste.yaml> pour détecter les erreurs de syntaxe et les versions d'API obsolètes. Pour une validation structurelle contre le schéma Kubernetes, utilisez kubeval ou kubectl apply --server-dry-run (nécessite v1.18+).
2. Inspecter la configuration NGINX générée Le contrôleur traduit les règles Ingress en un nginx.conf. Avant d'appliquer des modifications, inspectez la configuration actuelle en cours d'exécution pour comprendre la base de référence :
# Obtenir le nom du pod du contrôleur
POD=$(kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o jsonpath='{.items[0].metadata.name}')
# Extraire le nginx.conf actif
kubectl exec -n ingress-nginx $POD -- cat /etc/nginx/nginx.conf > current_nginx.conf
Recherchez dans ce fichier vos définitions d'upstream, les directives server_name et les paramètres SSL. Cela révèle comment les annotations correspondent aux directives NGINX réelles.
3. Utiliser des déploiements Canary ou Preview Pour les changements importants (par exemple, changer ingressClassName, modifier la réécriture de chemin, activer le TLS mutuel), déployez une ressource Ingress parallèle avec un nom d'hôte distinct (par exemple, canary.example.com) pointant vers le même Service backend. Validez le flux de trafic en utilisant kubectl port-forward vers le pod du contrôleur :
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller 8080:80
curl -H "Host: canary.example.com" http://localhost:8080
Ne promouvez le changement vers le nom d'hôte principal qu'après avoir vérifié les journaux, les métriques et la santé du backend.
4. Les modifications de ConfigMap nécessitent un rechargement du contrôleur Les modifications du ConfigMap ingress-nginx-controller (par exemple, proxy-body-size, use-forwarded-headers, ssl-protocols) déclenchent un rechargement dynamique. Vérifiez que le rechargement a réussi :
kubectl logs -n ingress-nginx $POD | grep -i "reloading\|configuration changed"
Un rechargement échoué laisse la configuration précédente active. Consultez les journaux d'erreur du contrôleur pour les erreurs de syntaxe dans les extraits personnalisés.
Vérification et diagnostics
Lorsqu'un Ingress renvoie des erreurs, isolez la couche de défaillance : résolution DNS, vérifications de santé de l'équilibreur de charge, routage du contrôleur, connectivité Service/Endpoint ou disponibilité des Pods.
Couche 1 : DNS et équilibreur de charge externe
- Vérifiez que le nom d'hôte résout vers les bonnes IP de l'équilibreur de charge :
dig +short example.com. - Vérifiez les vérifications de santé de l'équilibreur de charge du fournisseur cloud. Sur AWS, assurez-vous que le Target Group affiche les cibles comme
healthy. Sur GCP, vérifiez que la vérification de santé du Backend Service passe. Le chemin de vérification de santé du LB prend souvent par défaut/; assurez-vous que votre backend répond 200 sur ce chemin ou configurez l'annotation Ingressnginx.ingress.kubernetes.io/health-check-path: /healthz.
Couche 2 : Accessibilité du contrôleur Ingress Faites un port-forward directement vers le Service du contrôleur en contournant le LB cloud :
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller 8080:80 4433:443
curl -vk -H "Host: example.com" https://localhost:4433
- 200 OK : Le routage du contrôleur fonctionne ; le problème est en amont (LB, DNS, pare-feu).
- 404 Not Found : Aucune règle Ingress correspondante. Vérifiez que
spec.rules[].hostetspec.rules[].http.paths[].pathcorrespondent à la requête. La correspondance de chemin est basée sur le préfixe par défaut ; utilisezpathType: ExactouImplementationSpecificavec des annotations regex pour une correspondance précise. - 502/503/504 : Le contrôleur ne peut pas atteindre le backend. Passez à la Couche 3.
Couche 3 : Connectivité Service et Endpoint Vérifiez que le Service référencé par l'Ingress existe et possède des Endpoints :
kubectl get svc -n <namespace> <nom-service> -o yaml
kubectl get endpoints -n <namespace> <nom-service>
- Aucun Endpoint : Les Pods ne correspondent pas au
selectordu Service, les Pods ne sont pasReady, ou les Pods sont enCrashLoopBackOff. Vérifiezkubectl get pods -n <namespace> -l <selector> -o wide. - Endpoints existent mais 502 persiste : Politique réseau bloquant le trafic, incompatibilité de
targetPort(leservicePortde l'Ingress doit correspondre auportdu Service, qui cible letargetPortdu Pod), ou l'application du Pod n'écoute pas sur l'interface attendue (doit lier0.0.0.0, pas127.0.0.1).
Couche 4 : Problèmes TLS et certificats
- Certificat non servi : Vérifiez que le Secret référencé dans
spec.tls[].secretNameexiste dans le même espace de noms que l'Ingress (ou configureznamespacedans la référence du Secret si vous utilisez le contrôleur v1.2+ avec la portéeingressClassName). Le Secret doit être de typekubernetes.io/tlsavec les cléstls.crtettls.key. - Incompatibilité CN/SAN :
openssl s_client -connect example.com:443 -servername example.com < /dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name". Assurez-vous que le nom d'hôte demandé est listé. - Expiré/Révoqué : Vérifiez la date
Not Afterdans la même sortie. - Erreurs de format PEM : Les journaux du contrôleur affichent
unable to load SSL certificate. Recréez le Secret :kubectl create secret tls <nom> --cert=cert.pem --key=key.pem -n <namespace> --dry-run=client -o yaml | kubectl apply -f -.
Aide-mémoire des commandes de diagnostic
# Décrire l'Ingress pour les événements et le statut du backend
kubectl describe ingress -n <namespace> <nom-ingress>
# Vérifier les valeurs du configmap du contrôleur
kubectl get cm -n ingress-nginx ingress-nginx-controller -o yaml
# Tester le backend directement depuis un pod de débogage dans le même namespace
kubectl run -i --rm --restart=Never debug --image=curlimages/curl -- curl -v http://<nom-service>.<namespace>.svc.cluster.local:<port>/healthz
Modes de défaillance et récupération
Scénarios de défaillance courants et leurs récupérations ciblées :
1. Incompatibilité de classe Ingress / Contrôleur ne réconcilie pas Symptôme : Ressource Ingress créée, aucune configuration NGINX générée, aucun événement. Cause : spec.ingressClassName manquant ou ne correspond à aucune IngressClass avec controller: k8s.io/ingress-nginx. Récupération : Appliquez un patch à l'Ingress : kubectl patch ingress <nom> -n <ns> -p '{"spec":{"ingressClassName":"nginx"}}'. Vérifiez que l'IngressClass cible existe : kubectl get ingressclass nginx -o yaml.
2. Erreurs de syntaxe d'annotation causant un échec de rechargement de configuration Symptôme : Les journaux du contrôleur affichent nginx: [emerg] invalid parameter ou unknown directive. Les nouvelles règles ne sont pas appliquées. Cause : Valeur invalide dans des annotations comme nginx.ingress.kubernetes.io/server-snippet, configuration-snippet ou rewrite-target. Récupération : Annulez la modification d'annotation. Validez les extraits personnalisés contre la syntaxe NGINX avant d'appliquer. Utilisez la méthode canary décrite dans le Chemin de configuration sécurisé.
3. Incompatibilité de protocole backend (HTTP vs gRPC vs HTTPS) Symptôme : Erreurs 502, les clients gRPC reçoivent des erreurs unimplemented ou internal. Cause : Le port du Service cible HTTP mais le backend parle gRPC/HTTPS, ou vice versa. Annotation nginx.ingress.kubernetes.io/backend-protocol: "GRPC" ou "HTTPS" manquante. Récupération : Ajoutez l'annotation backend-protocol correcte. Pour les backends HTTPS, assurez-vous que le certificat du backend est de confiance (utilisez nginx.ingress.kubernetes.io/proxy-ssl-secret pour l'authentification par certificat client si nécessaire).
4. Rejet de corps de requête volumineux (413 Request Entity Too Large) Symptôme : Les téléversements de fichiers ou les charges utiles API volumineuses échouent avec 413. Cause : La valeur par défaut NGINX client_max_body_size est 1m. Récupération : Définissez nginx.ingress.kubernetes.io/proxy-body-size: "50m" sur l'Ingress (par règle) ou dans le ConfigMap (global). Rechargement vérifié via les journaux.
5. Politique de trafic externe / Préservation de l'IP source Symptôme : L'application voit l'IP de l'équilibreur de charge au lieu de l'IP client. Cause : Le LB cloud termine TLS/TCP et transmet via NodePort/ClusterIP sans protocole proxy. externalTrafficPolicy: Local sur le Service supprime le trafic si aucun pod local. Récupération : Activez use-proxy-protocol: "true" dans le ConfigMap du contrôleur et configurez le LB cloud pour envoyer le protocole PROXY (AWS NLB, Azure LB). Définissez externalTrafficPolicy: Local sur le Service du contrôleur uniquement si un déploiement DaemonSet ou hostNetwork garantit des pods locaux.
Procédure de retour arrière Si une modification dégrade le trafic :
- Revenez au manifeste Ingress précédent :
kubectl apply -f previous-known-good.yaml. - Ou annulez le déploiement du contrôleur :
kubectl rollout undo deployment/ingress-nginx-controller -n ingress-nginx. - Vérifiez la fin du retour arrière :
kubectl rollout status deployment/ingress-nginx-controller -n ingress-nginx --timeout=60s. - Confirmez le rechargement de configuration :
kubectl logs -n ingress-nginx $POD | grep "reloading".
Liste de contrôle opérationnelle
Intégrez ces vérifications dans les opérations de routine et les manuels d'intervention en cas d'incident.
Quotidien/Continu
- [ ] Pods du contrôleur
ReadyetRunningdans toutes les zones. - [ ] Aucun événement
ErrorouCrashLoopBackOffdans l'espace de nomsingress-nginx. - [ ] Les vérifications de santé du LB cloud rapportent
healthypour tous les backends. - [ ] Expiration des certificats TLS > 30 jours (automatisez avec les ressources
Certificatecert-manager etkubectl get cert -A -o custom-columns=NAME:.metadata.name,EXPIRY:.status.notAfter).
Hebdomadaire
- [ ] Examinez les journaux du contrôleur pour les motifs
WARN/ERROR(limitation de débit, délais d'attente upstream, échecs de rechargement de configuration). - [ ] Vérifiez que le nombre d'
IngressClasscorrespond aux attentes (évitez les ressources Ingress orphelines). - [ ] Vérifiez ponctuellement 3 à 5 hôtes Ingress critiques via curl externe (DNS -> LB -> Contrôleur -> Backend 200).
Mensuel / Avant changement
- [ ] Validez tous les manifestes Ingress avec
kubevaloukubectl --server-dry-rundans CI/CD. - [ ] Testez la mise à niveau du contrôleur en staging : déployez la nouvelle version du contrôleur, exécutez la suite d'intégration (TLS, réécriture de chemin, limitation de débit, canary, gRPC).
- [ ] Examinez la dérive du ConfigMap : diff du ConfigMap actuel par rapport à la ligne de base versionnée.
- [ ] Confirmez la procédure de sauvegarde/restauration pour les Secrets TLS et les manifestes Ingress (Velero ou snapshot etcd testé).
Réponse à incident (Premières 15 minutes)
kubectl get ingress -A --field-selector=status.loadBalancer.ingress!=— trouvez les Ingress sans adresse LB.kubectl describe ingress <nom> -n <ns>— vérifiez les événements pour les erreurs "Sync", avertissements "No endpoints".kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --since=10m | grep -i error— erreurs récentes du contrôleur.curl -vk -H "Host: <hôte>" https://<ip-lb>— reproduisez depuis le réseau du plan de contrôle.- Si 502 :
kubectl get ep <svc> -n <ns>— confirmez que les endpoints existent et correspondent aux pods prêts.
Conclusion
Le dépannage réseau de l'Ingress Kubernetes exige une approche disciplinée, couche par couche, qui respecte les frontières entre le réseau du cluster, la logique du contrôleur et l'infrastructure cloud. En maintenant un inventaire de versions à jour, en validant les changements par des chemins canary et en isolant systématiquement les défaillances du DNS jusqu'à la disponibilité des Pods, les équipes réduisent le temps moyen de résolution et évitent la dérive de configuration. Les opérations les plus fiables traitent l'Ingress comme un composant critique de production : versions épinglées, piloté par les manifestes, observable via des journaux et métriques structurés, et soutenu par une procédure de retour arrière testée. Commencez votre prochaine session en auditant un Ingress de production selon la section Inventaire des versions et de l'environnement, puis étendez la pratique à l'ensemble de la flotte.