Contactez-nous

Types de Services : ClusterIP, NodePort, LoadBalancer

Explorez les principaux types de Services Kubernetes (ClusterIP, NodePort, LoadBalancer) et comprenez quand et comment utiliser chacun pour exposer vos applications.

Choisir le bon mode d'exposition : les types de Services

Nous avons compris qu'un Service Kubernetes fournit une abstraction réseau stable pour accéder à un ensemble de Pods. Cependant, toutes les applications n'ont pas besoin d'être accessibles de la même manière. Certaines sont des services internes qui ne devraient être joignables que depuis d'autres Pods dans le cluster (comme une base de données), tandis que d'autres (comme une application web) doivent être exposées à l'extérieur du cluster, voire sur Internet.

Pour répondre à ces différents besoins, Kubernetes propose plusieurs types de Services. Le type de Service que vous choisissez détermine *comment* le Service est exposé et *d'où* il est accessible. Les trois principaux types que nous allons explorer sont `ClusterIP`, `NodePort`, et `LoadBalancer`.

Le type est spécifié dans le champ `spec.type` du manifeste YAML du Service. Si vous omettez ce champ, Kubernetes utilise le type par défaut : `ClusterIP`.

ClusterIP : l'accès interne par défaut

Type : `ClusterIP` (par défaut)

Objectif : Exposer le Service sur une adresse IP interne au cluster, accessible uniquement depuis l'intérieur du cluster (par d'autres Pods ou services).

Fonctionnement : Kubernetes attribue une adresse IP virtuelle stable, appelée ClusterIP, à partir d'une plage d'adresses réservée au sein du cluster. Cette adresse IP n'est routable que depuis l'intérieur du cluster. Le Service écoute sur les ports spécifiés (`spec.ports.port`) sur cette ClusterIP et redirige le trafic vers les `targetPort` des Pods correspondants au sélecteur.

Cas d'usage : C'est le type de Service le plus courant pour la communication inter-services au sein du cluster. Idéal pour les backends, les bases de données, les files d'attente, les API internes, ou tout service qui n'a pas besoin d'être directement exposé à l'extérieur.

Exemple YAML :

apiVersion: v1
kind: Service
metadata:
  name: mon-backend-service
spec:
  selector:
    app: mon-backend
  ports:
  - protocol: TCP
    port: 8080       # Port du Service (sur le ClusterIP)
    targetPort: 9000 # Port des Pods backend
  # type: ClusterIP  # Peut être omis car c'est le défaut

