繁体   English   中英

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

[英]What's the difference between ClusterIP, NodePort and LoadBalancer service types in Kubernetes?

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

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

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

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

NodePort 服务类型是否仍然使用ClusterIP ,但只是在不同的端口上,该端口对外部客户端开放? 那么在这种情况下<NodeIP>:<NodePort>是否与<ClusterIP>:<NodePort>相同?

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

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

在此处输入图像描述

ClientNode内部有什么特别的原因吗? 我假设在 ClusterIP 服务类型的情况下它需要在Cluster内?

如果为 NodePort 绘制了相同的图表,将客户端完全绘制在NodeCluster之外是否有效,或者我完全错过了这一点?

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.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 地址访问此服务,该地址将您的请求路由到 nodePort,然后将请求路由到 clusterIP 端口。 您也可以像访问 NodePort 或 ClusterIP 服务一样访问此服务。

为任何正在寻找更简单级别的 3 之间区别的人澄清。 您可以使用最小的 ClusterIp(在 k8s 集群内)或使用 NodePort(在 k8s 集群外部的集群内)或 LoadBalancer(外部世界或您在 LB 中定义的任何内容)公开您的服务。

ClusterIp 暴露 < NodePort 暴露 < LoadBalancer 暴露

  • 集群IP
    使用ip/name:port通过k8s 集群公开服务
  • 节点端口
    通过内部网络 VM公开服务也在 k8s ip/name:port外部
  • 负载均衡器
    通过外部世界或您在 LB 中定义的任何内容公开服务。

ClusterIP:集群中的 pods/services 可以访问服务
如果我在类型的默认命名空间中创建一个名为 myservice 的服务:ClusterIP,那么将为该服务创建以下可预测的静态 DNS 地址:

myservice.default.svc.cluster.local(或者只是 myservice.default,或者通过默认命名空间中的 pod,只有“myservice”可以工作)

并且该 DNS 名称只能由集群内的 pod 和服务解析。

NodePort:服务可由同一 LAN 上的客户端/客户端访问,这些客户端可以 ping K8s 主机节点(以及集群中的 pod/服务)(注意安全,您的 k8s 主机节点应位于私有子网上,因此互联网上的客户端获胜'无法访问此服务)
如果我在 mynamespace 类型的命名空间中创建一个名为 mynodeportservice 的服务:NodePort on a 3 Node Kubernetes Cluster。 然后将创建一个服务类型: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(因为 NodePort 被每个 Kubernetes 主机节点监听)Kubeproxy 会将请求转发到 mynodeportservice 的端口 80。

LoadBalancer:连接到互联网的每个人都可以访问服务*(常见的架构是 L4 LB 可以通过将其放在 DMZ 中或同时为其提供私有和公共 IP 而在互联网上公开访问,并且 k8s 主机节点位于私有子网中)
(注意:这是唯一不能在 100% 的 Kubernetes 实现中工作的服务类型,比如裸机 Kubernetes,它在 Kubernetes 具有云提供商集成时工作。)

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


你还问:NodePort服务类型还用ClusterIP吗? 是的*
或者 NodeIP 实际上是运行 kubectl get nodes 时找到的 IP? 也是*

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


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

假设您在本地计算机上创建了一个 Ubuntu VM。 它的 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

然后在您的浏览器上,您可以使用端口 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/

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

在此处输入图像描述

下图显示了基本关系。

在此处输入图像描述

Feature ClusterIP NodePort LoadBalancer
博览会 在集群中的内部 IP 上公开服务。 向外部客户公开服务 向外部客户公开服务
这种类型使服务只能从集群内访问 NodePort 服务,每个集群节点在节点本身上打开一个端口(因此得名)并将在该端口上接收到的流量重定向到底层服务。 可通过专用负载均衡器访问的 LoadBalancer 服务,由运行 Kubernetes 的云基础设施提供
可访问性 它是默认服务,内部客户端将请求发送到稳定的内部 IP 地址。 该服务可通过内部集群 IP 端口访问,也可通过所有节点上的专用端口访问。 客户端通过负载均衡器的 IP 连接到服务。
Yaml 配置 type: ClusterIP type: NodePort type: LoadBalancer
端口范围 任何公共 ip 形式的集群 30000 - 32767 任何公共 ip 形式的集群

资料来源:

  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 网络在节点之间分发它 [redirect it(iptables term)]。

  1. 负载均衡器

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

实际理解。

我为NodePort创建了 2 个服务 1 为ClusterIP创建了其他服务

在此处输入图像描述

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

在此处输入图像描述

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

在此处输入图像描述

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


是的,这是唯一的区别。

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

实际用例

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

在此处输入图像描述

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

并且不要忘记“新”服务类型( 来自 k8s 文档):

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

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

这是关于图表的问题 2的答案,因为它似乎仍然没有直接回答: 在此处输入图像描述

客户端在节点内部有什么特别的原因吗? 我认为在 ClusterIP 服务类型的情况下它需要在集群内?

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

如果为 NodePort 绘制了相同的图表,将客户端完全绘制在 Node 和集群之外是否有效,或者我完全错过了这一点?

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

  • 概括:

    • 有五种类型的服务:

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

      NodePort 类型是 ClusterIP 类型的扩展。 所以 NodePort 类型的 Service 有一个集群 IP 地址。

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


在此处输入图像描述


  • 细节

    • 集群IP

      • ClusterIP 是默认和最常见的服务类型。
      • Kubernetes 会为 ClusterIP 服务分配一个集群内部的 IP 地址。 这使得服务只能在集群内访问。
      • 您不能从集群外部向服务(pod)发出请求。 您可以选择在服务定义文件中设置集群 IP。
      • 用例
        • 集群内的服务间通信。 例如,应用程序的前端和后端组件之间的通信。
    • 节点端口

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM