Keepalived+LVS实现高可用负载均衡Web集群

、原理及简介:
1.1 Keepalived简介
      Keepalived是Linux下一个轻量级别的高可用解决方案。Keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四层、第五层交换机制检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived将检测到,并将出现的故障的服务器节点从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,需要人工完成的只是修复出现故障的服务节点。
      后来Keepalived又加入了VRRP的功能,VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)出现的目的是解决静态路由出现的单点故障问题,通过VRRP可以实现网络不间断稳定运行,实现高可用性,因此Keepalvied 一方面具有服务器状态检测和故障隔离功能,另外一方面也有HA cluster功能,下面介绍一下VRRP协议实现的过程。


上图是Keepalived的功能体系结构,大致分两层:用户空间(user space)和内核空间(kernel space)。
内核空间:主要包括IPVS(IP虚拟服务器,用于实现网络服务的负载均衡)和NETLINK(提供高级路由及其他相关的网络功能)两个部份。
用户空间:

  • WatchDog:负载监控checkers和VRRP进程的状况
  • VRRP Stack:负载负载均衡器之间的失败切换FailOver,如果只用一个负载均稀器,则VRRP不是必须的。
  • Checkers:负责真实服务器的健康检查healthchecking,是keepalived最主要的功能。换言之,可以没有VRRP Stack,但健康检查healthchecking是一定要有的。
  • IPVS wrapper:用户发送设定的规则到内核ipvs代码
  • Netlink Reflector:用来设定vrrp的vip地址等。

1.2 VRRP协议和工作原理
      VRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由,这个虚拟路由器通过虚拟IP(一个或者多个)对外提供服务,而在虚拟路由器内部十多个物理路由器协同工作,同一时间只有一台物理路由器对外提供服务,这台物理路由设备被成为:主路由器(Master角色),一般情况下Master是由选举算法产生,它拥有对外服务的虚拟IP,提供各种网络功能,如:ARP请求,ICMP 数据转发等,而且其它的物理路由器不拥有对外的虚拟IP,也不提供对外网络功能,仅仅接收MASTER的VRRP状态通告信息,这些路由器被统称为“BACKUP的角色”,当主路由器失败时,处于BACKUP角色的备份路由器将重新进行选举,产生一个新的主路由器进入MASTER角色,继续提供对外服务,整个切换对用户来说是完全透明的。
     每个虚拟路由器都有一个唯一的标识号,称为VRID,一个VRID与一组IP地址构成一个虚拟路由器,在VRRP协议中,所有的报文都是通过IP多播(一对多,一个Master对多个Backup)方式发送的,而在一个虚拟路由器中,只有处于Master角色的路由器会一直发送VRRP数据包,处于BACKUP角色的路由器只会接受Master角色发送过来的报文信息,用来监控Master运行状态,一般不会发生BACKUP抢占MASTER的情况,除非它的优先级更高,而当MASTER不可用时,BACKUP也就无法收到Master发过来的信息,于是就认定Master出现故障,接着多台BAKCUP就会进行选举,优先级最高的BACKUP将称为新的MASTER,这种选举角色切换非常之快,因而保证了服务的持续可用性。

 

1.3 LVS负载均衡模式 直接路由模式(DR)
直接路由,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变。  
Director和各RS都得配置使用VIP;
(1) 确保前端路由器将目标IP为VIP的请求报文发往Director;
 (a) 在前端网关做静态绑定;
 (b) 在RS上使用arptables;
 (c) 在RS上修改内核参数以限制arp通告及应答级别;
 限制响应级别:arp_ignore
                        0:默认值,表示可使用本地任意接口上配置的任意地址进行响应;
                        1: 仅在请求的目标IP配置在本地主机的接收到请求报文接口上时,才给予响应;
                    限制通告级别:arp_announce
                        0:默认值,把本机上的所有接口的所有信息向每个接口上的网络进行通告;
                        1:尽量避免向非直接连接网络进行通告;
                        2:必须避免向非本网络通告;
(2) RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director;
(3) RS跟Director要在同一个物理网络;
(4) 请求报文要经由Director,但响应不能经由Director,而是由RS直接发往Client;
(5) 不支持端口映射

 

、拓扑及环境介绍
2.1 网络拓扑图

2.2 环境介绍

 2.3 集群配置前提
(1) 各节点时间必须同步(chrony or ntp)                      
(2) 确保iptables及selinux不会成为阻碍        
(3) 各节点之间可通过主机名互相通信(并非必须)
       建议使用/etc/hosts文件实现
