kube-proxy
1、kube-proxy定义
为了支持集群的水平扩展、高可用性,k8s抽象出了Service的概念。而真正将Service的作用落实的是背后的kube-proxy服务进程。
在k8s集群的每个Node上面都会运行一个kube-proxy服务进程。这个进程可以看做Service的透明代理兼负载均衡器,核心功能是将某个Service的访问请求转发到后端的多个pod实例上。
2、工作原理
kube-proxy 监听 API server 中 资源对象的变化情况,包括以下三种:
- service
- endpoint/endpointslices
- node
然后根据监听资源变化操作代理后端来为服务配置负载均衡。
如果你的 kubernetes 使用EndpointSlice,那么kube-proxy会监听EndpointSlice,否则会监听Endpoint。
如果你启用了服务拓扑,那么 kube-proxy 也会监听 node 信息 。服务拓扑(Service Topology)可以让一个服务基于集群的 Node 拓扑进行流量路由。 例如,一个服务可以指定流量是被优先路由到一个和客户端在同一个 Node 或者在同一可用区域的端点。
3、代理模式
- userspace
- iptables
- ipvs
- kernelspace
其中 kernelspace 专用于windows,userspace 是早期版本的实现,本文我们不作过多阐述。
3.1 iptables
iptables是一种Linux内核功能,旨在成为一种高效的防火墙,具有足够的灵活性来处理各种常见的数据包操作和过滤需求。它允许将灵活的规则序列附加到内核的数据包处理管道中的各种钩子上。
在iptables模式下,kube-proxy将规则附加到“ NAT预路由”钩子上,以实现其NAT和负载均衡功能。这种方法很简单,使用成熟的内核功能,并且可以与通过iptables实现网络策略的组件“完美配合”。
默认的策略是,kube-proxy 在 iptables 模式下随机选择一个后端。
如果 kube-proxy 在 iptables 模式下运行,并且所选的第一个 Pod 没有响应, 则连接失败。 这与用户空间模式不同:在这种情况下,kube-proxy 将检测到与第一个 Pod 的连接已失败, 并会自动使用其他后端 Pod 重试。
但是,kube-proxy对iptables规则进行编程的方式是一种O(n)复杂度的算法,其中n与集群大小(或更确切地说,服务的数量和每个服务背后的后端Pod的数量)成比例地增长)。
3.2 ipvs
IPVS是专门用于负载均衡的Linux内核功能。在IPVS模式下,kube-proxy可以对IPVS负载均衡器进行编程,而不是使用iptables。这非常有效,它还使用了成熟的内核功能,并且IPVS旨在均衡许多服务的负载。它具有优化的API和优化的查找例程,而不是一系列顺序规则。 结果是IPVS模式下kube-proxy的连接处理的计算复杂度为O(1)。换句话说,在大多数情况下,其连接处理性能将保持恒定,而与集群大小无关。
与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。
IPVS的一个潜在缺点是,与正常情况下的数据包相比,由IPVS处理的数据包通过iptables筛选器钩子的路径不同。如果打算将IPVS与其他使用iptables的程序一起使用,则需要研究它们是否可以一起正常工作。 不过Ipvs代理模式已经推出很久了,很多组件已经适配的很好了,比如Calico。
参考文章: