LVS持久性:不论LVS使用怎样的调度算法,都能实现将来源同一个源IP的客户端的所有请求在一定时间内定向到同一RS。

LVS持久连接类型:

PCC(persistent client connections)                                    将来自于同一个客户端发往VIP的所有请求统统定向至同一个RS;

PPC(persistent port connections)                                    将来自于一个客户端发往某VIP的某端口的所有请求统统定向至同一个RS;

PNMPP(Persistent Netfilter Marked Packet Persistence)    基于防火墙标记,将两个或以上的端口绑定为同一个服务


实验环境基于LVS DR模型:https://blog.51cto.com/kaiyuandiantang/2329508


1、PCC持久连接实战(同一个IP的所有访问都被定向到同一台机器)

ipvsadm -C

ipvsadm -A -t 192.168.6.101:0 -s rr -p 120

ipvsadm -a -t 192.168.6.101:0 -r 192.168.60.101 -g

ipvsadm -a -t 192.168.6.101:0 -r 192.168.60.102 -g


在客户端192.168.130.192测试

[root@host ~]# curl http://192.168.6.101        

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# ssh root@192.168.6.101 "ifconfig"

root@192.168.6.101's password: 

eno16777736: flags=4163  mtu 1500

        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255

        inet6 fe80::20c:29ff:feef:ea79  prefixlen 64  scopeid 0x20

        ether 00:0c:29:ef:ea:79  txqueuelen 1000  (Ethernet)

        RX packets 35879  bytes 6573166 (6.2 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 22402  bytes 2972332 (2.8 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10

        loop  txqueuelen 0  (Local Loopback)

        RX packets 130  bytes 11271 (11.0 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 130  bytes 11271 (11.0 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo:0: flags=73  mtu 65536

        inet 192.168.6.101  netmask 255.255.255.255

        loop  txqueuelen 0  (Local Loopback)


[root@host ~]# 


在客户端192.168.130.195测试

[root@host ~]# curl http://192.168.6.101         

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]#  ssh root@192.168.6.101 "ifconfig"

root@192.168.6.101's password: 

eno16777736: flags=4163  mtu 1500

        inet 192.168.60.101  netmask 255.255.255.0  broadcast 192.168.60.255

        inet6 fe80::20c:29ff:fe34:9264  prefixlen 64  scopeid 0x20

        ether 00:0c:29:34:92:64  txqueuelen 1000  (Ethernet)

        RX packets 35851  bytes 6519910 (6.2 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 22338  bytes 2954434 (2.8 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10

        loop  txqueuelen 0  (Local Loopback)

        RX packets 90  bytes 7804 (7.6 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 90  bytes 7804 (7.6 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo:0: flags=73  mtu 65536

        inet 192.168.6.101  netmask 255.255.255.255

        loop  txqueuelen 0  (Local Loopback)


[root@host ~]# 



2、PPC持久连接实战(同一个IP的http、ssh访问可能被定向到不同机器)、

ipvsadm -C

ipvsadm -A -t 192.168.6.101:80 -s rr -p 120

ipvsadm -a -t 192.168.6.101:80 -r 192.168.60.101 -g

ipvsadm -a -t 192.168.6.101:80 -r 192.168.60.102 -g

ipvsadm -A -t 192.168.6.101:22 -s rr -p 120          

ipvsadm -a -t 192.168.6.101:22 -r 192.168.60.101 -g  

ipvsadm -a -t 192.168.6.101:22 -r 192.168.60.102 -g

在客户端192.168.130.192测试


[root@host ~]# curl http://192.168.6.101        

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# ssh root@192.168.6.101 "ifconfig"

root@192.168.6.101's password: 

eno16777736: flags=4163  mtu 1500

        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255

        inet6 fe80::20c:29ff:feef:ea79  prefixlen 64  scopeid 0x20

        ether 00:0c:29:ef:ea:79  txqueuelen 1000  (Ethernet)

        RX packets 36375  bytes 6621294 (6.3 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 22629  bytes 3029616 (2.8 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10

        loop  txqueuelen 0  (Local Loopback)

        RX packets 130  bytes 11271 (11.0 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 130  bytes 11271 (11.0 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo:0: flags=73  mtu 65536

        inet 192.168.6.101  netmask 255.255.255.255

        loop  txqueuelen 0  (Local Loopback)


[root@host ~]# 


在客户端192.168.130.195测试

[root@host ~]# curl http://192.168.6.101         

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]#  ssh root@192.168.6.101 "ifconfig"

root@192.168.6.101's password: 

eno16777736: flags=4163  mtu 1500

        inet 192.168.60.101  netmask 255.255.255.0  broadcast 192.168.60.255

        inet6 fe80::20c:29ff:fe34:9264  prefixlen 64  scopeid 0x20

        ether 00:0c:29:34:92:64  txqueuelen 1000  (Ethernet)

        RX packets 36382  bytes 6569326 (6.2 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 22576  bytes 3009558 (2.8 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10

        loop  txqueuelen 0  (Local Loopback)

        RX packets 90  bytes 7804 (7.6 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 90  bytes 7804 (7.6 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo:0: flags=73  mtu 65536

        inet 192.168.6.101  netmask 255.255.255.255

        loop  txqueuelen 0  (Local Loopback)


[root@host ~]# 


3、PNMPP持久连接实战(同一个IP的http、ssh都被定向到同一台机器)

关闭CentOS7的firewalld并启用iptables

yum install -y iptables-services iptables-devel.x86_64 iptables.x86_64

systemctl enable iptables

systemctl start iptables


ipvsadm -C

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

iptables -t mangle -A PREROUTING -d 192.168.6.101 -p tcp --dport 22 -j MARK --set-mark 10

iptables -L -n -t mangle

ipvsadm -A -f 10 -s rr -p 120

ipvsadm -a -f 10 -r 192.168.60.101 -g

ipvsadm -a -f 10 -r 192.168.60.102 -g


在客户端192.168.130.192测试

[root@host ~]# curl http://192.168.6.101        

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# curl http://192.168.6.101

RS2

[root@host ~]# ssh root@192.168.6.101 "ifconfig"

root@192.168.6.101's password: 

eno16777736: flags=4163  mtu 1500

        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255

        inet6 fe80::20c:29ff:feef:ea79  prefixlen 64  scopeid 0x20

        ether 00:0c:29:ef:ea:79  txqueuelen 1000  (Ethernet)

        RX packets 39865  bytes 6923746 (6.6 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 25619  bytes 3420774 (3.2 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10

        loop  txqueuelen 0  (Local Loopback)

        RX packets 130  bytes 11271 (11.0 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 130  bytes 11271 (11.0 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo:0: flags=73  mtu 65536

        inet 192.168.6.101  netmask 255.255.255.255

        loop  txqueuelen 0  (Local Loopback)


[root@host ~]# 


在客户端192.168.130.195测试

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]# curl http://192.168.6.101

RS1

[root@host ~]#  ssh root@192.168.6.101 "ifconfig"

root@192.168.6.101's password: 

eno16777736: flags=4163  mtu 1500

        inet 192.168.60.101  netmask 255.255.255.0  broadcast 192.168.60.255

        inet6 fe80::20c:29ff:fe34:9264  prefixlen 64  scopeid 0x20

        ether 00:0c:29:34:92:64  txqueuelen 1000  (Ethernet)

        RX packets 39919  bytes 6875769 (6.5 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 25533  bytes 3394523 (3.2 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10

        loop  txqueuelen 0  (Local Loopback)

        RX packets 90  bytes 7804 (7.6 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 90  bytes 7804 (7.6 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo:0: flags=73  mtu 65536

        inet 192.168.6.101  netmask 255.255.255.255

        loop  txqueuelen 0  (Local Loopback)


[root@host ~]# 




RS健康状态

RS1、RS2配置

echo "OK" > /var/www/html/.health.html


Director配置

cat health.sh

#!/bin/bash

#

CS='-f 10'

RS1=192.168.60.101

RS2=192.168.60.102


checkRS() {

    curl -s http://${1}/.health.html | grep "OK" &> /dev/null

    RetVal=$?

    if [ $RetVal -ne 0 ] && ipvsadm -L -n | grep "$1" &> /dev/null; then

        ipvsadm -d $CS -r $1

    fi


    if [ $RetVal -eq 0 ] && ! ipvsadm -L -n | grep "$1" &> /dev/null; then

        ipvsadm -a $CS -r $1 -g

    fi

}


while true; do

    checkRS $RS1

    checkRS $RS2

    sleep 3

done              


watch -n 1 'ipvsadm -L -n'


测试

RS1、RS2上启动、关闭HTTP