Quelle est la différence entre les types de service ClusterIP, NodePort et LoadBalancer dans Kubernetes?

230

1 - Je lis la documentation et je suis légèrement confus avec le libellé. Ça dit:

ClusterIP : expose le service sur une IP interne au cluster. Le choix de cette valeur rend le service uniquement accessible à partir du cluster. Il s'agit du ServiceType par défaut

NodePort : expose le service sur l'IP de chaque nœud à un port statique (le NodePort). Un service ClusterIP, vers lequel le service NodePort achemine, est automatiquement créé. Vous pourrez contacter le service NodePort, depuis l'extérieur du cluster, en faisant la demande <NodeIP>:<NodePort>.

LoadBalancer : expose le service en externe à l'aide de l'équilibreur de charge d'un fournisseur de cloud. Les services NodePort et ClusterIP, vers lesquels l'équilibreur de charge externe sera acheminé, sont automatiquement créés.

Le type de service NodePort utilise-t-il toujours le ClusterIPmais juste sur un port différent, qui est ouvert aux clients externes? Donc, dans ce cas, c'est <NodeIP>:<NodePort>la même chose que <ClusterIP>:<NodePort>?

Ou est-ce NodeIPréellement l'IP trouvée lors de l'exécution kubectl get nodeset non l'IP virtuelle utilisée pour le type de service ClusterIP?

2 - Également dans le diagramme du lien ci-dessous:

http://kubernetes.io/images/docs/services-iptables-overview.svg

Y a-t-il une raison particulière pour laquelle le Clientest à l'intérieur du Node? J'ai supposé qu'il devrait être à l'intérieur d'un Clusterdans le cas d'un type de service ClusterIP.

Si le même diagramme a été dessiné pour NodePort, serait-il valable de dessiner le client complètement en dehors du Nodeet Clusterou est-ce que je manque complètement le point?

AmazingBergkamp
la source

Réponses:

217

Un ClusterIP expose les éléments suivants:

  • spec.clusterIp:spec.ports[*].port

Vous ne pouvez accéder à ce service qu'à l'intérieur du cluster. Il est accessible depuis son spec.clusterIpport. Si a spec.ports[*].targetPortest défini, il sera acheminé du port vers le port cible. L'IP CLUSTER que vous obtenez lors de l'appel kubectl get servicesest l'IP attribuée à ce service au sein du cluster en interne.

Un NodePort expose les éléments suivants:

  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Si vous accédez à ce service sur un nodePort à partir de l'IP externe du nœud, il acheminera la demande vers spec.clusterIp:spec.ports[*].port, qui l'acheminera à son tour vers votre spec.ports[*].targetPort, s'il est défini. Ce service est également accessible de la même manière que ClusterIP.

Vos NodeIP sont les adresses IP externes des nœuds. Vous ne pouvez pas accéder à votre service depuis <ClusterIP>:spec.ports[*].nodePort.

Un LoadBalancer expose les éléments suivants:

  • spec.loadBalancerIp:spec.ports[*].port
  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Vous pouvez accéder à ce service à partir de l'adresse IP de votre équilibreur de charge, qui achemine votre demande vers un nodePort, qui à son tour achemine la demande vers le port clusterIP. Vous pouvez accéder à ce service comme vous le feriez pour un service NodePort ou ClusterIP.

