07月20, 2018

浅析kube-proxy中IPVS模式

浅析kube-proxy的IPVS模式

在k8s中,提供相同服务的一组pod可以抽象成一个service,通过service提供的统一入口对外提供服务,每个service都有一个虚拟IP地址(VIP)和端口号供客户端访问。Kube-proxy存在于各个node节点上,主要用于Service功能的实现,具体来说,就是实现集群内的客户端pod访问service,或者是集群外的主机通过NodePort等方式访问service。在当前版本的k8s中,kube-proxy默认使用的是iptables模式,通过各个node节点上的iptables规则来实现service的负载均衡,但是随着service数量的增大,iptables模式由于线性查找匹配、全量更新等特点,其性能会显著下降。从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables同样基于Netfilter,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能。

1. IPVS

IPVS是LVS的核心组件,是一种四层负载均衡器。IPVS具有以下特点:

  • 与Iptables同样基于Netfilter,但使用的是hash表;
  • 支持TCP, UDP,SCTP协议,支持IPV4,IPV6;
  • 支持多种负载均衡策略:rr, wrr, lc, wlc, sh, dh, lblc…
  • 支持会话保持;

LVS主要由两部分组成:

  • ipvs(ip virtual server):即ip虚拟服务,是工作在内核空间上的一段代码,主要是实现调度的代码,它是实现负载均衡的核心。
  • ipvsadm: 工作在用户空间,负责为ipvs内核框架编写规则,用于定义谁是集群服务,谁是后端真实服务器。我们可以通过ipvsadm指令创建集群服务,例如:
    # ipvsadm -A -t 192.168.2.xx:80 -s rr //创建一个DR,并指定调度算法采用rr。
    # ipvsadm -a -t 192.168.2.xx:80 -r 192.168.10.xx 
    # ipvsadm -a -t 192.168.2.xx:80 -r 192.168.11.xx //添加两个RS
    

IPVS基于Netfilter,在介绍IPVS的工作原理之前,首先介绍一下Netfilter的挂载点。 Netfilter 中制定了数据包的五个挂载点(Hook Point),我们可以将挂载点理解为回调函数点,数据包到达这些位置的时候会主动调用我们的函数,使我们有机会能在数据包路由的时候改变它们的方向、内容,如源和目的IP等,这5个挂载点分别是PRE_ROUTING、INPUT、OUTPUT、FORWARD、POST_ROUTING,如下图所示,IPVS工作在其中的INPUT链上。

alt

图片来源:https://blog.csdn.net/liukun321/article/details/54577433

LVS工作原理如下图所示:

alt

图片来源:https://www.cnblogs.com/daixiang/p/5445584.html

  1. 当客户端的请求到达负载均衡器的内核空间时,首先会到达PREROUTING链。
  2. 当内核发现请求数据包的目的地址是本机时,将数据包送往INPUT链。
  3. 当数据包到达INPUT链时,首先会被IPVS检查,如果数据包里面的目的地址及端口没有在IPVS规则里面,那么这条数据包将被放行至用户空间。
  4. 如果数据包里面的目的地址及端口在IPVS规则里面,那么这条数据报文的目的地址被修改为通过负载均衡调度算法选好的后端服务器(DNAT),并送往POSTROUTING链。
  5. 最后经由POSTROUTING链发往后端服务器。

2.kube-proxy使用IPVS做负载均衡

kube-proxy可以调用内核中的IPVS模块进行负载均衡,此时,客户端pod所在的node节点充当Director的角色。在kube-proxy的IPVS模式下,客户端pod通过service的Cluster IP 访问服务端pod的过程如下图所示。图中着重标注了数据包的源和目的IP在整个过程中的变化情况,从中可以看出kube-proxy工作在IPVS的NAT模式,并且负载均衡过程在客户端pod所在的Node节点上就已经完成了。

alt

  1. 客户端pod发出请求报文,请求报文源地址是CIP(客户端pod的IP),目标地址为service的VIP。
  2. 请求报文到达客户端pod所在的Node节点的INPUT链,此时,内核中IPVS模块 发挥作用,通过调度算法选择一个后端pod提供服务,将该请求报文的目的IP地址修改为选中的后端pod的IP,然后直接送到node节点的POSTROUTING链,发往后端pod。
  3. 请求 报文送到后端pod后,由于请求报文的目标地址是自己,所以会响应该请求,并将响应报文返回,响应报文的源IP为后端pod的IP,目的IP为客户端pod的IP。
  4. 响应报文到达客户端所在的Node节点, 然后IPVS将此报文的源地址修改为service的VIP并发送给客户端pod,这样对于客户端来说,为其提供服务便是service的VIP。

需要注意的是,由于IPVS工作在INPUT链,为了使客户端pod的请求数据包能够到达INPUT链,必须要让内核识别 service的VIP 是本机的 IP,因此必须绑定service的VIP,如下图所示,kube-proxy默认将service的VIP绑定在kube-ipvs0上。

alt

3. 总结

本文主要简单介绍了kube-proxy的IPVS模式,首先分析了IPVS的工作原理,然后介绍了其应用在kube-proxy中做负载均衡的大体流程。当service的数量达到一定规模时,大量的iptables规则会严重降低service的性能,IPVS基于hash表的查找方式、多种负载均衡策略等特点为k8s提供了一种大规模service场景下的解决方案。

本文链接:https://www.opsdev.cn/post/IPVSinKube-proxy.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。