keepalived+LVS 实现双机热备、负载均衡、失效转移 高性能 高可用 高伸缩性 服务器集群

本章笔者亲自动手,使用LVS技术实现实现一个可以支持庞大访问量、高可用性、高伸缩性的服务器集群

在读本章之前,可能有不少读者尚未使用该技术,或者部分读者使用Nginx实现应用层的负载均衡。这里大家都可以阅读本章,即使部分读者使用Nginx负载均衡,但是在大流量下性能相对于工作在链路层的LVS真是不能同日而语,并且LVS不仅可以实现WEB方面的负载均衡,其他诸如数据库、FTP、Mail等都可以实现。

 

通常对于小型网站,很多都使用单台服务器,顶多在弄个缓存服务器、数据库服务器。但是一旦流量上来,单台服务器在再害也无法应对流量洪峰,况且如果这台服务器挂了整个网站就算是挂了。而且大家会发现,一般都是在节假日或者做活动时流量突增,如果使用单台性能十分高的服务器,很多时候资源都在闲置着,那么我们是否能在流量高峰之前加几台等流量过去了再减几台,这样是不是省了很多money了。

高性能、搞可用性、高伸缩性,这些我想都是大部分IT人员日夜追寻的,笔者不才,亲自手动搭建一个LVS负载均衡集群来实现读者的梦想。

首先介绍下双机热备,负载均衡的架构

"主director server"和"备用director server"是路由调度层,平时由"住director server"进行路由分发,"备用director server"平时作为"主director server" 的备份,当"主director server"出现故障的时候自动切换到"备用director server"上面,当其恢复后再次切换回来,这样主备一起就实现了双机热备避免单点故障。

当用户访问时,包被发送到"主director server","主director server"根据相应规则以及服务器集群各个节点的负载情况将流量均衡分配给相应服务器节点。当服务器集群中有节点出现故障时,自动将该节点踢出,待修复后再自动加入该节点。以此实现分流,降低单台服务器压力,同时保证整个服务器集群的高可用性。

LVS是通过IP负载均衡技术实现负载均衡的,具体到本章的Centos环境,就是通过IPVS模块来实现的。IPVS的主要作用是:它安装在director server 上面,同时在director server上面虚拟出一个IP,用户必须通过虚拟的IP地址访问服务器,这个虚拟的IP一般称为LVS的虚拟IP,访问者的请求先经过VIP到达负载均衡调度器,然后由负载均衡调度器容从Real Server 列表中选择一个节点响应用户的请求。在用户的请求到达director server 后,director server如何提供服务器到real server, real server 节点如何返回数据给用户是IPVS技术的重点

 

IPVS实现负载均衡的技术有三种:

VS/NAT : 即网络地址翻译技术实现负载均衡, 当用户请求到达负载均衡调度器后,调度器将请求的目标地址(即虚拟IP)改为选定的real server地址,同时将目标端口改成相应的real server 端口,最后将报文发送给选定的real server。real server将数据返回给用户时,需要再次经过负载均衡调度器,将报文的源地址和端口地址改为相应的虚拟IP和端口,然后经过调度器发送给客户端。可以看出NAT模式下,报文都必须通过director server 对地址和端口进行改写,流量大的情况下,director server将成为瓶颈。

VS/TUN:通过IP隧道技术实现虚拟服务器。这种方式的链接调度管理和NAT方式相同,只是报文转发方法不一样。在VS/TUN模式下,调度器采用IP隧道技术将用户的请求转发到某个real server节点上,而这个real server 将直接响应用户的请求,不再经过前端调度器。此外对real server的地域位置没有要求,其可以喝director server在同一个网络,也可以位于单独的网络。因此,相对于NAT模式,VS/TUN模式大大提高系统吞吐量。

VS/DR:也就是直接路由技术实现虚拟服务器。这种方式的链接调度管理和前两种方式一样,但它的报文转发方法又有所不同,VS/DR通过改写报文的请求MAC地址,将请求发送到real server, 而real server将相应直接返回给客户,免去VS/TUN的IP隧道开销。这三种方式中,VS/TR的负载调度模式性能最好,但要求director server 与 real server 由同一块网卡链接在同一个物理网络中。

 

负载调度算法有四中:

轮叫调度:通过"轮叫"调度算法将外部用户请求按1:1的分配到集群中每个real server节点上,这种算法平等对待每台real server。

加权轮叫调度:该算法根据real server的不同处理能力来调度访问请求。可以对每台real server设置不同的调度权值,性能高的设置高些,性能低的设置低些,进而保证性能好的处理更多流量,充分合理利用服务器资源。同时调度器动态查询real server的负载情况,并动态调整其权值。

