service代理模式总结

Service资源的工作内容主要分为两大部分:

  1. 控制器模块:主要包括ServiceControllerEndpointControllerServiceController其实只处理了负载均衡类型的Service对象,它会调用云服务商的 API 接口,不同的云服务商会实现不同的适配器来创建LoadBalancer类型的资源;Service对象通过selector和pod建立关联。k8s会根据service对象关联到pod的podIP信息组合成一个endpoint。那么EndpointController就是同时订阅了Service对象和Pod资源对象的增删事件,从而映射生成相应的Endpoint对象。

  2. kube-porxy:每个节点的kube-proxy负责监听APIServer中ServiceEndpoint对象的变化情况,然后将变化信息写入本地userspace/iptables/ipvs,从而为节点内的客户端提供流量的转发和负载均衡等功能。

那么目前kube-proxy对Service的代理模式主要有:UserspaceIptablesIPVS三种

Userspace(已淘汰)

该模式下,所有的客户端请求service对象,先经过iptables重定向,然后再经过kube-proxy代理到pod(相当于kube-proxy充当路由器,转发请求到对应的pod),导致频繁切换内核/用户空间,因此可靠性和性能都不理想,早已被淘汰。

Iptables

该模式下直接使用 iptables 转发当前节点上的全部流量,这种脱离了用户空间在内核空间中实现转发的方式能够极大地提高 proxy 的效率,增加 kube-proxy 的吞吐量。对于每个service,它都生成相应的iptables规则,这些规则捕获到service的clusterIP和port的流量,并将这些流量随机重定向到service后端Pod。对于每个endpoint对象,它生成选择后端Pod的iptables规则。但iptables 因为它纯粹是为防火墙而设计的,并且基于内核规则列表,每次查询更新的复杂度是\(O(n)\),集群中service及其关联的pod越多,内核查询越繁忙。所以说,一直以来,基于 iptables 的 Service 实现,都是制约 Kubernetes 项目承载更多量级的 Pod 的主要障碍。

IPVS

在这种模式下,kube-proxy同样监听API Server中service和endpoint的变化情况,调用netlink接口创建相应的ipvs规则,并定期将ipvs规则与Kubernetes服 Services和Endpoints同步,保证IPVS状态。当访问Services时,IPVS将流量定向到后端pod之一。IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数, 但是使用哈希表作为基础数据结构(查询复杂度是\(O(1)\)),并且在内核空间中工作。这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。除此之外,相较于Iptables模式:

  • ipvs 为大型集群提供了更好的可扩展性和性能
  • ipvs 支持比 iptables 更复杂的负载均衡算法(最小负载、最少连接、加权等等)
  • ipvs 支持服务器健康检查和连接重试等功能