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

问题1 -我正在阅读文档,我对措辞有点困惑。它说:

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

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

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

NodePort服务类型仍然使用ClusterIP,但只是在一个不同的端口,这是开放给外部客户端吗?所以在这种情况下,<NodeIP>:<NodePort><ClusterIP>:<NodePort>是一样的吗?

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

问题2 -也在下面链接的图表中:

enter image description here

有什么特别的原因,为什么ClientNode里面?我假设它需要在一个__abc2在ClusterIP服务类型的情况下?

如果为NodePort绘制了相同的图,那么在Node和__abc1之外完全绘制客户端是否有效,或者我完全错过了重点?

253334 次浏览

ClusterIP公开了以下内容:

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

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

NodePort公开了以下内容:

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

如果你从节点的外部IP访问nodePort上的这个服务,它会将请求路由到spec.clusterIp:spec.ports[*].port,而spec.clusterIp:spec.ports[*].port会反过来将它路由到你的spec.ports[*].targetPort(如果设置了的话)。该服务的访问方式与ClusterIP相同。

nodeip是节点的外部IP地址。你不能从spec.clusterIp:spec.ports[*].nodePort访问你的服务。

LoadBalancer公开以下内容:

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

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

为了在更简单的层面上为那些正在寻找这三者之间的区别的人澄清。您可以使用最小的ClusterIp(在k8s集群内)公开您的服务,也可以使用NodePort(在k8s集群外部的集群内)或LoadBalancer(外部世界或您在LB中定义的任何东西)公开您的服务。

ClusterIp曝光<NodePort曝光<loadbalance暴露

    <李> ClusterIp < br > 通过ip/name:portk8集群公开服务 <李> NodePort < br > 通过内部网络虚拟机也在k8s ip/name:port之外公开服务 <李> loadbalance < br > 通过外部世界或你在LB中定义的任何东西来公开服务
< p > ClusterIP:集群中的pod /服务可达 < br > 如果我在默认类型为:ClusterIP的命名空间中创建一个名为myservice的服务,那么将为该服务创建以下可预测的静态DNS地址

myservice.default.svc.cluster.local(或者只使用myservice.default,或者在默认命名空间中使用pod,只使用“myservice”即可)

这个DNS名称只能由集群内的pod和服务解析。

< p > NodePort:同一LAN上的客户端/客户端可以ping通K8s主机节点(以及集群中的pods/服务)的服务(注意安全起见,您的K8s主机节点应该在私有子网上,因此internet上的客户端将无法到达此服务) < br > 如果我在3节点Kubernetes集群的mynamespace命名空间类型中创建一个名为mynodeportservice的服务:NodePort。然后将创建一个类型为:ClusterIP的Service,集群内的客户端可以通过以下可预测的静态DNS地址访问它:

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.1:31852(因为NodePort被每个Kubernetes主机节点监听),Kubeproxy会将请求转发到mynodeportservice的80端口。

< p > LoadBalancer:连接到互联网的每个人都可以访问服务*(常用的架构是L4 LB通过将其放在DMZ中或给它一个私有和公共IP和k8s主机节点在一个私有子网上可以在互联网上公开访问) < br > (注意:这是唯一一种不能在100%的Kubernetes实现中工作的服务类型,就像裸机Kubernetes,它在Kubernetes有云提供商集成时工作。)

