lvs+keepalived实现负载均衡
LVS简介:
lvs是负载均衡较常用的软件之一,lvs官方提供了一个命名的约定:
vip:虚拟ip地址,缩写是vip,vip是负载均衡器对外提供服务的ip。
rip:真实ip地址,缩写是rip,rip是集群下面节点上使用的ip地址。
dip:负载均衡器的真实ip,用于连接内外网络的ip。
cip:客户端的ip地址,访问来源ip。
lvs的工作模式有如下几种,直接路由(dr)模式、nat模式、tunnel模式、full nat模式。
DR模式-直接路由模式:
Virtual Server via Direct
VS/DR模式是通过改写请求报文的目标MAC地址,将请求发给真实服务器的,而真 实服务器将响应后的处理结果直接返回给客户端用户。同VS/TUN技术一样,VS/DR技术 可极大地提高集群系统的伸缩性。而且,这种DR模式没有IP隧道的开销,对集群中的真 实服务器也没有必须支持IP隧道协议的要求,但是要求调度器LB与直实服努器RS都有一块网卡连在同一物理网段上,即必须在同一个局域网环境。
当然也包括iptables防火墙的forward功能(DR和TUX模式不需要)
DR模式特点: 1、通过在调度器LB上修改数据包的目的MAC地址实现转发。注意,源IP地址仍然是 CIP,目的IP地址仍然是VIP。 2、请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此,并发访问量大时使用效率很高(和NAT模式比)。 3、因DR模式是通过MAC地址的改写机制实现的转发,因此,所有RS节点和调度器LB 只能在一个局域网LAN中(小缺点)。 4、需要注意RS节点的VTP的绑定(lo:vip,lo1:vip)和ARP抑制问题。 5、RS节点的默认网关不需要是调度器LB的DIP,而直接是IDC机房分配的上 级路由器的IP (这是RS带有外网IP地址的情况),理论上来说只要RS可以出网即可,不是必须要配置外网IP。 6、由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器LB无法改变请求的报文的目的端口(和NAT要区别)。 7、当前,调度器LB支持几乎所有的UNIX,LINUX系统,但目前不支持WINDOWS系统。真实服务器RS节点可以是WINDOWS系统。 8、总的来说DR模式效率很高,但是配置也较麻烦,因此,访问量不是特别大的公司可以 用haproxy/nginx取代之。这符合运维的原则:简单、易用、高效。日2000W PV或并发请 求1万以下都可以考虑用haproxy/nginx (LVS的NAT模式) 9、直接对外的访问业务,例如:web服务做RS节点,RS最好用公网IP地址。如果不直 接对外的业务,例如:MySQL,存储系统RS节点,最好只用内部IP地址。
NAT模式:
1、NAT技术将请求的报文(DNAT)和响应的报文(SNAT),通过调度器地址重写然后 在转发发给内部的服务器,报文返回时在改写成原来的用户请求的地址。
2、只需要在调度器LB上配置WAN公网IP即可,调度器也要有私有LAN IP和内部RS节点通信。
3、每台内部RS节点的网关地址,必须要配置成调度器LB的私有LAN内物理网卡地址(LDIP),这样才能确保数据报文返回时仍然经过调度器LB。
4、由于请求与响应的数据报文都经过调度器LB,因此,网站访问量大时,调度器LB有较大瓶颈,一般要求最多10-20台节点。
5、NAT模式支持对IP及端口的转换,即用户请求10.0.0.1:80,可以通过调度器转换到 RS 节点的10.0.0.2:8080 (DR和TUN模式不具备的)
6、所有NAT内部RS节点只需配置私有LAN IP即可。
7、由于数据包来回都需要经过调度器,因此要开启内核转发net.ipv4.ip_forward = 1
当然也包括iptables防火墙的forward功能(DR和TUN模式不需要)。
其他模式的负载均衡不太常用,这里不做详细说明。tunnel模式主要是把ip前端包装一个头,适合用于跨机房的情况。fullnat则是淘宝使用的负载均衡模式。
关于LVS的调度算法:
固定调度算法:rr,wrr,dh;sh
动态调度算法:wlc,lc,lblc,lblcr,SED,NQ(后两种官方站点没提到,编译LVS,make过 程可以看到 rr|wrr|lc|wlc|lblc|lblcrjdli|sli|sed|nq)
3常用种调度算法见如下:
rr 轮循调度(Round-Robin):
它将请求依次分配不同的RS节点,也就是在RS节点中 均摊请求。这种箅法简单,但是只适合于RS节点处理性能相差不大的情况。
wrr:
加权轮循调度(Weighted Round-Robin),它将依据不同RS节点的权值分配任务。权值较高的RS将优先获得任务,并且分配到的连接数将比权值较低的RS节点更多。 相同权值的RS得到相同数目的连接数。
Wlc加权最小连接数调度算法:
假设各台RS的全职依次为Wi,当前tcp连接数依次为Ti,依次去Ti/Wi为最小的RS作为下一个分配的RS
一、lvs服务的配置方法
1.安装内核开发包
[root@slave02 ~]# yum install -y kernel-devel [root@slave02 ~]# ln -s /usr/src/kernels/3.10.0-514.16.1.el7.x86_64/ /usr/src/linux [root@slave02 ~]# yum install -y ipvsadm
2.装载ip_vs模块到内核
[root@slave02 ~]# lsmod |grep ip_vs [root@slave02 ~]# modprobe ip_vs [root@slave02 ~]# lsmod |grep ip_vs ip_vs 141092 0 nf_conntrack 111302 6 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4 libcrc32c 12644 3 xfs,ip_vs,dm_persistent_data
3.手工添加lvs转发
[root@slave02 ~]# ifconfig eth0:0 192.168.3.177/24 up [root@slave02 ~]# route add -host 192.168.3.177 dev eth0 [root@slave02 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.3.1 0.0.0.0 UG 100 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 192.168.3.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 192.168.3.177 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
4.添加lvs服务并增加两台RS 192.168.3.12 和 192.168.3.13
[root@slave02 ~]# ipvsadm -C # clear the whole tables [root@slave02 ~]# ipvsadm --set 30 5 60 # set tcp tcpfin udp [root@slave02 ~]# ipvsadm -A -t 192.168.3.177:80 -s rr -p 20 [root@slave02 ~]# ipvsadm -a -t 192.168.3.177:80 -r 192.168.3.12 -g -w 1 [root@slave02 ~]# ipvsadm -a -t 192.168.3.177:80 -r 192.168.3.13 -g -w 1 [root@slave02 ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.3.177:80 rr persistent 20 -> 192.168.3.12:80 Route 1 0 6 -> 192.168.3.13:80 Route 1 0 1
删除方法:
[root@slave02 ~]# ipvsadm -D -t 192.168.3.177:80
此时访问http://192.168.3.177/不出意外是无法访问的
rs01操作:
[root@master ~]# ifconfig lo:0 192.168.3.177/32 up [root@master ~]# route add -host 192.168.3.177 dev lo [root@master ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.3.177 0.0.0.0 255.255.255.255 UH 0 0 0 lo 192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 192.168.3.1 0.0.0.0 UG 0 0 0 eth0
rs02操作:
[root@slave01 ~]# ifconfig lo:0 192.168.3.177/32 up [root@slave01 ~]# route add -host 192.168.3.177 dev lo [root@slave01 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.3.177 0.0.0.0 255.255.255.255 UH 0 0 0 lo 192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 192.168.3.1 0.0.0.0 UG 0 0 0 eth0
5.在RS端配置抑制ARP响应
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
lvs脚本:
[root@slave02 ~]# cat ipvs.sh
#!/bin/bash VIP=192.168.3.177 PORT=80 RIP=( 192.168.3.12 192.168.3.13 ) start(){ ipvsadm -C ipvsadm --set 30 5 60 ipvsadm -A -t $VIP:$PORT -s rr -p20 for ((i=0;i<${#RIP[*]};i++)) do ipvsadm -a -t $VIP:$PORT -r ${RIP[$i]} -g -w 1 done } stop(){ ipvsadm -C } main(){ case $1 in start) start echo "ipvs is started" ;; stop) stop echo "ipvs is stoped" ;; restart) stop echo "ipvs is stoped" start echo "ipvs is started" ;; *) echo "USAGE:$0 {start|stop|restart}" esac } main $1
二、keepalived的常用配置
1.在lvs节点上安装keepalived软件
# yum install -y keepalived
2.修改keepalived配置,并重启keepalived软件
# systemctl restart keepalived
主节点配置:
# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@chinasoft.com } notification_email_from haproxy-ha@chinasoft.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id lvs_01 } vrrp_instance VI_1 { interface eth0 state MASTER virtual_router_id 198 priority 150 advert_int 3 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.177 } }
backup节点配置:
# cat keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@chinasoft.com } notification_email_from haproxy-ha@chinasoft.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id lvs_02 } vrrp_instance VI_1 { interface eth0 state BACKUP virtual_router_id 198 priority 150 advert_int 3 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.177 } }
可以看到vip 192.168.3.177漂移到了master 192.168.3.198上
[root@slave02 keepalived]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:3b:dc:7e brd ff:ff:ff:ff:ff:ff inet 192.168.3.198/24 brd 192.168.3.255 scope global eth0 valid_lft forever preferred_lft forever inet 192.168.3.177/32 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::250:56ff:fe3b:dc7e/64 scope link valid_lft forever preferred_lft forever
3.双实例配置方法:
[root@slave02 keepalived]# cat keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@chinasoft.com } notification_email_from haproxy-ha@chinasoft.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id lvs_01 } vrrp_instance VI_1 { interface eth0 state MASTER virtual_router_id 198 priority 150 advert_int 3 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.177 } } vrrp_instance VI_2 { interface eth0 state BACKUP virtual_router_id 199 priority 100 advert_int 3 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.188 } }
互备的实例配置:
[root@manager keepalived]# cat keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@chinasoft.com } notification_email_from haproxy-ha@chinasoft.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id lvs_02 } vrrp_instance VI_1 { interface eth0 state BACKUP virtual_router_id 198 priority 150 advert_int 3 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.177 } } vrrp_instance VI_2 { interface eth0 state MASTER virtual_router_id 199 priority 150 advert_int 3 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.188 } }
三、构建实战:LVS+Keepalived实现负载均衡
1.实验结构总览
(1)本次基于centsos系统所构成的一个服务器集群,其中两台负载均衡服务器(一台为主机,另一台为备机),另外两台作为真实的Web服务器(向外部提供http服务,这里仅仅使用了CentOS的nginx服务。
(2)本次实验基于DR负载均衡模式,设置了一个VIP(Virtual IP)为192.168.3.177,用户只需要访问这个IP地址即可获得网页服务,在生产环境中一般将域名解析指向VIP地址。其中,负载均衡主机为192.168.3.198,备机为192.168.3.200。Web服务器A为192.168.3.12,Web服务器B为192.168.3.13。
2.编辑realserver脚本文件(主要是自动完成ARP抑制的设置)
# vim /etc/init.d/realserver SNS_VIP=192.168.3.177 #source /etc/rc.d/init.d/functions case "$1" in start) 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 sysctl -p >/dev/null 2>&1 echo "RealServer Start OK" ;; stop) echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce echo "RealServer Stoped" ;; *) echo "Usage: $0 {start|stop}" exit 1 esac
这里我们设置虚拟IP为:192.168.3.177
③保存脚本文件后更改该文件权限:chmod 755 /etc/init.d/realserver
④开启realserver服务:/etc/init.d/realserver start
3.配置主负载服务器
安装Keepalived相关包
yum install -y keepalived
(2)编辑keepalived.conf配置文件
①进入keepalived.conf所在目录:cd /etc/keepalived
②首先清除掉keepalived原有配置:> keepalived.conf
③重新编辑keepalived配置文件:vi keepalived.conf
global_defs { notification_email { edisonchou@hotmail.com } notification_email_from sns-lvs@gmail.com smtp_server 192.168.3.198 smtp_connection_timeout 30 router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的 } vrrp_instance VI_1 { state MASTER #指定Keepalived的角色,MASTER为主,BACKUP为备 interface eth0 #指定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.3.177 #定义虚拟IP(VIP)为192.168.2.33,可多设,每行一个 } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.3.177 80 { delay_loop 6 # 设置健康检查时间,单位是秒 lb_algo rr # 设置负载调度的算法为wlc lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式 nat_mask 255.255.255.0 persistence_timeout 0 protocol TCP real_server 192.168.3.12 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.3.13 80 { # 指定real server2的IP地址 weight 3 # 配置节点权值,数字越大权重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } }
重新启动keepalived服务
systemctl restart keepalived
4.配置从负载服务器
从负载服务器与主负载服务器大致相同,只是在keepalived的配置文件中需要改以下两处:
(1)将state由MASTER改为BACKUP
(2)将priority由100改为99
global_defs { notification_email { edisonchou@hotmail.com } notification_email_from sns-lvs@gmail.com smtp_server 192.168.3.200 smtp_connection_timeout 30 router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的 } vrrp_instance VI_1 { state BACKUP #指定Keepalived的角色,MASTER为主,BACKUP为备 interface eth0 #指定Keepalived的角色,MASTER为主,BACKUP为备 virtual_router_id 51 #虚拟路由编号,主备要一致 priority 99 #定义优先级,数字越大,优先级越高,主DR必须大于备用DR advert_int 1 #检查间隔,默认为1s authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.3.177 #定义虚拟IP(VIP)为192.168.2.33,可多设,每行一个 } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.3.177 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.3.12 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.3.13 80 { # 指定real server2的IP地址 weight 3 # 配置节点权值,数字越大权重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } }
停掉主节点的keepalived服务vip就漂移到了备用节点上,再次启动主节点VIP再次回到主节点上