lvs详细介绍及lvs和keepalived的使用

LVS简介

LVS介绍

LVS是Linux Virtual Server的缩写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统,属于4层负载均衡

ipvs和ipvsadm的关系

我们使用配置LVS的时候,不能直接配置内核中的ipvs,需要使用ipvs的管理工具ipvsadm进行管理  

LVS术语

未分类

LVS转发原理

LVS负载均衡器接受所有入站请求,并根据调度算法决定哪个realserver处理该请求

LVS调度算法

  • 轮询(rr):按照请求顺序轮流分发到后端RS
  • 加权轮询(wrr):权值高的获得的任务更多
  • 最小连接数(lc):动态的将请求建立到连接数较少的RS上
  • 加权最小连接数(wlc):调度器自动询问RS的真实负载情况,并动态的调整权

LVS调度算法生产环境选型

一般的网络服务,如:http、mail、MySQL等,常用的调度算法为:

  • 基本轮询调度rr算法
  • 加权轮询调度wrr算法
  • 加权最小连接调度wlc算法

LVS转发模式

  • NAT(Network Address Translation)
  • DR(Direct Routing)
  • TUN

LVS-DR模式

转发流程

将所有入站请求转发给后端realserver,后端realserver处理完直接将结果发给客户端

未分类

原理

当用户请求到达Direct Server,此时报文的源IP为CIP、MAC为CIP-MAC,目标IP为VIP、MAC为VIP-MAC
Direct Server根据调度算法确定一台处理请求的realserver,将请求转发给对应的realserver,此时源IP和目标IP均未改变,仅修改了源MAC为DIP-MAC,目标MAC为RIP-MAC
对应的realserver处理完请求,直接将结果发给客户端,此时源IP为VIP、MAC为VIP-MAC,目标IP为CIP、MAC为CIP-MAC

特性

  • 通过在调度器上修改数据包的目的MAC地址实现转发
  • Real-Server和Direct-Server必须在同一网段
  • Real-Server的lo接口必须绑定VIP

为什么要抑制ARP请求

  • 由于后端Real-Server要将VIP绑定到lo网卡上,这就出现了一个问题,客户端请求到达LVS前端路由器的时候,前端路由器会发送一个{目标地址为VIP}的请求报文,所以需要抑制Real-Server的ARP,保证让Direct-Server收到这个报文,而不是realserver收到这个报文

  • 一句话说明抑制Real-Server原因:保证前端路由将目标地址为VIP的报文发给Direct-Server,而不是Real-Server

优势

只有请求报文经过调度器,而Real-Server响应处理后无需经过调度器,因此并发量大的时候效率很高

LVS-NAT模式

转发流程

将所有入站请求转发给后端Real-Server,后端Real-Server处理完再发给Direct-Server,Direct-Server再发给客户端

特性

  • 既有RIP也有VIP
  • Real-Server必须得跟Direct-Server在同一网段
  • Real-Server必须将网关指向Direct-Server

优势

只需要一个公网IP给Direct-Server,Direct-Server始终跟外接打交道

劣势

需要依赖Direct-Server把请求转发给Real-Server,Real-Server处理完把结果发给Direct-Server,Direct-Server再把结果转发出去,并发高的时候会成为瓶颈

LVS三种模式对比

未分类

ipvsadm介绍

ipvsadm参数

添加虚拟服务器
    语法:ipvsadm -A [-t|u|f]  [vip_addr:port]  [-s:指定算法]
    -A:添加
    -t:TCP协议
    -u:UDP协议
    -f:防火墙标记
    -D:删除虚拟服务器记录
    -E:修改虚拟服务器记录
    -C:清空所有记录
    -L:查看
添加后端RealServer
    语法:ipvsadm -a [-t|u|f] [vip_addr:port] [-r ip_addr] [-g|i|m] [-w 指定权重]
    -a:添加
    -t:TCP协议
    -u:UDP协议
    -f:防火墙标记
    -r:指定后端realserver的IP
    -g:DR模式
    -i:TUN模式
    -m:NAT模式
    -w:指定权重
    -d:删除realserver记录
    -e:修改realserver记录
    -l:查看
通用:
    ipvsadm -ln:查看规则
    service ipvsadm save:保存规则

ipvsadm配置LVS负载均衡

需求

用LVS实现后端两台httpd的负载均衡

环境说明

未分类

负载均衡器端

安装LVS
    [root@lb01 ~]#yum -y install ipvsadm 
    [root@lb01 ~]#ipvsadm  
添加绑定VIP
    [root@lb01 ~]#ip addr add 192.168.0.89/24 dev eth0 label eth0:1
配置LVS-DR模式
    [root@lb01 ~]#ipvsadm -A -t 192.168.0.89:80 -s rr
    [root@lb01 ~]#ipvsadm -a -t 192.168.0.89:80 -r 192.168.0.93 -g 
    [root@lb01 ~]#ipvsadm -a -t 192.168.0.89:80 -r 192.168.0.94 -g

Real-Server端

配置测试后端realserver
    配置httpd省略
    [root@realserver-1 ~]#curl 192.168.0.93 #测试realserver-1网站是否正常    
    192.168.0.93
    [root@realserver-2 ~]#curl 192.168.0.94 #测试realserver-2网站是否正常
    192.168.0.94
绑定VIP到lo网卡
    [root@realserver-1 ~]#ip addr add 192.168.0.89/32 dev lo label lo:1  #由于DR模式需要realserver也有VIP
抑制ARP
    [root@realserver-1 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce  
    [root@realserver-1 ~]#echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
    [root@realserver-1 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    [root@realserver-1 ~]#echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore  

客户端测试

[root@test ~]#curl 192.168.0.89
192.168.0.93
[root@test ~]#curl 192.168.0.89
192.168.0.94

配置LVS+keepalived

需求

  • LVS给两台httpd做负载均衡
  • keepalived做lvs高可用,同时做Real-Server健康检查,如果发现Real-Server80端口没开,就认为故障,从集群中剔除
  • 在keepalived配置文件内就能配置LVS  

环境说明

未分类

在负载均衡器端配置lvs+keepalived

lb01节点

[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
##################全局配置##########################
global_defs {
    #如有故障,发邮件地址
    notification_email {      
    [email protected]              #收件人
    }
    notification_email_from [email protected]  #keepalived报警邮件,发件人
     smtp_server 192.168.200.1  #邮件服务器地址
    smtp_connect_timeout 30     #邮件服务器超时时间
    router_id LVS_01             #类似于MySQL的server-id,每个keepalived节点不能相同
}
#################keepalived配置#####################
vrrp_instance VI_1 {
    state MASTER              #keepalived角色,MASTER和BACKUP
    interface eth0            #通信接口,下面的virtual_ipaddress(VIP)绑定到这个网卡
    virtual_router_id 51      #vrrp_instance的唯一标识
    priority 150              #keepalived权重,数值越大权重越大,MASTER应大于BACKUP
    advert_int 1              #发送心跳间隔,如果backup1秒收不到心跳就接管,单位是秒
    authentication {          #每个keepalived节点通过这里设置的验证通信,必须得设置成一样
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.89/24       #VIP
    }
}
##################LVS配置##############            
#添加虚拟服务器
#相当于 ipvsadm -A -t 192.168.0.89:80 -s wrr 
virtual_server 192.168.0.89 80 {
    delay_loop 6             #服务健康检查周期,单位是秒
    lb_algo wrr                 #调度算法
    lb_kind DR                 #模式
    nat_mask 255.255.255.0   
    persistence_timeout 50   #回话保持时间,单位是秒
    protocol TCP             #TCP协议转发
#添加后端realserver
#相当于 ipvsadm -a -t 192.168.0.89:80 -r 192.168.0.93:80 -w 1
    real_server 192.168.0.93 80  {    #realserver的真实IP
        weight 1                      #权重
        #健康检查
        TCP_CHECK {
            connect_timeout 8         #超时时间
            nb_get_retry 3            #重试次数
            delay_before_retry 3      #重试间隔
            connect_port 80           #检查realserver的80端口,如果80端口没监听,就会从集群中剔除
        }
    }
    real_server 192.168.0.94 80  {
        weight 1
        TCP_CHECK {
           connect_timeout 8
           nb_get_retry 3
           delay_before_retry 3
           connect_port 80
        }
    }

}

lb02节点

[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
################全局配置###########################
global_defs {
    notification_email {      
    }
    notification_email_from [email protected]  
    smtp_server 192.168.200.1
    smtp_connect_timeout 30
        router_id LVS_02        
}
################keepalived配置#####################
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.0.89/24
    }
}
################lvs配置##########################
virtual_server 192.168.0.89 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.0.93 80  {
        weight 1             
        TCP_CHECK {            
            connect_timeout 8   
            nb_get_retry 3        
            delay_before_retry 3  
             connect_port 80      
        }
    }
    real_server 192.168.0.94 80  {
        weight 1
        TCP_CHECK {
         connect_timeout 8
         nb_get_retry 3
         delay_before_retry 3
         connect_port 80
        }
    }

                }

配置后端Real-Server

确保网站服务是正常的
    curl 192.168.0.93
    192.168.0.93
    curl 192.168.0.94
    192.168.0.94
绑定VIP到lo网卡
    ip addr add 192.168.0.89/32 dev lo label lo:0
抑制ARP
    [root@realserver-1 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce  
    [root@realserver-1 ~]#echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
    [root@realserver-1 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    [root@realserver-1 ~]#echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore  

客户端测试

  • 负载均衡是否正常
  • 后端Real-Server出问题是否自动剔除
  • lvs高可用是否正常,提供服务的LVS宕机,vip漂移到另一台LVS继续提供服务

一次Mysql改表引发LVS下RS机器全下线的问题

某天下午,正在和code苦战的我突然收到报警短信,告警我们有个业务电信机房LVS下的RS机器全部下线了。第一时间去看机器负载情况,发现CPU IDLE在80%左右,其他各项指标也都正常;怀疑是LVS的KeepAlive程序出问题了,上管理平台点了一遍RS上线,发现服务恢复了,于是未做进一步排查,只向OPS同学反馈了一下。

然而,刚过了半个小时,同样的报警又来了,看来还得找到根本原因。挑了一台机器保留现场,并在管理平台将其他机器操作上线,以保证充分的排查时间。

先检查Nginx allweb.log中lvscheck相关的日志,发现状态码全部为499且request_time达到5s:

[tabalt@server01 ~]$ tail -100 /data/nginx/logs/allweb.log | grep lvscheck
10.18.42.2 92 0 5.000[s] - - [12/Jul/2017:18:29:18 +0800] "GET /status.php HTTP/1.0" 499 - "-" "KeepAliveClient" lvscheck.domain.com 10.20.12.60 - -
10.18.42.2 92 0 5.000[s] - - [12/Jul/2017:18:29:22 +0800] "GET /status.php HTTP/1.0" 499 - "-" "KeepAliveClient" lvscheck.domain.com 10.20.12.60 - -
10.18.42.2 92 0 5.000[s] - - [12/Jul/2017:18:29:24 +0800] "GET /status.php HTTP/1.0" 499 - "-" "KeepAliveClient" lvscheck.domain.com 10.20.12.60 - -
...

原来KeepAlive程序请求http://lvscheck.domain.com/status.php页面探测服务情况时,竟然过了5s都没有收到响应,于是主动断开请求并将RS下线了。但机器很闲,为什么/status.php会处理超过5s呢?

检查PHP-FPM的日志,发现有报错/data/www/front/index.php文件执行很慢:

[tabalt@server01 ~]$ tail /data/php/log/php-fpm.log
12-Jul-2017 18:29:18] WARNING: [pool www] child 3988, script '/data/www/front/index.php' (request: "GET /index.php") executing too slow (11.301960 sec), logging
[12-Jul-2017 18:29:22] WARNING: [pool www] child 3945, script '/data/www/front/index.php' (request: "GET /index.php") executing too slow (11.863325 sec), logging
[12-Jul-2017 18:29:24] WARNING: [pool www] child 3887, script '/data/www/front/index.php' (request: "GET /index.php") executing too slow (10.498795 sec), logging
...

但/data/www/front/index.php只是入口文件,从这个日志看不出来问题在哪里,再检查下PHP-FPM的慢日志:

[tabalt@server01 ~]$ tail -100 /data/php/log/www.log.slow
...
script_filename = /data/www/front/index.php
[0x00007fecbd613f90] execute() /data/www/vendor/andals/vine/src/Component/Mysql/Driver.php:218
[0x00007fecbd613ec0] doExecute() /data/www/vendor/andals/vine/src/Component/Mysql/Driver.php:66
[0x00007fecbd613df0] query() /data/www/vendor/andals/vine/src/Component/Mysql/Dao/Base.php:206
[0x00007fecbd613d80] simpleQuery() /data/www/src/app/Model/Dao/Base.php:65
[0x00007fecbd613cc0] selectByParamsForFront() /data/www/src/app/Model/Svc/SqlBase.php:211
[0x00007fecbd613c10] selectByParamsForFront() /data/www/src/app/Model/Svc/Category.php:214
...
[0x00007fecbd613580] getEsData() /data/www/src/app/Controller/Front/ListController.php:26
[0x00007fecbd613400] indexAction() /data/www/vendor/andals/vine/src/Framework/App/Web.php:107
[0x00007fecbd613380] call_user_func_array() /data/www/vendor/andals/vine/src/Framework/App/Web.php:107
[0x00007fecbd613290] runController() /data/www/vendor/andals/vine/src/Framework/App/Web.php:73
[0x00007fecbd6131b0] handleRequest() /data/www/vendor/andals/vine/src/Framework/App/Web.php:48
[0x00007fecbd6130f0] run() /data/www/src/run/front/index.php:6

可以看到最终是执行SQL的时候很慢,上管理平台查看发现在报警的两个时间点,MySQL从库的QPS突然降到0而主库QPS突然大幅升高,于是连忙反馈给DBA同学。

DBA同学排查后发现,当前读写量比较大,且有个新增字段的改标语句正在运行,停止后问题恢复;而主从库QPS的突变是因为从库延时大被Proxy操作下线了。

我们梳理后发现,当前有个Task程序在批量往数据库里导数据,表里的数据较多(千万级),这种情况下改表导致数据库响应变慢;同时页面上有个查询没有加缓存,SQL语句执行超时设置得也有问题,最终导致PHP-FPM进程都被卡住了,没有空闲进程来处理LVS健康检查的页面,出现了LVS下RS机器全下线的问题。

事后,我们对发现的问题做了修复,并在确保没有大量访问的情况下提交了改表操作,改表顺利执行完成。

使用Vagrant进行LVS/DR的实验

未分类

LVS/DR模式,数据流来的时候走VS,回去的时候调度到RS上,然后用VIP的作为源地址返回回去。

实验采用Vagrant配置网络和主机信息。Vagrant的用法可参考 Vagrant–快速搭建实验环境利器(http://www.yulongjun.com/linux/20170811-vagrant/)。

Vagrantfile配置文件:

Vagrant.configure("2") do |config|
  # config为全局配置文件
  config.vm.box = "longdream/centos7"     # 这里是我自定义的centos7模板
  config.hostmanager.enabled = true       # 启用hostmanager插件
  config.hostmanager.manage_guest = true  # 允许更新虚拟机上的hosts文件
  config.hostmanager.manage_host = true   # 允许更新主机上的hosts文件
  # 定义Client
  config.vm.define "client" do |client|
    client.vm.network "private_network", ip: "172.16.111.123"
    client.vm.hostname = "client"
    client.vm.provision "shell", inline: "sudo bash /vagrant/client.sh"
  end
  # 定义Router
  config.vm.define "router" do |router|
    router.vm.network "private_network", ip: "172.16.111.222"
    router.vm.network "private_network", ip: "192.168.111.222"
    router.vm.hostname = "router"
    router.vm.provision "shell", inline: "sudo bash /vagrant/router.sh"
  end
  # 定义VS
  config.vm.define "vs" do |vs|
    vs.vm.network "private_network", ip: "192.168.111.100"
    vs.vm.hostname = "vs"
    vs.vm.provision "shell", inline: "sudo bash /vagrant/vs.sh"
  end
  # 定义RS1
  config.vm.define "rs1" do |rs1|
    rs1.vm.network "private_network", ip: "192.168.111.101"
    rs1.vm.hostname = "rs1"
    rs1.vm.provision "shell", inline: "sudo bash /vagrant/rs1.sh"
  end
  # 定义RS2
  config.vm.define "rs2" do |rs2|
    rs2.vm.network "private_network", ip: "192.168.111.102"
    rs2.vm.hostname = "rs2"
    rs2.vm.provision "shell", inline: "sudo bash /vagrant/rs2.sh"
  end
end

Vagrantfile里每一台机器都运行了相应的脚本。

Client:

client.sh

#!/bin/bash
echo "GATEWAY=172.16.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1

Router:

router.sh

#!/bin/bash
echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf
echo 1 > /proc/sys/net/ipv4/ip_forward

VS:

vs.sh

#!/bin/bash
echo "GATEWAY=192.168.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1
yum install -y ipvsadm
bash /vagrant/vs-dr-wlc.sh start

vs.sh引用的vs-dr-wlc.sh来启动VS。

vs-dr-wlc.sh:

#!/bin/bash
vip=192.168.111.200
mode=g  # m为NAT模式,g为DR模式,i为tun模式
schdule=wlc
rip1=192.168.111.101
rip2=192.168.111.102
dev=lo:1
case $1 in
start)
    ifconfig $dev $vip netmask 255.255.255.255 broadcast $vip up
    ipvsadm -A -t $vip:80 -s $schdule
    ipvsadm -a -t $vip:80 -r $rip1 -$mode -w 3
    ipvsadm -a -t $vip:80 -r $rip2 -$mode -w 1
    ;;
stop)
    ipvsadm -C
    ifconfig $dev down
    ;;
*)
    echo "Usage: `basename $0` start|stop"
    exit 1
    ;;
esac

RS1

rs1.sh:

#!/bin/bash
echo "GATEWAY=192.168.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1
yum install -y httpd
cat >/var/www/html/index.html<<EOF
Real Server 1
EOF
systemctl enable httpd
systemctl start httpd
bash /vagrant/rs-config.sh start

RS2

rs2.sh:

#!/bin/bash
echo "GATEWAY=192.168.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1
yum install -y httpd
cat >/var/www/html/index.html<<EOF
Real Server 2
EOF
systemctl enable httpd
systemctl start httpd
bash /vagrant/rs-config.sh start

两个RS都调用的一个脚本

rs-config.sh

#!/bin/bash
vip=192.168.111.200
dev=lo:1
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 $dev $vip netmask 255.255.255.255 broadcast $vip up
    echo "VS Server is Ready!"
    ;;
stop)
    ifconfig $dev 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 "VS Server is Cancel!"
    ;;
*)
    echo "Usage `basename $0` start|stop"
    exit 1
    ;;
esac

vagrant up启动所有机器后,在Virtualbox里关掉所有虚机的eth0(vagrant创建虚机时候,默认的一个NAT网络,默认在eth0上,关闭它以防止对实验造成影响):

ifdown eth0

然后从Client虚机里运行:

bash /vagrant/client-test.sh进行测试:

#!/bin.bash
# 测试LVS
vip=192.168.111.200
for i in `seq 100`;do
    curl --connect-timeout 1 $vip
    sleep 1
done

使用lvs-rrd工具监控存储lvs状态信息

1. 准备工作

rrdtool安装包下载:http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.7.tar.gz

lvs-rrd安装包下载:http://tepedino.org/lvs-rrd/lvs-rrd-v0.7.tar.gz

yum install php
yum install httpd
service httpd start

chkconfig httpd on

2. 部署rrdtool

yum groupinstall -y "Development Tools" "Server Platform Development" "Base" "Fonts"
yum -y install  libpng-devel freetype-devel libart_lgpl-devel libxml2-devel gd gd-devel cairo-devel pango-devel perl-ExtUtils-*
tar xvzf rrdtool-1.4.7.tar.gz
cd rrdtool-1.4.7
./configure –prefix=/usr/local/rrdtool
make
make install

安装完毕后将rrdtool库文件添加至系统库文件搜索路径

echo ‘/usr/local/rrdtool/lib’ >>/etc/ld.so.conf
ldconfig –v
/usr/local/rrdtool/bin/rrdtool –v      #查看rrdtool版本信息

3. 部署lvs-rrd

tar xvzf lvs-rrd-v0.7.tar.gz
mv lvs-rrd-v0.7 /var/www/html/lvs-rrd
cd /var/www/html/lvs-rrd
mkdir -p rrd

修改配置文件

vim lvs.rrd.update
RRDTOOL=”/usr/local/rrdtool/bin/rrdtool”#rrdtool可执行程序路径
IPVSADM=”/sbin/ipvsadm”#ipvsadm命令路径
WORKDIR=”/var/www/html/lvs-rrd”#rrdtool收集的数据的存放路径
vim graph-lvs.sh
# WORKDIR must match the directory used in the update script.
WORKDIR=”/var/www/html/lvs-rrd/rrd” #rrdtool收集的数据存放的路径
RRDTOOL=”/usr/local/rrdtool/bin/rrdtool”#rrdtool可执行程序路径
# Where to put the graphs.
GRAPHS=“/var/www/html/lvs-rrd/graphs”#生成的图片保存路径
WEBPATH=”/lvs-rrd/graphs”#图片路径
vim lvs-rrd.php
<?php
header(“Cache-Control: max-age=300, must-revalidate”);
system(“/var/www/html/lvs-rrd/graph-lvs.sh -H”);#修改路径为部署服务的路径
?>
chown –R apache.apache /var/www/html/lvs-rrd
执行一次lvs.rrd.update生成初始rrd数据

配置计划任务

crontab –e

增加以下配置:

#lvs status
* * * * * /var/www/html/lvs-rrd/lvs.rrd.update 2>/dev/null >/dev/null

4. 配置httpd认证

在/etc/httpd/conf/httpd.conf中添加如下内容:

<Directory "/var/www/html/lvs">
Options All
AllowOverride AuthConfig
AuthType Basic
AuthBasicProvider file
AuthName "LVS Status"
AuthUserFile /etc/httpd/conf/.htpasswd
Require valid-user
</Directory>
htpasswd -cm /etc/httpd/conf/.htpasswd admin

5. 测试

服务配置完毕后,过几分钟之后,访问http://10.0.0.10/lvs-rrd(LVS与lvs-rrd所在服务器),输入帐号admin及其密码通过认证之后,即可看到当前lvs的连接状态等信息。

centos7.1 LVS健康检查bash脚本

环境:centos7.1

简介:

当脚本检测到某个RS的http服务掉线时,在LVS中自动移除RS;当所有RS的http服务掉线时,在LVS中移除所有RS,并将LVS调度器上的http服务加入到LVS中,作为告警页面。

当脚本检测到某个RS的http服务活跃时,自动将其加入到LVS中,如果有调度器本身的存在LVS中,将其删除。

该脚本经本人测试,完全达到要求。

以下为脚本:

