Kubernetes中的ClusterIP,NodePort和LoadBalancer服务类型之间有什么区别?


230

1-我正在阅读文档,但措词有些困惑。它说:

ClusterIP:在群集内部IP上公开服务。选择此值将使服务仅可从群集内访问。这是默认的ServiceType

NodePort:在静态端口(NodePort)上的每个节点的IP上公开服务。将自动创建NodePort服务将路由到的ClusterIP服务。您可以通过请求从集群外部联系NodePort服务<NodeIP>:<NodePort>

LoadBalancer:使用云提供商的负载平衡器在外部公开服务。将自动创建外部负载均衡器将路由到的NodePort和ClusterIP服务。

NodePort服务类型是否仍然使用,ClusterIP但是仅在一个对外部客户端开放的端口上使用?那么在这种情况下是<NodeIP>:<NodePort>一样的<ClusterIP>:<NodePort>吗?

还是NodeIP在运行时实际找到的IP,kubectl get nodes而不是用于ClusterIP服务类型的虚拟IP?

2-同样在以下链接的图表中:

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

有什么特别的原因Client是里面的Node?我假设Cluster在ClusterIP服务类型的情况下,它必须位于内。

如果为NodePort绘制了相同的图,那么将客户端完全绘制在Node和之外是否有效,Cluster或者我是否完全忽略了要点?

Answers:


217

ClusterIP公开以下内容:

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

您只能在群集内访问此服务。可从其spec.clusterIp端口访问。如果spec.ports[*].targetPort设置了a ,它将从端口路由到targetPort。调用时获得的CLUSTER-IP kubectl get services是群集内部分配给该服务的IP。

NodePort公开以下内容:

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

如果您从节点的外部IP在nodePort上访问此服务,它将把请求路由到spec.clusterIp:spec.ports[*].port,然后将请求路由到您的spec.ports[*].targetPort(如果已设置)。也可以使用与ClusterIP相同的方式访问此服务。

您的NodeIP是节点的外部IP地址。您无法从访问服务<ClusterIP>:spec.ports[*].nodePort

LoadBalancer公开以下内容:

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

您可以从负载均衡器的IP地址访问此服务,该服务会将您的请求路由到nodePort,后者又将请求路由到clusterIP端口。您可以像访问NodePort或ClusterIP服务一样访问此服务。


3
您能否评论一下如何externalIPs改变方程式?具体来说,可以为-type服务分配一个externalIPs数组ClusterIP,然后该服务也可以在外部IP上访问?您何时会在NodePort上选择它?
波什

这个问题没有提到externalIPs-我认为最好将其发布为新问题来为您服务。
kellanburket

39
与正式的Kubernetes文档本身相比,这篇文章实际上对于澄清这些差异更有用。
adrpino

@kellanburket,这是如何工作的:spec.clusterIp。可以在service.yaml中明确提及ClusterIP。同样spec.loadBalancerIp
-samshers,

您的回答让我很高兴,非常感谢!(作为旁注,在2020年,联网文档仍然有点晦涩)
user430191

103

在任何更简单的层次上向正在寻找3的区别的人进行澄清。您可以使用最少的ClusterIp(在k8s集群内)公开服务,或者使用NodePort(在k8s集群外部的集群内)或LoadBalancer(外部世界或您在LB中定义的任何东西)公开更大的服务。

ClusterIp暴露<NodePort暴露<LoadBalancer暴露


  • 通过k8s群集使用ClusterIp公开服务ip/name:port

  • 通过内部网络虚拟机(也位于k8s外部)的NodePort Expose服务ip/name:port

  • 通过外部世界或您在LB中定义的任何内容进行LoadBalancer Expose服务。

53

ClusterIP:群集中的pod /服务可以访问服务。
如果在默认类型的名称空间中创建了名为myservice的服务:ClusterIP,则将为该服务创建以下可预测的静态DNS地址:

myservice.default.svc.cluster.local(或仅是myservice.default,或者通过默认名称空间中的Pod可以使用“ myservice”)

