[svc]高并发场景 LVS DR +KeepAlive高可用实现及ka的persistence_timeout参数

LVS-DR+keepalived模式是一种非常经典的常用生产组合

高可用场景及LVS架构

一般都用一(负载)拖多(Server Array)方式

使用LVS架设的服务器集群系统有三个部分组成:

(1)最前端的负载均衡层,用Load Balancer表示;
(2)中间的服务器集群层,用Server Array表示;
(3)最底端的数据共享存储层,用Shared Storage表示;

在用户看来,所有的内部应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。

系统环境准备

参考

系统环境

  • 采用4台cenos7.4来做实验
DS:Director Server。指的是前端负载均衡器节点。
RS:Real Server。后端真实的工作服务器。
  • 将selinux和防火墙关掉
[root@n1 ~]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@n1 ~]# uname -a
Linux lb03 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@n1 ~]# systemctl status firewalld.service 
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
[root@n1 ~]# getenforce 
Disabled
  • web节点准备(两台nginx)
[root@n1 ~]# curl 192.168.14.13
web03
[root@n1 ~]# curl 192.168.14.14
web04
  • 安装lvs的命令行管理软件ipvsadm
yum -y install ipvsadm
ipvsadm          # 激活lvs内核模块
lsmod|grep ip_vs # 查看模块是否加载

lvs介绍和ipvsadm与ipvs的关系

早在2.2内核时, IPVS就已经以内核补丁的形式出现。
从2.4.23版本开始,IPVS软件就合并到Linux内核的常用版本的内核补丁的集合。
2.4.24以后IPVS已经成为Linux官方标准内核的一部分。(uname -r)

  • LVS无需安装
  • 安装的是管理工具,第一种叫ipvsadm,第二种叫keepalive
  • ipvsadm是通过命令行管理,而keepalive读取配置文件管理
  • 后面我们会用Shell脚本实现keepalive的功能

配置LVS负载均衡服务(在n1操作)

负载节点n1设置

lb上配虚ip -- 清理lvs规则 -- 设置tcp/tcpfin/udp连接timeout -- 添加VIP -- 给VIP挂RS -- 检查

步骤1:在eth0网卡绑定VIP地址(ip)
步骤2:清除当前所有LVS规则(-C)
步骤3:设置tcp、tcpfin、udp链接超时时间(--set)
步骤4:添加虚拟服务(-A),
        -t指定虚拟服务的IP端口,
        -s 指定调度算法 调度算法见man ipvsadm, rr wrr 权重轮询
        -p 指定超时时间
        
步骤5:将虚拟服务关联到真实服务上(-a)
        -r指定真实服务的IP端口
        -g LVS的模式 DR模式
        -w 指定权重
步骤6:查看配置结果(-ln)
ip addr add 192.168.14.100/24 dev eth0
ipvsadm -C                    
ipvsadm --set 30 5 60        
ipvsadm -A -t 192.168.14.100:80 -s wrr -p 20   
ipvsadm -a -t 192.168.14.100:80 -r 192.168.14.13:80 -g -w 1 
ipvsadm -a -t 192.168.14.100:80 -r 192.168.14.14:80 -g -w 1
ipvsadm -ln
[root@n1 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.14.100:80 rr persistent 20
  -> 192.168.14.13:80             Route   1      0          0         
  -> 192.168.14.14:80             Route   1      0          0 

ipvsadm 参数:
-l --list 显示内核虚拟服务器表
-n --numeric ip和端口以数字形式显示(不以域名)

两台web节点设置

步骤1:修改内核参数抑制ARP响应
步骤2:在lo网卡绑定VIP地址(ip)

- 抑制arp响应
cat >>/etc/sysctl.conf<<EOF
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
EOF
sysctl -p

- 为lo绑定虚vip
ip addr add 192.168.14.100/32 dev lo

- 清空arp表(web节点+负载节点)
ip neigh flush dev eth0
ip neigh flush dev lo

- 测试
curl 192.168.14.100

LVS的模式

DR模式

DR负载均衡模式数据分发过程中不修改IP地址,只修改mac地址,由于实际处理请求的真实物理IP地址和数据请求目的IP地址一致,所以不需要通过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。因此,DR模式具有较好的性能,也是目前大型网站使用最广泛的一种负载均衡手段。

参考

lvs使用场景说明:

a)通过在调度器LB上修改数据包的目的MAC地址实现转发。注意,源IP地址仍然是CIP,目的IP地址仍然是VIP。

b)请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此,并发访问量大时使用效率很高,比Nginx代理模式强于此处。

c)因DR模式是通过MAC地址的改写机制实现转发的,因此,所有RS节点和调度器LB只能在同一个局域网中。需要注意RS节点的VIP的绑定(lo:vip/32)和ARP抑制问题。

