Routage des points de terminaison API Microservice – Débogage 404
Problème
Un point de terminaison API retourne 404 même si le code l'implémentant a été déployé. Cela arrive couramment dans les architectures microservice où plusieurs services partagent le même nom d'hôte et les règles HTTPRoutes/Ingress déterminent quel service gère quels chemins.
Contexte / Conditions de déclenchement
- Un nouveau point de terminaison retourne 404 mais le code est clairement déployé
- Plusieurs services (par ex. relay + api) partagent le même nom d'hôte externe
- Les logs du service montrent "Health server listening" ou des messages similaires (santé seulement)
- Les règles HTTPRoute ou Ingress divisent le trafic par préfixe de chemin
- Les builds du monorepo produisent plusieurs images Docker à partir du même commit
Solution
Étape 1 : Identifier quel service gère réellement le chemin
Vérifier les règles HTTPRoute/Ingress pour voir le routage :
kubectl get httproute <name> -n <namespace> -o yaml | grep -A 50 "rules:"
Chercher les règles de correspondance de chemin et le service backend auquel elles pointent :
/api/*peut aller àapi-service:8080/peut aller àwebsocket-service:7777
Étape 2 : Tester le point de terminaison directement sur chaque service depuis l'intérieur du cluster
kubectl run curl-test -n <namespace> --image=curlimages/curl --restart=Never \
-- curl -v "http://<service-name>:<port>/<endpoint>" \
&& sleep 5 \
&& kubectl logs -n <namespace> curl-test \
&& kubectl delete pod -n <namespace> curl-test
Cela contourne le routage externe et teste directement chaque service.
Étape 3 : Vérifier les logs du service pour l'enregistrement du point de terminaison
kubectl logs -l app=<service-name> -n <namespace> --tail=50 | grep -i -E "(endpoint|route|api|listening)"
Chercher des messages comme :
- "Health server listening on 0.0.0.0:8080" = santé seulement, pas d'API
- "API server listening" ou "Registered /api/..." = sert les points de terminaison API
Étape 4 : Pour les monorepos, vérifier que l'image correspondante existe pour le bon service
Si la fonctionnalité a été ajoutée au service A mais le point de terminaison est servi par le service B, vérifier que le service B a le même tag de commit :
gcloud artifacts docker images list <registry>/<service-b> --include-tags --limit=10
Étape 5 : Déployer le service correct avec la fonctionnalité + variables d'environnement requises
Mettre à jour le service qui gère réellement le chemin du point de terminaison :
- Nouveau tag d'image avec la fonctionnalité
- Toutes les variables d'environnement (clés API, URLs) dont la fonctionnalité a besoin
- Tous les secrets référencés par la fonctionnalité
Vérification
- Les logs du service montrent le point de terminaison enregistré : "Recommendations API enabled at /api/users/:pubkey/recommendations"
- Un curl direct depuis l'intérieur du cluster retourne 200
- Une requête externe via HTTPRoute retourne les données attendues
Exemple
Architecture :
Hostname: relay.example.com
/api/* → funnelcake-api:8080 (REST API)
/ → funnelcake-relay:7777 (WebSocket)
Problème : /api/users/x/recommendations retourne 404
Investigation :
- HTTPRoute montre
/api/*→ funnelcake-api (pas relay) - Test direct vers relay:8080 retourne 404 (health server seulement)
- Test direct vers api:8080 retourne aussi 404 (image ancienne)
- Le registre montre que api et relay ont tous deux le tag d'image
3c0696a - L'API exécutait l'ancien tag
487178e
Correction : Déployer funnelcake-api avec le tag 3c0696a + variables d'environnement GORSE_URL et GORSE_API_KEY
Notes
- Les services dans le même namespace peuvent partager les Secrets Kubernetes
- Les points de terminaison de santé (/livez, /readyz) sont souvent sur un port séparé de l'API
- Correspondance de chemin HTTPRoute : les chemins plus spécifiques ont la priorité
- Toujours vérifier quel service gère quels chemins avant de supposer la localisation du point de terminaison