最少连接调度:该调度算法动态的将请求调度到连接数最少的real server 上。

加权最少连接调度:该算法是"最少连接调度"算法的增强版,每个服务器可以设定相应的权值表示其处理能力,而系统管理员可以设置其权值,其在分配请求时尽可能使服务器连接数和其权值成正比。

 

好了,介绍完以上知识,我们这里就要实践一下这个HA双机热备、负载均衡集群了

架构图如下

 

第一步:配置各个服务器IP

这里私有IP怎样配置笔者就不再累述了,这里就讲下虚拟IP如何配置(主备不需要虚拟IP的配置,keepalived或者heartbeat会自动进行配置,笔者这里主要是讲的real server节点的虚拟IP配置),这里笔者通过shell脚本实现,shell的内如如下(/etc/init.d/functions 要给755权限奥)

#!/bin/bash
#开启或关闭real server 服务

VIP=192.168.138.200
./etc/rc.d/init.d/functions
case "$1" in
        start)
        echo "Start LVS of Real Server 3"
        /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
        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
        ;;
        stop)
        /sbin/ifconfig lo:0 down
        echo "Close LVS Director Server"
        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 "Usage:$0 {start|stop}"
        exit 1
esac

 

 

然后放到 '/etc/init.d/lvsrs' 并赋予权限

chomd 755 /etc/init.d/lvsrs

 

 

第二步:在主、备 director server 上安装 keepalived ipvsadm 等软件

其中keepalived 用来监控服务器集群各个节点的状态,如果某个服务节点出现异常或工作出现故障,keepalived将检测到并将故障的节点从集群中踢出出去,当节点恢复正常后keepalived又自动的将节点加入到集群中。

ipvsadm 是ipvs模块的管理软件,而LVS(Linux 虚拟主机)就是通过IPVS模块来实现的,由于笔者使用的是Centos6.4,内核已经默认支持LSV功能了,这里可以通过命令检测kernel是否已经支持LVS的IPVS模块

modprobe -l|grep 'ipvs'

如果列出以下结果就算支持了

kernel/net/netfilter/ipvs/ip_vs.ko
kernel/net/netfilter/ipvs/ip_vs_rr.ko
kernel/net/netfilter/ipvs/ip_vs_wrr.ko
kernel/net/netfilter/ipvs/ip_vs_lc.ko
kernel/net/netfilter/ipvs/ip_vs_wlc.ko
kernel/net/netfilter/ipvs/ip_vs_lblc.ko
kernel/net/netfilter/ipvs/ip_vs_lblcr.ko
kernel/net/netfilter/ipvs/ip_vs_dh.ko
kernel/net/netfilter/ipvs/ip_vs_sh.ko
kernel/net/netfilter/ipvs/ip_vs_sed.ko
kernel/net/netfilter/ipvs/ip_vs_nq.ko
kernel/net/netfilter/ipvs/ip_vs_ftp.ko

 

先到其官网上下载最新版本的源码安装包

安装之前你先确认下 /usr/src/kernels/目录是不是空的,如果是空的还要安装这两个东东

yum install -y kernel-devel kernel
tar -zxvf keepalived-1.2.19.tar.gz 
cd keepalived-1.2.19
./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.32-573.12.1.el6.i686
make && make install

 安装ipvsadm 管理软件

yum install ipvsadm

 

第三步:配置keepalived 

 

用keepalived + lvs 来实现双机热备和负载均衡

先对"主director server"进行配置,这里笔者贴出自己的配置文件 '/usr/local/keepalived/etc/keepalived/keepalived.conf'

#这里是全局定义部分
global_defs {
   notification_email {
    admin@laiwojia.la   #设置报警邮件地址 每行一个 可以设置多个
    boss@laiwojia.la
    cto@laiwojia.la
   }
   notification_email_from server@laiwojia.la #邮件的发送地址
   smtp_server 192.168.138.10 #smtp 地址
   smtp_connect_timeout 30 #连接smtp服务器超时的实际
   router_id LVS_DEVEL
}

