Kube-Proxy是实现K8S服务网络的关键底层组件,K8S的服务发现,内部Service到Pod的转发,外部流量接入内部service的网络,都是通过kube-proxy实现的。

在这里插入图片描述

理解Netfilter和Iptables

在这里插入图片描述
Kube-Proxy是如何将cluster IP转换到Pod IP,并且将流量路由到具体的Pod上去的呢。实际上,Kube-Proxy是间接通过Linux内核提供的两个机制(Netfilter和IPtables)。通过这两个机制的配置,来实现地址转换和流量路由的。

简单讲,Netfilter是Linux内核支持的一组钩子方法。它允许内核的其他模块注册各种回调方法,这些回调方法可以截获网络包,并且可以改变他们的目的地路由。

IPtables是一组用户空间程序,通过它们可以设置Netfilter里面的路由规则,IPtables中的程序可以检查,转发,修改,重定向,或者丢弃网络包,简单讲,IPtables是netfilter的用户空间接口。

kube-proxy可以通过iptables间接操作netfilter里面的路由规则。netfilter可以截获底层网卡的IP网络包,并且修改它们的路由。

Kube-Proxy的三种工作模式

用户空间代理模式

在这里插入图片描述
用户空间代理模式,更贴近前面提到的反向代理,在这种模式下,大部分的网络功能,包括路由规则,负载均衡,都是由运行在用户空间的kube-proxy来直接完成的。

Kube-proxy监听请求,来执行路由和负载均衡,将请求转发到目标Pod。

在该模式下,kube-proxy需要频繁在用户空间和内核空间进行切换,英文叫context switch,因为它需要通过iptables来进行交互,来实现负载均衡。

如图:
假设某个服务cluster IP是10.104.14.67:80,节点IP是10.100.0.2:10400。

  1. 首先,kube-proxy会监听master(api server组件+etcd)上面服务的创建,删除相关事件,也监听服务背后,端点(pod)的ip地址。
  2. 当有一个类型为cluster ip的服务被创建,Kube-proxy会在节点上,开启一个随机端口,如图,在节点10.100.0.2这个work node上开启了10400端口。通过这个端口,可以将对应的请求转发到目标Pod上。
  3. Kube-proxy会通过IPtables设置转发规则。让netfilter在接收到目标为cluster ip+端口的某个请求时,转发到node上10400端口上面去。
  4. 当节点上有客户端对cluster ip 10.104.14.67:80的服务发起调用。
  5. 这个请求会被netfilter截获到,并且转发到node上10400端口上。也就是kube-proxy在监听的端口。
  6. kube-proxy接收到请求,就会采用负载均衡的方式将请求转发到pod上去。

1,2,3,是服务发现阶段。4,5,6是运行调用阶段。

这个模式设计到诸多的上下文切换,当有请求被转发到端口10400时,Kube-proxy必须切换到内核模式来接收包,然后切换到用户空间,进行负载均衡调用,因为负载均衡策略不是设置在netfilter当中。

由于频繁的上下文切换,这个模式的性能不理想。

Iptables模式

在这里插入图片描述

考虑到kube-proxy用户空间代理的模式不理想,kubenetes又引入了iptables模式。

如图:
假定服务的cluster IP是10.104.14.67,端口80。节点ip是10.100.0.2。

流程如下:

  1. 首先,kube-proxy会监听master(api server组件+etcd)上面服务的创建,删除相关事件,也监听服务背后,端点(pod)的ip地址。
  2. 当有一个类型为cluster ip的新服务被创建时,Kube-proxy会通过IPtables设置转发规则。让netfilter在接收到目标为cluster ip+端口的某个请求时,直接进行负载均衡并且转发到后端的pod。
  3. 当节点上面有客户端,对cluster ip+port 10.104.14.67:80发起调用的时候。
  4. 请求会被netfilter直接截获,进行负载均衡,转发到后端pod。

这个模式的特点,是不穿透kube-proxy。是直接通过netfilter,iptables直接进行转发的。

不足:netfilter, iptables支持的负载均衡策略比较简单,一般不支持高级的负载均衡机制,也不具备失效重试机制,一般需要readiness probe(就绪探针)进行配合。

iptables模式只适用于中小规模的K8S集群。
假设我们有一个5000个节点的集群,2000个服务,每个服务大约10个POD,那么我们就需要在每个节点上同步20000条IPtables记录。同时云环境中,后端pod ip随时可能发生变化,这样iptables规则需要经常同步。大规模同步会给linux内核带来巨大开销。

为了支持K8S更大规模集群,K8S后续版本中推出了新的kube-proxy工作模式。IPVS模式。

IPVS模式

在这里插入图片描述
IPVS是linux内核支持的一种服务虚拟化技术。是构建于netfilter基础之上的,是为内核传输层,高性能负载均衡设计的一种技术。不仅支持round-robin的负载均衡算法,还支持,最少连接,目标源哈希,
等高级路由算法。

IPVS采取高效的哈希算法,来存储网络路由规则。相比IPtables,它可以显著减少这规则的同步开销,可以大大提升K8S集群的扩展规模。

三种模式中,IPVS效率最高,扩展性最好,配置最复杂。

总结

在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