Kubernetes在集群接入层设计并提供了两种原生资源Service和Ingress,分别负责四层和七层的网络接入层配置。
传统的做法是创建Ingress或LoadBalancer类型的Service来绑定腾讯云的负载均衡将服务对外暴露。这种做法将用户流量负载到用户节点的NodePort上,通过KubeProxy组件转发到容器网络中,但这种方案在业务的性能和能力支持会有所局限。
为了解决这个问题,TKE容器团队为在腾讯云上使用独立或托管集群的用户提供了一种新的网络模式,利用弹性网卡直连Pod的方案很大的增强了性能和业务能力的支持。
本文将会从传统的模式的问题入手,比较新旧模式的区别,并在最后提供新直连模式的使用指引。
传统模式面临的问题与挑战 性能与特性KubeProxy在集群中会将用户NodePort的流量通过NAT的方式转发到集群网络中。这个NAT转发带来了以下一些问题。
NAT转发导致请求在性能上有一定的损失。
进行NAT操作本身会带来性能上的损失。
NAT转发的目的地址可能会使得流量在容器网络内跨节点转发。
NAT转发导致请求的来源IP被修改了,客户端无法获取来源IP。
当负载均衡的流量集中到几个NodePort时。过于集中的流量会导致NodePort的SNAT转发过多,使得源端口耗尽流量异常。还可能导致 conntrack 插入冲突导致丢包,影响性能。
KubeProxy的转发具有随机性,无法支持会话保持。
KubeProxy的每个NodePort其实也起到独立的负载均衡作用,由于负载均衡无法收敛到一个地方,所以难以达到全局的负载均衡。
为了解决以上问题,我们以前给用户提供的技术建议主要是通过Local转发的方式,避免KubeProxyNAT转发带来的问题。但是因为转发的随机性,一个节点上部署多个副本时会话保持依旧无法支持。而且Local转发在滚动更新时,容易出现服务的闪断,对业务的滚动更新策略以及优雅停机提出了更高的要求。我们有理由去寻找更好的方案解决这个问题。
业务可用性通过NodePort接入服务时,NodePort的设计存在极大的容错性。负载均衡会绑定集群所有节点的NodePort作为后端。集群任意一个节点的访问服务时,流量将随机分配到集群的工作负载中。这就意味着部分NodePort的不可用,或者是Pod的不可用都不会影响服务的流量接入。
和Local访问一样,直接将负载均衡后端连接到用户Pod的情况下,当业务在滚动更新时,如果负载均衡不能够及时绑定上新的Pod,业务的快速滚动可能导致业务入口的负载均衡后端数量严重不足甚至被清空。因此,业务滚动更新的时候,接入层的负载均衡的状态良好,方能保证滚动更新的安全平稳。
负载均衡的控制面性能负载均衡的控制面接口。包括创建删除修改四层、七层监听器,创建删除七层规则,绑定各个监听器或者规则的后端。这些接口大部分是异步接口,需要轮询请求结果,接口的调用时间相对较长。当用户集群规模较大时,大量的接入层资源同步会导致组件存在很大的时延上的压力。
新旧模式对比 性能对比Pod直连模式已经在腾讯TKE上线,是对负载均衡的控制面优化。针对整个同步流程,重点优化了批量调用和后端实例查询两个远程调用比较频繁的地方。优化完成后,Ingress典型场景下的控制面性能较优化前版本有了95%-97%左右的性能提升。目前同步的耗时主要集中在异步接口的等待上。
后端节点突增 (应对集群扩容的场景) 七层规则突增(应对业务第一次上线部署到集群的场景)除去控制面性能优化这样的硬核优化,负载均衡能够直接访问容器网络的Pod就是组件业务能力最重要的组成部分了,其不仅避免了NAT转发性能上的损失,同时避免了NAT转发带来的各种对集群内业务功能影响。但是在启动该项目时这一块还没有特别好的访问容器网络的支持。所以一期考虑集群CNI网络模式下Pod有弹性网卡入口,这个入口可以直接接入到负载均衡以达到直接访问的目的。负载均衡直接后端访问到容器网络,目前已经有通过云联网解决的方案,后续也会继续跟进这种更贴近集群网络的直连方案。