LVS(3)之进阶使用

LVS(3)之进阶使用

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

基于 FWM 的负载均衡

在请求报文到达主机经过 PREROUTING 链时,我们可通过 mangle 表给我们指定规则下匹配到的请求打上标记,这个标记可以是 1 ~ 65535 之间的数字(通常我们只使用 1 ~ 100),这就是防火墙标记。

我们知道,ipvs 规则是附着于 INPUT 链的,所以在 PREROUTING 链被标记的请求到达 INPUT 链时,我们可以获取到这个标记,然后基于有此类标记的请求做负载均衡的操作。

在上篇文章中有提到 ipvsadm 还有一个 -f 选项如下:

-f service-address:基于 fwm(防火墙标记),此时 service-address 为一个数字,-f mark;

该选项就是用来指定一个标记,然后将有此类标记的请求作为集群服务使用。

下面我们基于上篇文章的 lvs-dr 模型实例做做修改,来使用防火墙标记完成集群服务。

做下面操作之前要保证不存在 iptables 规则的哦,我们在这里仅需要修改 Director 主机。


1、添加 iptables 标记规则,给目标地址为 10.0.1.199、目标端口为 80 的请求报文打上 10 标记。

$ iptables -t mangle -A PREROUTING -d 10.0.1.199 -p tcp --dport 80 -j MARK --set-mark=10

2、重新添加 ipvs 规则如下:

$ ipvsadm -C
$ ipvsadm -A -f 10 -s rr
$ ipvsadm -a -f 10 -r 10.0.1.201 -g
$ ipvsadm -a -f 10 -r 10.0.1.202 -g

3、测试访问 10.0.1.199 会发现效果和之前是一样样的~


这个防火墙标记有啥用呢?

举个例子,如果在上面集群服务中的每个 RS 中除了 80 端口之外还有个 Web 服务监听在 8080 端口,我们依旧是希望通过上面的集群服务完成调度,此时仅需要添加如下规则:

$ iptables -t mangle -A PREROUTING -d 10.0.1.199 -p tcp --dport 8080 -j MARK --set-mark=10

即通过防火墙标记我们可以将监听在不同端口的服务通过相同的标记完成统一的调度。

要注意的是,如果我们此时使用 sh 算法进行调度,它并不能保证同一个客户端请求监听在 80 和 8080 的服务可到达同一个 RS,因为 sh 算法的调度是基于单个服务的,即对于多个共享同一组 RS 的服务,它们之间对于 sh 算法来说是互不相干的。

持久连接

LVS 的持久连接的功能是:无论 ipvs 使用何种调度方法,其都能实现在一定时间内将来自于同一个 Client 的请求始终定向至第一次调度时选出的 RS。

该功能是基于持久连接模板实现的,持久连接模板的结构可以想象一下,大致是这个样子:

客户端标识请求的服务端口FWM 标记到达的 RS超时倒计时
Client 18010RS 1200s
Client 2808010RS 228s
...

当一个请求到达 LVS 时,LVS 会检查持久连接模板中是否保存了该 Client 的请求信息:

  • 如果持久连接模板有匹配到对应该请求的条目,则直接将该请求分发到信息中记录的上次调度到的 RS;
  • 如果持久连接模板未匹配到对应该请求的条目,则按实际的调度算法进行请求分发;

持久连接模板中会对每个记录的条目使用它的持久连接时长进行倒计时:

  • 如果在对应时长内没有访问,则删除该条目,下次该条目对应的请求再过来则重新按照调度算法进行调度;
  • 如果在对应时长内一直在访问,则会持续更新超时时间;

要使用持久连接也很简单,在定义集群服务时使用 -p 选项指定一个持久连接的时长即可,不指定时长时默认为 360 秒,以修改上面示例为持久连接为例:

$ ipvsadm -E -t 10.0.1.199 -s rr -p

此时我们会发现即便使用的是轮询算法,但是我们不管怎么刷新都是访问同一个 RS。

下面来说说一下持久连接实现的几种分类:

  • 每端口持久调度(PPC):单服务持久调度,服务是监听在端口之上的,所以每端口持久调度也可称为每服务持久调度,它实现的其实就是类似 sh 算法调度的功能(源地址哈希),即相同客户端请求同一个服务会被持续分配到同一个 RS 上,只是它可以额外的定义连接的持久时长,使用 -p 选项默认使用的就是此种类型的持久连接,如 ipvsadm -A -t 10.0.1.199:80 -s rr -p
  • 每 FWM 持久(PFWMC):单 FWM 持久调度,即客户端和 FWM 标记相同的请求在持久连接时长内始终分配到同一个 RS,使用 FWM 方式定义集群服务然后使用 -p 选项就实现了单 FWM 调度,如 ipvsadm -A -f 10 -s rr -p
  • 每客户端持久(PCC):单客户端持久调度,Director 会将用户的任何请求都识别为集群服务请求,并将来自相同客户端的请求始终分发至同一个 RS,实现也很简单,在添加集群服务和集群服务中的 RS 时,指定 VIP 以及 RS 对应的端口为 0 即可,如 ipvsadm -A -t 10.0.1.199:0 -s rr -p

具体使用哪种类型的持久连接,还是看具体场景,在上面 FWM 示例的最后有说到,如果仅使用 sh 算法进行调度,它并不能保证同一个客户端请求监听在 80 和 8080 的服务可到达同一个 RS。

这个问题现在就可以解决啦~这里可以将对 80 和 8080 服务的请求做一个统一的标记,使用 PFWMC 的方式来实现同一个客户端始终访问到同一个 RS 的 80 和 8080 服务啦~~~

当然使用 PCC 的方式也能实现,但是没必要,因为我们仅代理两个服务,而 PCC 的方式会将每个请求都识别为对集群服务的请求。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/lvs3-other.html

Buy me a cup of coffee ☕.