#!/bin/bash
#
rs=("152.168.1.12" "152.168.1.13")
vip="152.168.1.10"
port=80
logfile="/usr/local/scripts/lvs.log"
function check_alldown {
   #有一个rs主机能访问,就说明不是全部掉了
   #检查到一个rs主机存活就退出检查
   #如果全部rs不能访问,说明主机全掉了
   for www in `echo ${rs[*]}`
   do
      curl --connect-timeout 1 http://$www &> /dev/null
      if [ $? -eq 0 ]
      then
          echo 0 
          exit 0 
      fi      
   done
   echo 100 
}
function lvs_add {
   ipvsadm -a -t $vip:$port -r $1
   echo "add rs host:$1 to lvs"
}
function lvs_rm {
   ipvsadm -d -t $vip:$port -r $1
   echo "remove rs host:$1 to lvs"
}
function lvs_local {
   #如果全部rs主机掉线,并且lvs中没有127.0.0.1就添加它
   #如果可以访问一个rs主机,并且lvs中有127.0.0.1就删除它
   all_down=`check_alldown`
   rip=$(ipvsadm -L -n | gawk '/127.0.0.1/')
   if [ $all_down -eq 100 ]
   then
       if [ "$rip" = "" ] 
       then   
           echo "`date +%F:%H-%M-%S` all rs host is down!" >> $logfile
           lvs_add "127.0.0.1"
       fi
   else
       if [ $all_down -eq 0 ] && [ ! "$rip" = "" ]  
       then
           echo "`date +%F:%H-%M-%S` one rs host is up,remove local rs host!" >> $logfile
           lvs_rm "127.0.0.1"
       fi
   fi
}
function lvs_rs {
   #如果可以访问一个rs主机,并且lvs中没有它就添加它
   #如果不能访问一个rs主机,并且lvs中有它就删除它
   lvs_local
   for www in `echo ${rs[*]}`
   do
      rip=$(ipvsadm -L -n | gawk "/$www/")
      curl --connect-timeout 1 http://$www &> /dev/null
      if [ $? -eq 0 ]
      then
          if [ "$rip" = "" ]
          then
              echo "`date +%F:%H-%M-%S` rs host:$www is up!" >> $logfile
              lvs_add "$www"
          fi
      else
          if [ ! "$rip" = "" ]
          then
              echo "`date +%F:%H-%M-%S` rs host:$www is down!" >> $logfile
              lvs_rm "$www"
          fi
      fi
   done
}
function lvs_monitor {
   while true
   do
     echo "check lvs rs health!"
     lvs_rs
     sleep 1
   done
}
lvs_monitor

完毕。

Lvs自动部署及监控shell脚本

先申明,本文现在已经在我公司的测试环境和生产测试环境使用。正式环境请用keepalived+lvs.

安装ipvsadm不多说了,先说说脚本的功能,脚本分为redirect server 端和realserver 端,脚本分别为 lvs_redirector.sh 和realserver.sh脚本。另外加一个监控脚本lvs_monitor.sh(此脚本来源网友,做了一点修改,算是 取之于网络,共享给网络吧)。

脚本功能

执行 lvs_redirector.sh nat|dr|tun|stop,中的一个选项可以启动或关闭相应的lvs模式,并调用lvs_monitor.sh 监控realserver。当realserver故障,或者重新启动时,自动删除,添加相应的realserver.当realserver 全故障时,自动添加redirector server 本地127.0.0.1的web页面的故障提示。当realserver只要有一台恢复时,自动添加相应的realserver,并删除127.0.0.1。

实验环境图

Lvs具体原理可以看我的博客:Lvs通俗易懂的总结(http://qiaomiao.blog.51cto.com/484197/1729587) 。

本文脚本的使用如下图的场景:

未分类

未分类

未分类

具体脚本

lvs_redirector.sh 脚本如下:

#!/bin/bash
# blog:http://qiaomiao.blog.51cto.com
#
# 20151223 v2.8 20160115
# home:http://www.qmlab.cn 
#
# description:this script is use start lvs (nat/dr/tun),and stop lvs.


#define the variable
  NAT_VIP="172.16.8.11"
  DR_VIP="10.0.8.20"
  TUN_VIP="10.0.8.20"
  DIP="10.0.8.11"
  RIP1="10.0.8.21"
  RIP2="10.0.8.22"
  RNET="10.0.8.0/24"
  DPORT=80
  RPORT1=80
  RPORT2=80
  GATEWAY01=172.16.8.254         #做nat模式时,redirector 服务器的外网卡的路由器网关地址。
  GATEWAY02=10.0.8.254           #路由器网关地址,做dr 和 tun 模式时用到。
                                 #两个GATEWAY,请根据具体网络环境做取舍。
  logfile=/tmp/myself_log/lvs.log

#create log dir
mkdir -p /tmp/myself_log            # 在这个目录可以看到启动lvs日志。
#general funiction
lvs_monitor(){
     if [ $1 = stop  ];then
        PS=`ps -ef |grep lvs_monitor.sh |awk '{printf $2" "}'`
        for X in `echo $PS`
             do
                kill -9 $X
             done
     else
        sh  ./lvs_monitor.sh &
     fi
}

# LVS/NAT mode    
# start
function nat_start {
     nat_stop
     VIP=$NAT_VIP
     echo 1 >/proc/sys/net/ipv4/ip_forward
 # start  NAT mode
     ifconfig eth1 $VIP netmask 255.255.255.0 up
     route del -net 0.0.0.0
     route add  -net 0.0.0.0 netmask 0.0.0.0 gw $GATEWAY01
     #ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up
     ipvsadm -C
     ipvsadm -A -t $VIP:$DPORT -s wlc
     ipvsadm -a -t $VIP:$DPORT -r $RIP1:$RPORT1 -m -w 1
     ipvsadm -a -t $VIP:$DPORT -r $RIP2:$RPORT2 -m -w 2
     ipvsadm -ln
     ipvsadm -lnc
 }
# stop
function nat_stop {
     VIP=$NAT_VIP
     echo 0 >/proc/sys/net/ipv4/ip_forward
 # stop  NAT mode
     ifconfig eth1 down
     route del -net 0.0.0.0
     route add  -net 0.0.0.0 netmask 0.0.0.0 gw $GATEWAY02 > /dev/null 2>&1
     ipvsadm -C
 }


# LVS/dricert routing  mode
# start
function dr_start {
     dr_stop
     VIP=$DR_VIP
     echo 1 >/proc/sys/net/ipv4/ip_forward
     ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.255 up
     route add  -host $VIP dev eth0:0
 # start  DR  mode
     ipvsadm -C
     ipvsadm -A -t $VIP:$DPORT -s wlc
     ipvsadm -a -t $VIP:$DPORT -r $RIP1 -g -w 1
     ipvsadm -a -t $VIP:$DPORT -r $RIP2 -g -w 2
     ipvsadm -ln
     ipvsadm -lnc

 }
# stop
function dr_stop {
     VIP=$DR_VIP
     echo 0 >/proc/sys/net/ipv4/ip_forward
     ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.255 down
     route del -host $VIP dev eth0:0 > /dev/null 2>&1
 # stop  DR  mode
     ipvsadm -C

 }



# LVS/tunneling  mode
# start
function tun_start {
     tun_stop
     VIP=$TUN_VIP
 # set interface
     #echo 1 >/proc/sys/net/ipv4/ip_forward
     ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 up
     route add -host $VIP dev tunl0
 # start  tun  mode
     ipvsadm -C
     ipvsadm -A -t $VIP:$DPORT -s wlc
     ipvsadm -a -t $VIP:$DPORT -r $RIP1 -i -w 1
     ipvsadm -a -t $VIP:$DPORT -r $RIP2 -i -w 2
     ipvsadm -ln
     ipvsadm -lnc

 }
# stop
function tun_stop {
     VIP=$TUN_VIP
 # set interface
     #echo 1 >/proc/sys/net/ipv4/ip_forward
     ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 down
     ip addr flush tunl0
     route del  -host $VIP dev tunl0 >/dev/null 2>&1
 # stop  tun  mode
     ipvsadm -C
}


service iptables stop
case "$1" in
        nat)
        echo -e  "n  `date +%F" "%H:%M:%S` nat模式启动...." > $logfile
        tun_stop
        dr_stop
        nat_start
        lvs_monitor $1
        ;;
        dr)
        echo -e  "n  `date +%F" "%H:%M:%S` dr模式启动...." > $logfile
        tun_stop
        nat_stop
        dr_start
        lvs_monitor $1
        ;;
        tun)
        echo -e  " n  `date +%F" "%H:%M:%S ` tun模式启动...." > $logfile
        dr_stop
        nat_stop
        tun_start
        lvs_monitor $1
        ;;
        stop)
        echo -e "n `date +%F" "%H:%M:%S` 关闭lvs...." > $logfile
        dr_stop
        nat_stop
        tun_stop
        lvs_monitor $1
        ;;
        *)
        echo $"Usage: $0 {nat|dr|tun|stop}"  
        ;;
 esac

lvs_realserver.sh 脚本如下:

#!/bin/bash
# write by lijing QQ 858080796, 
# blog:http://qiaomiao.blog.51cto.com
# 20151223 v2.8 20160115
# home:http://www.qmlab.cn 
#
# description:this script is use start lvs (nat/dr/tun).

#define the variable
  #NAT_VIP="10.0.8.20"
  DR_VIP="10.0.8.20"
  TUN_VIP="10.0.8.20"
  DIP="10.0.8.11"
  RIP1="10.0.8.21"
  RIP2="10.0.8.22"
  RNET="10.0.8.0/24"
  DPORT=80
  RPORT1=80
  RPORT2=80
  GATEWAY="10.0.8.254"
#


# LVS/NAT mode
# start
function nat_start {
    nat_stop
 # set realserver gateway
    route del -net 0.0.0.0
    route add -net 0.0.0.0 netmask 0.0.0.0 gw $DIP

 }
# stop
function nat_stop {
 # set realserver gateway
    route del -net 0.0.0.0
    route add -net 0.0.0.0 netmask 0.0.0.0 gw $GATEWAY

 }


# LVS/dricert routing  mode
# start
function dr_start {
    dr_stop
    VIP=$DR_VIP
 #  set interface
    ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
    route add -host $VIP dev lo:0
 # set realserver  
    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
function dr_stop {
    VIP=$DR_VIP
 #  set interface
    ifconfig lo:0 down
    route del -host $VIP dev lo:0 >/dev/null 2>&1
 # set realserver  
    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

 }


# LVS/tunneling  mode
# start
function tun_start {
     tun_stop
     VIP=$TUN_VIP
 # set interface
     ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 up
     route add -host $VIP dev tunl0
 # set realserver  
    echo 1 > /proc/sys/net/ipv4/conf/tunl0/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/tunl0/arp_announce
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/tunl0/rp_filter
    echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
 }
# stop
function tun_stop {
     VIP=$TUN_VIP
 # set interface
 ip addr flush tunl0
     ifconfig tunl0 down
     route del -host $VIP dev tunl0  >/dev/null 2>&1
 # set realserver  
    echo 0 > /proc/sys/net/ipv4/conf/tunl0/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/tunl0/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/tunl0/rp_filter
    echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
 }

service iptables stop
case "$1" in
        nat)
        tun_stop
        dr_stop
        nat_start
        ;;
        dr)
        tun_stop
        nat_stop
        dr_start
        ;;
        tun)
        nat_stop
        dr_stop
        tun_start
        ;;
        stop)
        nat_stop
        dr_stop
        tun_stop
        ;;
        *)
        echo $"Usage: $0 {nat|dr|tun|stop}"  
        ;;
 esac

lvs_monitor.sh 脚本如下:(注意要放在lvs_redirector.sh在同一个目录下)

#!/bin/bash
# write by http://small.blog.51cto.com/259970/1728082
# 感谢 网友 super_color

rs=("10.0.8.21" "10.0.8.22")
vip="10.0.8.20"
port=80
logfile="/tmp/myself_log/lvs_monitor.log"
function check_alldown {
   #有一个rs主机能访问,就说明不是全部掉了
   #检查到一个rs主机存活就退出检查
   #如果全部rs不能访问,说明主机全掉了
   for www in `echo ${rs[*]}`
   do
      curl --connect-timeout 1 http://$www &> /dev/null
      if [ $? -eq 0 ]
      then
          echo 0 
          exit 0
      fi
   done
   echo 100 
}
function lvs_add {
   ipvsadm -a -t $vip:$port -r $1
   echo "add rs host:$1 to lvs"
}
function lvs_rm {
   ipvsadm -d -t $vip:$port -r $1
   echo "remove rs host:$1 to lvs"
}
function lvs_local {
   #如果全部rs主机掉线,并且lvs中没有127.0.0.1就添加它
   #如果可以访问一个rs主机,并且lvs中有127.0.0.1就删除它
   all_down=`check_alldown`
   rip=$(ipvsadm -L -n | gawk '/127.0.0.1/')
   if [ $all_down -eq 100 ]
   then
       if [ "$rip" = "" ]
       then
           echo "`date +%F:%H-%M-%S` all rs host is down!" >> $logfile
           lvs_add "127.0.0.1"
       fi
   else
       if [ $all_down -eq 0 ] && [ ! "$rip" = "" ]
       then
           echo "`date +%F:%H-%M-%S` one rs host is up,remove local rs host!" >> $logfile
           lvs_rm "127.0.0.1"
       fi
   fi
}
function lvs_rs {
   #如果可以访问一个rs主机,并且lvs中没有它就添加它
   #如果不能访问一个rs主机,并且lvs中有它就删除它
   lvs_local
   for www in `echo ${rs[*]}`
   do
      rip=$(ipvsadm -L -n | gawk "/$www/")
      curl --connect-timeout 1 http://$www &> /dev/null
      if [ $? -eq 0 ]
      then
          if [ "$rip" = "" ]
          then
              echo "`date +%F:%H-%M-%S` rs host:$www is up!" >> $logfile
              lvs_add "$www"
          fi
      else
          if [ ! "$rip" = "" ]
          then
              echo "`date +%F:%H-%M-%S` rs host:$www is down!" >> $logfile
              lvs_rm "$www"
          fi
      fi
   done
}
function lvs_monitor {
   while true
   do
#     echo "check lvs rs health!"
     lvs_rs
     sleep 1
   done
}
lvs_monitor

结果验证

在验证结果之前,要保证你的路由器的端口映射是正确,且生效的,上面图中:

当外网客户端192.168.20.200访问时,nat模式路由器192.168.20.14映射到172.16.8.11这个IP,

dr和 tun模式映射到 10.0.8.20这个IP。

验证方法:先测试直接内网访问两台realserver web是不是正常,以及redirector server 的本地127.0.0.1 web 是不是正常,再测试访问192.168.20.14,当其中一台故障时是不是还可以访问,到全故障时,有没有切的本地127.0.0.1(故障提示页)的web,当其中只要有一台恢复时,会不会启动添加启用,并删除127.0.0.1的web.

未分类

未分类

LVS NAT模式负载均衡实验

实验环境:

  • LVS 调度器(BL)作为Web1、Web2 两台Web 服务器池的网关

  • BL 两块网卡,分别连接内外网

  • BL 主机(负载调度器):

外网地址:192.168.102.100/24,同时也作为整个群集的VIP
内网地址:192.168.108.113/24
Web1 主机:192.168.108.111/24
Web2 主机:192.168.108.112/24
NFS 主机:192.168.108.113/24

  • 使用轮询(rr)调度算法

一、开启两台web服务器,访问测试

  • 192.168.108.111

  • 192.168.108.222

未分类

未分类

二、开一台作为BL主机

外网地址是192.168.102.100

内网地址是192.168.108.113

LVS-NAT部署

1、加载ip_vs 模块,安装ipvsadm 工具

[root@www ~]# modprobe ip_vs     

[root@www ~]# yum -y install ipvsadm

2、配置负载调度器SNAT 转发规则

[root@www ~]# ipvsadm -A -t 192.168.102.100:80 -s rr

[root@www ~]# ipvsadm -a -t 192.168.102.100:80 -r 192.168.108.111:80 -m -w 1

[root@www ~]# ipvsadm -a -t 192.168.102.100:80 -r 192.168.108.112:80 -m -w 1

[root@www ~]# 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.102.100:80 rr

  -> 192.168.108.111:80           Masq    1      0          0        

  -> 192.168.108.112:80           Masq    1      0          0     

[root@www ~]# /etc/init.d/ipvsadm save

ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm:      [确定]

[root@www ~]# chkconfig ipvsadm on

3、开启路由转发功能

[root@www ~]# sed -i '/net.ipv4.ip_forward/ s/0/1/' /etc/sysctl.conf

[root@www ~]# sysctl –p

三、客户机访问,测试rr轮换机制

未分类

未分类

四、再开一台虚拟机,作NFS 共享储存部署

1、安装nfs-utils、rpcbind 软件包

[root@www ~]# rpm -q nfs-utils rpcbind

nfs-utils-1.2.3-75.el6.x86_64

rpcbind-0.2.0-13.el6.x86_64

2、设置共享目录

将/opt/www 作为共享目录,要求192.168.108.0/24 网段只读权限访问网页数据(若增加读写速度和安全性,可结合raid5+LVM)