如果使用mylbservice,则会生成一个L4 LB虚拟机(一个集群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?是的* < br > 或者NodeIP实际上是运行kubectl get nodes时找到的IP ?也是*

让我们在基本面之间画一个平行:
一个容器在一个豆荚里面。一个豆荚在一个复制集里。复制集位于部署内部。< br > 同样:< br > ClusterIP服务是NodePort服务的一部分。NodePort服务是负载均衡器服务的一部分。< / p >


在您展示的图表中,客户端将是集群中的一个pod。

假设你在本地机器上创建了一个Ubuntu虚拟机。它的IP地址是192.168.1.104

登录VM,安装Kubernetes。然后你创建了一个运行nginx图像的pod。

1-如果你想在你的虚拟机中访问这个nginx pod,你将创建一个绑定到该pod的ClusterIP,例如:

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

然后在浏览器上输入nginxclusterip的ip地址,端口为80,如下所示:

< a href = " http://10.152.183.2:80 " rel = " noreferrer > http://10.152.183.2:80 < / >

2-如果你想从你的主机上访问这个nginx pod,你需要用NodePort公开你的部署。例如:

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

现在你可以从你的主机上访问nginx,像这样:

< a href = " http://192.168.1.104:31865 " rel = " noreferrer " > http://192.168.1.104:31865 < / >

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

enter image description here

下图显示了基本关系。

enter image description here

  1. clusterIP:集群内可访问的IP(跨d集群内的节点)。
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。

不要忘记“新”;服务类型(从k8s文档):

ExternalName:通过返回带有值的CNAME记录,将服务映射到externalName字段的内容(例如foo.bar.example.com)。没有设置任何类型的代理。

注意:使用ExternalName类型需要kube-dns版本1.7或CoreDNS版本0.0.8或更高版本。

< span style=" font - family:宋体;"> Feature < / th > < span style=" font - family:宋体;"> ClusterIP < / th > < span style=" font - family:宋体;"> NodePort < / th > < span style=" font - family:宋体;"> LoadBalancer < / th > < span style=" font - family:宋体;"< / > < >强博览会强> < / td > < span style=" font - family:宋体;" . >公开集群内部IP上的服务 < span style=" font - family:宋体;">向外部客户端公开服务 < span style=" font - family:宋体;">向外部客户端公开服务 < span style=" font - family:宋体;"< / > < >强集群强劲> < / td > < span style=" font - family:宋体;">该类型使服务只能从 < span style=" font - family:宋体;">一个NodePort服务,每个集群节点在节点本身上打开一个端口(因此得名),并将从该端口接收的流量重定向到基础服务 < span style=" font - family:宋体;">通过专用负载均衡器访问的LoadBalancer服务,由Kubernetes云基础设施提供,运行在上 < span style=" font - family:宋体;"< / > < >强易访问性强> < / td > < span style=" font - family:宋体;"> default业务,内部客户端向稳定的内部IP地址发送请求 < span style=" font - family:宋体;"该服务可以通过内部集群IP-port访问,也可以通过所有节点上的专用端口访问 < span style=" font - family:宋体;" . >客户端通过负载均衡器的IP连接服务 < span style=" font - family:宋体;"< / > < >强Yaml配置强> < / td > < span style=" font - family:宋体;"> type: ClusterIP td > < / < span style=" font - family:宋体;"> type: NodePort td > < / < span style=" font - family:宋体;"> type: LoadBalancer td > < / < span style=" font - family:宋体;"< / > < >强端口范围强烈> < / td > < span style=" font - family:宋体;">任何公共ip形式的集群 . b < span style=" font - family:宋体;">30000 - 32767 < span style=" font - family:宋体;">任何公共ip形式的集群 . b < span style=" font - family:宋体;"< / > < >强用户情况下强> < / td > < span style=" font - family:宋体;">用于内部通信 . > < span style=" font - family:宋体;">最适合测试公共或私人访问或提供少量时间的访问 < span style=" font - family:宋体;">广泛用于对外通信

来源:

实际的理解。

我已经为NodePortClusterIP创建了2个服务

enter image description here

如果我想访问集群内的服务(从主节点或任何工作节点),那么两者都是可访问的。

enter image description here

现在如果我想从集群外部访问服务,那么Nodeport只能访问而不能访问ClusterIP

enter image description here

在这里你可以看到localhost不会监听端口80,即使我的nginx容器监听端口80。


是的,这是唯一的区别。

  • ClusterIP。公开只能从集群内部访问的服务。
  • NodePort。通过每个节点IP上的静态端口公开服务。
  • loadbalance。通过云提供商的负载平衡器公开服务。
  • ExternalName。通过返回CNAME记录的值,将服务映射到预定义的externalName字段。

实际使用案例

假设您必须在集群中创建以下架构。我想这很常见。

enter image description here

现在,用户只会在某个端口上与前端通信。后端和DB服务始终对外部世界隐藏。

下面是关于图表的问题2的答案,因为它似乎仍然没有直接回答: enter image description here < / p >

客户端在节点内部有什么特别的原因吗?我 假设它需要在ClusterIP的情况下在ClusterIP中 服务类型?< / p >

在图中,客户端被放置在节点内部,以突出显示ClusterIP只能在运行kube-proxy守护进程的机器上访问。Kube-proxy负责根据apiserver提供的数据(在图中也可以看到)配置iptables。因此,如果您创建了一个虚拟机,并将其放入集群节点所在的网络中,并在该机器上正确地配置了网络,以便从该机器访问单个集群pod,即使有了ClusterIP服务,也无法从该VM访问,除非VM正确地配置了它的iptables(没有在该VM上运行kubeproxy,这就不会发生)。

如果为NodePort绘制了相同的图,那么绘制是否有效 客户端完全外部的节点和集群或我 完全没抓住重点?< / p >

在节点和集群外部绘制客户端是有效的,因为NodePort可以被任何能够访问集群节点和相应端口的机器访问,包括集群外部的机器。

  • < p >概要:

    • < p > 有五种类型的服务:

      • ClusterIP(默认):内部客户端发送请求到一个稳定的内部IP地址。
      • NodePort:客户端通过服务指定的一个或多个nodePort值向节点的IP地址发送请求。
      • loadbalance:客户端向网络负载均衡器的IP地址发送请求。
      • ExternalName:内部客户端使用服务的DNS名称作为外部DNS名称的别名。
      • 无头:当你想要Pod分组时,你可以使用无头服务,但不需要稳定的IP地址。

      NodePort类型是ClusterIP类型的扩展。因此NodePort类型的服务有一个集群IP地址。

      LoadBalancer类型是NodePort类型的扩展。因此,LoadBalancer类型的Service有一个集群IP地址和一个或多个nodePort值。


enter image description here


  • < p > 细节

    • < p > ClusterIP

      • ClusterIP是默认的,也是最常见的服务类型。
      • Kubernetes将为ClusterIP服务分配一个集群内部IP地址。这使得服务只能在集群内可达。
      • 您不能从集群外部向服务(pods)发出请求。 您也可以在服务定义文件中设置集群IP <李>用例
        • 集群内的服务间通信。例如,应用程序前端和后端组件之间的通信。
    • < p > NodePort

      • NodePort服务是ClusterIP服务的扩展。自动创建NodePort Service路由到的ClusterIP Service。
      • 它通过在ClusterIP之上添加一个集群范围的端口,在集群外部公开服务。
      • NodePort在静态端口(NodePort)上公开每个节点IP上的服务。每个节点代理到您的服务的端口。因此,外部流量可以访问每个节点上的固定端口。这意味着在该端口上对集群的任何请求都将转发到服务。
      • 您可以从集群外部通过请求:来联系NodePort服务。
      • 节点端口取值范围为30000-32767。手动为服务分配端口是可选的。如果没有定义,Kubernetes会自动分配一个。
      • 如果要显式地选择节点端口,请确保该端口尚未被其他服务使用。
      • <李>用例
        • 当您想启用服务的外部连接时。 使用NodePort可以让您自由地设置自己的负载平衡解决方案,以配置
        • 不完全支持的环境
        • Kubernetes,甚至直接暴露一个或多个节点的ip。
        • . .
    • < p > loadbalance

      • LoadBalancer服务是NodePort服务的扩展。自动创建外部负载均衡器路由的NodePort和ClusterIP Services。
      • 它集成了NodePort和基于云的负载均衡器。
      • 它使用云提供商的负载均衡器在外部公开服务。
      • 每个云提供商(AWS、Azure、GCP等)都有自己的本地负载均衡器实现。云提供商将创建一个负载均衡器,然后自动将请求路由到Kubernetes服务。
      • 来自外部负载均衡器的流量被定向到后端pod。云提供商决定如何进行负载平衡。
      • 负载均衡器的实际创建是异步进行的。
      • 每次您希望向外部世界公开服务时,都必须创建一个新的LoadBalancer并获取一个IP地址。
      • <李>用例
        • 当您使用云提供商托管Kubernetes集群时。
    • < p > ExternalName

      • ExternalName类型的服务将服务映射到DNS名称,而不是典型的选择器,如my-service。
      • 你可以用spec.externalName参数来指定这些服务。 它将Service映射到externalName字段的内容(例如,foo.bar.example.com),通过返回带有值的CNAME记录
      • 没有建立任何形式的代理。
      • <李>用例
        • 这通常用于在Kubernetes内部创建服务,以表示外部数据存储,例如在Kubernetes外部运行的数据库。
        • 当来自一个命名空间的Pods与另一个命名空间中的服务通信时,您可以使用ExternalName服务(作为本地服务)。