Kubernetes 中的 ClusterIP、NodePort 和 LoadBalancer 服务类型有什么区别?
What's the difference between ClusterIP, NodePort and LoadBalancer service types in Kubernetes?
问题 1 - 我正在阅读文档,但对措辞有点困惑。它说:
ClusterIP: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. This is the default ServiceType
NodePort: Exposes the service on each Node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service will route, is automatically created. You’ll be able to contact the NodePort service, from outside the cluster, by requesting <NodeIP>:<NodePort>
.
LoadBalancer: Exposes the service externally using a cloud provider’s load balancer. NodePort and ClusterIP services, to which the external load balancer will route, are automatically created.
NodePort 服务类型是否仍然使用 ClusterIP
但只是在一个不同的端口,对外部客户端开放?所以在这种情况下 <NodeIP>:<NodePort>
与 <ClusterIP>:<NodePort>
相同吗?
或者 NodeIP
实际上是您 运行 kubectl get nodes
时找到的 IP,而不是用于 ClusterIP 服务类型的虚拟 IP?
问题 2 - 同样在下面 link 的图表中:
为什么 Client
在 Node
里面有什么特别的原因吗?我认为如果是 ClusterIP 服务类型,它需要在 Cluster
内?
如果为 NodePort 绘制相同的图表,将客户端完全绘制在 Node
和 Cluster
之外是否有效,还是我完全忽略了这一点?
ClusterIP 公开以下内容:
spec.clusterIp:spec.ports[*].port
您只能在集群内访问此服务。它可以从它的 spec.clusterIp
端口访问。如果设置了 spec.ports[*].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,而 nodePort 又将请求路由到 clusterIP 端口。您也可以像访问 NodePort 或 ClusterIP 服务一样访问此服务。
为了更简单地向正在寻找这 3 个之间的区别的任何人澄清。您可以使用最小的 ClusterIp(在 k8s 集群内)或使用 NodePort(在 k8s 集群外部的集群内)或 LoadBalancer(外部世界或您在 LB 中定义的任何内容)来公开您的服务。
ClusterIp 暴露 < NodePort 暴露 < LoadBalancer 暴露
- ClusterIp
通过 k8s 集群 和 ip/name:port
公开服务
- 节点端口
通过 内部网络 VM 的 以及 k8s 外部的 ip/name:port
公开服务
- 负载均衡器
通过 外部世界 或您在 LB 中定义的任何内容公开服务。
ClusterIP:集群中的 pods/services 可以访问服务
如果我在类型为 ClusterIP 的默认命名空间中创建名为 myservice 的服务,则将为该服务创建以下可预测的静态 DNS 地址:
myservice.default.svc.cluster.local (or just myservice.default, or by pods in the default namespace just "myservice" will work)
并且该 DNS 名称只能由 pods 和集群内的服务解析。
NodePort:服务可由同一个 LAN/clients 上的客户端访问,他们可以 ping K8s 主机节点(以及集群中的 pods/services)(请注意您的 k8s 主机的安全性节点应位于私有子网上,因此互联网上的客户端将无法访问此服务)
如果我在类型为 NodePort 的 mynamespace 命名空间中创建名为 mynodeportservice 的服务,在 3 节点 Kubernetes 集群上。然后将创建一个类型为 ClusterIP 的服务,集群内的客户端可以通过以下可预测的静态 DNS 地址访问它:
mynodeportservice.mynamespace.svc.cluster.local (or just mynodeportservice.mynamespace)
对于 mynodeportservice 在 30000 - 32767 范围内的节点端口上侦听的每个端口,将随机选择。这样集群外部的外部客户端就可以访问集群内部存在的 ClusterIP 服务。
假设我们的 3 个 K8s 主机节点的 IP 分别为 10.10.10.1、10.10.10.2、10.10.10.3,Kubernetes 服务正在侦听端口 80,随机选择的节点端口为 31852。
存在于集群外部的客户端可以访问 10.10.10.1:31852、10.10.10.2:31852 或 10.10.10.3:31852(因为 NodePort 被每个 Kubernetes 主机节点监听) Kubeproxy 会将请求转发到 mynodeportservice 的 80 端口。
LoadBalancer:每个连接到互联网的人都可以访问服务*(常见架构是 L4 LB public只能通过将其置于 DMZ 中或同时提供private and public IP 和 k8s host nodes are on a private subnet)
(注意:这是唯一不能在 100% 的 Kubernetes 实现中工作的服务类型,就像裸机 Kubernetes,它在 Kubernetes 有云提供商集成时工作。)
如果您创建 mylbservice,那么将生成一个 L4 LB VM(一个集群 IP 服务和一个 NodePort 服务也将被隐式生成)。这次我们的 NodePort 是 30222。想法是 L4 LB 将有一个 public 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 获取节点时找到的 IP?也对*
让我们在基本面之间画一个平行线:
一个容器在一个 pod 里面。一个 pod 在一个 replicaset 里面。副本集在部署中。
那么类似的:
ClusterIP 服务是 NodePort 服务的一部分。 NodePort 服务是负载均衡器服务的一部分。
在您展示的图表中,客户端将是集群内的一个 pod。
假设您在本地计算机上创建了一个 Ubuntu 虚拟机。它的 IP 地址是 192.168.1.104.
您登录到 VM,并安装了 Kubernetes。然后你创建了一个 pod,上面有 nginx image 运行。
1- 如果你想在你的 VM 中访问这个 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,例如:
在我的仪表板中,它们显示为:
下图显示了基本关系。
- clusterIP : 集群内部可访问的 IP(d 集群内跨节点)。
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.
pod3 可以通过其 clusterIP 网络与 pod1 通信。
- nodeport : 使 pods 通过 nodeIP:nodeport 从集群外部访问,它将 create/keep clusterIP 作为其 clusterIP 网络。
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX
您可以通过 nodeIPA:nodeportX 或 nodeIPB:nodeportX 访问 pod1 上的服务。任何一种方式都可以工作,因为 kube-proxy(安装在每个节点中)将接收您的请求并使用 clusterIP 网络将其分发[重定向(iptables 术语)]。
- 负载均衡器
基本上就是把LB放在前面,让入站流量分配给nodeIPA:nodeportX和nodeIPB:nodeportX然后继续上面的流程2
并且不要忘记“新”服务类型 (from the k8s docu):
ExternalName:通过返回 CNAME 记录及其值,将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。没有设置任何类型的代理。
Note: You need either kube-dns version 1.7 or CoreDNS version 0.0.8 or higher to use the ExternalName type.
Feature
ClusterIP
NodePort
LoadBalancer
Exposition
Exposes the Service on an internal IP in the cluster.
Exposing services to external clients
Exposing services to external clients
Cluster
This type makes the Service only reachable from within the cluster
A NodePort service, each cluster node opens a port on the node itself (hence the name) and redirects traffic received on that port to the underlying service.
A LoadBalancer service accessible through a dedicated load balancer, provisioned from the cloud infrastructure Kubernetes is running on
Accessibility
It is default service and Internal clients send requests to a stable internal IP address.
The service is accessible at the internal cluster IP-port, and also through a dedicated port on all nodes.
Clients connect to the service through the load balancer’s IP.
Yaml Config
type: ClusterIP
type: NodePort
type: LoadBalancer
Port Range
Any public ip form Cluster
30000 - 32767
Any public ip form Cluster
来源:
实际理解。
我已经为 NodePort 创建了 2 个服务 1,为 ClusterIP
创建了另一个
如果我想访问集群内的服务(从主节点或任何工作节点),那么两者都可以访问。
现在,如果我想从集群外部访问服务,那么 Nodeport 只能访问而不是 ClusterIP.
在这里你可以看到 localhost 不会监听 80 端口,即使我的 nginx 容器正在监听 80 端口。
是的,这是唯一的区别。
- 集群 IP。公开只能从集群内访问的服务。
- 节点端口。通过每个节点 IP 上的静态端口公开服务。
- 负载均衡器。通过云提供商的负载均衡器公开服务。
- 外部名称。通过返回 CNAME 记录的值将服务映射到预定义的 externalName 字段。
实际用例
假设您必须在集群中创建以下架构。我想这很常见。
现在,用户只需要在某个端口上与前端通信。后端和数据库服务始终对外界隐藏。
问题 1 - 我正在阅读文档,但对措辞有点困惑。它说:
ClusterIP: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. This is the default ServiceType
NodePort: Exposes the service on each Node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service will route, is automatically created. You’ll be able to contact the NodePort service, from outside the cluster, by requesting
<NodeIP>:<NodePort>
.LoadBalancer: Exposes the service externally using a cloud provider’s load balancer. NodePort and ClusterIP services, to which the external load balancer will route, are automatically created.
NodePort 服务类型是否仍然使用 ClusterIP
但只是在一个不同的端口,对外部客户端开放?所以在这种情况下 <NodeIP>:<NodePort>
与 <ClusterIP>:<NodePort>
相同吗?
或者 NodeIP
实际上是您 运行 kubectl get nodes
时找到的 IP,而不是用于 ClusterIP 服务类型的虚拟 IP?
问题 2 - 同样在下面 link 的图表中:
为什么 Client
在 Node
里面有什么特别的原因吗?我认为如果是 ClusterIP 服务类型,它需要在 Cluster
内?
如果为 NodePort 绘制相同的图表,将客户端完全绘制在 Node
和 Cluster
之外是否有效,还是我完全忽略了这一点?
ClusterIP 公开以下内容:
spec.clusterIp:spec.ports[*].port
您只能在集群内访问此服务。它可以从它的 spec.clusterIp
端口访问。如果设置了 spec.ports[*].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,而 nodePort 又将请求路由到 clusterIP 端口。您也可以像访问 NodePort 或 ClusterIP 服务一样访问此服务。
为了更简单地向正在寻找这 3 个之间的区别的任何人澄清。您可以使用最小的 ClusterIp(在 k8s 集群内)或使用 NodePort(在 k8s 集群外部的集群内)或 LoadBalancer(外部世界或您在 LB 中定义的任何内容)来公开您的服务。
ClusterIp 暴露 < NodePort 暴露 < LoadBalancer 暴露
- ClusterIp
通过 k8s 集群 和ip/name:port
公开服务
- 节点端口
通过 内部网络 VM 的 以及 k8s 外部的ip/name:port
公开服务
- 负载均衡器
通过 外部世界 或您在 LB 中定义的任何内容公开服务。
ClusterIP:集群中的 pods/services 可以访问服务
如果我在类型为 ClusterIP 的默认命名空间中创建名为 myservice 的服务,则将为该服务创建以下可预测的静态 DNS 地址:
myservice.default.svc.cluster.local (or just myservice.default, or by pods in the default namespace just "myservice" will work)
并且该 DNS 名称只能由 pods 和集群内的服务解析。
NodePort:服务可由同一个 LAN/clients 上的客户端访问,他们可以 ping K8s 主机节点(以及集群中的 pods/services)(请注意您的 k8s 主机的安全性节点应位于私有子网上,因此互联网上的客户端将无法访问此服务)
如果我在类型为 NodePort 的 mynamespace 命名空间中创建名为 mynodeportservice 的服务,在 3 节点 Kubernetes 集群上。然后将创建一个类型为 ClusterIP 的服务,集群内的客户端可以通过以下可预测的静态 DNS 地址访问它:
mynodeportservice.mynamespace.svc.cluster.local (or just mynodeportservice.mynamespace)
对于 mynodeportservice 在 30000 - 32767 范围内的节点端口上侦听的每个端口,将随机选择。这样集群外部的外部客户端就可以访问集群内部存在的 ClusterIP 服务。
假设我们的 3 个 K8s 主机节点的 IP 分别为 10.10.10.1、10.10.10.2、10.10.10.3,Kubernetes 服务正在侦听端口 80,随机选择的节点端口为 31852。
存在于集群外部的客户端可以访问 10.10.10.1:31852、10.10.10.2:31852 或 10.10.10.3:31852(因为 NodePort 被每个 Kubernetes 主机节点监听) Kubeproxy 会将请求转发到 mynodeportservice 的 80 端口。
LoadBalancer:每个连接到互联网的人都可以访问服务*(常见架构是 L4 LB public只能通过将其置于 DMZ 中或同时提供private and public IP 和 k8s host nodes are on a private subnet)
(注意:这是唯一不能在 100% 的 Kubernetes 实现中工作的服务类型,就像裸机 Kubernetes,它在 Kubernetes 有云提供商集成时工作。)
如果您创建 mylbservice,那么将生成一个 L4 LB VM(一个集群 IP 服务和一个 NodePort 服务也将被隐式生成)。这次我们的 NodePort 是 30222。想法是 L4 LB 将有一个 public 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 获取节点时找到的 IP?也对*
让我们在基本面之间画一个平行线:
一个容器在一个 pod 里面。一个 pod 在一个 replicaset 里面。副本集在部署中。
那么类似的:
ClusterIP 服务是 NodePort 服务的一部分。 NodePort 服务是负载均衡器服务的一部分。
在您展示的图表中,客户端将是集群内的一个 pod。
假设您在本地计算机上创建了一个 Ubuntu 虚拟机。它的 IP 地址是 192.168.1.104.
您登录到 VM,并安装了 Kubernetes。然后你创建了一个 pod,上面有 nginx image 运行。
1- 如果你想在你的 VM 中访问这个 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,例如:
在我的仪表板中,它们显示为:
下图显示了基本关系。
- clusterIP : 集群内部可访问的 IP(d 集群内跨节点)。
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.
pod3 可以通过其 clusterIP 网络与 pod1 通信。
- nodeport : 使 pods 通过 nodeIP:nodeport 从集群外部访问,它将 create/keep clusterIP 作为其 clusterIP 网络。
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX
您可以通过 nodeIPA:nodeportX 或 nodeIPB:nodeportX 访问 pod1 上的服务。任何一种方式都可以工作,因为 kube-proxy(安装在每个节点中)将接收您的请求并使用 clusterIP 网络将其分发[重定向(iptables 术语)]。
- 负载均衡器
基本上就是把LB放在前面,让入站流量分配给nodeIPA:nodeportX和nodeIPB:nodeportX然后继续上面的流程2
并且不要忘记“新”服务类型 (from the k8s docu):
ExternalName:通过返回 CNAME 记录及其值,将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。没有设置任何类型的代理。
Note: You need either kube-dns version 1.7 or CoreDNS version 0.0.8 or higher to use the ExternalName type.
Feature |
ClusterIP |
NodePort |
LoadBalancer |
---|---|---|---|
Exposition | Exposes the Service on an internal IP in the cluster. | Exposing services to external clients | Exposing services to external clients |
Cluster | This type makes the Service only reachable from within the cluster | A NodePort service, each cluster node opens a port on the node itself (hence the name) and redirects traffic received on that port to the underlying service. | A LoadBalancer service accessible through a dedicated load balancer, provisioned from the cloud infrastructure Kubernetes is running on |
Accessibility | It is default service and Internal clients send requests to a stable internal IP address. | The service is accessible at the internal cluster IP-port, and also through a dedicated port on all nodes. | Clients connect to the service through the load balancer’s IP. |
Yaml Config | type: ClusterIP |
type: NodePort |
type: LoadBalancer |
Port Range | Any public ip form Cluster | 30000 - 32767 | Any public ip form Cluster |
来源:
实际理解。
我已经为 NodePort 创建了 2 个服务 1,为 ClusterIP
创建了另一个如果我想访问集群内的服务(从主节点或任何工作节点),那么两者都可以访问。
现在,如果我想从集群外部访问服务,那么 Nodeport 只能访问而不是 ClusterIP.
在这里你可以看到 localhost 不会监听 80 端口,即使我的 nginx 容器正在监听 80 端口。
是的,这是唯一的区别。
- 集群 IP。公开只能从集群内访问的服务。
- 节点端口。通过每个节点 IP 上的静态端口公开服务。
- 负载均衡器。通过云提供商的负载均衡器公开服务。
- 外部名称。通过返回 CNAME 记录的值将服务映射到预定义的 externalName 字段。
实际用例
假设您必须在集群中创建以下架构。我想这很常见。
现在,用户只需要在某个端口上与前端通信。后端和数据库服务始终对外界隐藏。