[root@www ~]# mkdir /opt/www

[root@www ~]# vim /etc/exports

/opt/www        192.168.108.0/24(ro,sync,no_root_squash)

3、启动服务并查看共享目录

[root@www ~]# /etc/init.d/rpcbind start

[root@www ~]# /etc/init.d/nfs start

启动 NFS 服务:                                            [确定]

关掉 NFS 配额:                                            [确定]

启动 NFS mountd:                                          [确定]

启动 NFS 守护进程:                                        [确定]

正在启动 RPC idmapd:                                      [确定]

[root@www ~]# showmount -e 192.168.108.114

Export list for 192.168.108.114:

/opt/www 192.168.108.0/24

[root@www ~]# chkconfig rpcbind on

[root@www ~]# chkconfig nfs on

[root@www ~]# echo "<h1>哈哈哈</h1>" > /opt/www/index.html

4、Web1服务器配置

[root@www ~]# yum -y install nfs-utils

[root@www ~]# mount 192.168.108.114:/opt/www/ /var/www/html/

[root@www ~]# df -hT

Filesystem           Type   Size  Used Avail Use% Mounted on

/dev/sda3            ext4    18G  4.5G   12G  28% /

tmpfs                tmpfs  491M     0  491M   0% /dev/shm

/dev/sda1            ext4   283M   35M  233M  14% /boot

192.168.108.114:/opt/www/

                     nfs     18G  4.5G   13G  27% /var/www/html

[root@www ~]# cp -p /etc/fstab /etc/fstab.bak

[root@www ~]# vim /etc/fstab

192.168.108.114:/opt/www/       /var/www/html/  nfs     defaults,_netdev 1 2

[root@www ~]# umount /var/www/html/

[root@www ~]# mount -a

[root@www ~]# df -hT

Filesystem           Type   Size  Used Avail Use% Mounted on

/dev/sda3            ext4    18G  4.5G   12G  28% /

tmpfs                tmpfs  491M     0  491M   0% /dev/shm

/dev/sda1            ext4   283M   35M  233M  14% /boot

192.168.108.114:/opt/www/

                     nfs     18G  4.5G   13G  27% /var/www/html

5、Web2 服务器配置

同web1

五、客户机访问测试

未分类

BL主机查看:

未分类

LVS三种负载均衡方式对比

未分类

LVS的三种负载均衡方式

  • Virtual Server via Network Address Translation NAT(VS/NAT)

VS/NAT用法本来是因为网络IP地址不足而把内部保留IP地址通过映射转换成公网地址的一种上网方式(原地址NAT)。如果把NAT的过程稍微变化,就可以成为负载均衡的一种方式。原理其实就是把从客户端发来的IP包的IP头目的地址在DR上换成其中一台REALSERVER的IP地址并发至此REALSERVER,而REALSERVER则在处理完成后把数据经过DR主机发回给客户端,DR在这个时候再把数据包的原IP地址改为DR接口上的IP地址即可。期间,无论是进来的流量,还是出去的流量,都必须经过DR。VS/NAT的VS/NAT的体系结构如图所示。

未分类

  • Virtual Server via IP Tunneling(VS/TUN)

IP隧道(IP tunneling)模式则类似于VPN的方式,使用网络分层的原理,在从客户端发来的数据包的基础上,封装一个新的IP头标记(不完整的IP头,只有目的IP部)发给REALSERVER,REALSERVER收到后,先把DR发过来的数据包的头给解开,还原其数据包原样,处理后,直接返回给客户端,而不需要再经过DR。需要注意的是,由于REALSERVER需要对DR发过来的数据包进行还原,也就是说必须支持IPTUNNEL协议。所以,在REALSERVER的内核中,必须编译支持IPTUNNEL这个选项。IPTUNNEL也在Net working options里面。

未分类

VS/TUN的工作流程

未分类

  • Virtual Server via Direct Routing(VS/DR)

VS/DR方式是通过改写请求报文中的MAC地址部分来实现的。Director和RealServer必需在物理上有一个网卡通过不间断的局域网相连。 RealServer上绑定的VIP配置在各自Non-ARP的网络设备上(如lo或tunl),Director的VIP地址对外可见,而RealServer的VIP对外是不可见的。RealServer的地址即可以是内部地址,也可以是真实地址。

未分类

VS/DR的工作流程

VS/DR的工作流程如图所示:它的连接调度和管理与VS/NAT和VS/TUN中的一样,它的报文转发方法又有不同,将报文直接路由给目标服务器。在VS/DR中,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP报文,而是将数据帧的MAC地址改为选出服务器的MAC地址,再将修改后的数据帧在与服务器组的局域网上发送。因为数据帧的MAC地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该IP报文。当服务器发现报文的目标地址VIP是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。

未分类

三种负载均衡方式比较

  • Virtual Server via NAT

VS/NAT 的优点是服务器可以运行任何支持TCP/IP的操作系统,它只需要一个IP地址配置在调度器上,服务器组可以用私有的IP地址。缺点是它的伸缩能力有限,当服务器结点数目升到20时,调度器本身有可能成为系统的新瓶颈,因为在VS/NAT中请求和响应报文都需要通过负载调度器。我们在Pentium166 处理器的主机上测得重写报文的平均延时为60us,性能更高的处理器上延时会短一些。假设TCP报文的平均长度为536 Bytes,则调度器的最大吞吐量为8.93 MBytes/s. 我们再假设每台服务器的吞吐量为800KBytes/s,这样一个调度器可以带动10台服务器。(注:这是很早以前测得的数据)

基于 VS/NAT的的集群系统可以适合许多服务器的性能要求。如果负载调度器成为系统新的瓶颈,可以有三种方法解决这个问题:混合方法、VS/TUN和 VS/DR。在DNS混合集群系统中,有若干个VS/NAT负调度器,每个负载调度器带自己的服务器集群,同时这些负载调度器又通过RR-DNS组成简单的域名。

但VS/TUN和VS/DR是提高系统吞吐量的更好方法。

对于那些将IP地址或者端口号在报文数据中传送的网络服务,需要编写相应的应用模块来转换报文数据中的IP地址或者端口号。这会带来实现的工作量,同时应用模块检查报文的开销会降低系统的吞吐率。

  • Virtual Server via IP Tunneling

在VS/TUN 的集群系统中,负载调度器只将请求调度到不同的后端服务器,后端服务器将应答的数据直接返回给用户。这样,负载调度器就可以处理大量的请求,它甚至可以调度百台以上的服务器(同等规模的服务器),而它不会成为系统的瓶颈。即使负载调度器只有100Mbps的全双工网卡,整个系统的最大吞吐量可超过 1Gbps。所以,VS/TUN可以极大地增加负载调度器调度的服务器数量。VS/TUN调度器可以调度上百台服务器,而它本身不会成为系统的瓶颈,可以用来构建高性能的超级服务器。VS/TUN技术对服务器有要求,即所有的服务器必须支持“IP Tunneling”或者“IP Encapsulation”协议。目前,VS/TUN的后端服务器主要运行Linux操作系统,我们没对其他操作系统进行测试。因为“IP Tunneling”正成为各个操作系统的标准协议,所以VS/TUN应该会适用运行其他操作系统的后端服务器。

  • Virtual Server via Direct Routing

跟VS/TUN方法一样,VS/DR调度器只处理客户到服务器端的连接,响应数据可以直接从独立的网络路由返回给客户。这可以极大地提高LVS集群系统的伸缩性。跟VS/TUN相比,这种方法没有IP隧道的开销,但是要求负载调度器与实际服务器都有一块网卡连在同一物理网段上,服务器网络设备(或者设备别名)不作ARP响应,或者能将报文重定向(Redirect)到本地的Socket端口上。

三种LVS负载均衡技术的优缺点归纳以下表:

未分类

注:以上三种方法所能支持最大服务器数目的估计是假设调度器使用100M网卡,调度器的硬件配置与后端服务器的硬件配置相同,而且是对一般Web服务。使 用更高的硬件配置(如千兆网卡和更快的处理器)作为调度器,调度器所能调度的服务器数量会相应增加。当应用不同时,服务器的数目也会相应地改变。所以,以上数据估计主要是为三种方法的伸缩性进行量化比较。

