NodePort vs. LoadBalancer vs. Ingress : Choisir la meilleure exposition de service

Naviguez dans le choix crucial de l'exposition externe des services Kubernetes en comparant NodePort, LoadBalancer et Ingress. Ce guide détaille l'architecture, la couche opérationnelle (L4 vs L7), les cas d'utilisation et les différences clés en termes de coût et de complexité pour chaque méthode. Apprenez quand utiliser le simple NodePort pour les tests, le LoadBalancer dédié pour les services uniques, ou le puissant Ingress pour un routage centralisé et économique en couche 7 et des environnements multi-services complexes.

NodePort vs. LoadBalancer vs. Ingress : Choisir la meilleure exposition de service

Kubernetes attribue des adresses IP temporaires aux Pods, puis utilise des Services pour fournir un moyen stable de les atteindre. À l'intérieur du cluster, un Service ClusterIP normal est souvent suffisant. La question devient plus intéressante lorsque quelque chose à l'extérieur du cluster doit se connecter.

Les trois noms qui reviennent le plus souvent sont NodePort, LoadBalancer et Ingress. Ils sont liés, mais ils ne sont pas interchangeables. NodePort ouvre un port sur chaque nœud. LoadBalancer demande au fournisseur d'infrastructure un équilibreur de charge externe. Ingress définit des règles de routage HTTP et nécessite un contrôleur Ingress pour concrétiser ces règles.


1. Type d'exposition de service : NodePort

Le type de service NodePort est le moyen le plus simple et le plus primitif d'exposer un service de l'extérieur. Lorsque vous définissez un service comme NodePort, Kubernetes ouvre un port statique spécifique sur chaque nœud du cluster. Tout trafic dirigé vers ce port sur n'importe quel nœud est routé directement vers le service.

Comment fonctionne NodePort

  1. Un port aléatoire dans une plage désignée (par défaut : 30000-32767) est automatiquement sélectionné.
  2. Ce port est ouvert sur tous les nœuds du cluster.
  3. Le Service écoute sur ce NodePort, redirigeant le trafic vers les Pods appropriés.

Pour accéder à l'application, vous utilisez http://<IP_du_Noeud>:<NodePort>.

Cas d'utilisation et limitations