kellanburket
la source
3
Pourriez-vous commenter comment externalIPschange l'équation ici? Plus précisément, il est possible d'affecter un externalIPstableau à un ClusterIPservice de type, puis le service devient également accessible sur l'IP externe? Quand choisiriez-vous cela sur un NodePort?
Bosh
La question ne mentionne pas les IP externes - je pense que vous seriez probablement mieux servi en publiant ceci comme une nouvelle question.
kellanburket
39
Ce message est en fait plus utile pour clarifier ces différences que la documentation officielle de Kubernetes elle-même.
adrpino
@kellanburket, comment cela fonctionne: spec.clusterIp. ClusterIP peut-il être explicitement mentionné dans service.yaml. Et de mêmespec.loadBalancerIp
samshers
vous avez fait ma journée avec votre réponse, merci beaucoup! (en
passant
103

Pour clarifier pour quiconque cherche quelle est la différence entre les 3 à un niveau plus simple. Vous pouvez exposer votre service avec un ClusterIp minimal (dans le cluster k8s) ou une exposition plus importante avec NodePort (dans le cluster externe au cluster k8s) ou LoadBalancer (monde externe ou tout ce que vous avez défini dans votre LB).

Exposition ClusterIp <Exposition NodePort <Exposition LoadBalancer

  • ClusterIp
    Expose service via le cluster k8s avecip/name:port
  • Le
    service NodePort Expose via les machines virtuelles du réseau interne est également externe aux k8ip/name:port
  • LoadBalancer
    Expose service via le monde externe ou tout ce que vous avez défini dans votre LB.
Tomer Ben David
la source
53

ClusterIP: les services sont accessibles par des modules / services dans le cluster
Si je crée un service appelé myservice dans l'espace de noms par défaut de type: ClusterIP, l'adresse DNS statique prévisible suivante pour le service sera créée:

myservice.default.svc.cluster.local (ou simplement myservice.default, ou par des pods dans l'espace de noms par défaut, juste "myservice" fonctionnera)

Et ce nom DNS ne peut être résolu que par des pods et des services à l'intérieur du cluster.

NodePort: Les services sont accessibles par les clients sur le même LAN / clients qui peuvent envoyer une requête ping aux nœuds hôtes K8 (et aux pods / services du cluster) (Remarque pour la sécurité, vos nœuds hôtes k8 devraient être sur un sous-réseau privé, donc les clients sur Internet ont gagné ne pourra pas accéder à ce service)
Si je crée un service appelé mynodeportservice dans l'espace de noms mynamespace de type: NodePort sur un cluster Kubernetes à 3 nœuds. Ensuite, un service de type: ClusterIP sera créé et il sera accessible par les clients à l'intérieur du cluster à l'adresse DNS statique prévisible suivante:

mynodeportservice.mynamespace.svc.cluster.local (ou simplement mynodeportservice.mynamespace)

Pour chaque port que mynodeportservice écoute sur un port de noeud dans la plage de 30000 à 32767 sera choisi au hasard. Pour que les clients externes situés en dehors du cluster puissent accéder au service ClusterIP qui existe à l'intérieur du cluster. Disons que nos 3 nœuds hôtes K8 ont des adresses IP 10.10.10.1, 10.10.10.2, 10.10.10.3, le service Kubernetes écoute sur le port 80 et le Nodeport choisi au hasard était 31852.

Un client qui existe en dehors du cluster pourrait visiter 10.10.10.1:31852, 10.10.10.2:31852 ou 10.10.10.3:31852 (car NodePort est écouté par chaque nœud hôte Kubernetes) Kubeproxy transmet la demande au port 80 de mynodeportservice.

LoadBalancer: les services sont accessibles à tous ceux qui sont connectés à Internet * (L'architecture courante est que L4 LB est accessible au public sur Internet en le plaçant dans une DMZ ou en lui donnant à la fois une IP privée et publique et les nœuds hôtes k8s se trouvent sur un sous-réseau privé)
( Remarque: Il s'agit du seul type de service qui ne fonctionne pas dans 100% des implémentations de Kubernetes, comme Kubernetes bare metal, il fonctionne lorsque Kubernetes a des intégrations de fournisseur de cloud.)

Si vous créez mylbservice, une machine virtuelle L4 LB sera générée (un service IP de cluster et un service NodePort seront également implicitement générés). Cette fois, notre NodePort est 30222. L'idée est que le L4 LB aura une IP publique de 1.2.3.4 et qu'il chargera l'équilibre et acheminera le trafic vers les 3 nœuds hôtes K8 qui ont des adresses IP privées. (10.10.10.1:30222, 10.10.10.2:30222, 10.10.10.3:30222), puis Kube Proxy le transmettra au service de type ClusterIP qui existe à l'intérieur du cluster.


Vous avez également demandé: le type de service NodePort utilise-t-il toujours le ClusterIP? Oui *
Ou le NodeIP est-il réellement l'IP trouvé lorsque vous exécutez kubectl get nodes? Aussi Oui *

Permet de dessiner un parallèle entre les principes de base:
un conteneur est à l'intérieur d'un pod. un pod se trouve à l'intérieur d'un jeu de répliques. un jeu de répliques se trouve dans un déploiement.
De même,
un service ClusterIP fait partie d'un service NodePort. Un service NodePort fait partie d'un service d'équilibrage de charge.


Dans ce diagramme que vous avez montré, le client serait un pod à l'intérieur du cluster.

neokyle
la source
Sur la base de vos questions de suivi, j'avais l'impression que vous vouliez savoir comment le trafic était entré dans le cluster. J'ai pris la liberté de faire un Q&A à ce sujet si vous êtes intéressé. stackoverflow.com/questions/52241501/…
neokyle
1
Hé, vraiment une bonne explication, je me pose des questions sur le LoadBalancer. Le LoadBalancer transmettra tout trafic à un NodeIP: NodePort (ce nœud qui est le suivant dans le tournoi à la ronde) et comment l'appel se déroule-t-il sur ce nœud? Comment le port de nœud sait-il qu'il s'agit d'un appel de service et qu'il doit le distribuer via le proxy de cube à l'adresse IP virtuelle du service? Le kube-proxy fera-t-il un simple transfert de port?
ItFreak
kube-proxy joue 3 rôles principaux: 1. faire en sorte que les services existent / fonctionnent en faisant correspondre les iptables sur le nœud à l'état souhaité des services dans etcd. 2. est responsable de la mise en correspondance du port du nœud avec le service au pod (si j'ai bien compris, il le fait via iptables) + remappage des ports 3. assurez-vous que chaque pod a une adresse IP unique. Le nodeport pourrait entrer sur 1 noeud, les définitions de service existent dans les iptables de chaque noeud / services existent sur chaque noeud, les pods sont généralement sur un réseau de superposition virtualisé, et les noeuds doublent comme routeurs, donc bien que le trafic arrive sur 1 noeud, il est routé vers un pod existant sur un autre nœud.
neokyle
Savoir comment cela fonctionne à un niveau plus profond que cela est inutile, car Kubernetes est fait de pièces modulaires, et comme la façon dont Linux a des saveurs / distributions qui fonctionnent toutes un peu différemment avec certains thèmes primordiaux, chaque distribution K8s est légèrement différente. Exemple cilium cni cherche à remplacer complètement kube-proxy, ce qui signifie que son fonctionnement en arrière-plan est une cible mobile, donc ne vaut pas la peine d'être compris à moins que vous ne contribuiez réellement au projet / que vous essayiez de corriger un bogue.
neokyle
Existe-t-il un moyen de vous contacter? J'écris une thèse de licence sur la sécurité dans les k8 et j'aimerais en savoir plus sur les fonctions internes du proxy, par exemple, comment distribuer les adresses IP aux nœuds et aux pods et comment les services obtiennent-ils leur IP virtuelle
ItFreak
45

Supposons que vous avez créé une machine virtuelle Ubuntu sur votre machine locale. Son adresse IP est 192.168.1.104 .

Vous vous connectez à VM et installez Kubernetes. Ensuite, vous avez créé un pod où l'image nginx s'exécute dessus.

1- Si vous souhaitez accéder à ce pod nginx à l'intérieur de votre VM, vous allez créer un ClusterIP lié à ce pod par exemple:

$ kubectl expose deployment nginxapp --name=nginxclusterip --port=80 --target-port=8080

Ensuite, sur votre navigateur, vous pouvez taper l'adresse IP de nginxclusterip avec le port 80, comme:

http://10.152.183.2:80

2- Si vous souhaitez accéder à ce pod nginx depuis votre machine hôte, vous devrez exposer votre déploiement avec NodePort . Par exemple:

$ kubectl expose deployment nginxapp --name=nginxnodeport --port=80 --target-port=8080 --type=NodePort

Maintenant, à partir de votre machine hôte, vous pouvez accéder à nginx comme:

http://192.168.1.104:31865/

Dans mon tableau de bord, ils apparaissent comme:

entrez la description de l'image ici

Ci-dessous, un diagramme montre la relation de base.

entrez la description de l'image ici

Teoman shipahi
la source
D'où vient 31865? généré?
HoaPhan
1
@HoaPhan Vous pouvez explicitement spécifier votre port dans la plage de 30000-32767 ou le laisser choisi au hasard par Kubernetes dans cette plage
Mohammad Torkashvand
20

Même si cette question a déjà une réponse, j'en fournirai une autre, peut-être avec quelques photos supplémentaires afin d'avoir une meilleure compréhension.

1. ClusterIP c'est le type de service par défaut dans Kubernetes et ce type vous donne un service à l'intérieur du cluster. En l'utilisant, d'autres applications du cluster peuvent accéder au service via le proxy Kubernetes.

Je dois mentionner que ce type de service ne doit pas être utilisé pour exposer des services de production. Cependant, il peut être utilisé pour

  • débogage de l'intégration entre les services;
  • accéder à des services internes qui exposent des données non commerciales (surveillance des tableaux de bord).

La façon dont la demande se déroule est la suivante: trafic -> proxy K8s -> service K8s (ClusterIP) -> pods et il est affiché dans l'image suivante.

entrez la description de l'image ici

2. NodePort est le moyen le plus primitif d'accepter le trafic externe et de le transmettre aux services kubernetes. Comme son nom l'indique, le type de service NodePort ouvre un port spécifique sur toutes les machines virtuelles, qui sont en fait les nœuds Kubernetes, afin de permettre au trafic envoyé à ce port spécifique d'être transféré au service.

Le type de service NodePort présente certains inconvénients:

  • il est nécessaire d'avoir un seul service par port;
  • si l'ip de la machine virtuelle sera modifiée, certaines modifications doivent être effectuées dans le cluster;
  • seul le port entre 3000-32767 peut être utilisé.

La façon dont cette demande se déroule est la suivante: trafic -> port exposé sur la machine virtuelle -> service K8s (NodePort) -> pods et il est affiché dans l'image suivante:

entrez la description de l'image ici

3. LoadBalancer est le moyen standard d'exposer un service à Internet. Si vous souhaitez exposer directement un service et tout le trafic sur un port spécifique pour être averti du service, alors c'est la façon de le faire. De plus, le type de service LoadBalancer n'implique aucun filtrage ni routage. Vous pouvez également lui envoyer du trafic TCP, UDP, HTTP gRPC.

Inconvénient: chaque service exposé via un LoadBalancer aura sa propre adresse IP et chaque service sera exposé via un seul LoadBalancer qui peut devenir coûteux.

La demande a le chemin suivant: trafic -> LoadBalancer -> Service K8s -> pods et elle est affichée dans l'image suivante.

entrez la description de l'image ici

Dina Bogdan
la source
7
  1. clusterIP: IP accessible à l'intérieur du cluster (entre les nœuds du cluster d).
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3 peut parler à pod1 via leur réseau clusterIP.

  1. nodeport: pour rendre les pods accessibles de l'extérieur du cluster via nodeIP: nodeport, il créera / gardera clusterIP ci-dessus comme son réseau clusterIP.
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

vous pouvez accéder au service sur pod1 via nodeIPA: nodeportX OU nodeIPB: nodeportX. Dans les deux cas, cela fonctionnera car kube-proxy (qui est installé dans chaque nœud) recevra votre demande et la distribuera [la redirigera (terme iptables)] sur les nœuds à l'aide du réseau clusterIP.

  1. Équilibreur de charge

en gros, il suffit de mettre LB en avant, afin que le trafic entrant soit distribué à nodeIPA: nodeportX et nodeIPB: nodeportX, puis continuez avec le flux de processus numéro 2 ci-dessus.

Alfred
la source