
Service inaccessible : vérifier les sélecteurs et les ports
Diagnostiquez pourquoi un Service Kubernetes est inaccessible. Apprenez à vérifier les sélecteurs de labels, les ports (port, targetPort) et les Endpoints pour rétablir la connexion.
Mon Service existe, mais pourquoi ne répond-il pas ?
Les Services sont le mécanisme fondamental de Kubernetes pour exposer un ensemble de Pods sous une adresse IP et un nom DNS stables. Ils permettent le découplage et la découverte de services au sein du cluster (et parfois depuis l'extérieur). Cependant, il est fréquent de créer un Service, de vérifier qu'il existe avec `kubectl get svc`, mais de constater qu'il est impossible de le joindre ou qu'il ne route pas le trafic vers les Pods attendus.
Lorsque vous faites face à un Service inaccessible, deux des coupables les plus courants sont une mauvaise configuration des sélecteurs de labels (`selector`) ou une incohérence dans la définition des ports (`port`, `targetPort`). Ces éléments sont cruciaux car ils déterminent *quels* Pods le Service doit cibler et *comment* leur transférer le trafic.
Ce sous-chapitre vous guidera à travers les étapes de vérification des sélecteurs et des ports pour diagnostiquer et résoudre les problèmes d'accessibilité des Services Kubernetes.
Etape 1 : Vérifier la correspondance entre Sélecteur et Labels des Pods
Le lien fondamental entre un Service et les Pods qu'il doit exposer est établi par le champ `selector` dans la définition du Service et les `labels` appliqués aux Pods. Le Service recherche continuellement les Pods qui possèdent des labels correspondant exactement à son sélecteur.
Pour diagnostiquer un problème potentiel ici :
- Inspectez le Sélecteur du Service : Utilisez `kubectl describe service
` et repérez la ligne `Selector:`. Notez précisément les paires clé=valeur. Vous pouvez aussi utiliser `kubectl get service -o yaml` et regarder sous `spec.selector`.
Ici, le sélecteur exige les labels `app=frontend` ET `tier=web`.kubectl describe service mon-frontend-svc # Output (extrait): # Name: mon-frontend-svc # Namespace: default # Labels:# Annotations: # Selector: app=frontend,tier=web # Type: ClusterIP # ... - Vérifiez les Labels des Pods cibles : Listez les Pods que vous vous attendez à ce que le Service cible, en affichant leurs labels : `kubectl get pods --show-labels` ou filtrez directement : `kubectl get pods -l app=frontend`.
kubectl get pods --show-labels # Output (extrait): # NAME READY STATUS RESTARTS AGE LABELS # mon-frontend-pod-123 1/1 Running 0 5m app=frontend,tier=web # mon-frontend-pod-456 1/1 Running 0 5m app=frontend,tier=web # mon-backend-pod-789 1/1 Running 0 10m app=backend,tier=api - Comparez rigoureusement : Les labels des Pods doivent correspondre exactement (clé et valeur) au sélecteur du Service. Une faute de frappe (`app=fronted` au lieu de `app=frontend`), une casse différente si les labels sont sensibles à la casse, ou un label manquant suffisent à rompre le lien. Dans l'exemple ci-dessus, les deux `mon-frontend-pod` correspondent, mais `mon-backend-pod` ne correspond pas.
Etape 2 : Examiner les Endpoints du Service
Le véritable routage du trafic par un Service ne se base pas directement sur le sélecteur, mais sur un objet distinct appelé `Endpoints` (ou le plus récent `EndpointSlice`) que Kubernetes maintient automatiquement à jour. Cet objet contient la liste des adresses IP et des ports des Pods qui correspondent *actuellement* au sélecteur du Service ET qui sont dans l'état `Ready`.
Pour vérifier cet objet :
kubectl get endpoints [-n ] (Pour EndpointSlices, plus efficaces pour les services ciblant de nombreux pods : `kubectl get endpointslice -l kubernetes.io/service-name=
Examinez la colonne `ENDPOINTS` :
NAME ENDPOINTS AGE
mon-frontend-svc 10.1.2.3:8080,10.1.2.4:8080 15mIci, le Service a trouvé deux Pods prêts (`10.1.2.3` et `10.1.2.4`) et sait qu'il doit router le trafic vers le port `8080` de ces Pods.
Le signe d'alerte majeur est une liste d'Endpoints vide :NAME ENDPOINTS AGE
mon-frontend-svc 15m Si vous voyez `
Etape 3 : Valider la configuration des Ports
Une fois que vous êtes sûr que le Service est correctement lié aux bons Pods via le sélecteur et que les Endpoints sont peuplés, le problème peut résider dans la configuration des ports. Il est essentiel de comprendre les différents ports dans la définition d'un Service :
- `port` : C'est le port sur lequel le Service lui-même écoute à l'intérieur du cluster (sur son IP virtuelle ClusterIP). C'est le port que les autres Pods du cluster utiliseront pour contacter ce Service.
- `targetPort` : C'est le port sur lequel l'application *à l'intérieur du conteneur* écoute réellement le trafic. Kubernetes redirige le trafic arrivant sur le `port` du Service vers le `targetPort` des Pods listés dans les Endpoints. Ce `targetPort` doit correspondre exactement au port exposé par votre application dans son conteneur.
- `nodePort` : Uniquement pour les Services de type `NodePort` ou `LoadBalancer`. C'est un port statique (dans une plage par défaut 30000-32767) ouvert sur l'adresse IP de *chaque* Noeud du cluster. Le trafic arrivant sur ce `nodePort` est ensuite routé vers le `port` interne du Service, puis vers le `targetPort` des Pods.
Utilisez `kubectl describe service
# Extrait de kubectl get svc my-service -o yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- name: http
port: 80 # Le Service écoute sur le port 80
protocol: TCP
targetPort: 8080 # Le conteneur applicatif doit écouter sur le port 8080
selector:
app: my-app
type: ClusterIPErreurs courantes liées aux ports :- Incohérence `targetPort` / Application : L'erreur la plus fréquente. Le `targetPort` dans le Service est défini à `80`, mais l'application dans le conteneur écoute sur le `8080` (ou vice-versa). Le trafic arrive au Pod mais n'atteint jamais l'application. Vérifiez la configuration de votre serveur web/application ou le `Dockerfile` (`EXPOSE`) pour connaître le port réel d'écoute.
- Oubli ou mauvaise définition du `targetPort` : Si `targetPort` n'est pas défini, il prend par défaut la même valeur que `port`. Si votre application écoute sur un port différent, cela échouera. Il est souvent plus clair de définir explicitement `targetPort`, qui peut aussi être un nom de port défini dans la section `ports` du conteneur dans le Pod/Déploiement.
- Confusion lors de l'accès : Tenter d'accéder directement au `targetPort` de l'IP du Service (ne fonctionnera pas). Utiliser le `port` pour l'accès ClusterIP. Oublier d'utiliser le `nodePort` (et l'IP d'un Noeud) pour accéder à un Service NodePort depuis l'extérieur du cluster.
Checklist rapide pour les Services inaccessibles
Face à un Service Kubernetes qui ne répond pas :
- Existe-t-il ? `kubectl get svc
` - Le Sélecteur est-il correct ? `kubectl describe svc
` (notez le `Selector`). - Les Pods ont-ils les bons Labels ? `kubectl get pods --show-labels` ou `kubectl get pods -l
` (vérifiez la correspondance exacte). - Les Endpoints sont-ils peuplés ? `kubectl get endpoints
` (doit lister des IP:Port, pas ` `). - Les Pods cibles sont-ils `Ready` ? `kubectl get pods -l
` (vérifiez la colonne `READY`, doit être `1/1`, `2/2`, etc.). - Les Ports sont-ils cohérents ? `kubectl describe svc
` (vérifiez `Port`, `TargetPort`, `NodePort`). - Le `targetPort` correspond-il au port d'écoute de l'application dans le conteneur ? (Vérifiez la configuration de l'application ou le Dockerfile).
- Utilisez-vous le bon port/IP pour accéder au Service ? (ClusterIP:`
: ` ou ` : ` ; NodePort:` : `).
En vérifiant méthodiquement les sélecteurs et les ports, ainsi que l'état des Pods sous-jacents et la liste des Endpoints, vous pouvez résoudre la majorité des problèmes empêchant vos Services Kubernetes de fonctionner correctement.