而且该DNS名称只能由群集中的Pod和服务来解析。

NodePort:服务可在同一局域网上的客户端访问,而客户端可以ping通K8s主机节点(以及集群中的Pod /服务)(为安全起见,k8s主机节点应位于私有子网中,因此赢得了Internet上的客户端)无法获得此服务)
如果我在mynamespace名称空间类型中创建了一个名为mynodeportservice的服务,该名称空间类型为:3 Node Kubernetes Cluster上的NodePort。然后将创建一个类型为Service的服务:ClusterIP,群集内的客户端可以通过以下可预测的静态DNS地址访问该服务:

mynodeportservice.mynamespace.svc.cluster.local(或仅mynodeportservice.mynamespace)

对于mynodeportservice在节点端口上侦听的每个端口,范围为30000-32767将被随机选择。这样,群集外部的外部客户端可以访问群集内部存在的ClusterIP服务。假设我们的3个K8s主机节点具有IP 10.10.10.1、10.10.10.2、10.10.10.3,Kubernetes服务正在侦听端口80,并且随机选择的Nodeport是31852。

集群外部的客户端可以访问10.10.10.1:31852、10.10.10.2:31852或10.10.10.3:31852(因为每个Kubernetes主机节点都在侦听NodePort),Kubeproxy会将请求转发到mynodeportservice的端口80。

LoadBalancer:连接到Internet的每个人都可以访问服务*(通用架构是L4 LB可通过将其放置在DMZ中或为它提供专用IP和公用IP并将k8s主机节点放在专用子网中在Internet上公开访问)
(注意:这是唯一在100%的Kubernetes实现中不起作用的服务类型,例如裸机Kubernetes,当Kubernetes具有云提供商集成时才有效。)

如果使用mylbservice,则将生成L4 LB VM(群集IP服务和NodePort服务也将被隐式生成)。这次,我们的NodePort为30222。我们的想法是L4 LB将具有1.2.3.4的公共IP,它将负载均衡并将流量转发到具有私有IP地址的3个K8s主机节点。(10.10.10.1:30222、10.10.10.2:30222、10.10.10.3:30222),然后Kube Proxy会将其转发到集群中存在的ClusterIP类型的服务。


您还询问:NodePort服务类型是否仍使用ClusterIP?是*
还是运行kubectl get节点时找到的NodeIP实际上是IP?也可以*

让我们在基本原理之间画一个平行线:
一个容器位于容器内。吊舱位于副本集中。副本集位于部署内部。
同样,
ClusterIP服务是NodePort服务的一部分。NodePort服务是负载均衡器服务的一部分。


在您显示的该图中,客户端将是群集内的一个pod。


根据您的后续问题,我给您的印象是您想知道流量如何进入集群。如果您有兴趣,我可以自由地对此进行问答。 stackoverflow.com/questions/52241501/...
neokyle

1
嘿,真的很好的解释,我想知道LoadBalancer。LoadBalancer会将所有流量转发到NodeIP:NodePort(循环中的下一个节点),并且该呼叫如何在该节点上进行?节点端口如何知道这是一个服务调用,并且应该通过kube-proxy将其分发到服务的虚拟IP?kube-proxy是否可以简单地转发端口?
ItFreak

kube-proxy扮演3个主要角色:1.通过使节点上的iptables与etcd中所需的服务状态匹配来使服务存在/工作。2.负责将节点端口映射到服务到Pod(我的理解是通过iptables完成此操作)+端口重新映射3.确保每个Pod具有唯一的ip。节点端口可以在1个节点上进入,服务定义存在于每个节点的iptables中/服务存在于每个节点上,pod通常位于虚拟化覆盖网络上,并且节点兼作路由器,因此尽管流量在1个节点上进入,被路由到另一个节点上存在的pod。
neokyle

知道它是如何在一个比这更深的层次上工作是没有意义的,因为kubernetes是由模块化的部件组成的,就像linux的口味/发行方式在某些总体主题上都稍有不同,每个k8s发行版都略有不同。示例cilium cni正在寻求完全替换kube-proxy,这意味着它在幕后的工作方式是一个移动的目标,因此不值得理解,除非您实际上为该项目做出了贡献/试图修复一个bug。
neokyle