d)强调下:**RS节点的默认网关不需要是调度器LB的DIP**,而应该直接是IDC机房分配的上级路由器的IP(这是RS带有外网IP地址的情况),理论上讲,只要RS可以出网即可,不需要必须配置外网IP,但走自己的网关,那网关就成为瓶颈了。

e)由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器LB无法改变请求报文的目的端口。LVS DR模式的办公室在二层数据链路层(MAC),NAT模式则工作在三层网络层(IP)和四层传输层(端口)。

f)当前,调度器LB支持几乎所有UNIX、Linux系统,但不支持windows系统。真实服务器RS节点可以是windows系统。

g)总之,DR模式效率很高,但是配置也较麻烦。因此,访问量不是特别大的公司可以用haproxy/Nginx取代之。这符合运维的原则:简单、易用、高效。日1000-2000W PV或并发请求1万以下都可以考虑用haproxy/Nginx(LVS的NAT模式)

h)直接对外的访问业务,例如web服务做RS节点,RS最好用公网IP地址。如果不直接对外的业务,例如:MySQL,存储系统RS节点,最好只用内部IP地址。

DR模式说明:

(a) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP

(b) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链

(c) IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址

(d) 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。

(e) RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP

(f) 响应报文最终送达至客户端

iptables实战

注意点:
RS:
1.VIP的绑定(lo:vip/32)
2.ARP抑制问题

1.RS不需要将网关指向DR
2.DR不支持端口改写,仅是路由转发.
3.1-2kw的并发用nginx可以搞定,dr模式配置较为麻烦.

LVS/DR模式原理剖析(常见问题)

结合keepalive实现lb的高可用

- keepalive的作用
1. 添加VIP
2. 添加LVS配置
3. 高可用(VIP漂移)
4. web服务器健康检查

参考

安装keepalive

ipadm -C
yum install keepalive -y

priority 越高越优先成为master

lb-n1配置

root@n1 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_01
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
     192.168.14.100/24
    }
}