Fonctionnalité Description
Cas d'utilisation Environnements de développement, de test, ou lorsque l'équilibrage de charge externe est géré par un appareil externe non-cloud.
Complexité Très faible.
Coût Zéro (si l'on ignore les coûts sous-jacents des VM).
Limitation Nécessite la gestion manuelle des règles de pare-feu externes. Les adresses IP des nœuds sont souvent dynamiques. Restriction de plage de ports (30000-32767).

Exemple NodePort

apiVersion: v1
kind: Service
metadata:
  name: my-app-nodeport
spec:
  type: NodePort
  selector:
    app: my-web-app
  ports:
    - port: 80
      targetPort: 8080
      # Optionnel : spécifier un NodePort, sinon un est choisi automatiquement
      # nodePort: 30001 

Avertissement : NodePort expose le service via les adresses IP des nœuds et un port élevé. Il peut être utile derrière votre propre équilibreur de charge externe, surtout sur du bare metal, mais il est peu pratique comme interface publique pour une application web de production.


2. Type d'exposition de service : LoadBalancer

Le type de service LoadBalancer est la méthode standard pour exposer les applications à l'internet public dans les environnements cloud (AWS EKS, GCP GKE, Azure AKS).

Lorsqu'un service est défini comme LoadBalancer, Kubernetes demande à l'intégration d'équilibreur de charge du cluster de provisionner un équilibreur de charge externe. Dans les clusters cloud gérés, cela signifie souvent un équilibreur de charge cloud L4. Dans les clusters bare metal, cela peut signifier un projet tel que MetalLB ou une autre intégration locale. Le résultat est généralement une adresse externe stable qui redirige le trafic vers le Service.

Intégration avec le fournisseur cloud

Le différenciateur clé de LoadBalancer est l'intégration profonde avec l'infrastructure cloud sous-jacente. Le fournisseur cloud gère le cycle de vie de l'équilibreur de charge, les vérifications de santé et le routage.

Cas d'utilisation et implications de coût

Fonctionnalité Description
Cas d'utilisation Applications simples orientées public nécessitant une adresse IP stable et dédiée. Convient aux protocoles non-HTTP/S (TCP/UDP).
Complexité Faible (en termes de configuration).
Coût Souvent plus élevé dans les environnements cloud car chaque Service peut créer une ressource d'équilibreur de charge distincte.
Avantage Offre une haute disponibilité immédiate et des vérifications de santé automatiques.

Exemple LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: my-app-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: my-api-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Lors de la création, le cluster attribuera une adresse IP externe (visible dans le statut du service) gérée par le fournisseur cloud.


3. Ingress Kubernetes : Routage en couche 7

Ingress est fondamentalement différent de NodePort et LoadBalancer. Ingress n'est pas un type de Service mais plutôt un objet API qui définit des règles d'accès externe, généralement HTTP et HTTPS (Couche 7).

Ingress agit comme un point d'entrée central, permettant un routage sophistiqué basé sur les noms d'hôte et les chemins d'URL. Cette approche est essentielle pour gérer plusieurs services derrière une seule adresse IP.

Le rôle du contrôleur Ingress

Pour que les règles Ingress fonctionnent, vous devez d'abord déployer un contrôleur Ingress tel que ingress-nginx, Traefik, HAProxy, ou un contrôleur de fournisseur cloud. Les maillages de services tels qu'Istio peuvent également fournir une gestion du trafic de type passerelle, mais ils ne sont pas la même chose que l'API Ingress de base de Kubernetes.

Le contrôleur Ingress lui-même est généralement exposé à l'aide d'un seul Service LoadBalancer ou NodePort.

Fonctionnalités avancées d'Ingress

Ingress excelle lorsque vous avez besoin de fonctionnalités avancées de gestion du trafic :

  1. Optimisation des coûts : Utilisez un seul équilibreur de charge cloud (pour exposer le contrôleur) au lieu d'un équilibreur de charge par service applicatif.
  2. Hébergement virtuel : Routez le trafic en fonction des noms d'hôte (api.example.com va au Service A ; www.example.com va au Service B).
  3. Routage basé sur le chemin : Routez le trafic en fonction des chemins d'URL (/v1/utilisateurs va au Service A ; /v2/articles va au Service B).
  4. Terminaison SSL/TLS : Gérez la gestion des certificats et le déchiffrement de manière centralisée.

Exemple de ressource Ingress

Cet exemple route le trafic pour api.example.com/v1 vers le service my-api-v1.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  ingressClassName: nginx # Spécifiez le contrôleur utilisé
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: my-api-v1
            port:
              number: 80
  # ... autres règles pour différents services/hôtes

4. Comparaison et guide de sélection

Choisir la méthode optimale implique de peser des facteurs tels que l'environnement, la complexité, l'ensemble des fonctionnalités et le coût opérationnel.

Tableau comparatif des fonctionnalités

Fonctionnalité NodePort LoadBalancer Ingress
Couche L4 (TCP/UDP) L4 (TCP/UDP) L7 (HTTP/S)
Stabilité (IP) Instable (utilise l'IP du nœud) Stable (IP cloud dédiée) Stable (utilise l'IP du contrôleur)
Coût Faible (frais opérationnels élevés) Élevé (coût de ressource par service) Modéré (un équilibreur de charge pour le contrôleur)
Logique de routage Redirection de port simple Redirection de port simple Nom d'hôte, Chemin, Terminaison SSL
Dépendance cloud Aucune Dépend de l'intégration du fournisseur Dépend du contrôleur et de la méthode d'exposition
Prêt pour la production Parfois, généralement derrière un autre équilibreur de charge Oui pour une exposition L4 simple Oui pour le routage HTTP/S

Critères de décision : Choisir votre méthode d'exposition

  1. Pour un usage interne ou de test uniquement : Si vous avez simplement besoin de tester la connectivité au sein de votre cluster, ou si vous gérez vous-même la mise en réseau externe (par exemple, dans un environnement bare metal), utilisez NodePort.

  2. Pour une exposition L4 simple et dédiée : Si votre application utilise des protocoles non-HTTP (comme des protocoles TCP personnalisés ou UDP) ou si vous n'avez qu'une seule application publique qui nécessite un accès L4 immédiat et dédié, utilisez LoadBalancer.

  3. Pour une exposition L7 complexe et multi-services : Si vous avez plusieurs services à exposer, nécessitez un routage basé sur le chemin ou le nom d'hôte, avez besoin d'une terminaison SSL centralisée, ou souhaitez minimiser les coûts cloud en partageant une seule adresse IP externe, utilisez Ingress.

Pour de nombreuses applications HTTP/S de production, Ingress est le choix habituel car il centralise les certificats et le routage. Pour les bases de données, les courtiers de messages, les serveurs de jeux, les services TCP bruts, ou tout ce qui n'est pas vraiment HTTP, un Service LoadBalancer peut être plus clair. Pour les clusters bare metal, NodePort peut encore faire partie de la conception, mais il est généralement placé derrière un équilibreur de charge externe approprié ou une règle de pare-feu.

Comment ils s'assemblent dans les clusters réels

Une partie déroutante est que ces options peuvent s'empiler les unes sur les autres. Un objet Ingress n'expose pas les paquets par lui-même. Le contrôleur reçoit le trafic d'une manière ou d'une autre, et ce "d'une manière ou d'une autre" est souvent un Service LoadBalancer dans un cluster cloud :

Internet
  -> Équilibreur de charge cloud
  -> Service type LoadBalancer pour ingress-nginx
  -> Pods du contrôleur Ingress
  -> Règle Ingress
  -> Service ClusterIP
  -> Pods de l'application

Sur bare metal, le chemin peut utiliser NodePort à la place :

Réseau internet ou d'entreprise
  -> Équilibreur de charge externe / pare-feu
  -> NodeIP:NodePort
  -> Pods du contrôleur Ingress
  -> Service de l'application

C'est pourquoi dire "utilisez Ingress au lieu de LoadBalancer" est un peu imprécis. Ingress utilise souvent encore un équilibreur de charge, mais il permet à de nombreuses applications HTTP de partager un seul point d'entrée.

Exemples pratiques

Utilisez NodePort lorsque vous déboguez un cluster de laboratoire, exposez un service temporairement à un réseau privé, ou intégrez-le avec du matériel d'équilibrage de charge que vous gérez déjà. Ne forcez pas les utilisateurs à se souvenir de https://app.example.com:31427 à moins qu'il ne s'agisse véritablement d'un outil interne.

Utilisez LoadBalancer lorsqu'un service a besoin d'une adresse externe stable et que le transfert L4 est suffisant. Une API TCP publique, un service UDP ou un point de terminaison d'administration interne unique peuvent être plus simples de cette façon. C'est également utile lorsque le protocole applicatif ne correspond pas au routage HTTP standard hôte/chemin.

Utilisez Ingress lorsque vous avez des applications web. Si api.example.com, docs.example.com et app.example.com vivent tous dans le même cluster, Ingress vous offre un endroit unique pour gérer le routage des hôtes et TLS. Ajoutez cert-manager, et le renouvellement des certificats peut devenir un flux de travail normal du cluster au lieu d'une tâche manuelle sur le serveur.

Vérifications de sécurité et opérations

L'objet d'exposition n'est qu'une partie de la décision de production. Vous devez également vous demander qui peut atteindre le point de terminaison, où TLS se termine, comment les adresses IP source sont préservées et comment les défaillances sont observées.

Avec NodePort, vérifiez attentivement les règles de pare-feu. Kubernetes peut ouvrir le port sur chaque nœud, mais votre réseau décide toujours si le monde extérieur peut l'atteindre. Dans les environnements cloud, les groupes de sécurité ou les règles de pare-feu doivent souvent autoriser la plage NodePort. Sur bare metal, la même préoccupation peut résider dans un pare-feu périmétrique. Si vous souhaitez qu'un outil d'administration privé ne soit accessible que depuis un VPN, appliquez cette restriction en dehors de Kubernetes ainsi qu'à l'intérieur.

Avec LoadBalancer, inspectez les annotations spécifiques au fournisseur. Elles contrôlent souvent si l'équilibreur de charge est interne ou orienté internet, quel protocole il utilise, quel chemin de vérification de santé il sonde et s'il préserve l'adresse IP source du client. Ces détails varient selon le fournisseur, alors ne supposez pas qu'un manifeste copié d'un cloud se comportera de la même manière dans un autre.

Avec Ingress, le centre opérationnel se déplace vers le contrôleur. Vous avez besoin de journaux et de métriques provenant des pods du contrôleur, pas seulement des pods de l'application. Si une route échoue, le Service et les Pods peuvent être sains tandis que le contrôleur a rejeté la règle, utilisé la mauvaise classe Ingress, manqué un secret TLS, ou routé vers le mauvais chemin de backend. Une liste de contrôle rapide vous aide :

kubectl get ingress
kubectl describe ingress example-ingress
kubectl get svc -n ingress-nginx
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller

Soyez également clair sur TLS. Ingress termine généralement HTTPS au niveau du contrôleur et envoie HTTP au Service backend. C'est acceptable pour de nombreux clusters internes, mais certaines équipes exigent un chiffrement jusqu'au pod applicatif. Si c'est votre exigence, configurez le TLS backend intentionnellement au lieu de supposer qu'Ingress le fournit automatiquement.

Modes de défaillance courants

Si un NodePort fonctionne depuis un nœud mais pas depuis un autre, vérifiez si kube-proxy ou le CNI du cluster est sain sur le nœud défaillant. Vérifiez également si le pare-feu externe autorise le trafic vers chaque adresse IP de nœud que vous prévoyez d'utiliser.

Si un Service LoadBalancer reste en Pending, le cluster ne peut probablement pas provisionner l'équilibreur de charge externe. Dans Kubernetes géré, cela peut signifier une intégration de contrôleur cloud manquante, des autorisations, des balises de sous-réseau, un quota ou des paramètres spécifiques au fournisseur. Dans Kubernetes bare metal, cela signifie généralement qu'aucune implémentation d'équilibreur de charge n'est installée.

Si un Ingress renvoie une page de backend par défaut ou une 404 du contrôleur, la requête a atteint le contrôleur mais n'a pas correspondu à votre règle d'hôte ou de chemin. Vérifiez le DNS, l'en-tête Host, ingressClassName, le type de chemin, et si le nom et le port du Service sont corrects. Si vous obtenez un certificat TLS pour le mauvais nom d'hôte, vérifiez le secret référencé par l'Ingress et si une autre règle Ingress revendique le même hôte.

Un raccourci de décision simple

Commencez par le protocole. S'il s'agit de HTTP ou HTTPS et que plus d'une application pourrait éventuellement partager le point d'entrée, utilisez Ingress. S'il s'agit de TCP ou UDP brut et nécessite une adresse externe stable, utilisez LoadBalancer. Si vous testez, intégrez avec votre propre équipement réseau ou construisez un chemin bare metal, NodePort peut faire partie de la réponse.

Ensuite, vérifiez le modèle opérationnel. Une petite équipe gérant une seule API publique peut préférer un LoadBalancer car il est évident et facile à déboguer. Une équipe de plateforme hébergeant des dizaines de services web préférera généralement Ingress car le routage partagé, les certificats et les politiques sont plus importants que la couche de contrôleur supplémentaire.

Remarques finales

Choisissez en fonction du protocole et des opérations, pas de l'objet qui semble le plus avancé. NodePort est un bloc de construction. LoadBalancer est un accès L4 externe simple. Ingress est un routage HTTP/S via un contrôleur. Dans un petit cluster, les trois peuvent apparaître dans la même conception, et c'est acceptable tant que chacun a un travail clair.