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"
 
  RIP1="10.0.8.21"
  RIP2="10.0.8.22"
 
  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"
 
  RIP1="10.0.8.21"
  RIP2="10.0.8.22"
 
  DPORT=80
  RPORT1=80
  RPORT2=80
 
#


# 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")
port=80
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.

标签:部署监控Shell 发布于:2019-11-13 04:48:20