Introduction
Kubernetes Ingress est la passerelle entre votre cluster et le monde extérieur. Si l'utilisation de base est simple, les environnements de production exigent une compréhension approfondie des règles de routage, de la terminaison TLS, du comportement du contrôleur et des modes de défaillance. Ce guide va au-delà du démarrage rapide et aborde les concepts avancés dont les opérateurs, les développeurs et les équipes techniques de startups ont besoin pour exploiter Ingress de manière fiable.
Nous explorerons l'architecture interne des contrôleurs Ingress, nous analyserons le flux de trafic du client au pod, et nous passerons en revue des exemples pratiques de routage par chemin, de routage par hôte, de configuration TLS et de fonctionnalités avancées comme les déploiements canary et les règles de réécriture. Chaque section comprend des commandes concrètes, les sorties attendues, les signaux de défaillance et les étapes de récupération. L'objectif est la sécurité opérationnelle : observez avant de modifier, limitez le rayon d'impact et vérifiez chaque résultat.
Cet article suppose que vous disposez d'un cluster Kubernetes fonctionnel (version 1.19 ou ultérieure) et de kubectl configuré. Les exemples utilisent le contrôleur NGINX Ingress en raison de sa large adoption, mais les concepts s'appliquent à d'autres contrôleurs comme Traefik, HAProxy ou les solutions cloud natives.
Inventaire de la version et de l'environnement
Avant de toucher à une ressource Ingress, vous devez comprendre votre environnement. Commencez par identifier la version du contrôleur Ingress, sa topologie de déploiement et la version de l'API des ressources Ingress de votre cluster.
Vérifier la version du contrôleur Ingress
Exécutez la commande suivante pour lister tous les pods dans l'espace de noms ingress-nginx (ou là où votre contrôleur est déployé) :
kubectl get pods -n ingress-nginx -o wide
La sortie attendue inclut le nom du pod, son statut et l'étiquette de l'image. Par exemple :
NAME READY STATUS RESTARTS AGE IP NODE
nginx-ingress-controller-7c66d668b-4k7s2 1/1 Running 0 5d 10.244.1.12 node1
L'étiquette de l'image vous indique la version du contrôleur. Vous pouvez obtenir plus de détails avec :
kubectl describe pod nginx-ingress-controller-7c66d668b-4k7s2 -n ingress-nginx | grep Image:
Sortie :
Image: registry.k8s.io/ingress-nginx/controller:v1.8.1
Connaître la version exacte est essentiel car les fonctionnalités et les annotations varient selon les versions. Par exemple, l'annotation canary a été introduite dans le contrôleur NGINX Ingress 0.21.0, et la valeur par défaut de nginx.ingress.kubernetes.io/ssl-redirect a changé dans la 0.22.0.
Vérifier la version de l'API et la classe Ingress
Vérifiez les versions d'API Ingress prises en charge :
kubectl api-versions | grep networking.k8s.io
Sortie attendue :
networking.k8s.io/v1
networking.k8s.io/v1beta1
Remarque : v1beta1 a été supprimé dans Kubernetes 1.22. Utilisez networking.k8s.io/v1 si votre cluster est récent. L'API v1 nécessite un champ pathType et adopte des comportements par défaut différents.
Listez les IngressClasses existantes :
kubectl get ingressclass
Sortie :
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 10d
Observation en lecture seule
Avant toute modification, enregistrez l'état actuel des ressources Ingress :
kubectl get ingress --all-namespaces -o wide
Exemple de sortie :
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
default app-ing nginx example.com 192.0.2.10 80, 443 3d
Conservez cette sortie pour comparaison après les modifications. Capturez également la configuration du contrôleur :
kubectl get configmap -n ingress-nginx
Si vous avez des configurations personnalisées, sachez ce qu'elles contiennent avant de les modifier.
Prérequis pour les opérations avancées
- Cluster avec Kubernetes 1.19+ (pour une Ingress v1 stable)
- Contrôleur Ingress installé et sain
kubectlavec des permissions RBAC appropriées- Un domaine de test ou la possibilité de modifier
/etc/hostspour des tests locaux - OpenSSL pour la génération de certificats (si vous testez TLS)
Chemin de configuration sûr
Les modifications de configuration Ingress peuvent perturber le trafic. Suivez un chemin sûr : comprenez l'état actuel, appliquez une modification à la fois, vérifiez et ayez un plan de retour en arrière.
Comprendre la structure de la ressource Ingress
Une ressource Ingress définit les règles de routage du trafic HTTP/HTTPS externe vers les services. Examinons un manifeste complet avec routage par hôte et par chemin :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Points clés :
ingressClassNamedoit correspondre à une IngressClass existante.pathTypepeut êtrePrefixouExact(etImplementationSpecificpour certains contrôleurs).backenddéfinit le service et le port cibles.- L'annotation
rewrite-targetsupprime le chemin correspondant avant de le transmettre (par exemple,/app/foodevient/foopour le backend).
Gestion des modifications : petites étapes réversibles
- Sauvegardez les manifestes Ingress actuels.
kubectl get ingress example-ingress -o yaml > example-ingress-backup.yaml
- Appliquez la nouvelle configuration.
kubectl apply -f example-ingress.yaml
- Vérifiez que l'Ingress est acceptée.
kubectl describe ingress example-ingress
Recherchez des événements indiquant un succès ou des erreurs de validation :
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 2m nginx-ingress-controller Scheduled for sync
- Testez localement avec port-forward avant d'exposer en externe.
kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80
Accédez ensuite à http://localhost:8080 et envoyez une requête avec l'en-tête Host approprié :
curl -H "Host: example.com" http://localhost:8080/app
Si le service backend app-service possède un gestionnaire de chemin racine, vous devriez voir sa réponse.
- Si vous utilisez TLS, testez avec un certificat auto-signé temporaire.
Générez-en un :
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=example.com"
Créez un secret :
kubectl create secret tls example-tls --key tls.key --cert tls.crt
Mettez à jour l'Ingress pour utiliser ce secret (comme indiqué précédemment) et testez avec curl -k https://localhost:443 après avoir redirigé le port 443.
Stratégie de retour en arrière
Si la modification cause des problèmes, revenez immédiatement en arrière :
kubectl apply -f example-ingress-backup.yaml
Ou supprimez l'Ingress si elle vient d'être créée :
kubectl delete ingress example-ingress
Ayez toujours le manifeste précédent à portée de main ou utilisez un contrôle de version.
Vérification et diagnostic
Après avoir appliqué la configuration, vérifiez que le routage fonctionne comme prévu. Cette section couvre les commandes pour inspecter l'état de l'Ingress, les journaux du contrôleur et le flux de trafic.
Inspecter l'état de l'Ingress
Le champ status de la ressource Ingress affiche l'adresse allouée (IP du load balancer ou nom d'hôte). Cela peut prendre quelques minutes.
kubectl get ingress example-ingress -o wide
Sortie :
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx example.com 192.0.2.10 80, 443 5m
Si ADDRESS reste vide, le contrôleur ne l'a peut-être pas encore assignée ou il y a un problème avec l'intégration du fournisseur cloud. Vérifiez les événements :
kubectl describe ingress example-ingress
Les événements peuvent montrer :
Warning FailedToUpdateEndpoint 5m (x3 over 10m) nginx-ingress-controller Failed to update endpoint default/example-ingress: Operation cannot be fulfilled on ingresses.networking.k8s.io "example-ingress": the object has been modified; please apply your changes to the latest version and try again
Cela indique un conflit ; réappliquez votre manifeste.
Journaux du contrôleur et débogage
Vérifiez les journaux du contrôleur pour détecter des erreurs :
kubectl logs -n ingress-nginx deployment/nginx-ingress-controller --tail=50
Recherchez les lignes contenant error, warn ou des références au nom de votre Ingress. Par exemple :
E1030 14:25:32.123456 1 controller.go:152] Unexpected error validating ingress: ingress "default/example-ingress" contains invalid path type "Invalid"
Si vous pensez que le contrôleur n'a pas rechargé sa configuration, forcez un rechargement en redémarrant les pods du contrôleur :
kubectl rollout restart deployment nginx-ingress-controller -n ingress-nginx
Tracer le trafic avec curl et sortie détaillée
Utilisez curl -v pour voir l'échange complet requête/réponse :
curl -v -H "Host: example.com" http://<adresse-ingress>/app
La sortie montre le statut HTTP, les en-têtes et les éventuelles redirections. Pour TLS, utilisez curl -kv pour ignorer la validation du certificat.
Vérifier les services backend
Assurez-vous que les services backend sont joignables et sains :
kubectl get endpoints app-service
Sortie :
NAME ENDPOINTS AGE
app-service 10.244.2.15:8080 1h
Si les endpoints sont vides, le sélecteur de service ne correspond à aucun pod.
Modes de défaillance et récupération
Les défaillances d'Ingress peuvent survenir à plusieurs niveaux : erreurs de configuration, problèmes du contrôleur, problèmes de backend ou mauvaises configurations réseau. Cette section décrit les modes de défaillance courants, comment les diagnostiquer et les étapes de récupération.
Défaillance : erreurs 404 ou 503 d'Ingress
Symptôme : le client reçoit 404 Not Found ou 503 Service Unavailable en accédant à un chemin valide.
Diagnostic :
- Vérifiez si la ressource Ingress existe et possède des règles d'hôte/chemin correctes.
- Vérifiez si les pods backend sont en cours d'exécution et prêts :
kubectl get pods -l app=myapp
Si les pods ne sont pas prêts, décrivez-les :
kubectl describe pod <nom-du-pod>
Recherchez des événements comme FailedScheduling ou CrashLoopBackOff.
- Vérifiez la configuration nginx générée par le contrôleur. Vous pouvez exécuter la commande suivante dans le pod du contrôleur et inspecter
/etc/nginx/nginx.conf:
kubectl exec -n ingress-nginx nginx-ingress-controller-7c66d668b-4k7s2 -- cat /etc/nginx/nginx.conf | grep -A 10 "example.com"
Cela montre le bloc serveur pour votre hôte. S'il est absent, l'Ingress n'est peut-être pas pris en compte en raison d'une incompatibilité de classe ou d'erreurs d'annotation.
Récupération :
- Corrigez le problème sous-jacent du pod (par exemple, extraction d'image, limites de ressources).
- Assurez-vous que le sélecteur de service correspond aux étiquettes des pods.
- Si l'Ingress ne se synchronise pas, vérifiez les erreurs de validation dans les journaux du contrôleur et corrigez le manifeste.
- Forcez un rechargement du contrôleur après correction.
Défaillance : le certificat TLS ne fonctionne pas
Symptôme : le navigateur affiche une erreur de certificat, ou curl indique que le certificat est pour le mauvais domaine.
Diagnostic :
- Vérifiez que le secret TLS existe et contient un certificat et une clé valides :
kubectl get secret example-tls -o yaml
Les données doivent contenir tls.crt et tls.key encodés en base64.
- Vérifiez que le certificat correspond à l'hôte :
kubectl get secret example-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep -A 1 "Subject Alternative Name"
La sortie attendue inclut votre domaine dans la liste SAN.
- Vérifiez que la section tls de l'Ingress référence le bon nom de secret.
Récupération :
- Mettez à jour le secret avec un certificat valide :
kubectl delete secret example-tls
kubectl create secret tls example-tls --key new-tls.key --cert new-tls.crt
- Ou ajoutez
nginx.ingress.kubernetes.io/ssl-redirect: "false"si vous souhaitez désactiver temporairement la redirection HTTPS à des fins de test.
Défaillance : le contrôleur ne traite pas les ressources Ingress
Symptôme : l'Ingress est créée mais aucune adresse n'est assignée, et les journaux du contrôleur ne montrent aucune activité.
Diagnostic :
- Vérifiez si la classe Ingress correspond à la classe du contrôleur. La ressource IngressClass doit avoir un nom de contrôleur que le contrôleur surveille.
- Listez les IngressClasses :
kubectl get ingressclass
- Vérifiez l'argument
--ingress-classdu contrôleur :
kubectl get deployment nginx-ingress-controller -n ingress-nginx -o yaml | grep -A 1 "ingress-class"
La valeur par défaut est nginx, donc votre Ingress doit avoir ingressClassName: nginx.
- Si vous utilisez l'ancienne annotation
kubernetes.io/ingress.class, assurez-vous qu'elle correspond.
Récupération :
- Mettez à jour l'Ingress pour utiliser la bonne classe.
- Ou mettez à jour la classe du contrôleur pour correspondre (nécessite un redémarrage).
Défaillance : service backend injoignable
Symptôme : 502 Bad Gateway ou 504 Gateway Timeout.
Diagnostic :
- Vérifiez les endpoints du service comme indiqué précédemment.
- Vérifiez les politiques réseau qui pourraient bloquer le trafic du contrôleur vers les pods.
- Vérifiez les journaux du contrôleur pour des erreurs en amont.
- Testez le backend directement en utilisant port-forward :
kubectl port-forward service/app-service 8080:80
curl http://localhost:8080
Si l'accès direct fonctionne mais pas l'Ingress, le problème se situe dans le routage ou la configuration du contrôleur.
Récupération :
- Corrigez les politiques réseau pour autoriser l'espace de noms du contrôleur Ingress à accéder aux ports des pods.
- Ajustez le
targetPortdu service pour correspondre au port du conteneur. - En cas de délai d'attente, vérifiez si le backend est lent et ajustez les délais du proxy via des annotations :
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour des opérations Ingress sûres en production.
Avant la modification
- [ ] Enregistrez la configuration Ingress actuelle :
kubectl get ingress -o yaml > ingress-backup-$(date +%Y%m%d).yaml
- [ ] Notez la version du contrôleur et la ligne de base des journaux.
- [ ] Identifiez la modification exacte et son rayon d'impact.
- [ ] Ayez un plan de retour en arrière.
- [ ] En cas de modifications TLS, sauvegardez les secrets.
Pendant la modification
- [ ] Appliquez un manifeste Ingress à la fois.
- [ ] Surveillez les journaux du contrôleur pendant le déploiement :
kubectl logs -f deployment/nginx-ingress-controller -n ingress-nginx
- [ ] Vérifiez l'état et les événements de l'Ingress.
Après la modification
- [ ] Vérifiez le routage avec
curlen utilisant l'en-tête Host correct. - [ ] Testez HTTPS le cas échéant (vérifiez la validité du certificat).
- [ ] Confirmez qu'il n'y a pas de régressions involontaires pour d'autres hôtes/chemins.
- [ ] Exécutez un test de fumée du trafic (par exemple, un petit script qui sollicite les endpoints).
- [ ] Documentez la modification et le résultat.
Surveillance continue
- [ ] Configurez des alertes sur les journaux d'erreurs du contrôleur.
- [ ] Surveillez l'état de la ressource Ingress pour l'assignation d'adresse.
- [ ] Examinez régulièrement les classes Ingress et les dépréciations.
Conclusion
Kubernetes Ingress est puissant mais complexe. En suivant une approche structurée – inventorier votre environnement, effectuer des modifications en toute sécurité, vérifier avec des commandes concrètes et se préparer aux défaillances – vous pouvez éviter les pièges courants et maintenir le trafic fluide.
Les points clés à retenir sont :
- Connaissez toujours la version de votre contrôleur et les versions d'API.
- Utilisez des modifications de configuration petites et réversibles.
- Vérifiez chaque étape avec des commandes et des sorties attendues.
- Comprenez les modes de défaillance et ayez des procédures de récupération prêtes.
- Maintenez une liste de contrôle opérationnelle pour institutionnaliser la sécurité.
Comme prochaine étape, choisissez une vérification à faible risque de ce guide : créez une Ingress de test avec un backend simple, appliquez-la et utilisez curl avec un en-tête Host pour confirmer le routage. Intégrez ensuite progressivement TLS et les fonctionnalités avancées. Rappelez-vous : en production, l'observabilité et la réversibilité sont vos meilleurs alliés.