LVS负载均衡原理及安装配置详解

负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群。常用的负载均衡开源软件有nginx、lvs、haproxy,商业的硬件负载均衡设备F5、Netscale。这里主要是学习 LVS 并对其进行了详细的总结记录。

一、负载均衡LVS基本介绍

LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(real server)上。为了避免不同机器上用户请求得到的数据不一样,需要用到了共享存储,这样保证所有用户请求的数据是一样的。

LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器。这是一个由章文嵩博士发起的一个开源项目,它的官方网站是 http://www.linuxvirtualserver.org 现在 LVS 已经是 Linux 内核标准的一部分。使用 LVS 可以达到的技术目标是:通过 LVS 达到的负载均衡技术和 Linux 操作系统实现一个高性能高可用的 Linux 服务器集群,它具有良好的可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的性能。LVS 是一个实现负载均衡集群的开源软件项目,LVS架构从逻辑上可分为调度层、Server集群层和共享存储。

二、LVS的基本工作原理

未分类

  1. 当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间
  2. PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链
  3. IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链
  4. POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器

三、LVS的组成

LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。

  1. ipvs(ip virtual server):一段代码工作在内核空间,叫ipvs,是真正生效实现调度的代码。
  2. ipvsadm:另外一段是工作在用户空间,叫ipvsadm,负责为ipvs内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(Real Server)

四、LVS相关术语

  1. DS:Director Server。指的是前端负载均衡器节点。
  2. RS:Real Server。后端真实的工作服务器。
  3. VIP:向外部直接面向用户请求,作为用户请求的目标的IP地址。
  4. DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
  5. RIP:Real Server IP,后端服务器的IP地址。
  6. CIP:Client IP,访问客户端的IP地址。

下边是三种工作模式的原理和特点总结。

五、LVS/NAT原理和特点

1、重点理解NAT方式的实现原理和数据包的改变。

未分类

(a). 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(b). PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c). IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。 此时报文的源IP为CIP,目标IP为RIP
(d). POSTROUTING链通过选路,将数据包发送给Real Server
(e). Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP
(f). Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP

2、LVS-NAT模型的特性

  • RS应该使用私有地址,RS的网关必须指向DIP
  • DIP和RIP必须在同一个网段内
  • 请求和响应报文都需要经过Director Server,高负载场景中,Director Server易成为性能瓶颈
  • 支持端口映射
  • RS可以使用任意操作系统
  • 缺陷:对Director Server压力会比较大,请求和响应都需经过director server

六、LVS/DR原理和特点

1、重将请求报文的目标MAC地址设定为挑选出的RS的MAC地址

未分类

(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) 响应报文最终送达至客户端

2、LVS-DR模型的特性

  • 特点1:保证前端路由将目标地址为VIP报文统统发给Director Server,而不是RS
  • RS可以使用私有地址;也可以是公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问
  • RS跟Director Server必须在同一个物理网络中
  • 所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
  • 不支持地址转换,也不支持端口映射
  • RS可以是大多数常见的操作系统
  • RS的网关绝不允许指向DIP(因为我们不允许他经过director)
  • RS上的lo接口配置VIP的IP地址
  • 缺陷:RS和DS必须在同一机房中

3、特点1的解决方案:

  • 在前端路由器做静态地址路由绑定,将对于VIP的地址仅路由到Director Server
  • 存在问题:用户未必有路由操作权限,因为有可能是运营商提供的,所以这个方法未必实用
  • arptables:在arp的层次上实现在ARP解析时做防火墙规则,过滤RS响应ARP请求。这是由iptables提供的
  • 修改RS上内核参数(arp_ignore和arp_announce)将RS上的VIP配置在lo接口的别名上,并限制其不能响应对VIP地址解析请求。

七、LVS/Tun原理和特点

在原有的IP报文外再次封装多一层IP首部,内部IP首部(源地址为CIP,目标IIP为VIP),外层IP首部(源地址为DIP,目标IP为RIP)

未分类

(a) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP 。
(b) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c) IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP,目标IP为RIP。然后发至POSTROUTING链。 此时源IP为DIP,目标IP为RIP
(d) POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。 此时源IP为DIP,目标IP为RIP
(e) RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求,处理完成之后,通过lo接口送给eth0网卡,然后向外传递。 此时的源IP地址为VIP,目标IP为CIP
(f) 响应报文最终送达至客户端

LVS-Tun模型特性

  • RIP、VIP、DIP全是公网地址
  • RS的网关不会也不可能指向DIP
  • 所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
  • 不支持端口映射
  • RS的系统必须支持隧道

其实企业中最常用的是 DR 实现方式,而 NAT 配置上比较简单和方便,后边实践中会总结 DR 和 NAT 具体使用配置过程。

八、LVS的八种调度算法

  1. 轮叫调度 rr
    这种算法是最简单的,就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是简单。轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器,不管后端 RS 配置和处理能力,非常均衡地分发下去。

  2. 加权轮叫 wrr
    这种算法比 rr 的算法多了一个权重的概念,可以给 RS 设置权重,权重越高,那么分发的请求数越多,权重的取值范围 0 – 100。主要是对rr算法的一种优化和补充, LVS 会考虑每台服务器的性能,并给每台服务器添加要给权值,如果服务器A的权值为1,服务器B的权值为2,则调度到服务器B的请求会是服务器A的2倍。权值越高的服务器,处理的请求越多。

  3. 最少链接 lc
    这个算法会根据后端 RS 的连接数来决定把请求分发给谁,比如 RS1 连接数比 RS2 连接数少,那么请求就优先发给 RS1

  4. 加权最少链接 wlc
    这个算法比 lc 多了一个权重的概念。

  5. 基于局部性的最少连接调度算法 lblc
    这个算法是请求数据包的目标 IP 地址的一种调度算法,该算法先根据请求的目标 IP 地址寻找最近的该目标 IP 地址所有使用的服务器,如果这台服务器依然可用,并且有能力处理该请求,调度器会尽量选择相同的服务器,否则会继续选择其它可行的服务器

  6. 复杂的基于局部性最少的连接算法 lblcr
    记录的不是要给目标 IP 与一台服务器之间的连接记录,它会维护一个目标 IP 到一组服务器之间的映射关系,防止单点服务器负载过高。

  7. 目标地址散列调度算法 dh
    该算法是根据目标 IP 地址通过散列函数将目标 IP 与服务器建立映射关系,出现服务器不可用或负载过高的情况下,发往该目标 IP 的请求会固定发给该服务器。

  8. 源地址散列调度算法 sh
    与目标地址散列调度算法类似,但它是根据源地址散列算法进行静态分配固定的服务器资源。

九、实践LVS的NAT模式

1、实验环境

三台服务器,一台作为 director,两台作为 real server,director 有一个外网网卡(172.16.254.200) 和一个内网ip(192.168.0.8),两个 real server 上只有内网 ip (192.168.0.18) 和 (192.168.0.28),并且需要把两个 real server 的内网网关设置为 director 的内网 ip(192.168.0.8)

2、安装和配置

两个 real server 上都安装 nginx 服务
# yum install -y nginx

Director 上安装 ipvsadm
# yum install -y ipvsadm

Director 上编辑 nat 实现脚本

# vim /usr/local/sbin/lvs_nat.sh
# 编辑写入如下内容:
#! /bin/bash
# director服务器上开启路由转发功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
# 关闭 icmp 的重定向
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth1/send_redirects
# director设置 nat 防火墙
iptables -t nat -F
iptables -t nat -X
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
# director设置 ipvsadm
IPVSADM='/sbin/ipvsadm'
$IPVSADM -C
$IPVSADM -A -t 172.16.254.200:80 -s wrr
$IPVSADM -a -t 172.16.254.200:80 -r 192.168.0.18:80 -m -w 1
$IPVSADM -a -t 172.16.254.200:80 -r 192.168.0.28:80 -m -w 1

保存后,在 Director 上直接运行这个脚本就可以完成 lvs/nat 的配置

/bin/bash /usr/local/sbin/lvs_nat.sh

查看ipvsadm设置的规则

ipvsadm -ln

3、测试LVS的效果

