Introduction
NGINX Ingress est souvent le point d'entrée unique vers vos clusters Kubernetes. Quand une requête n'atteint pas votre application ou retourne un HTTP 404 ou 502, la priorité est d'isoler précisément l'étape défaillante: DNS et routage d'hôte, règle Ingress, TLS, Service, ou Pods derrière le Service.
Ce guide propose un workflow concret, étape par étape, avec des commandes sûres et des manifestes minimaux. Vous apprendrez à vérifier les règles d'hôte et la correspondance des chemins, valider le TLS, interpréter 404 vs 502 et confirmer les backends et endpoints. L'objectif est de permettre un K8s ingress troubleshooting efficace, reproductible et à faible risque en environnements proches de la production.
Aperçu du workflow
Suivez cette séquence pour dépanner NGINX ingress en toute sécurité. Chaque étape réduit le périmètre et évite les changements disruptifs.
- Identifier la requête en échec
- Notez le schéma, l'hôte et le chemin complets, par exemple: https://api.example.com/v1/ping
- Capturez le code de statut et, si possible, les en-têtes de réponse
- Confirmer DNS et routage d'hôte
- Côté client, résolvez l'hôte:
nslookup api.example.com
- Depuis un nœud ou un pod de diagnostic dans le cluster, testez le routage HTTP avec l'en-tête Host:
kubectl -n default run curl --rm -it --image=curlimages/curl:8.7.1 --restart=Never --command -- sh -lc \
"curl -sS -o /dev/null -w '%{http_code} %{remote_ip}\n' -H 'Host: api.example.com' http://<ingress-external-ip>/v1/ping"
- Si l'Ingress est derrière un LoadBalancer, remplacez <ingress-external-ip> par l'IP publique ou le DNS du load balancer.
- Vérifier l'objet Ingress et sa classe
- Lister et inspecter l'Ingress du namespace ciblé:
kubectl get ingress
kubectl describe ingress api-ing
- Confirmez que spec.ingressClassName correspond au contrôleur (souvent "nginx" ou "ingress-nginx"). Si l'annotation héritée est utilisée: kubernetes.io/ingress.class: nginx.
- Assurez-vous que l'hôte et les chemins correspondent exactement, y compris la casse et les barres obliques finales.
- Valider la correspondance des chemins et les réécritures
- Comprendre pathType:
- Prefix: fait correspondre par préfixe. Exemple: /api correspond à /api, /api/v1.
- Exact: ne correspond qu'au chemin exact.
- Si votre backend attend des chemins sans le préfixe, utilisez une réécriture:
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: api.example.com
http:
paths:
- path: /api/(.*)
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- Après modifications, refaites les tests curl, avec et sans slash final, pour confirmer le comportement.
- Différencier 404 et 502 au niveau Ingress
- 404 Not Found depuis NGINX indique généralement qu'aucune règle d'hôte ou de chemin ne correspond à la requête. Vérifiez:
- L'hôte de la requête correspond à spec.rules[].host
- Le chemin et pathType correspondent à l'URI entrant
- L'IngressClass est correcte
- 502 Bad Gateway indique que la règle a correspondu mais que l'upstream a échoué. Causes fréquentes:
- Le Service n'a pas d'endpoints (zéro Pod prêt)
- Le port du Service ne correspond pas au containerPort
- NetworkPolicy ou pare-feu bloquant le trafic vers le Pod
- L'application backend ferme la connexion ou expire
- Vérifier Service, Endpoints et Pods
- Confirmer selectors et ports:
kubectl get svc api-svc -o wide
kubectl describe svc api-svc
kubectl get endpoints api-svc -o wide
- Si la liste des endpoints est vide, vérifiez que les labels des Pods correspondent au selector du Service:
kubectl get pods -l app=api -o wide
kubectl get pod <pod> -o jsonpath='{.metadata.labels}'
- Contrôler les ports de conteneur et la readiness:
kubectl describe pod <pod>
- Si les probes de readiness échouent, le Pod ne sera pas un endpoint prêt et NGINX retournera 502.
- Inspecter le contrôleur NGINX Ingress
- Vérifier que le contrôleur fonctionne et est sain:
kubectl -n ingress-nginx get pods -o wide
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller | tail -n 100
- Recherchez des rechargements de configuration, des erreurs upstream ou TLS.
- Valider la configuration TLS
- Vérifier le bloc TLS et la référence au secret:
kubectl get ingress api-ing -o yaml | sed -n '/tls:/,/rules:/p'
kubectl get secret api-tls -o yaml
- Le type du secret doit être kubernetes.io/tls avec tls.crt et tls.key.
- Depuis un client, inspecter la chaîne de certificats:
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts < /dev/null | openssl x509 -noout -issuer -subject -dates
- Si le certificat ne correspond pas à l'hôte attendu, le SNI ne correspond pas ou l'hôte de l'Ingress ne correspond pas à la requête.
- Timeouts et en-têtes ou corps volumineux
- Les réponses longues côté backend peuvent nécessiter des ajustements ciblés:
- nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
- nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
- nginx.ingress.kubernetes.io/proxy-body-size: "10m"
- Appliquez les annotations sur des chemins ou Ingress spécifiques plutôt que globalement pour minimiser le risque.
- Validation sûre avant mise en production
- Utiliser kubectl diff pour prévisualiser les changements:
kubectl apply -f ingress.yaml --server-side --dry-run=server
kubectl diff -f ingress.yaml
- Valider en curlant le load balancer avec des en-têtes Host et en ciblant les Services ClusterIP depuis un pod de diagnostic pour isoler Service vs Ingress:
# Tester le Service directement dans le cluster
kubectl -n default run diag --rm -it --image=curlimages/curl:8.7.1 --restart=Never --command -- sh -lc \
"curl -sS -i http://api-svc.default.svc.cluster.local:80/healthz"
Plan pilote local
Mettez en place un pilote ciblé dans un namespace isolé afin de valider le routage, le TLS et les backends de bout en bout.
- Namespace et application d'exemple
apiVersion: v1
kind: Namespace
metadata:
name: ingress-pilot
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
namespace: ingress-pilot
spec:
replicas: 2
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: hashicorp/http-echo:0.2.3
args: ["-text=hello", "-listen=:8080"]
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: echo-svc
namespace: ingress-pilot
spec:
selector:
app: echo
ports:
- port: 80
targetPort: 8080
- Ingress HTTP de base
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ing
namespace: ingress-pilot
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
ingressClassName: nginx
rules:
- host: echo.local
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: echo-svc
port:
number: 80
- Test sûr
- Appliquer et vérifier:
kubectl apply -f pilot.yaml
kubectl -n ingress-pilot get ingress echo-ing -o wide
kubectl -n ingress-pilot describe ingress echo-ing
kubectl -n ingress-pilot get endpoints echo-svc
- Depuis un pod de diagnostic, appeler l'Ingress avec Host:
kubectl -n ingress-pilot run tester --rm -it --image=curlimages/curl:8.7.1 --restart=Never --command -- sh -lc \
"curl -i -H 'Host: echo.local' http://<ingress-external-ip>/"
- Attendu: HTTP/1.1 200 et corps "hello".
- Pilote TLS (optionnel)
- Créer un secret TLS dans le même namespace:
kubectl -n ingress-pilot create secret tls echo-tls \
--cert=server.crt --key=server.key
- Ajouter TLS à l'Ingress:
spec:
tls:
- hosts:
- echo.local
secretName: echo-tls
- Valider le certificat et le SNI:
openssl s_client -connect <ingress-external-ip>:443 -servername echo.local < /dev/null | openssl x509 -noout -subject -dates
- Critères de succès
- Le chemin / retourne 200 avec "hello".
- Changer l'en-tête Host pour un hôte non correspondant retourne 404.
- Supprimer tous les endpoints du Service entraîne un 502, puis retour à 200 lorsque les endpoints sont restaurés.
- Avec TLS, le sujet du certificat correspond à echo.local et la requête retourne 200.
Conclusion
Quand NGINX Ingress échoue, considérez-le comme un puzzle de routage à résoudre méthodiquement: confirmez DNS et Host, vérifiez classe et règles Ingress, contrôlez la correspondance des chemins et les réécritures, distinguez 404 de 502, et validez Services, Endpoints et Pods. N'appliquez des annotations de tuning qu'au plus près du besoin et testez toujours dans un pilote restreint avant tout élargissement.
Prochaines étapes:
- Conservez un modèle de pod de diagnostic pour curl des Services et de l'Ingress avec des en-têtes Host.
- Standardisez des patrons Ingress (hôtes, chemins, TLS) réutilisables.
- Tenez une courte checklist 404 vs 502 et ajoutez-la à vos runbooks d'app.
Remarque de référencement naturel: ce guide s'adresse aussi aux recherches courantes telles que Kubernetes ingress, NGINX ingress, K8s ingress troubleshooting, Kubernetes 502 et Kubernetes TLS ingress.