zl程序教程

您现在的位置是:首页 >  其他

当前栏目

TKE集群超级节点pod访问Local模式LoadBalancer类型service不通

2023-02-25 18:21:59 时间

1. 问题现象

tke集群添加了超级节点,然后部署的服务通过LoadBalancer模式的servcie对外提供服务,当客户端pod调度到普通节点上,可以通过clb的vip访问到后端服务,当pod调度到超级节点上,访问clb的vip不通,具体测试看下图。

这里clb的vip是172.16.200.2,并且配置了service的模式是Local模式,一般配置Local模式是为了后端pod能获取到真实的客户端ip,因为Local模式,能够保留来源IP,并可以保证公网、VPC内网访问(LoadBalancer)和主机端口访问(NodePort)模式下流量仅在本节点转发。

当pod调度在正常节点上,是可以直接通过vip访问到后端nginx服务的,下面我们将客户端pod调度到超级节点上测试下。

这里pod ip和节点ip一致并且有计费规格,则说明pod是调度到了超级节点上,登陆容器测试可以发现,通过vip访问nginx服务就不通了,这里是什么原因呢?为什么客户端pod在普通节点就可以正常访问,调度到超级节点就不行了。

2. 问题原因

解释说明这个现象前,这里简单的说明下超级节点的pod底层的是一个什么样构成,因为超级节点底层是没有物理资源的,其实只是k8s的一个对象而且。超级节点的每一个pod,都是单独一台机器,上面会运行containerd,和类似于kubelet、kube-proxy的组件,但是kube-proxy都是ipvs模式,这也是为什么超级节点pod能访问到集群的svc原因。

其实在超级节点上pod无法访问,就是因为ipvs模式本身实现导致的,因为ipvs模式下,service为Local模式,只会放过同节点上的流量,当前客户端pod和服务端不在同一个节点,则访问不通,具体可以参考这个issue https://github.com/kubernetes/kubernetes/issues/93456

那很多人又会疑惑,为什么普通节点能通,这里是因为我的集群是iptables模式,普通节点部署的kube-proxy是iptables模式,iptables模式是没问题,如果是集群是ipvs模式,也是同样的现象,大家可以测试下。

3. 解决方案

3.1 服务端pod和客户端pod在同一个节点

这里大致了解原因了,先我们来看看如何解决这个问题。首先超级节点的pod kube-proxy模式是不能改的,默认都是ipvs,如果因为需要获取到真实客户端ip,servcie模式不能改成cluster模式,那就只能将服务端pod调度到和客户端同一个超级节点上

这里nginx pod调度到超级节点后,客户端pod就能正常通过vip访问了,但是这里因为我是测试集群,只有一个超级节点,因此会在同一个节点上,如果是集群有多个超级节点,为了让服务端pod和客户端pod在同一个超级节点,需要通过nodeselector或者节点亲和性来保证。

3.2 service采用直连模式

除了让服务端pod和客户端pod在同一个节点这个方法,还有别的方案,service配置Local模式一般都是为了获取真实客户端ip,这里获取真实客户端ip,其实可以service采用直连pod的模式,因为clb会直接透传客户端ip到后端rs的,这里直连模式,clb监听的后端rs直接就是pod,不再经过nodeport的转发了,因此pod也能直接获取到真实的客户端ip,现在VPC-CNI和GlobalRoute这2种网络模式都支持直连了,具体如何配置直连可以参考文档https://cloud.tencent.com/document/product/457/41897

如果service采用了直连,就可以不用配置为Local模式来获取真实客户端ip了,这里超级节点pod通过clb vip访问也就没问题。