LVS:persistent+ldirectord

醉酒当歌 提交于 2020-02-27 15:00:15

=======================================================================
张贺,多年互联网行业工作经验,担任过网络工程师、系统集成工程师、LINUX系统运维工程师
笔者微信:zhanghe15069028807,现居济南历下区
=======================================================================

persistent

persistent:持久连接

以下演示都是基于这张拓扑图:

在LVS上三种方法可实现持久连接:

  1. 每端口持久,通过端口映射,结合sh(源IP地址HASH算法)最常见办法
  2. 每防火墙标识持久,通过iptables在数据包上打mark
  3. 每客户端持久,基于0端口定义集群服务,即将客户端对所有应用的请求统统调度至后端主机,必须定义为持久模式;

第一种方式:每端口持久,注意要结合sh算法才能实现

[root@lvs ~]# ipvsadm -A -t 192.168.80.99:80 -s sh
[root@lvs ~]# ipvsadm -a -t 192.168.80.99:80 -r 192.168.80.11 -g 
[root@lvs ~]# ipvsadm -a -t 192.168.80.99:80 -r 192.168.80.12 -g 
[root@lvs ~]# ipvsadm -Ln
TCP  192.168.80.99:80 sh
  -> 192.168.80.11:80             Route   1      0          0         
  -> 192.168.80.12:80             Route   1      0          0       

第三种方式:通过防火墙标识持久,关于这个我专门有一篇博文,这里不过多阐述。

[root@lvs ~]# iptables -t mangle -A PREROUTING -d 192.168.80.99/32 -p tcp -m multiport --ports 80,443 -j MARK --set-mark 3
[root@lvs ~]# ipvsadm -C
[root@lvs ~]# ipvsadm -A -f 3 -s rr
[root@lvs ~]# ipvsadm -a -f 3 -r 192.168.80.11:80 -g
[root@lvs ~]# ipvsadm -a -f 3 -r 192.168.80.12:80 -g
[root@lvs ~]# ipvsadm -Ln
FWM  3 rr
  -> 192.168.80.11:80             Route   1      0          0         
  -> 192.168.80.12:80             Route   1      0          0         

第三种方式:每客户端持久

[root@lvs ~]# ipvsadm -A -t 192.168.80.99:80 -s rr -p
[root@lvs ~]# ipvsadm -a -t 192.168.80.99:80 -r 192.168.80.11 -g
[root@lvs ~]# ipvsadm -a -t 192.168.80.99:80 -r 192.168.80.12 -g
[root@lvs ~]# ipvsadm -Ln
TCP  192.168.80.99:80 rr persistent 360
  -> 192.168.80.11:80             Route   1      0          0         
  -> 192.168.80.12:80             Route   1      0          0         

仔细观察上面的配置,发现第一条命令后一个-p,意为持久连接之意,但是我们下面又是用的rr算法,这岂不是冲突了吗?如果使用了上面的配置,当用户访问的时候只有第一次是rr算法(轮询),而以后rr算法都不再生效,-p会生效,也就说当一个用户第一次访问时LVS替用户选定了一个R-SERVER,那以后用户再进来时都由同一台R-SERVER服务,rr算法失效,持久连接在算法之前生效,而且持久连接保持长达360秒。

[root@lvs ~]# ipvsadm -A -t 192.168.80.99 -s rr -p
[root@lvs ~]# ipvsadm -a -t 192.168.80.99 -r 192.168.80.12 -g
[root@lvs ~]# ipvsadm -a -t 192.168.80.99 -r 192.168.80.11 -g
[root@lvs ~]# ipvsadm -Ln
TCP  192.168.80.99:0 rr persistent 360
  -> 192.168.80.11:0              Route   1      0          0         
  -> 192.168.80.12:0              Route   1      0          0  

基于0端口定义集群服务,0代表全部端口,即将客户端对所有应用的请求统统调度至后端主机,必须定义为持久模式;

ldirectord

健康检测原理

健康检测有三种类型:

​ (a) 网络层检测,能ping通就认为对方在线,粗糙,能ping通但服务挂了也不成呀!

​ (b) 传输层检测,端口探测,端口处于侦听状态就认为对方在线,也是粗糙,万一是别人服务侦听的端口呢?

​ (c) 应用层检测,请求某关键资源;请求某个页面,要求返回的页面包括某个字符串就认为对方在线,这个还可以,我们下面用的ldirectord就是这种,当然也可以实现前两种。

应用场景

