Introduction
Les mises à niveau Kubernetes Ingress touchent l'un des bords les plus sensibles de votre plateforme : la façon dont les utilisateurs accèdent à vos applications. Un bon plan permet de passer aux API supportées, aux contrôleurs modernes et aux meilleures politiques de trafic sans casser les routes ni le TLS. Ce guide fournit une approche pratique et à faible risque pour la mise à niveau et la migration Kubernetes Ingress, de l'inventaire et la planification jusqu'à la vérification, les modes de défaillance et la restauration.
Ce que vous obtiendrez :
- Prérequis clairs et étapes d'inventaire d'environnement.
- Trois chemins sûrs : mise à niveau API seule, mise à niveau contrôleur sur place, et migration parallèle.
- YAML concrets, commandes et résultats attendus.
- Modes de défaillance, restauration et liste de contrôle reproductible.
Le premier projet pilote doit être étroit, mesurable et facile à inspecter localement et en préproduction avant tout changement en production. Gardez le périmètre serré, vérifiez minutieusement, puis étendez.
Inventaire des versions et de l'environnement
Avant de changer quoi que ce soit, capturez une image précise de ce que vous avez. Cela vous indique quel chemin de mise à niveau est viable et évite les surprises.
Identifier les capacités du cluster et de l'API
- Vérifiez la version du cluster :
kubectl version --short
- Confirmez les groupes d'API Ingress disponibles et les versions préférées :
kubectl api-resources | grep -i ingress
kubectl explain ingress | head -n 5
Attendu : networking.k8s.io/v1 est disponible sur les clusters modernes (1.19+). Si vous dépendez encore de extensions/v1beta1, planifiez d'abord une migration d'API.
Trouver vos contrôleurs et classes Ingress
- Listez les ressources IngressClass :
kubectl get ingressclass
- Trouvez les déploiements de contrôleur (souvent dans des espaces de noms comme
ingress-nginx,nginx-ingress,traefik, ou spécifiques au fournisseur) :
kubectl get deploy,ds,svc -A | grep -i ingress
- Inspectez l'IngressClass pour la chaîne controller (exemple pour ingress-nginx) :
kubectl get ingressclass -o yaml
Attendu : vous voyez quelque chose comme spec.controller: k8s.io/ingress-nginx pour le contrôleur communautaire ingress-nginx.
Cartographier le trafic et le TLS
- Listez les Ingresses et leurs adresses :
kubectl get ing -A -o wide
- Faites l'inventaire des hôtes, chemins et secrets TLS (note : les secrets TLS vivent dans le même espace de noms que l'Ingress) :
kubectl get ing -A -o jsonpath='{range .items[*]}{.metadata.namespace} {.metadata.name} {.spec.rules[*].host} {.spec.tls[*].secretName}{"\n"}{end}'
- Pour chaque Ingress public, identifiez les enregistrements DNS et les TTL actuels. Baissez les TTL avant tout basculement planifié (par exemple, de 3600 à 60 secondes).
- Tri des risques pour les fonctionnalités incompatibles :
- Notez les annotations utilisées pour les réécritures, timeouts, authentification ou canary. Certaines peuvent se comporter différemment entre versions de contrôleur.
- Identifiez les backends utilisant des ports nommés vs numériques, et les services avec des vérifications de santé non standard.
Changements d'API Ingress en un coup d'œil
| Domaine | v1beta1 | networking.k8s.io/v1 | Notes |
|---|---|---|---|
| Groupe d'API | extensions/v1beta1 | networking.k8s.io/v1 | v1beta1 supprimé dans les clusters récents |
| Référence backend | serviceName/servicePort | backend.service.name/port.number ou port.name | Structure changée en v1 |
| Type de chemin | implicite | pathType: Prefix, Exact, ou ImplementationSpecific | Vous devez définir pathType en v1 |
| Sélection de classe | annotation: kubernetes.io/ingress.class | spec.ingressClassName | Préférez ingressClassName en v1 |
| Secret TLS | même espace de noms que l'Ingress | même | Pas de changement ; vérifiez l'alignement des espaces de noms |
Chemin de configuration sécurisé
Choisissez le plus petit changement qui atteint votre objectif. Trois options éprouvées :
A) Mise à niveau API seule (garde votre contrôleur)
- Quand : Votre contrôleur supporte déjà
networking.k8s.io/v1, et vous n'avez besoin que de mettre à jour les manifestes de ressources. - Avantage : Un minimum de pièces mobiles. Idéal pour le premier pilote.
B) Mise à niveau contrôleur sur place (même classe et Service)
- Quand : Vous voulez de nouvelles fonctionnalités de contrôleur ou correctifs CVE mais garderez le même Service LoadBalancer ou NodePort.
- Avantage : Pas de changement DNS. Gardez les déploiements serrés avec surge et paramètres zéro-downtime.
C) Migration contrôleur parallèle (nouvelle classe et Service)
- Quand : Vous remplacerez la famille de contrôleur ou changerez la configuration majeure. Vous faites tourner l'ancien et le nouveau contrôleur en parallèle avec différentes valeurs IngressClass.
- Avantage : Basculement canary ou hôte par hôte sécurisé. Restauration facile en changeant
ingressClassNameou le poids DNS.
A) Exemple de mise à niveau API seule
Supposons que vous ayez cet Ingress legacy (exemple construit) :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-legacy
namespace: prod
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts: ["app.example.com
d secretName: tls-app
rules:
- host: app.example.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
Migrez vers v1 avec pathType explicite et backend structuré :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: prod
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: tls-app
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Appliquez en toute sécurité :
kubectl apply -f web-ingress-v1.yaml
kubectl describe ing -n prod web
Attendu : L'adresse reste la même, le secret TLS est trouvé, et les règles correspondent à votre ancien Ingress.
B) Exemple de mise à niveau contrôleur sur place (ingress-nginx)
- Confirmez la classe et le Service existants :
kubectl get ingressclass
kubectl get svc -n ingress-nginx
- Préparez une mise à niveau de déploiement contrôlée (commandes construites ; adaptez à vos outils) :
- Assurez-vous que le déploiement contrôleur a un PodDisruptionBudget et que les readinessProbes sont vertes.
- Définissez une stratégie de déploiement sûre (exemple) :
kubectl patch deploy -n ingress-nginx ingress-nginx-controller \
-p '{"spec":{"strategy":{"type":"RollingUpdate","rollingUpdate":{"maxUnavailable":0,"maxSurge":1}}}}'
- Mettez à niveau l'image du contrôleur vers la version cible, puis surveillez :
kubectl set image deploy/ingress-nginx-controller -n ingress-nginx \
controller=registry.k8s.io/ingress-nginx/controller:v1.9.6
kubectl rollout status deploy/ingress-nginx-controller -n ingress-nginx --timeout=3m
kubectl logs deploy/ingress-nginx-controller -n ingress-nginx --tail=100
Attendu : Aucune chute des endpoints, IP externe du Service inchangée, et les Ingresses existants se resynchronisent proprement.
Restauration (si nécessaire) :
kubectl rollout undo deploy/ingress-nginx-controller -n ingress-nginx
C) Exemple de migration contrôleur parallèle (basculement par classe)
Objectif : Faire tourner un nouveau contrôleur en parallèle, lier seulement certains Ingresses à lui, vérifier, puis déplacer plus de trafic.
- Créez une nouvelle IngressClass pour le nouveau contrôleur (exemple construit) :
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx-new
spec:
controller: k8s.io/ingress-nginx
- Déployez le nouveau contrôleur référençant cette classe (suivez la documentation de votre fournisseur ou chart). Assurez-vous qu'il crée un Service distinct tel que
ingress-nginx-new-controlleravec sa propre IP externe.
- Dupliquez un seul Ingress à faible risque pour cibler la nouvelle classe :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-new
namespace: prod
spec:
ingressClassName: nginx-new
tls:
- hosts:
- app-canary.example.com
secretName: tls-app
rules:
- host: app-canary.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
- Créez un DNS pour
app-canary.example.compointant vers l'IP du nouveau Service contrôleur avec un TTL court (par exemple, 60 secondes). Vérifiez de bout en bout avant de déplacer les hôtes de production.
- Basculement hôte par hôte : changez l'Ingress de production pour
ingressClassName: nginx-newet réappliquez. Alternativement, utilisez un DNS pondéré pour répartir le trafic entre les anciens et nouveaux Services contrôleur pendant la transition.
Canary au sein d'un seul contrôleur (drapeau de fonctionnalité)
Si vous n'avez besoin que de canary une nouvelle version de backend (pas un nouveau contrôleur), vous pouvez utiliser un Ingress canary avec ingress-nginx.
Ingress primaire (stable) :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-stable
namespace: prod
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Ingress canary (10% du trafic vers le service web-canary) :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-canary
namespace: prod
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-canary
port:
number: 80
Augmentez le poids à mesure que vous gagnez en confiance.
Vérification et diagnostics
Validez chaque étape avec des vérifications explicites et des signaux attendus. Gardez les TTL bas et observez pendant une fenêtre complète de budget d'erreur avant de continuer.
Vérifications principales et signaux attendus
| Vérification | Commande | Résultat attendu |
|---|---|---|
| Support API | kubectl api-resources | Ingress affiche networking.k8s.io/v1 |
| Statut Ingress | kubectl get ing -A -o wide | Colonne ADDRESS remplie pour chaque Ingress |
| Mapping classe | kubectl get ingressclass -o wide | Noms de classe et chaînes controller corrects |
| Événements | kubectl describe ing NOM -n ESPACE_NOM | Aucune erreur : secret TLS trouvé, backends résolus |
| Logs contrôleur | kubectl logs deploy/ingress-nginx-controller -n ingress-nginx | Cycles de sync sans erreur ni crashloop |
| Santé backend | curl -I https://hote/healthz | HTTP 200/204 ; latence dans les limites normales |
Diagnostics additionnels
- Confirmez la config générée (ingress-nginx) :
# Identifiez un pod contrôleur
POD=$(kubectl get pods -n ingress-nginx -l app.kubernetes.io/component=controller -o jsonpath='{.items[0].metadata.name}')
# Inspectez un extrait de la config NGINX générée
kubectl exec -n ingress-nginx $POD -- cat /etc/nginx/nginx.conf | head -n 50
- Validez le contenu du secret TLS et l'alignement d'espace de noms :
kubectl get secret tls-app -n prod -o yaml | grep -E 'tls\.crt|tls\.key'
- Confirmez les endpoints du Service :
kubectl get endpoints web -n prod -o yaml | grep addresses -A2
- Test de charge un petit échantillon (exemple construit) :
for i in $(seq 1 50); do curl -s -o /dev/null -w "%{http_code} %{time_total}\n" https://app.example.com/healthz; done | sort | uniq -c
Attendu : 200 stables avec timings cohérents.
Modes de défaillance et restauration
Planifiez l'échec pour pouvoir récupérer rapidement et en confiance.
1. 404 Not Found après basculement
- Cause : Mauvais hôte, désaccord de chemin, ou backend par défaut manquant. En v1,
pathTypeest requis et change le comportement de correspondance. - Correction : Assurez-vous
pathType: PrefixouExactselon l'intention, confirmez l'orthographe de l'hôte, et que le service backend existe. - Restauration : Réappliquez le dernier manifeste Ingress connu-bon (gardez-le sous la main), ou revenez à l'ancienne classe si vous avez utilisé la migration parallèle.
2. 502/504 depuis l'amont
- Cause : Endpoints du service non prêts, désaccord de port, ou vérifications de readiness échouant.
- Correction : Vérifiez les sélecteurs de service, endpoints, et readiness des pods. Confirmez le numéro de port backend vs nom.
- Restauration : Mettez le poids canary à 0 ou revenez à l'Ingress avec le backend stable.
3. Erreurs de handshake TLS ou certificat
- Cause : Secret TLS non trouvé, mauvais espace de noms, ou SAN manquant pour l'hôte.
- Correction : Assurez-vous que le secret existe dans l'espace de noms de l'Ingress et contient
tls.crtettls.keyvalides pour l'hôte. - Restauration : Remettez le secret TLS précédent et réappliquez.
4. Le contrôleur n'assigne jamais d'adresse
- Cause : Délai de provisionnement LoadBalancer, permissions cloud, ou mauvaise configuration.
- Correction : Inspectez les événements du Service, logs du fournisseur cloud, et logs du contrôleur. Vérifiez le type de Service et annotations.
- Restauration : Gardez l'ancien contrôleur comme principal ; évitez le changement DNS tant que le nouveau Service n'a pas d'adresse.
5. Changement de comportement d'annotation
- Cause : Certaines annotations peuvent différer entre versions de contrôleur.
- Correction : Comparez les annotations supportées, testez sur un hôte canary, et supprimez ou ajustez les clés dépréciées.
- Restauration : Remettez le jeu d'annotations précédent et la version de contrôleur précédente.
6. Routage inattendu après migration d'API
- Cause : Les hypothèses du matching de chemin v1beta1 ne tiennent plus.
- Correction : Définissez
pathTypeexplicitement ; pour regex ou réécritures, assurez-vous que les annotations spécifiques au contrôleur sont correctes. - Restauration : Si supporté par votre cluster, revenez au manifeste précédent pendant que vous corrigez les chemins.
Playbooks de restauration
A) Restauration mise à niveau API seule
# Réappliquez le manifeste précédemment fonctionnel
kubectl apply -f web-ingress-precedent.yaml
# Confirmez le statut
kubectl describe ing -n prod web
B) Restauration mise à niveau contrôleur sur place
# Remettez le déploiement au ReplicaSet précédent
kubectl rollout undo deploy/ingress-nginx-controller -n ingress-nginx
# Regardez les pods revenir à Ready
kubectl rollout status deploy/ingress-nginx-controller -n ingress-nginx --timeout=3m
C) Restauration migration contrôleur parallèle
- Repointez l'Ingress de production de
ingressClassName: nginx-newversingressClassName: nginxet appliquez. - Si vous avez utilisé un DNS split, remettez le poids à 100% ancien contrôleur et 0% nouveau contrôleur.
- Supprimez les Ingresses canary ou dupliqués ciblant la nouvelle classe une fois stable.
Vérification après restauration :
kubectl get ing -A -o wide
kubectl logs deploy/ingress-nginx-controller -n ingress-nginx --tail=100
curl -I https://app.example.com/healthz
Attendu : Comportement précédent restauré avec réponses saines.
Liste de contrôle opérationnelle
Utilisez cette liste pour guider chaque mise à niveau ou migration. Cochez les éléments faits ; ne sautez pas les portes de vérification.
Planification et inventaire
- [ ] Enregistrez la version du cluster et confirmez la disponibilité de
networking.k8s.io/v1. - [ ] Listez tous les Ingresses, hôtes, chemins, et secrets TLS.
- [ ] Identifiez les contrôleurs Ingress actuels, classes, et Services.
- [ ] Baissez les TTL DNS pour les hôtes affectés.
Sélection du pilote
- [ ] Choisissez un seul hôte ou chemin à faible risque comme premier pilote.
- [ ] Décidez de l'approche : API seule, mise à niveau sur place, ou migration parallèle.
- [ ] Préparez les manifestes pour le pilote, incluant
pathTypeetingressClassName.
Exécution du changement
- [ ] Appliquez les changements d'abord en environnement non-production ; vérifiez de bout en bout.
- [ ] Pour les mises à niveau contrôleur sur place, assurez le rollout surge/zéro-indisponible.
- [ ] Pour la migration parallèle, créez une nouvelle IngressClass et un nouveau Service contrôleur.
- [ ] Si canarying, commencez à 5-10% de poids et observez.
Vérification
- [ ] Vérifiez le statut Ingress et les champs ADDRESS.
- [ ] Revoyez les logs contrôleur pour erreurs et rechargements de config.
- [ ] Validez les certificats TLS et SANs pour tous les hôtes.
- [ ] Sondez les endpoints de santé ; confirmez latence et taux d'erreur.
Décision et extension
- [ ] Maintenez l'état stable pendant une fenêtre d'observation convenue.
- [ ] Augmentez le poids canary ou déplacez des hôtes additionnels.
- [ ] Documentez tout changement d'annotation ou comportement découvert.
Préparation à la restauration
- [ ] Gardez les manifestes antérieurs et versions de contrôleur notées.
- [ ] Ayez les poids DNS ou toggles
ingressClassNameprêts. - [ ] Vérifiez les commandes de restauration en environnement de staging.
Conclusion
Mettre à niveau et migrer Kubernetes Ingress en toute sécurité, c'est définir le périmètre du changement, vérifier à chaque étape, et garder un chemin propre vers la restauration. Commencez par une mise à niveau API seule quand c'est possible, puis passez aux mises à niveau contrôleur sur place ou migrations parallèles quand vous avez besoin de nouvelles fonctionnalités ou d'une famille de contrôleur différente. Gardez les pilotes petits, utilisez pathType et ingressClassName explicites, validez avec les logs et sondes, et stockez les manifestes connus-bons pour une récupération instantanée. Avec une liste de contrôle courte, reproductible, et un premier pilote étroit, vous pouvez moderniser Ingress avec confiance et perturbation minimale.