![](/img/trans.png)
[英]What's the difference between service type: 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 - 同样在以下链接的图表中:
Client
在Node
内部有什么特别的原因吗? 我假设在 ClusterIP 服务类型的情况下它需要在Cluster
内?
如果为 NodePort 绘制了相同的图表,将客户端完全绘制在Node
和Cluster
之外是否有效,或者我完全错过了这一点?
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/name:port
通过k8s 集群公开服务ip/name:port
外部 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 地址,例如:
2-如果您想从您的主机访问这个 nginx pod,您需要使用NodePort公开您的部署。 例如:
$ kubectl expose deployment nginxapp --name=nginxnodeport --port=80 --target-port=8080 --type=NodePort
现在,您可以从您的主机访问 nginx,例如:
在我的仪表板中,它们显示为:
下图显示了基本关系。
Feature |
ClusterIP |
NodePort |
LoadBalancer |
---|---|---|---|
博览会 | 在集群中的内部 IP 上公开服务。 | 向外部客户公开服务 | 向外部客户公开服务 |
簇 | 这种类型使服务只能从集群内访问 | NodePort 服务,每个集群节点在节点本身上打开一个端口(因此得名)并将在该端口上接收到的流量重定向到底层服务。 | 可通过专用负载均衡器访问的 LoadBalancer 服务,由运行 Kubernetes 的云基础设施提供 |
可访问性 | 它是默认服务,内部客户端将请求发送到稳定的内部 IP 地址。 | 该服务可通过内部集群 IP 端口访问,也可通过所有节点上的专用端口访问。 | 客户端通过负载均衡器的 IP 连接到服务。 |
Yaml 配置 | type: ClusterIP |
type: NodePort |
type: LoadBalancer |
端口范围 | 任何公共 ip 形式的集群 | 30000 - 32767 | 任何公共 ip 形式的集群 |
资料来源:
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.
pod3 可以通过其 clusterIP 网络与 pod1 通信。
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX
您可以通过 nodeIPA:nodeportX 或 nodeIPB:nodeportX 访问 pod1 上的服务。 无论哪种方式都可以,因为 kube-proxy(安装在每个节点中)将接收您的请求并使用 clusterIP 网络在节点之间分发它 [redirect it(iptables term)]。
基本上只是将 LB 放在前面,以便将入站流量分配到 nodeIPA:nodeportX 和 nodeIPB:nodeportX 然后继续上面的流程编号 2。
我为NodePort创建了 2 个服务 1 为ClusterIP创建了其他服务
如果我想访问集群内的服务(从主节点或任何工作节点),那么两者都可以访问。
现在,如果我想从集群外部访问服务,那么Nodeport只能访问,不能访问ClusterIP 。
在这里你可以看到 localhost 不会监听端口 80,即使我的 nginx 容器正在监听端口 80。
是的,这是唯一的区别。
假设您必须在集群中创建以下架构。 我想它很常见。
现在,用户只会在某个端口上与前端通信。 后端和数据库服务始终对外部世界隐藏。
并且不要忘记“新”服务类型( 来自 k8s 文档):
ExternalName :通过返回带有其值的 CNAME 记录,将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。 没有设置任何类型的代理。
注意:您需要 kube-dns 版本 1.7 或 CoreDNS 版本 0.0.8 或更高版本才能使用 ExternalName 类型。
客户端在节点内部有什么特别的原因吗? 我认为在 ClusterIP 服务类型的情况下它需要在集群内?
在图中,客户端被放置在节点内,以强调 ClusterIP 只能在运行 kube-proxy 守护进程的机器上访问。 kube-proxy 负责根据 apiserver 提供的数据配置 iptables(在图中也可以看到)。 因此,如果您创建一个虚拟机并将其放入集群节点所在的网络,并在该计算机上正确配置网络,以便可以从那里访问单个集群 pod,即使使用该 VM 无法访问 ClusterIP 服务, 除非 VM 正确配置了 iptables(如果没有在该 VM 上运行 kubeproxy 就不会发生这种情况)。
如果为 NodePort 绘制了相同的图表,将客户端完全绘制在 Node 和集群之外是否有效,或者我完全错过了这一点?
在节点和集群之外绘制客户端是有效的,因为可以从任何可以访问集群节点和相应端口的机器访问 NodePort,包括集群外的机器。
概括:
NodePort 类型是 ClusterIP 类型的扩展。 所以 NodePort 类型的 Service 有一个集群 IP 地址。
LoadBalancer 类型是 NodePort 类型的扩展。 因此 LoadBalancer 类型的 Service 具有集群 IP 地址和一个或多个 nodePort 值。
集群IP
节点端口
负载均衡器
外部名称
spec.externalName
参数指定这些服务。 它通过返回带有其值的 CNAME 记录将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.