通过浏览器测试2台机器上的web内容 http://172.16.254.200 。为了区分开,我们可以把 nginx 的默认页修改一下:

在 RS1 上执行
# echo "rs1rs1" >/usr/share/nginx/html/index.html

在 RS2 上执行
# echo "rs2rs2" >/usr/share/nginx/html/index.html

注意,切记一定要在两台 RS 上设置网关的 IP 为 director 的内网 IP。

十、实践LVS的DR模式

1、实验环境

三台机器:

  • Director节点: (eth0 192.168.0.8 vip eth0:0 192.168.0.38)
  • Real server1: (eth0 192.168.0.18 vip lo:0 192.168.0.38)
  • Real server2: (eth0 192.168.0.28 vip lo:0 192.168.0.38)

2、安装

两个 real server 上都安装 nginx 服务
# yum install -y nginx

Director 上安装 ipvsadm
# yum install -y ipvsadm

3、Director 上配置脚本

# vim /usr/local/sbin/lvs_dr.sh
#! /bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
ipv=/sbin/ipvsadm
vip=192.168.0.38
rs1=192.168.0.18
rs2=192.168.0.28
ifconfig eth0:0 down
ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip dev eth0:0
$ipv -C
$ipv -A -t $vip:80 -s wrr 
$ipv -a -t $vip:80 -r $rs1:80 -g -w 3
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1

执行脚本:

# bash /usr/local/sbin/lvs_dr.sh

4、在2台 rs 上配置脚本:

# vim /usr/local/sbin/lvs_dr_rs.sh
#! /bin/bash
vip=192.168.0.38
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
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

rs 上分别执行脚本:

bash /usr/local/sbin/lvs_dr_rs.sh

5、实验测试

测试方式同上,浏览器访问 http://192.168.0.38

注意:在 DR 模式下,2台 rs 节点的 gateway 不需要设置成 dir 节点的 IP 。

参考链接地址:http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html

十一、LVS结合keepalive

LVS可以实现负载均衡,但是不能够进行健康检查,比如一个rs出现故障,LVS 仍然会把请求转发给故障的rs服务器,这样就会导致请求的无效性。keepalive 软件可以进行健康检查,而且能同时实现 LVS 的高可用性,解决 LVS 单点故障的问题,其实 keepalive 就是为 LVS 而生的。

1、实验环境

4台节点

  • Keepalived1 + lvs1(Director1):192.168.0.48
  • Keepalived2 + lvs2(Director2):192.168.0.58
  • Real server1:192.168.0.18
  • Real server2:192.168.0.28
  • IP: 192.168.0.38

2、安装系统软件

Lvs + keepalived的2个节点安装

# yum install ipvsadm keepalived -y

Real server + nginx服务的2个节点安装

# yum install epel-release -y
# yum install nginx -y

3、设置配置脚本

Real server节点2台配置脚本:

# vim /usr/local/sbin/lvs_dr_rs.sh
#! /bin/bash
vip=192.168.0.38
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
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

2节点rs 上分别执行脚本:
bash /usr/local/sbin/lvs_dr_rs.sh

keepalived节点配置(2节点):

主节点( MASTER )配置文件
vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.38
    }
}

virtual_server 192.168.0.38 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 0
    protocol TCP

    real_server 192.168.0.18 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }

    real_server 192.168.0.28 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }
}

从节点( BACKUP )配置文件

拷贝主节点的配置文件keepalived.conf,然后修改如下内容:

state MASTER -> state BACKUP
priority 100 -> priority 90

keepalived的2个节点执行如下命令,开启转发功能:

# echo 1 > /proc/sys/net/ipv4/ip_forward

4、启动keepalive

先主后从分别启动keepalive
service keepalived start

5、验证结果

实验1

手动关闭192.168.0.18节点的nginx,service nginx stop 在客户端上去测试访问 http://192.168.0.38 结果正常,不会出现访问18节点,一直访问的是28节点的内容。

实验2

手动重新开启 192.168.0.18 节点的nginx, service nginx start 在客户端上去测试访问 http://192.168.0.38 结果正常,按照 rr 调度算法访问18节点和28节点。

实验3

测试 keepalived 的HA特性,首先在master上执行命令 ip addr ,可以看到38的vip在master节点上的;这时如果在master上执行 service keepalived stop 命令,这时vip已经不再master上,在slave节点上执行 ip addr 命令可以看到 vip 已经正确漂到slave节点,这时客户端去访问 http://192.168.0.38 访问依然正常,验证了 keepalived的HA特性。

配置LVS keepalived主从切换时同步连接状态信息

由于LVS负载均衡器需要保存大量的连接信息,记录每个TCP连接由哪台真实服务器处理。

[root@localhost keepshell]# ipvsadm -L -n -c
IPVS connection entries
pro expire state       source             virtual            destination
TCP 14:58  ESTABLISHED 192.168.80.1:57622 192.168.80.138:8080 192.168.80.135:8080
TCP 14:58  ESTABLISHED 192.168.80.1:57624 192.168.80.138:8080 192.168.80.135:8080
TCP 14:58  ESTABLISHED 192.168.80.1:57621 192.168.80.138:8080 192.168.80.136:8080
TCP 14:58  ESTABLISHED 192.168.80.1:57625 192.168.80.138:8080 192.168.80.136:8080
TCP 14:58  ESTABLISHED 192.168.80.1:57623 192.168.80.138:8080 192.168.80.136:8080
TCP 14:58  ESTABLISHED 192.168.80.1:57626 192.168.80.138:8080 192.168.80.135:8080

当主负载均衡器宕机以后,备机提升为主,但备机缺省没有这些连接信息,会导致客户端的连接失效,为了解决这一问题,LVS在Linux内核实现了同步连接信息的功能.

ipvsadm -L --daemon  查看同步进程信息

ipvsadm --start-daemon master|backup --mcast-interface=网卡名称 --syncid 编号,主备需要一致

ipvsadm --stop-daemon master|backup 停止同步
ipvsadm -L -n -c 查看连接状态信息

下面给出配置

keepalived.conf

! Configuration File for keepalived  

global_defs {  
   notification_email {  
     root@localhost  
   }  
   notification_email_from root@localhost    
   smtp_server localhost    
   smtp_connect_timeout 30    
   router_id  NodeA  
} 


! Configuration File for keepalived  

global_defs {  
   notification_email {  
     root@localhost  
   }  
   notification_email_from root@localhost    
   smtp_server localhost    
   smtp_connect_timeout 30    
   router_id  NodeA  
} 

virtual_server 192.168.80.138 8080 {   
   delay_loop 6                    
   lb_algo rr                       
   lb_kind DR                            
   persistence_timeout 0             
   protocol TCP                      
   real_server 192.168.80.135 8080 {     
       weight 1                        
        HTTP_GET {  
            url {   
              path /index.jsp  
              digest 5cce221db9752be2116860efb866144e  
            }  
            connect_timeout 5  
            nb_get_retry 3  
            delay_before_retry 3  
        }         
   }  

   real_server 192.168.80.136 8080 {      
       weight 1  
        HTTP_GET {  
            url {   
              path /index.jsp  
              digest 345e829e9a900a87a8fce740ef243198  
            }  
            connect_timeout 5  
            nb_get_retry 3  
            delay_before_retry 3  
        }          
   }  
}  

notify_master.sh

#!/bin/bash  
echo $(date "+%Y-%m-%d %H:%M:%S") "The keepalived service is master." >> /home/keepshell/gexin.txt  
ipvsadm --stop-daemon backup  
ipvsadm --start-daemon master --mcast-interface=eno16777736 --syncid 1 

notify_backup.sh

#!/bin/bash  
echo $(date "+%Y-%m-%d %H:%M:%S") "The keepalived service is backup." >> /home/keepshell/gexin.txt  
ipvsadm --stop-daemon master  
ipvsadm --start-daemon backup --mcast-interface=eno16777736 --syncid 1  

notify_stop.sh

#!/bin/bash  
echo $(date "+%Y-%m-%d %H:%M:%S") "The keepalived service is stop." >> /home/keepshell/gexin.txt  
ipvsadm --stop-daemon master  
ipvsadm --stop-daemon backup