Les autres Pods du cluster peuvent accéder à ce service via son nom DNS (`mon-backend-service.nom-du-namespace.svc.cluster.local` ou simplement `mon-backend-service` s'ils sont dans le même namespace) ou via son ClusterIP et le port 8080.

NodePort : exposition basique via les noeuds

Type : `NodePort`

Objectif : Exposer le Service sur un port statique (le NodePort) sur l'adresse IP de *chaque* Noeud Worker du cluster. Cela rend le service accessible depuis l'extérieur du cluster en utilisant `:`.

Fonctionnement :

  • Un Service de type `NodePort` fait tout ce qu'un `ClusterIP` fait (il obtient une ClusterIP interne).
  • En plus, Kubernetes choisit un port dans une plage spécifique (par défaut 30000-32767) ou utilise celui que vous spécifiez explicitement dans `spec.ports.nodePort`.
  • Kube-proxy configure alors chaque noeud pour qu'il écoute sur ce NodePort et redirige le trafic reçu vers la ClusterIP du Service (qui à son tour le redirige vers les Pods).

Cas d'usage :

  • Développement, tests, ou démonstrations où une exposition externe rapide est nécessaire.
  • Situations où vous gérez votre propre équilibreur de charge externe et que vous le configurez pour pointer vers les `NodePort` de vos noeuds Kubernetes.
  • Environnements où un service de type `LoadBalancer` n'est pas disponible (par exemple, on-premise sans intégration spécifique).

Inconvénients : Vous devez connaître l'adresse IP d'au moins un noeud, la plage de ports est limitée et généralement élevée, et ce n'est pas une solution très robuste ou élégante pour une exposition en production à grande échelle (pas de gestion de la santé des noeuds par un LB externe par défaut).

Exemple YAML :

apiVersion: v1
kind: Service
metadata:
  name: mon-app-nodeport
spec:
  type: NodePort
  selector:
    app: mon-app
  ports:
  - protocol: TCP
    port: 80         # Port interne du Service (sur le ClusterIP)
    targetPort: 8080 # Port des Pods
    nodePort: 30080  # Port statique sur chaque noeud (optionnel, K8s choisit sinon)

Ce service sera accessible via `http://:30080` depuis l'extérieur du cluster, ainsi que via `mon-app-nodeport` sur le port 80 depuis l'intérieur.

LoadBalancer : intégration cloud pour l'accès externe

Type : `LoadBalancer`

Objectif : Exposer le Service à l'extérieur du cluster en utilisant l'équilibreur de charge du fournisseur de cloud (ou une solution équivalente on-premise).

Fonctionnement :

  • Un Service de type `LoadBalancer` fait tout ce qu'un `NodePort` fait (il crée un NodePort et une ClusterIP).
  • En plus, il demande à l'infrastructure sous-jacente (généralement le cloud provider via le cloud-controller-manager) de provisionner un équilibreur de charge externe (par exemple, un AWS Elastic Load Balancer, un Google Cloud Load Balancer, un Azure Load Balancer).
  • Cet équilibreur de charge externe obtient une adresse IP publique stable et est configuré pour router le trafic externe vers les `NodePort` (ou parfois directement vers les Pods, selon l'implémentation CNI/cloud) des noeuds du cluster.
  • L'adresse IP externe de l'équilibreur de charge est ensuite enregistrée dans le champ `status.loadBalancer.ingress` de l'objet Service.

Cas d'usage : C'est la méthode standard et recommandée pour exposer des applications (comme des sites web ou des API) à Internet ou à des réseaux externes lorsque vous exécutez Kubernetes sur un fournisseur de cloud supporté.

Prérequis et Inconvénients : Nécessite une infrastructure supportant la fourniture automatique d'équilibreurs de charge (principalement les clouds publics ou des solutions on-premise comme MetalLB). Chaque Service de type `LoadBalancer` provisionne généralement son propre équilibreur de charge, ce qui peut entraîner des coûts supplémentaires auprès du fournisseur de cloud.

Exemple YAML :

apiVersion: v1
kind: Service
metadata:
  name: mon-app-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: mon-app
  ports:
  - protocol: TCP
    port: 80         # Port du Service (sur le ClusterIP ET sur le LoadBalancer)
    targetPort: 8080 # Port des Pods

Après quelques instants, vous pourrez obtenir l'IP externe avec `kubectl get service mon-app-loadbalancer` et accéder à l'application via `http://:80`.

ExternalName : un alias DNS externe

Il existe un quatrième type, moins courant : `ExternalName`.

Type : `ExternalName`

Objectif : Créer un alias DNS interne au cluster vers un nom de service externe (en dehors du cluster).

Fonctionnement : Ce type de Service ne fait pas de proxying ni d'équilibrage de charge. Il ne sélectionne aucun Pod. Il configure simplement le DNS interne du cluster (CoreDNS) pour qu'une requête vers le nom du Service (par exemple, `mon-service-externe.mon-namespace`) retourne un enregistrement CNAME pointant vers le nom externe spécifié dans `spec.externalName`.

Cas d'usage : Permettre aux applications à l'intérieur du cluster d'accéder à un service externe (par exemple, une base de données managée par le cloud provider ou une API tierce) en utilisant un nom interne stable, sans avoir à coder en dur le nom externe dans la configuration des applications.

Exemple YAML :

apiVersion: v1
kind: Service
metadata:
  name: ma-db-externe
  namespace: production
spec:
  type: ExternalName
  externalName: abcd1234efgh.us-west-2.rds.amazonaws.com

Les Pods dans le namespace `production` peuvent maintenant contacter `ma-db-externe` et le DNS résoudra cela en l'adresse RDS externe.

Résumé des types de Services

TypeAccessibilitéIP StableCas d'usage principalPrérequis
ClusterIP (défaut)Interne au cluster uniquementClusterIP (interne)Communication inter-servicesAucun
NodePortInterne + Externe (via IP Noeud:NodePort)ClusterIP (interne) + NodePort (sur chaque noeud)Dev/Test, LB externe manuelAucun
LoadBalancerInterne + Externe (via IP du LB)ClusterIP (interne) + IP Externe du LBExposition externe en production (Cloud)Support Cloud/Infra
ExternalNameN/A (Alias DNS)N/AAccéder à des services externes via un nom interneAucun

Choisir le bon type de Service est essentiel pour contrôler comment et par qui vos applications peuvent être atteintes. Maintenant que nous savons comment exposer les services, il faut comprendre comment ils découvrent les Pods cibles : c'est le rôle du DNS interne.