(4) 确保各节点的用于集群服务的接口支持MULTICAST通信
    打开或关闭支持组播通信 on|off

[root@Director1 ~]# ip link set multicast on dev ens33   //打开组播功能,默认为开启状态
[root@Director1 ~]# ifconfig | grep MULTICAST          
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500

 

、前端调度服务器配置
(1)安装keepalived

[root@Director1 ~]# yum -y install keepalived   //安装keepalived
[root@Director1 ~]# cd /etc/keepalived/
[root@Director1 keepalived]# cp keepalived.conf{,.bak}  //复制一份配置文件

(2)主配置文件(Director1)

[root@Director1 keepalived]# vim /etc/keepalived/keepalived.conf    //编辑配置文件
! Configuration File for keepalived
##################全局配置##########################
global_defs {
   notification_email {
        root@localhost
        371304@qq.com                  //设置报警邮件单个或多个地址
   }

   notification_email_from keepalived@localhost    //keepalived报警邮件,发件人
   smtp_server 127.0.0.1        //邮件服务器地址
   smtp_connect_timeout 30      //邮件服务器超时时间
   router_id Direcotr1        //路由ID两台机器不能相同
   vrrp_mcast_group4 224.0.0.18    //多播地址,范围224.0.0.0~239.255.255.255
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
#################keepalived配置#####################
vrrp_instance VI_1 {
    state MASTER        //keepalived角色,MASTER和BACKUP
    interface ens33     //指定HA监测网络的接口
    virtual_router_id 99    //虚拟路由ID号,0~255,MASTER和BACKUP必须是一致的
    priority 100   //定义优先级,数字越大 优先级越高 MASTER的优先级高于BACKUP优先级
    advert_int 1   //设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
    authentication {   //设置验证类型和密码
        auth_type PASS  //设置验证类型,主要有PASS和AH两种
        auth_pass QeiVWCxs //设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码
    }                      //密码生成openssl rand -base64 6取前8位即可
    virtual_ipaddress {       //设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个            
        192.168.10.99/24 dev ens33 label ens33:0         
    }

    notify_master "/etc/keepalived/notify.sh master"    //调用通知脚本
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
##################LVS配置############## 

#添加虚拟服务器 #相当于 ipvsadm -A -t 192.168.10.99:80 -s wrr virtual_server 192.168.10.99 80 { //设置虚拟服务器,需要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开 delay_loop 1 //设置运行情况检查时间,单位是秒 lb_algo wrr //设置负载调度算法 lb_kind DR //设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选 protocol TCP //指定转发协议类型,有TCP和UDP两种 sorry_server 127.0.0.1 80 //当后端服务器全部脱机时,访问即调用本地 real_server 192.168.10.61 80 { //配置服务节点1,需要指定real server的真实IP地址和端口,IP与端口之间用空格隔开 weight 1 //配置服务节点的权值 HTTP_GET { //http进行检测 url { path /index.html status_code 200 } connect_timeout 3 //表示3秒无响应超时 nb_get_retry 3 //表示重试次数 delay_before_retry 2 //表示重试间隔 } } real_server 192.168.10.62 80 { //配置服务节点2 weight 1 HTTP_GET { url { path /index.html status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 2 } } }

 (3)备配置文件(Director2)

[root@Director2 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
        root@localhost
        371304@qq.com
   }

   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id Director2   //与主节点不一致
   vrrp_mcast_group4 224.0.0.18
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP     //状态为BACKUP
    interface ens33
    virtual_router_id 99   //必须保持一致
    priority 96  //优先级低于Master
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass QeiVWCxs
    }
    virtual_ipaddress {
        192.168.10.99/24 dev ens33 label ens33:0 
    }

        notify_master "/etc/keepalived/notify.sh master"
        notify_backup "/etc/keepalived/notify.sh backup"
        notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server 192.168.10.99 80 {
        delay_loop 1
        lb_algo wrr
        lb_kind DR
        protocol TCP
        sorry_server 127.0.0.1 80

        real_server 192.168.10.61 80 {
        weight 1
        HTTP_GET {
                url {
                  path /index.html
                  status_code 200
                }
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 2
          }
        }

        real_server 192.168.10.62 80 {
        weight 1
        HTTP_GET {
                url {
                  path /index.html
                  status_code 200
                }
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 2
          }
        }
}

 (4)邮件通知脚本
当双主高可用集群主备切换时可通过邮件通知管理员,此时在配置文件中可自动调用实现编辑好的脚本

[root@Director1 keepalived]# vim /etc/keepalived/notify.sh   //编辑脚本
#!/bin/bash
#
contact='root@localhost'

notify() {
        local mailsubject="$(hostname) to be $1, vip floating"
        local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
        echo "$mailbody" | mail -s "$mailsubject" $contact
}

case $1 in
master)
        notify master
        ;;