virtual_server 192.168.14.100 80 {
    delay_loop 6              
    lb_algo wrr                
    lb_kind DR                
    nat_mask 255.255.255.0
    persistence_timeout 50     
    protocol TCP                

    real_server 192.168.14.13 80 {
        weight 1              
        TCP_CHECK {
        connect_timeout 8       
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }

    real_server 192.168.14.14 80 {
        weight 1              
        TCP_CHECK {
        connect_timeout 8       
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
}

lb2-n2的配置

root@n2 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_02
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
     192.168.14.100/24
    }
}
virtual_server 192.168.14.100 80 {
    delay_loop 6          
    lb_algo wrr                
    lb_kind DR                
    nat_mask 255.255.255.0
    persistence_timeout 50     
    protocol TCP                

    real_server 192.168.14.13 80 {
        weight 1              
        TCP_CHECK {
        connect_timeout 8       
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }

    real_server 192.168.14.14 80 {
        weight 1              
        TCP_CHECK {
        connect_timeout 8       
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
}

启动后就ok.
高可用测试: 将n3的nginx关掉, 访问就自动跑到了n4上.

附录: keepalive配置说明

global_defs {  
   notification_email {  
         edisonchou@hotmail.com  
   }  
   notification_email_from sns-lvs@gmail.com  
   smtp_server 192.168.80.1  
   smtp_connection_timeout 30
   router_id LVS_DEVEL  # 设置lvs的id,在一个网络内应该是唯一的
}  
vrrp_instance VI_1 {  
    state MASTER   #指定Keepalived的角色,MASTER为主,BACKUP为备          
    interface eth1  #指定Keepalived的角色,MASTER为主,BACKUP为备
    virtual_router_id 51  #虚拟路由编号,主备要一致
    priority 100  #定义优先级,数字越大,优先级越高,主DR必须大于备用DR    
    advert_int 1  #检查间隔,默认为1s
    authentication {  
        auth_type PASS  
        auth_pass 1111  
    }  
    virtual_ipaddress {  
        192.168.80.200  #定义虚拟IP(VIP)为192.168.2.33,可多设,每行一个
    }  
}  
# 定义对外提供服务的LVS的VIP以及port
virtual_server 192.168.80.200 80 {  
    delay_loop 6 # 设置健康检查时间,单位是秒                    
    lb_algo wrr # 设置负载调度的算法为wlc                   
    lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式   
    nat_mask 255.255.255.0                
    persistence_timeout 0          
    protocol TCP                  
    real_server 192.168.80.102 80 {  # 指定real server1的IP地址
        weight 3   # 配置节点权值,数字越大权重越高              
        TCP_CHECK {  
        connect_timeout 10         
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
    }  
    real_server 192.168.80.103 80 {  # 指定real server2的IP地址
        weight 3  # 配置节点权值,数字越大权重越高  
        TCP_CHECK {  
        connect_timeout 10  
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
     }  
} 

keepalived persistence_timeout参数意义 LVS Persistence 参数的作用

persistence_timeout参数

persistence_timeout 300  # 单位秒, 这个参数的意义是保持客户端的请求在这个时间段内全部发到同一个真实服务器。

正常情况下LVS会保证同一个TCP链接数据包会发往同一个真实服务器。
例如:(192.168.80.1:49165 192.168.80.120:8080 192.168.80.136:8080)LVS会记录这个TCP链接的【原IP与端口,目标IP与端口】,后续的数据包会发送到192.168.80.136:8080

但是如果设置了persistence_timeout那么在这个时间段内,当前IP地址下所有的TCP链接数据包都会被发送到同一个真实服务器。假设客户端使用5个端口 建立了5个TCP链接,那么这5个链接会被发往相同的后端服务器,反之亦然。

我们使用命令查看IPVS的规则,可以看到-p 300 已经被设置进去了。

[root@bogon ~]# ipvsadm -S -n
-A -t 192.168.80.120:8080 -s rr -p 300
-a -t 192.168.80.120:8080 -r 192.168.80.135:8080 -i -w 1
-a -t 192.168.80.120:8080 -r 192.168.80.136:8080 -i -w 1

然后客户端请求LVS服务器。我们通过ipvsadm -L -n -c命令查看转发规则。发现所有的TCP链接都指向了一个后端服务器。
我们注意看(TCP 02:36 NONE 192.168.80.1:0 192.168.80.120:8080 192.168.80.136:8080)
就是它记录这当前客户端的IP地址,这样无论后续多少TCP请求都会被发到同一个后端服务器。

TCP 00:16  FIN_WAIT    192.168.80.1:49165 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16  FIN_WAIT    192.168.80.1:49168 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16  FIN_WAIT    192.168.80.1:49169 192.168.80.120:8080 192.168.80.136:8080
TCP 02:36  NONE        192.168.80.1:0     192.168.80.120:8080 192.168.80.136:8080
TCP 00:16  FIN_WAIT    192.168.80.1:49167 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16  FIN_WAIT    192.168.80.1:49170 192.168.80.120:8080 192.168.80.136:8080

为什么要这么做?是因为:

官方解释:http://www.linuxvirtualserver.org/docs/persistence.html
我翻译了一部分。
有些Web服务可能用到HTTP Cookie,它是将数据存储在客户的浏览器来追踪和标识客户的机制。使用HTTP Cookie后,来同一客户的不同连接存在相关性,这些连接必须被发送到同一Web服务器。一些Web服务使用安全的HTTPS协议,它是HTTP协议加 SSL(Secure Socket Layer)协议。另有些Web服务可能使用安全的HTTPS协议,它是HTTP协议加SSL协议。当客户访问HTTPS服务(HTTPS的缺省端口为 443)时,会先建立一个SSL连接,来交换对称公钥加密的证书并协商一个SSL Key,来加密以后的会
话。在SSL Key的生命周期内,后续的所有HTTPS连接都使用这个SSL Key,所以同一客户的不同HTTPS连接也存在相关性。针对这些需要,IPVS调度器提供了持久服务的功能,它可以使得在设定的时间内,来自同一IP地 址的不同连接会被发送到集群中同一个服务器结点,可以很好地解决客户连接的相关性问题。

DR模式2个问题

参考

1.rs的vip为何配在lo口?
2.dr模式中抑制了谁的arp响应?

内核针对arp的限制参数

echo"1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo"2" >/proc/sys/net/ipv4/conf/lo/arp_announce

echo"1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo"2" >/proc/sys/net/ipv4/conf/all/arp_announce

arp_ignore:定义对目标地址为本地IP的ARP询问不同的应答模式0 

为何是all,这里提了一下

我做了个arping的响应实验:arpping链路层检测

 arping -I eth0 192.168.14.13  #通
 arping -I eth0 192.168.14.100 #不通

说明 dr模式抑制了VIP的arp应答.

dr模式2个问题: 1,rs的vip为何配在lo口? 答: 防ip冲突 2,dr模式中抑制了谁的arp响应? 答: vip

怎么实现的呢? 通过arp的参数

0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求 
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求 
2 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内 
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应 
4-7 - 保留未使用 
8 -不回应所有(本地地址)的arp查询

arp响应限制

1)arp_ignore:
定义对目标地址为本地IP的ARP询问不同的应答模式0

0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7 - 保留未使用
8 -不回应所有(本地地址)的arp查询

2)arp_announce:
对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口

0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.

posted @ 2018-03-08 12:54  _毛台  阅读(729)  评论(0编辑  收藏  举报