Services - ii02735/learn-k8 GitHub Wiki

Les Services

Qu'est-ce qu'un Service ?

Un Service est une abstraction réseau qui expose un ensemble de Pods derrière une adresse IP stable et un nom DNS stable.

Les Pods sont éphémères : à chaque recréation (mise à jour, redémarrage, ajout de réplica), ils obtiennent une nouvelle adresse IP. Un Service résout ce problème :

  • il fournit une IP virtuelle (ClusterIP) et un nom DNS qui ne changent pas
  • il sélectionne les Pods via un sélecteur de labels
  • il répartit le trafic entre les Pods sélectionnés (load balancing)

Un Service qui répartit le trafic vers trois Pods

Sélecteur et endpoints

  • spec.selector choisit les Pods cibles par leurs labels (comme le ReplicaSet).
  • Kubernetes maintient la liste des adresses des Pods prêts dans les objets Endpoints / EndpointSlice.
  • Un Pod n'est ajouté aux endpoints que s'il est prêt (readinessProbe réussie). Les Pods en échec de readiness sont donc retirés du trafic automatiquement.

⚠️ Si le sélecteur ne correspond à aucun Pod (ou que tous les Pods sont not ready), le Service n'a aucun endpoint : les requêtes échouent.

Les types de Service

ClusterIP (par défaut) : une IP virtuelle joignable uniquement depuis le cluster.

  • Quand ? pour la communication interne entre services, sans exposition à l'extérieur.
  • Exemple : le frontend web appelle la base de données via http://db-svc:5432. C'est le type le plus courant : les autres types sont construits par-dessus.

NodePort : expose le Service sur un port fixe (30000-32767) de chaque noeud.

  • Quand ? pour joindre un Service depuis l'extérieur quand on n'a pas de load balancer (bare-metal, minikube, homelab).
  • Exemple : http://192.168.1.10:30080 — l'IP d'un noeud, suivie du port du Service.

LoadBalancer : demande au fournisseur Cloud de provisionner un load balancer externe (AWS, GCP, Azure…).

  • Quand ? pour exposer publiquement une application en production sur un cloud.
  • Exemple : une API publique joignable via l'URL fournie par le cloud. Derrière le rideau, le Service reste un ClusterIP + NodePort.

ExternalName : un simple alias DNS (CNAME) vers un nom externe ; ne route aucun trafic.

  • Quand ? pour désigner un service hors du cluster sous un nom interne stable.
  • Exemple : faire pointer billing-svc vers billing.example.com, puis remplacer l'un par l'autre sans toucher au code de l'application.

Note

NodePort et LoadBalancer exposent l'application en L4 (TCP/UDP). Pour du routage HTTP/HTTPS en L7 (par hôte ou par chemin), on utilise un Ingress, placé devant des Services ClusterIP.

En résumé : ClusterIP pour l'interne, NodePort sans cloud, LoadBalancer pour exposer en production, ExternalName pour un simple alias DNS.

Le DNS interne

Chaque Service obtient un nom DNS de la forme :

<service>.<namespace>.svc.cluster.local

Depuis un Pod du même namespace, le nom court web-svc suffit. Depuis un autre namespace, il faut web-svc.<namespace>.

Un Service sans sélecteur (headless)

Un Service headless (spec.clusterIP: None) n'a pas d'IP virtuelle : le DNS renvoie directement les IP des Pods. On l'utilise notamment avec les StatefulSet pour adresser chaque réplica individuellement (pod-0.web.<namespace>.svc.cluster.local).

port, targetPort et nodePort

  • port : le port du Service (celui que les clients appellent).
  • targetPort : le port du container vers lequel le trafic est redirigé. Peut être un numéro ou le nom d'un port du Pod (ex. http).
  • nodePort : le port exposé sur chaque noeud (uniquement pour le type NodePort / LoadBalancer).

Un manifeste Service

apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: http
      protocol: TCP

Exposer un Service

  • de façon impérative : kubectl expose deployment web --name=web-svc --port=80 --target-port=80
  • pour tester en local sans exposer publiquement : kubectl port-forward service/web-svc 8080:80

Les commandes principales

  • Lister les Services : kubectl get services
  • Obtenir les détails : kubectl describe service web-svc
  • Voir les endpoints : kubectl get endpoints web-svc (ou kubectl get endpointslices)
  • Exposer un Deployment : kubectl expose deployment web --port=80 --target-port=80
  • Rediriger un port en local : kubectl port-forward service/web-svc 8080:80
  • Supprimer un Service : kubectl delete service web-svc
⚠️ **GitHub.com Fallback** ⚠️