backup)
        notify backup
        ;;
fault)
        notify fault
        ;;
*)
        echo "Usage: $(basename $0) {master|backup|fault}"
        exit 1
        ;;
esac

[root@Director1 keepalived]# chmod a+x /etc/keepalived/notify.sh  //赋予执行权限
[root@Director1 keepalived]# scp -p /etc/keepalived/notify.sh Director2:/etc/keepalived/  //拷贝到Director2服务上的/etc/keepalived目录下
root@director2's password: 
notify.sh                                                                                                          100%  408    22.3KB/s   00:00  
~    

 (5)两节点安装httpd软件及配置默认首页

[root@Director1 ~]# yum -y install httpd  
[root@Director2 ~]# yum -y install httpd
[root@Director1 ~]# echo '<h1>Sorry!!!Server maintenance is in process. Please wait...</h1>'>/var/www/html/index.html 
[root@Director2 ~]# echo '<h1>Sorry!!!Server maintenance is in process. Please wait...</h1>'>/var/www/html/index.html 
[root@Director1 ~]# systemctl start httpd.service;ssh Director2 'systemctl start httpd.service'  
root@director2's password: 
[root@Director1 ~]# systemctl enable httpd.service;ssh Director2 'systemctl enable httpd.service'  //两节点设置开机自启动
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
root@director2's password: 
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@Director1 ~]# curl 192.168.10.7  //测试主节点
<h1>Sorry!!!Server maintenance is in process. Please wait...</h1>
[root@Director1 ~]# curl 192.168.10.8 //测试另一节点
<h1>Sorry!!!Server maintenance is in process. Please wait...</h1>

  (6)两节点安装ipvsadmin软件

[root@Director1 ~]# yum -y install ipvsadm
[root@Director2~]# yum -y install ipvsadm
[root@Director1 ~]# rpm -qa ipvsadm
ipvsadm-1.27-7.el7.x86_64

 
、后端RS服务器的配置
(1)后端真实服务器两节点安装httpd软件及配置默认首页

[root@RS1 ~]# yum -y install httpd
[root@RS2 ~]# yum -y install httpd
[root@RS1 ~]# echo "<h1>RS1:192.168.10.61</h1>" > /var/www/html/index.html
[root@RS2 ~]# echo "<h1>RS2:192.168.10.62</h1>" > /var/www/html/index.html
[root@RS1 ~]# /etc/init.d/httpd start;ssh RS2 '/etc/init.d/httpd start'
Starting httpd: 
root@rs2's password: 
Starting httpd: 
[root@RS1 ~]# chkconfig httpd on;ssh RS2 'chkconfig httpd on'
root@rs2's password: [root@Director1
~]# curl 192.168.10.61 <h1>RS1:192.168.10.61</h1> [root@Director1 ~]# curl 192.168.10.62 <h1>RS1:192.168.10.62</h1>

 (2)修改RS内核参数可以通过脚本实现
   a、 脚本编写如下:

#!/bin/bash
#Desc: LVS_DR Real Server in the lo configuration VIP
#Author:tony QQ:317104
#Date:2017-7-10
vip=192.168.10.99
mask='255.255.255.255'

case $1 in
start)
        echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
        echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

        ifconfig lo:0 $vip netmask $mask broadcast $vip up
        route add -host $vip dev lo:0
        ;;
stop)
        ifconfig lo:0 down

        echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce

        ;;
*)
        echo "Usage $(basename $0) start|stop"
        exit 1
        ;;
esac
View Code

    b、将脚本复制到RS2目录下,并两台执行该脚本

[root@RS1 script]# chmod a+x /usr/src/script/lvs_DR.sh  //赋予执行权限
[root@RS1 script]# cd /usr/src/script/
[root@RS1 script]# ./lvs_DR.sh start  //执行脚本
[root@RS1 script]# scp -p lvs_DR.sh rs2:/usr/src/script/
root@rs2's password: 
lvs_DR.sh                                                                                                          100%  743     0.7KB/s   00:00

