我对k8s中headless service的理解和验证的两个问题

My understanding of headless service in k8s and two questions to verify

正在学习kubernetes的headless service

以下我理解无误(如有错误请指正):

我不太确定的是:

If you don't need load balancing but want to directly connect to the pod (e.g. database) you can use headless service

但这到底是什么意思?

所以,以下是我对 k8s 中的无头服务的想法和两个问题的示例

假设我在服务后面有 3 个 PostgreSQL 数据库实例副本,如果它是常规服务,我知道默认情况下对数据库的请求将以循环方式路由到三个数据库 pod 之一。那确实是一个负载均衡。

问题一:

如果改用无头服务,上面引用的语句是否意味着无头服务将坚持使用三个数据库 pod 之一,直到 pod 死掉才改变?我问这个是因为如果不坚持使用三个 pod 之一,它仍然会进行负载平衡。有人可以澄清一下吗?

问题二:

我觉得无论是常规服务还是无头服务,客户端应用程序只需要知道服务的DNS名称就可以与k8s集群中的数据库通信。不是这样吗?我的意思是,那么使用无头服务有什么意义呢?对我来说,无头服务只有在客户端应用程序代码确实需要知道它所连接的 pod 的 IP 地址时才有意义。因此,只要客户端应用程序不需要知道 IP 地址,它始终可以通过集群中的服务 DNS 名称使用常规服务或无头服务与数据库通信,我就在这里吗?

无头服务将 return 所有 通过选择器关联的 Pod IP。顺序不稳定,因此如果客户端重复进行 DNS 查询并仅使用第一个 returned IP,这也会导致某种负载平衡。

关于你的第二个问题:是的。一般来说,如果客户端不需要知道所有实例 - 并处理不稳定的 IP - 常规服务会提供更多好处。

普通服务带有负载均衡器(即使它是 ClusterIP-type 服务)。该负载平衡器有一个 IP 地址。 in-cluster 服务的 DNS 名称解析为负载均衡器的 IP 地址,然后转发到选定的 Pods。

无头服务没有负载平衡器。服务的 DNS 名称解析为 Pods 自身的 IP 地址。

这意味着,对于无头服务,基本上一切都取决于调用者。如果调用者进行 DNS 查找,选择它给出的第一个地址,并在进程的生命周期内使用该地址,那么它不会 round-robin 在支持 Pods 之间请求,并且它不会注意到如果那个 Pod 消失了。对于普通服务,只要调用方获得服务的(cluster-internal 负载均衡器的)IP 地址,这些问题就会自动处理。

无头服务与有状态工作负载没有特别关联,除了 StatefulSets 需要无头服务作为其配置的一部分。一个单独的 StatefulSet Pod 实际上会是 given a unique hostname connected to that headless Service。不过,您可以让普通服务和无头服务都指向同一个 Pods,并且在您不关心(最初)联系哪个副本的情况下,使用普通服务可能是有意义的。