LVS支持的算法有一个很大的缺点,就是它只会根据本身的算法和服务器的负载进行分发,全然不顾R-SERVER是否存活,LVS本身并没有健康检测的功能,当某一个R-SERVER宕机了LVS并不会检测到,当然也就不能从规则当中踢出R-SERVER对应的IPVS规则了。

最常见的解决方案有两种:

  1. keepalived
  2. ldirectord

第一种方案:keepalived

keepalived我们会拿出专门的博文来重点阐述的,这里不过多说明,其实keepalived最大的作用就是利用数据通信领域当中VRRP协议进行冗余,通常配合LVS,实现前端负载均衡的冗余,防止负载均衡器的单点故障。其实keepalived的作用并不仅仅只有这一项,keepalived还能实现对后端R-SERVER的健康检测功能,如果R-SERVER出现了问题无法被客户端正常访问时,keepalived会及时检测到故障R-SERVER,并不会将客户端的数据发送到出问题的R-SERVER上。这是最常见的方案,一举两得。

第二种方案: ldirectord

我们刚才说过keepalived的两种功能,冗余LVS和健康检测R-SERVER, ldirectord只能实现一种功能,那就是健康检测R-SERVER,当R-SREVER出现问题时,能及时通过调用ipvsadm将问题R-SERVER从规则当中踢出。我们在这篇博文时主要演示一下第二种方案。

实现过程

拓扑

  1. 下载并安装idrectord
//安装包可以向我索要,很多yum里面都没有
yum localinstall ldirectord-3.9.6-0rc1.1.1.x86_64.rpm 
[root@lvs ~]# rpm -ql ldirectord
/etc/ha.d
/etc/ha.d/resource.d
/etc/ha.d/resource.d/ldirectord
/etc/logrotate.d/ldirectord
/usr/lib/ocf/resource.d/heartbeat/ldirectord
/usr/lib/systemd/system/ldirectord.service
/usr/sbin/ldirectord
/usr/share/doc/ldirectord-3.9.6
/usr/share/doc/ldirectord-3.9.6/COPYING
/usr/share/doc/ldirectord-3.9.6/ldirectord.cf
/usr/share/man/man8/ldirectord.8.gz
  1. 将模板配置文件cp到主目录下
 cp /usr/share/doc/ldirectord-3.9.6/ldirectord.cf /etc/ha.d/
  1. 解释主配置文件
# Global Directives
checktimeout=3   健康检测超时时间3秒,也就说三秒不通才能判定R-SERVER宕机了
checkinterval=1  一秒检查一次
#fallback=127.0.0.1:80 如果所有的R-SERVER都宕机了,谁来响应,通常是本机说sorry
autoreload=yes      自动重载
#logfile="/var/log/ldirectord.log"  日志相关
#logfile="local0"                   日志发送到rsyslog
#emailalert="admin@x.y.z"           邮件相关
#emailalertfreq=3600
#emailalertstatus=all
quiescent=no

# Sample for an http virtual service
virtual=192.168.80.99:80      #vip
        real=192.168.80.11:80 gate  #-g代表DR模型
        real=192.168.80.12:80 gate
        service=http                #检测协议
        scheduler=rr                 #rr算法
        #persistent=600
        #netmask=255.255.255.255
        protocol=tcp
        checktype=negotiate
        checkport=80
        request="index.html"    #请求的默认界面
        receive="80"     #界面当中必须要用什么字符才能判定没有问题
       #virtualhost=www.x.y.z
  1. 配置示例
[root@lvs ~]# vim /etc/ha.d/ldirectord.cf  
# Global Directives
checktimeout=3
checkinterval=1
#fallback=127.0.0.1:80
autoreload=yes
#logfile="/var/log/ldirectord.log"
#logfile="local0"
#emailalert="admin@x.y.z"
#emailalertfreq=3600
#emailalertstatus=all
quiescent=no

# Sample for an http virtual service
virtual=192.168.80.99:80
        real=192.168.80.11:80 gate
        real=192.168.80.12:80 gate
        fallback=127.0.0.1:80 gate
        service=http
        scheduler=rr
        #persistent=600
        #netmask=255.255.255.255
        protocol=tcp
        checktype=negotiate
        checkport=80
        request="index.html"
        receive="80"
        #virtualhost=www.x.y.z
//清空规则,让此服务接管
ipvsadm -C
//启动服务
systemctl restart ldirectord.service
[root@lvs ~]# ipvsadm -Ln
TCP  192.168.80.99:80 rr
  -> 192.168.80.11:80             Route   1      0          0         
  -> 192.168.80.12:80             Route   1      0          0   
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!