[root@RS2 ~]# /usr/src/script/lvs_DR.sh start

  (3)查看后端两节点的VIP是否配置上,及相应的http的服务器已经起来

[root@RS1 script]# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    inet 127.0.0.1/8 scope host lo
    inet 192.168.10.99/32 brd 192.168.10.99 scope global lo:0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.10.61/24 brd 192.168.10.255 scope global eth0
[root@RS1 script]# ss -tnl | grep 80
LISTEN     0      128                      :::80                      :::*   
[root@RS2 ~]# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    inet 127.0.0.1/8 scope host lo
    inet 192.168.10.99/32 brd 192.168.10.99 scope global lo:0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.10.62/24 brd 192.168.10.255 scope global eth0
[root@RS2 script]# ss -tnl | grep 80
LISTEN     0      128                      :::80                      :::*   

 

 、测试
 (1)开启Director2的keepalived服务

 (2)查看ipvsadmin生成列表

[root@Director2 ~]# 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.10.99:80 wrr
  -> 192.168.10.61:80             Route   1      0          0         
  -> 192.168.10.62:80             Route   1      0          0 

 (3)测试访问VIP

[root@Director1 ~]#  for i in {1..10};do curl http://www.contoso.com/index.html;done
<h1>RS1:192.168.10.61</h1>
<h1>RS2:192.168.10.62</h1>
<h1>RS1:192.168.10.61</h1>
<h1>RS2:192.168.10.62</h1>
<h1>RS1:192.168.10.61</h1>
<h1>RS2:192.168.10.62</h1>
<h1>RS1:192.168.10.61</h1>
<h1>RS2:192.168.10.62</h1>
<h1>RS1:192.168.10.61</h1>
<h1>RS2:192.168.10.62</h1>

 (4)开启Director1的keepalived服务,查看及状态

[root@Director1 ~]# systemctl start keepalived.service   //开启keepalived服务
[root@Director1 ~]# systemctl enable keepalived.service 
[root@Director2 ~]# systemctl enable keepalived.service

       查看状态

   (5)停掉后端两节点的http服务,查看LVS列表

[root@RS1 script]# /etc/init.d/httpd stop  
Stopping httpd:                                            [  OK  ]
[root@Director1 ~]# ipvsadm -L -n              //自动移除RS1节点
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.10.99:80 wrr
  -> 192.168.10.62:80             Route   1      0          0         
You have new mail in /var/spool/mail/root
[root@RS2 ~]# /etc/init.d/httpd stop
Stopping httpd:                                            [  OK  ]
[root@Director1 ~]# 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.10.99:80 wrr
  -> 127.0.0.1:80                 Route   1      0          0 

  (6)查看网站

  7)、启动RS2节点,再访问

[root@RS2 ~]# /etc/init.d/httpd start
Starting httpd:                                            [  OK  ]

 

  (8)、启动RS1节点,再访问,,LVS规则又正常了

[root@RS1 script]# /etc/init.d/httpd start
Starting httpd:                                            [  OK  ]
[root@Director1 ~]# 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.10.99:80 wrr
  -> 192.168.10.61:80             Route   1      0          2         
  -> 192.168.10.62:80             Route   1      2          0  

   (9)、停掉Director1的keepavlied服务,看是否节点转移成功

[root@Director1 ~]# systemctl stop keepalived.service  //停掉keepalived服务
[root@Director1 ~]# ipvsadm -L -n 
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@Director2 ~]# ip -4 addr  //查看Director2VIP地址是否绑定成功
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.10.8/24 brd 192.168.10.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet 192.168.10.99/24 scope global secondary ens33:0
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
You have new mail in /var/spool/mail/root
[root@Director2 ~]# ipvsadm -L -n  //查看规则在Direcotr2上
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.10.99:80 wrr
  -> 192.168.10.61:80             Route   1      0          0         
  -> 192.168.10.62:80             Route   1      0          0    

    (10)、检查邮件是否正常

 (11)、使用抓包工具tcpdump查看VIP地址漂移情况,

[root@Director1 ~]# tcpdump -i ens33 -nn host 224.0.0.18 
[root@Director1 ~]# tcpdump -i ens33 -vvv host 224.0.0.18

    *****停掉Director1的keepalived服务之后,我们发现VIP瞬间转移至Director2上 *****

posted @ 2018-02-07 13:05  cloudos  阅读(2262)  评论(0编辑  收藏  举报