gRPC连接在Kubernetes服务ClusterIP上的工作原理是什么?

3
我在理解网络和gRPC方面可能还有一些遗漏。我想通过一个例子来解释我的理解。
我有一个名为“app”的默认命名空间中的3个副本部署,它们具有以下Pod IP:10.3.0.110.3.0.210.3.0.3
我有一个名为“app-service”的ClusterIP服务,它的IP是:10.24.0.0
kube-dns会有一条记录将app-service.default.svc.cluster.local映射到10.24.0.0。每个节点上的kube-proxy都会看到这个配置,并使用映射10.24.0.0 -> 10.3.0.1, 10.3.0.2, 10.3.0.3更新netfilter。
现在在我的集群中有另一个客户端pod,它对app-service.default.svc.cluster.local进行了gRPC调用。
我期望发生的是app-service.default.svc.cluster.local将解析为单个IP10.24.0.0,并且gRPC将创建一个子通道并尝试建立长连接。
这个调用会离开pod并到达节点,在经过netfilter时10.24.0.0变成10.3.0.1,最终到达第一个pod。
现在客户端有了第二个调用,经过netfilter时10.24.0.0变成10.3.0.2,这个调用会到达另一个pod,这个pod不知道它们已经建立了连接吗?
此外,我看到这些博客提到gRPC将创建粘性会话到单个pod IP,但我认为Pod IP不会在application/grpc客户端中解析,而是在netfilter中解析。
2个回答

1
我认为你可以从gRPC中的负载均衡找到一些答案。
负载均衡策略适用于gRPC客户端流程,在名称解析和与服务器建立连接之间。

enter image description here

启动时,gRPC客户端会发出一个名称解析请求以获取服务器名称。名称将会被解析为IP地址列表、指示使用哪种客户端负载均衡策略的服务配置(例如round_robingrpclb),并提供该策略的配置和一组属性(在C-core中称为通道参数)。
客户端实例化负载平衡策略,并传递其来自服务配置的配置、IP地址列表和属性。
负载平衡策略为服务器的IP地址创建一组子通道(这些IP地址可能与解析器返回的IP地址不同;请参见下文)。它还监视子通道的连接状态,并决定每个子通道何时应尝试连接。
对于发送的每个RPC,负载平衡策略都会决定将RPC发送到哪个子通道(即哪个服务器)。
当Pod重启导致Pod的IP地址发生更改时,现在gRPC会在任何子连接进入短暂失败状态时尝试重新解析。这里有一个相关的讨论代码

0

虽然你的思考过程听起来是正确的,但它的实际运作方式与你想象中可能不同。

当你有一个单独的clusterIP服务时,它会有一个单独的A DNS记录。所以连接看起来像这样:

enter image description here

所以在给定的时刻只会有一个/单个持久连接,其他两个Pod将不会被使用。 kube-proxy 在内部使用 netfilter 进行映射,但它不是一个适当的物理负载均衡器,没有POD的IP地址将被公开,客户端只会知道 service's clusterIP。如果创建了新连接,则将使用已经创建的连接,并借助于 grpc multiplexing

这里需要的是 headless service type。它的作用是:

对于定义选择器的无头服务,端点控制器会在API中创建端点记录,并修改DNS配置以返回直接指向支持服务的Pod的A记录(IP地址)。

现在模式看起来会有所不同:

enter image description here

换句话说,使用无头服务类型的服务时,FQDN将在3个POD IP地址中解析,gRPC客户端可以建立不同的连接。
更多细节请阅读一篇好文章(我从中获取了这些图片)- 在没有服务网格的情况下平衡K8S中的gRPC流量
此外,服务网格也可用于负载均衡(代理负载均衡)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接