#vrrp 实例定义部分
vrrp_instance VI_1 {
    state MASTER  #keepalived 的角色 MASTER 表示主机是主服务器 BACKUP表示是以备用服务器
    interface eth0 #指定监测的网络网卡
    virtual_router_id 51 #虚拟路由标示
    priority 100 #定义优先级 数字越大 优先级越高 MASTER的优先级必须大于BACKUP的优先级
    advert_int 1 #设定主备之间检查时间 单位s
    authentication {  #设定验证类型和密码
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress { #设定虚拟IP地址 可以设置多个 每行一个
        192.168.138.200
    }
}

#虚拟服务器部分
virtual_server 192.168.138.200 80 {
    delay_loop 6 #设定运行情况检查时间 单位s
    lb_algo rr #负载调度算法 rr即轮叫算法
    lb_kind DR #设置LVS负载机制 NAT TUN DR 三种模式可选
    nat_mask 255.255.255.0
    persistence_timeout 0  #会话保持时间
                            #有了这个会话保持功能 用户的请求会被一直分发到某个服务节点
                            #如果用户在动态页面50s内没有任何动作,那么后面就会被分发到其他节点
                            #如果用户一直有动作,不受50s限制

    protocol TCP  #协议

    #real server部分
    real_server 192.168.138.3 80 {
        weight 1  #服务节点权值,数字越大,权值越高
                  #权值的大小可以为不同性能的服务器分配不同的负载
                  #这样才能有效合理的利用服务器资源
        TCP_CHECK {  #状态检查部分    
          connect_timeout 3 #3s无响应超时                                                     
          nb_get_retry 3  #重试次数
          delay_before_retry 3   #重试间隔
          connect_port 80 #连接端口                                                    
        }  
    }

    #real server部分
    real_server 192.168.138.4 80 {
        weight 1  #服务节点权值,数字越大,权值越高
                  #权值的大小可以为不同性能的服务器分配不同的负载
                  #这样才能有效合理的利用服务器资源
        TCP_CHECK {  #状态检查部分    
          connect_timeout 3 #3s无响应超时                                                     
          nb_get_retry 3  #重试次数
          delay_before_retry 3   #重试间隔
          connect_port 80 #连接端口                                                    
        }  
    }
}

然后笔者再贴出备分主机的配置

#这里是全局定义部分
global_defs {
   notification_email {
    admin@laiwojia.la   #设置报警邮件地址 每行一个 可以设置多个
    boss@laiwojia.la
    cto@laiwojia.la
   }
   notification_email_from server@laiwojia.la #邮件的发送地址
   smtp_server 192.168.138.10 #smtp 地址
   smtp_connect_timeout 30 #连接smtp服务器超时的实际
   router_id LVS_DEVEL
}

#vrrp 实例定义部分
vrrp_instance VI_1 {
    state BACKUP  #keepalived 的角色 MASTER 表示主机是主服务器 BACKUP表示是以备用服务器
    interface eth0 #指定监测的网络网卡
    virtual_router_id 51 #虚拟路由标示
    priority 80 #定义优先级 数字越大 优先级越高 MASTER的优先级必须大于BACKUP的优先级
    advert_int 1 #设定主备之间检查时间 单位s
    authentication {  #设定验证类型和密码
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress { #设定虚拟IP地址 可以设置多个 每行一个
        192.168.138.200
    }
}

#虚拟服务器部分
virtual_server 192.168.138.200 80 {
    delay_loop 6 #设定运行情况检查时间 单位s
    lb_algo rr #负载调度算法 rr即轮叫算法
    lb_kind DR #设置LVS负载机制 NAT TUN DR 三种模式可选
    nat_mask 255.255.255.0
    persistence_timeout 0  #会话保持时间
                            #有了这个会话保持功能 用户的请求会被一直分发到某个服务节点
                            #如果用户在动态页面50s内没有任何动作,那么后面就会被分发到其他节点
                            #如果用户一直有动作,不受50s限制

    protocol TCP  #协议

    #real server部分
    real_server 192.168.138.3 80 {
        weight 1  #服务节点权值,数字越大,权值越高
                  #权值的大小可以为不同性能的服务器分配不同的负载
                  #这样才能有效合理的利用服务器资源
        TCP_CHECK {  #状态检查部分    
          connect_timeout 3 #3s无响应超时                                                     
          nb_get_retry 3  #重试次数
          delay_before_retry 3   #重试间隔
          connect_port 80 #连接端口                                                    
        }  
    }

    #real server部分
    real_server 192.168.138.4 80 {
        weight 1  #服务节点权值,数字越大,权值越高
                  #权值的大小可以为不同性能的服务器分配不同的负载
                  #这样才能有效合理的利用服务器资源
        TCP_CHECK {  #状态检查部分    
          connect_timeout 3 #3s无响应超时                                                     
          nb_get_retry 3  #重试次数
          delay_before_retry 3   #重试间隔
          connect_port 80 #连接端口                                                    
        }  
    }
}

整完了之后要把'/usr/local/keepalived/etc/rc.d/init.d/keepalived'复制到'/etc/rc.d/init.d/'目录下

吧'/usr/local/keepalived/etc/sysconfig/keepalived' 复制到'/etc/sysconfig/'目录下

把'/usr/local/keepalived/sbin/keepalived' 复制到'/sbin/'目录下

把'/usr/local/keepalived/etc/keepalived/keepalived.conf'复制到'/etc/keepalived/'目录下

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived  /etc/rc.d/init.d/
cp /usr/local/keepalived/etc/sysconfig/keepalived  /etc/sysconfig/
cp  /usr/local/keepalived/sbin/keepalived /sbin/
mkdir -p /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf  /etc/keepalived/

 由于keepalived日志文件放在'/var/log/message'下,该文件还有其他东西的日志不便于阅读,这里笔者为其指定单独的位置 '/usr/local/keepalived/logs/keepalived.log'

先要修改 '/etc/sysconfig/keepalived' 文件,在最后一行 KEEPALIVED_OPTIONS="-D" 换成 KEEPALIVED_OPTIONS="-D -d -S 0" (笔者算是醉了,尼玛软件开发者难道不能给个参数指定日志文件路径吗),然后在/etc/rsyslog.conf 后面加上一句

#keepalived -S 0 
local0.*                                                /usr/local/keepalived/logs/keepalived.log

然后建立日志目录

mkdir -p /usr/local/keepalived/logs

 然后重新启动系统日志

/etc/init.d/rsyslog restart

 

然后我们启动 主备 keepalived 和 服务节点的lvsrs

service keepalived start
service lvsrs start

然后我们启动 real server 的nginx

/usr/local/nginx/sbin/nginx

 

第四步:测试

首先我们来测试负载均衡部分,笔者这里整个脚本 test.sh

#!/bin/bash

if [ ! -f "/root/backup/test.txt" ]
then
touch /root/backup/test.txt
fi

for((i=0;i<10;i++))
do
curl http://192.168.138.200 >>  /root/backup/test.txt
sleep 1
done

然后运行之

./test.sh

然后我们到 主director server 上面瞅瞅

ipvsadm

然后出现下面这个结果

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.138.200:http rr
-> 192.168.138.3:http Route 1 0 5
-> 192.168.138.4:http Route 1 0 5

就对了,每个都被分发了5次

当然,你不放心可以查看'/root/backup/test.txt'文件,看看里面的内容是否都是循环的列出的(笔者这里两个首页内容略有不同以便于区分)

 

接着我们将real server 某台nginx停掉,看看效果

/usr/local/nginx/sbin/nginx -s stop

我们来看看master的日志

cat /usr/local/keepalived/keepalived.log

Feb 3 18:01:46 localhost Keepalived_healthcheckers[706]: TCP connection to [192.168.138.3]:80 failed !!!
Feb 3 18:01:46 localhost Keepalived_healthcheckers[706]: Removing service [192.168.138.3]:80 from VS [192.168.138.200]:80
Feb 3 18:01:46 localhost Keepalived_healthcheckers[706]: SMTP connection ERROR to [192.168.138.10]:25.

瞅着了吧先是连接不上192.168.138.3,然后从列表中移除,然后发送预警邮件(笔者这里邮件瞎配的所以连接不上SMTP服务器)

当然你也可以访问下页面,再也看不到192.168.138.4 了

 

最后我们来验证双机热备部分

我们把master keepalived 服务停掉

service  keepalived stop

然后我们查看下backup的日志

Feb 3 18:05:06 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) Transition to MASTER STATE
Feb 3 18:05:07 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 3 18:05:07 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) setting protocol VIPs.
Feb 3 18:05:07 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.138.200
Feb 3 18:05:07 localhost Keepalived_healthcheckers[5548]: Netlink reflector reports IP 192.168.138.200 added
Feb 3 18:05:12 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.138.200

可以看到backup director 自动变为MASTER , 我们可以访问下 192.168.138.200

OK,然后我们再次启动MASTER

service keepalived start

再看看BACKUP的日志文件

b 3 18:08:09 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) Received higher prio advert
Feb 3 18:08:09 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) Entering BACKUP STATE
Feb 3 18:08:09 localhost Keepalived_vrrp[5549]: VRRP_Instance(VI_1) removing protocol VIPs.
Feb 3 18:08:09 localhost Keepalived_healthcheckers[5548]: Netlink reflector reports IP 192.168.138.200 removed

自动切换回BACKUP

 

OK,自此,笔者所说的双机热备+负载均衡+实效转移 实现高可用、高性能、高伸缩性能的服务集群已经搭建完成,希望能应用到读者日常工作中

posted @ 2016-02-03 18:17  八面碰壁居士  阅读(3619)  评论(4编辑  收藏