
Un Service Kubernetes permet d’exposer un ou plusieurs Pods via une adresse IP stable et un nom DNS interne. Comme les Pods sont éphémères et changent d’adresse IP, le Service fournit un point d’accès durable pour la communication réseau entre applications ou vers l’extérieur du cluster. Ce guide vous montre comment créer des Services, choisir le bon type (ClusterIP, NodePort, LoadBalancer) et diagnostiquer les problèmes de connectivité.
Prérequis : un cluster Kubernetes fonctionnel avec au moins un Deployment ou des Pods.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Créer un Service avec kubectl expose et avec un fichier YAML
- Choisir le bon type : ClusterIP, NodePort, LoadBalancer, Headless
- Comprendre la résolution DNS entre Pods et Services
- Utiliser les labels/selectors pour cibler les bons Pods
- Diagnostiquer quand un Service ne fonctionne pas
Ce qu’est un Service Kubernetes
Section intitulée « Ce qu’est un Service Kubernetes »Un Service est une abstraction réseau qui expose un groupe de Pods via une adresse IP stable et un nom DNS.
Pour un débutant, retenez simplement :
- Les Pods changent d’IP à chaque recréation
- Le Service garde une IP fixe qui redirige vers les Pods
- Les autres Pods appellent le Service par son nom, pas par IP
Pourquoi utiliser des Services
Section intitulée « Pourquoi utiliser des Services »Sans Services, chaque Pod devrait connaître l’adresse IP des autres Pods — une adresse qui change à chaque redémarrage.
Les Services résolvent ce problème en fournissant :
| Fonctionnalité | Description |
|---|---|
| IP stable | Une adresse fixe qui ne change pas quand les Pods sont recréés |
| Nom DNS | Un nom comme backend-service au lieu d’une IP |
| Load balancing | Répartition automatique du trafic entre plusieurs Pods |
| Découverte | Les Pods trouvent les autres services par leur nom |
Exemple concret
Section intitulée « Exemple concret »Une application web avec :
- Un frontend (React)
- Un backend (API Node.js)
- Une base de données (PostgreSQL)
Le frontend appelle backend-service:8080 au lieu de chercher l’IP du Pod backend. Si le Pod backend redémarre avec une nouvelle IP, le Service redirige automatiquement.
Créer son premier Service
Section intitulée « Créer son premier Service »Méthode impérative : kubectl expose
Section intitulée « Méthode impérative : kubectl expose »La façon la plus rapide de créer un Service pour un Deployment existant :
kubectl expose deployment nginx --name=nginx-service --port=80 --target-port=80Résultat : un Service ClusterIP nommé nginx-service qui expose le port 80.
Vérifiez sa création :
kubectl get svc nginx-serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-service ClusterIP 10.43.7.235 <none> 80/TCP 5sMéthode déclarative : fichier YAML
Section intitulée « Méthode déclarative : fichier YAML »Pour un contrôle total, créez un fichier manifest :
apiVersion: v1kind: Servicemetadata: name: nginx-servicespec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIPLes champs essentiels :
| Champ | Description |
|---|---|
selector | Labels des Pods à cibler (ici app: nginx) |
port | Port exposé par le Service |
targetPort | Port sur lequel écoutent les Pods |
type | Type de Service (ClusterIP par défaut) |
Appliquez-le :
kubectl apply -f nginx-service.yamlObserver et inspecter un Service
Section intitulée « Observer et inspecter un Service »Une fois votre Service créé, vérifiez qu’il fonctionne.
kubectl get svc : vue d’ensemble
Section intitulée « kubectl get svc : vue d’ensemble »kubectl get svc -o wideNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORnginx-service ClusterIP 10.43.7.235 <none> 80/TCP 2m app=nginxLes colonnes importantes :
| Colonne | Signification |
|---|---|
| TYPE | ClusterIP, NodePort, LoadBalancer… |
| CLUSTER-IP | Adresse IP interne du Service |
| PORT(S) | Ports exposés |
| SELECTOR | Labels utilisés pour trouver les Pods |
kubectl describe : détails complets
Section intitulée « kubectl describe : détails complets »kubectl describe svc nginx-serviceCette commande montre :
- Endpoints : IPs des Pods ciblés par le Service
- Session Affinity : sticky sessions ou non
- Events : historique (rarement utile pour les Services)
Name: nginx-serviceSelector: app=nginxType: ClusterIPIP: 10.43.7.235Port: <unset> 80/TCPTargetPort: 80/TCPEndpoints: 10.42.0.9:80,10.42.1.8:80,10.42.1.9:80kubectl get endpoints : voir les Pods ciblés
Section intitulée « kubectl get endpoints : voir les Pods ciblés »kubectl get endpoints nginx-serviceNAME ENDPOINTS AGEnginx-service 10.42.0.9:80,10.42.1.8:80,10.42.1.9:80 5mChaque IP correspond à un Pod qui recevra du trafic.
Types de Services
Section intitulée « Types de Services »Kubernetes propose quatre types de Services selon vos besoins d’exposition.
ClusterIP : communication interne (défaut)
Section intitulée « ClusterIP : communication interne (défaut) »Le Service est accessible uniquement depuis l’intérieur du cluster.
spec: type: ClusterIP # ou omettez, c'est le défautCas d’usage : communication entre microservices (backend ↔ base de données).
┌─────────────────────────────────────────────┐│ Cluster ││ ││ Frontend Pod ──────► backend-service ││ │ ││ ▼ ││ Backend Pods │└─────────────────────────────────────────────┘NodePort : exposition sur chaque nœud
Section intitulée « NodePort : exposition sur chaque nœud »Le Service est accessible via un port sur chaque nœud du cluster.
spec: type: NodePort ports: - port: 80 targetPort: 80 nodePort: 30080 # optionnel, entre 30000-32767Accès : http://<IP-du-noeud>:30080
Cas d’usage : tests locaux, environnements sans cloud provider.
┌─────────────────────────────────────────────────┐│ ││ Internet/Réseau externe ││ │ ││ ▼ :30080 ││ ┌─────────────┐ ┌─────────────┐ ││ │ Node 1 │ │ Node 2 │ ││ │ :30080 │ │ :30080 │ ││ └──────┬──────┘ └──────┬──────┘ ││ └────────┬──────────┘ ││ ▼ ││ Service (ClusterIP) ││ │ ││ ▼ ││ Pods │└─────────────────────────────────────────────────┘LoadBalancer : exposition via cloud provider
Section intitulée « LoadBalancer : exposition via cloud provider »Le Service demande un équilibreur de charge externe au cloud provider (AWS, GCP, Azure…).
spec: type: LoadBalancer ports: - port: 80 targetPort: 80Accès : via l’IP externe fournie par le cloud (EXTERNAL-IP).
Cas d’usage : applications en production sur le cloud.
kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-service LoadBalancer 10.43.7.235 203.0.113.50 80:30262/TCP 2mQuel type choisir ?
Section intitulée « Quel type choisir ? »| Besoin | Type recommandé |
|---|---|
| Communication interne | ClusterIP |
| Test local sans cloud | NodePort |
| Production sur cloud | LoadBalancer |
Cas particulier : ExternalName
Section intitulée « Cas particulier : ExternalName »Le type ExternalName est à part : il ne sélectionne pas de Pods et ne fait pas de proxy. Il redirige simplement vers un nom DNS externe.
spec: type: ExternalName externalName: database.example.comCas d’usage : pointer vers une base de données managée (RDS, Cloud SQL…). Les Pods appellent external-db et sont redirigés vers database.example.com.
Cas particulier : Headless Services
Section intitulée « Cas particulier : Headless Services »Un Headless Service (clusterIP: None) ne possède pas d’IP de cluster. Le DNS retourne directement les IPs des Pods au lieu de l’IP du Service.
spec: clusterIP: None selector: app: nginx| Service normal | Headless Service |
|---|---|
| DNS → IP du Service | DNS → IPs des Pods |
| Load balancing par kube-proxy | Client choisit le Pod |
Cas d’usage : bases de données stateful, StatefulSets avec identité réseau stable. Voir le guide StatefulSets pour plus de détails.
Résolution DNS
Section intitulée « Résolution DNS »Kubernetes crée automatiquement des enregistrements DNS pour chaque Service.
Format du nom DNS
Section intitulée « Format du nom DNS »<service-name>.<namespace>.svc.cluster.localExemples
Section intitulée « Exemples »| Appel depuis | Nom à utiliser |
|---|---|
| Même namespace | nginx-service |
| Autre namespace | nginx-service.production |
| Nom complet (FQDN) | nginx-service.production.svc.cluster.local |
Tester la résolution DNS
Section intitulée « Tester la résolution DNS »kubectl run test-dns --image=busybox:1.36 --rm -it --restart=Never -- nslookup nginx-serviceServer: 10.43.0.10Address: 10.43.0.10:53
Name: nginx-service.default.svc.cluster.localAddress: 10.43.7.235Option avancée : sessionAffinity
Section intitulée « Option avancée : sessionAffinity »Par défaut, kube-proxy répartit le trafic aléatoirement. Pour garder un client sur le même Pod, ajoutez sessionAffinity: ClientIP :
spec: sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 600Cas d’usage : websockets, sessions en mémoire. Attention : ne fonctionne pas bien derrière un proxy qui masque l’IP client.
Service ou Ingress ?
Section intitulée « Service ou Ingress ? »Une question fréquente : quand utiliser un Service, quand utiliser un Ingress ?
| Service | Ingress | |
|---|---|---|
| Couche | L4 (TCP/UDP) | L7 (HTTP/HTTPS) |
| Routage | Par IP/port | Par path, host, headers |
| TLS | Non | Oui (terminaison) |
| Usage | Communication interne ou exposition simple | API publique, sites web |
Règle simple : utilisez un Service pour la communication interne ou l’exposition basique, un Ingress pour du routage HTTP avancé.
Ce qu’un Service ne fait PAS
Section intitulée « Ce qu’un Service ne fait PAS »Un Service Kubernetes est un outil Layer 4 (TCP/UDP). Il a des limitations :
| Besoin | Solution |
|---|---|
| Routage HTTP (path, host) | Ingress |
| Terminaison TLS | Ingress + cert-manager |
| Filtrage de sécurité | NetworkPolicies |
| Rate limiting, circuit breaker | Service mesh |
Debug : diagnostiquer un Service
Section intitulée « Debug : diagnostiquer un Service »1. Aucun endpoint
Section intitulée « 1. Aucun endpoint »Symptôme : Endpoints: <none> dans kubectl describe svc.
# Vérifier les labels des Podskubectl get pods --show-labels
# Comparer avec le selector du Servicekubectl get svc nginx-service -o jsonpath='{.spec.selector}'Cause : le selector ne correspond pas aux labels des Pods.
2. TargetPort incorrect
Section intitulée « 2. TargetPort incorrect »Symptôme : curl nginx-service timeout ou connexion refusée.
kubectl describe svc nginx-service | grep TargetPortkubectl exec -it nginx-pod -- netstat -tlnpCause : le targetPort ne correspond pas au port de l’application.
3. DNS défaillant
Section intitulée « 3. DNS défaillant »Symptôme : nslookup nginx-service échoue.
kubectl -n kube-system get pods -l k8s-app=kube-dnskubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- nslookup kubernetes4. Test depuis un Pod de debug
Section intitulée « 4. Test depuis un Pod de debug »kubectl run debug --image=nicolaka/netshoot --rm -it --restart=Never -- bashDepuis ce Pod : curl, nslookup, dig, tcpdump…
Testez vos Connaissances
Section intitulée « Testez vos Connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »- Un Service donne une IP stable et un nom DNS à un groupe de Pods
- Le selector doit correspondre aux labels des Pods (sinon pas d’endpoints)
- ClusterIP (défaut) : communication interne uniquement
- NodePort : exposition sur un port de chaque nœud (30000-32767)
- LoadBalancer : demande un équilibreur externe au cloud provider
- Headless (
clusterIP: None) : DNS retourne directement les IPs des Pods - EndpointSlices : API moderne qui stocke les adresses des Pods
- Un Service ne fait pas de routage HTTP, TLS ou filtrage sécurité — utilisez Ingress et NetworkPolicies