有什么联系方式吗?我正在写有关k8s中安全性的学士论文,很想了解代理的内部功能,例如,他如何将IP地址分配给节点和Pod,以及服务如何获得其虚拟IP
ItFreak,

45

假设您在本地计算机上创建了Ubuntu VM。它的IP地址是192.168.1.104

您登录到VM,并安装了Kubernetes。然后,您在其中运行了nginx图像的地方创建了一个Pod。

1-如果要访问VM中的此Nginx Pod,则将创建绑定到该Pod 的ClusterIP,例如:

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

然后,在浏览器上,您可以使用端口80输入nginxclusterip的IP地址,例如:

http://10.152.183.2:80

2-如果要从主机访问此nginx pod,则需要使用NodePort公开部署。例如:

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

现在,您可以从主机访问nginx,例如:

http://192.168.1.104:31865/

在我的仪表板中,它们显示为:

在此处输入图片说明

下图显示了基本关系。

在此处输入图片说明


31865来自哪里?产生了?
HoaPhan

1
@HoaPhan您可以显式指定端口在30000-32767取值范围还是让它随机通过Kubernetes在这个范围内选择
穆罕默德沙·托克什万

19

即使这个问题已经有了答案,我也将提供另一个问题,也许还会提供更多图片,以便更好地理解。

1. ClusterIP是Kubernetes中的默认服务类型,此类型为您提供集群内部的服务。通过使用此功能,集群中的其他应用程序可以通过Kubernetes代理访问服务。

我应该提到,此类服务不应用于公开生产服务。但是,它可以用于

  • 调试服务之间的集成;
  • 访问暴露非业务相关数据的内部服务(监视仪表板)。

请求的处理方式如下:通信-> K8s代理-> K8s服务(ClusterIP)-> Pod,它显示在下图中。

在此处输入图片说明

2. NodePort是接受外部流量并将其转发到kubernetes服务的最原始的方式。顾名思义,NodePort服务类型在所有虚拟机(实际上是Kubernetes节点)上打开特定端口,以便将发送到该特定端口的流量转发到该服务。

NodePort服务类型有一些缺点:

  • 每个端口仅需要一项服务;
  • 如果将更改虚拟机的IP,则必须在群集中进行一些更改;
  • 只能使用3000-32767之间的端口。

请求的处理方式如下:流量->虚拟机上暴露的端口-> K8s服务(NodePort)-> Pod,它显示在下图中:

在此处输入图片说明

3. LoadBalancer是将服务公开到Internet的标准方法。如果您希望直接公开服务,并将特定端口上的所有流量都转发给该服务,那么这就是这样做的方法。同样,LoadBalancer服务类型不涉及任何过滤或路由。另外,您可以向其发送TCP,UDP,HTTP gRPC通信。

缺点:通过LoadBalancer公开的每个服务将具有自己的IP地址,并且每个服务将通过单个LoadBalancer公开,这可能会变得昂贵。

该请求具有以下路径:traffic-> LoadBalancer-> K8s Service-> pods,它显示在下图中。

在此处输入图片说明


7
  1. clusterIP:群集内部(跨d群集中的节点)可访问的IP。
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3可以通过其clusterIP网络与pod1对话。

  1. nodeport:为了使pod可以通过nodeIP:nodeport从群集外部访问,它将在上面创建/保留clusterIP作为其clusterIP网络。
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

您可以通过nodeIPA:nodeportX或nodeIPB:nodeportX访问pod1上的服务。每种方法都可以使用,因为kube-proxy(安装在每个节点中)将接收您的请求,并使用clusterIP网络在节点之间分发[重定向(iptables术语)]。

  1. 负载均衡器

基本上只是将LB放在前面,以便将入站流量分配到nodeIPA:nodeportX和nodeIPB:nodeportX,然后继续上面的流程2。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.