82870034 发表于 2015-9-4 13:03:37

Apache+lvs高可用+keepalive(主从+双主模型)

  Apache+lvs高可用+keepalive(主从+双主模型)    
  keepalive实验准备环境:
  httpd-2.2.15-39.el6.centos.x86_64
  keepalived-1.2.13-1.el6.x86_64.rpm
  
  
  
  实验拓扑图:

  
  
  
  
  LVS+Keepalived 实现高可用的前端负载均衡器
  
  node15:
  1.安装httpd
  # yum intsall -y httpd
  2.配置httpd
  # vim /var/www/html/index.html
  <h1>RS1.stu21.com</h1>
  3.启动httpd
  # service httpd start
  
  4.测试

  5.设置开机自启动
  # chkconfig httpd on
  # chkconfig--list httpd
  httpd              0:off    1:off    2:on    3:on    4:on    5:on    6:off
  
  6.配置node1
  # mkdir src
  # cd src/
  # vim realserver.sh
  #!/bin/bash
  #   
  # Script to start LVS DR real server.   
  # description: LVS DR real server   
  #   
  ./etc/rc.d/init.d/functions
  VIP=172.16.21.100 #修改你的VIP
  host=`/bin/hostname`
  case "$1" in
  start)   
         # Start LVS-DR real server on this machine.   
        /sbin/ifconfig lo down   
        /sbin/ifconfig lo 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
        /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
        /sbin/route add -host $VIP dev lo:0
  ;;
  stop)
        # Stop LVS-DR real server loopback device(s).
        /sbin/ifconfig lo:0 down   
        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
  ;;
  status)
        # Status of LVS-DR real server.
        islothere=`/sbin/ifconfig lo:0 | grep $VIP`   
        isrothere=`netstat -rn | grep "lo:0" | grep $VIP`   
        if [ ! "$islothere" -o ! "isrothere" ];then   
              # Either the route or the lo:0 device   
              # not found.   
              echo "LVS-DR real server Stopped."   
        else   
              echo "LVS-DR real server Running."   
        fi   
  ;;   
  *)   
              # Invalid entry.   
              echo "$0: Usage: $0 {start|status|stop}"   
              exit 1   
  ;;   
  esac
  
  
  # chmod +x realserver.sh
  # ll
  total 4
  -rwxr-xr-x 1 root root 1602 Jan 16 11:01 realserver.sh
  
  # ./realserver.sh start
  # ifconfig
  eth0      Link encap:EthernetHWaddr 00:0C:29:01:0D:11
  inet addr:172.16.21.15Bcast:172.16.255.255Mask:255.255.0.0
  inet6 addr: fe80::20c:29ff:fe01:d11/64 Scope:Link
  UP BROADCAST RUNNING MULTICASTMTU:1500Metric:1
  RX packets:8587 errors:0 dropped:0 overruns:0 frame:0
  TX packets:1659 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000
  RX bytes:788734 (770.2 KiB)TX bytes:245057 (239.3 KiB)
  
  lo      Link encap:Local Loopback
  inet addr:127.0.0.1Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNINGMTU:65536Metric:1
  RX packets:8 errors:0 dropped:0 overruns:0 frame:0
  TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:0
  RX bytes:684 (684.0 b)TX bytes:684 (684.0 b)
  
  lo:0      Link encap:Local Loopback
  inet addr:172.16.21.100Mask:255.255.255.255
  UP LOOPBACK RUNNINGMTU:65536Metric:1
  
  # route -n
  Kernel IP routing table
  Destination   Gateway         Genmask         Flags Metric Ref    Use Iface
  172.16.21.100   0.0.0.0         255.255.255.255 UH    0      0      0 lo
  169.254.0.0   0.0.0.0         255.255.0.0   U   1002   0      0 eth0
  172.16.0.0      0.0.0.0         255.255.0.0   U   0      0      0 eth0
  0.0.0.0         172.16.0.1      0.0.0.0         UG    0      0      0 eth0
  # cat /proc/sys/net/ipv4/conf/lo/arp_ignore   
  1
  # cat /proc/sys/net/ipv4/conf/lo/arp_announce
  2
  # cat /proc/sys/net/ipv4/conf/all/arp_ignore   
  1
  # cat /proc/sys/net/ipv4/conf/all/arp_announce
  2
  
  好了,node15到这里基本配置完成,下面我们来配置node16。
  
  node16:
  1.安装httpd
  # yum -y install httpd
  2.配置httpd
  # vim /var/www/html/index.html
  <h1>RS2.stu21.com</h1>
  
  3.启动httpd
  # service httpd start
  
  4.测试

  5.设置开机自启动
  # chkconfighttpd on
  # chkconfig --listhttpd
  httpd              0:off    1:off    2:on    3:on    4:on    5:on    6:off
  
  6.配置node16
  #mkdir src
  # cd src/
  # vim realserver.sh
  #!/bin/bash
  #   
  # Script to start LVS DR real server.   
  # description: LVS DR real server   
  #   
  ./etc/rc.d/init.d/functions
  VIP=172.16.21.100
  host=`/bin/hostname`
  case "$1" in
  start)   
         # Start LVS-DR real server on this machine.   
        /sbin/ifconfig lo down   
        /sbin/ifconfig lo 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
        /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
        /sbin/route add -host $VIP dev lo:0
  ;;
  stop)
        # Stop LVS-DR real server loopback device(s).
        /sbin/ifconfig lo:0 down   
        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
  ;;
  status)
        # Status of LVS-DR real server.
        islothere=`/sbin/ifconfig lo:0 | grep $VIP`   
        isrothere=`netstat -rn | grep "lo:0" | grep $VIP`   
        if [ ! "$islothere" -o ! "isrothere" ];then   
              # Either the route or the lo:0 device   
              # not found.   
              echo "LVS-DR real server Stopped."   
        else   
              echo "LVS-DR real server Running."   
        fi   
  ;;   
  *)   
              # Invalid entry.   
              echo "$0: Usage: $0 {start|status|stop}"   
              exit 1   
  ;;   
  esac
  
  
  # chmod +x realserver.sh
  # ./realserver.sh start
  # ifconfig
  eth0      Link encap:EthernetHWaddr 00:0C:29:C4:F0:75
  inet addr:172.16.21.16Bcast:172.16.255.255Mask:255.255.0.0
  inet6 addr: fe80::20c:29ff:fec4:f075/64 Scope:Link
  UP BROADCAST RUNNING MULTICASTMTU:1500Metric:1
  RX packets:195309 errors:0 dropped:0 overruns:0 frame:0
  TX packets:11581 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000
  RX bytes:185306532 (176.7 MiB)TX bytes:1258818 (1.2 MiB)
  
  lo      Link encap:Local Loopback
  inet addr:127.0.0.1Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNINGMTU:65536Metric:1
  RX packets:24 errors:0 dropped:0 overruns:0 frame:0
  TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:0
  RX bytes:2056 (2.0 KiB)TX bytes:2056 (2.0 KiB)
  
  lo:0      Link encap:Local Loopback
  inet addr:172.16.21.100Mask:255.255.255.255
  UP LOOPBACK RUNNINGMTU:65536Metric:1
  
  # route -n
  Kernel IP routing table
  Destination   Gateway         Genmask         Flags Metric Ref    Use Iface
  172.16.21.100   0.0.0.0         255.255.255.255 UH    0      0      0 lo
  169.254.0.0   0.0.0.0         255.255.0.0   U   1002   0      0 eth0
  172.16.0.0      0.0.0.0         255.255.0.0   U   0      0      0 eth0
  0.0.0.0         172.16.0.1      0.0.0.0         UG    0      0      0 eth0
  
  好了,到这里node16也基本配置完成。下面我们来配置master与slave。
  
  master 与 slave:
  
  1.安装keepalived与ipvsadm
  master(节点node17):
  # yuminstall -y ipvsadm
  # yum -y install keepalived
  
  # yuminstall -y ipvsadm
  # yum -y install keepalived
  
  2.修改配置文件
  master(node17)
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  
  vrrp_instance VI_1 {
      state MASTER   #配置模式
      interface eth0
      virtual_router_id 51
      priority 101   #配置优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  3.将配置文件同步到slave   # scp /etc/keepalived/keepalived.conf root@192.168.18.207:/etc/keepalived/
  
  4.简单修改一下slave配置文件
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  
  vrrp_instance VI_1 {
      state BACKUP   #配置模式 #修改为BACKUP
      interface eth0
      virtual_router_id 51
      priority 100   #配置优先级 #修改优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  
  5.启动master与slave的keepalived服务
  
  # service keepalived start
  Starting keepalived:
  # service keepalived start
  Starting keepalived:                                       
  
  6.查看一下LVS状态
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.21.100:80 rr
  -> 172.16.21.15:80            Route   1      0          0         
  -> 172.16.21.16:80            Route   1      0          0   
  
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.21.100:80 rr
  -> 172.16.21.15:80            Route   1      0          0         
  -> 172.16.21.16:80            Route   1      0          0      
  7.测试


  8.模拟故障
  (1).停止一下node15上的httpd
  # service httpd stop
  Stopping httpd:
  (2).查看一下的lvs(master)
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.21.100:80 rr
  -> 172.16.21.16:80            Route   1      0          0         
  You have mail in /var/spool/mail/root
  
  (3).测试一下

  
  (4).查看一下邮件
  # mail

  
  (5).重新启动一下node15上的httpd
  
  (6).再查看一下lvs状态(master)
  #ipvsadm -L -n   
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.21.100:80 rr
  -> 172.16.21.15:80            Route   1      0          0         
  -> 172.16.21.16:80            Route   1      0          0         
  You have new mail in /var/spool/mail/root
  
  (7).再查看一下邮件
  # mail

  
  (8).关闭master上keepalived
  
  # service keepalived stop
  Stopping keepalived:                                       
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  
  (9).查看一下slave状态
  
  # ip addr show
  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  inet 127.0.0.1/8 scope host lo
  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:0c:29:15:10:48 brd ff:ff:ff:ff:ff:ff
  inet 172.16.21.18/16 brd 172.16.255.255 scope global eth0
  inet 172.16.21.100/32 scope global eth0
  inet6 fe80::20c:29ff:fe15:1048/64 scope link
  valid_lft forever preferred_lft forever
  3: pan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
  link/ether 0a:6b:ef:b8:23:05 brd ff:ff:ff:ff:ff:ff
  You have new mail in /var/spool/mail/root
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.21.100:80 rr
  -> 172.16.21.15:80            Route   1      0          0         
  -> 172.16.21.16:80            Route   1      0          0   
  
  
  (10).再次测试一下
  


  
  
  注,大家可以看到,经过上面的演示我们现在LVS的高可用即前端负载均衡的高可用,同时实现对后端realserver监控,也实现后端realserver宕机时会给管理员发送邮件。但还有几个问题我们还没有解决,问题如下:

[*]所有realserver都down机,怎么处理?是不是用户就没法打开,还是提供一下维护页面。


[*]怎么完成维护模式keepalived切换?
[*]如何在keepalived故障时,发送警告邮件给指定的管理员?
[*]9.所有realserver都down机,怎么处理?
[*]问题:在集群中如果所有real server全部宕机了,客户端访问时就会出现错误页面,这样是很不友好的,我们得提供一个维护页面来提醒用户,服务器正在维护,什么时间可以访问等,下面我们就来解决一下这个问题。解决方案有两种,一种是提供一台备用的real server当所有的服务器宕机时,提供维护页面,但这样做有点浪费服务器。另一种就是在负载均衡器上提供维护页面,这样是比较靠谱的,也比较常用。下面我们就来具体操作一下。
  (1).master(node17)与slave(node18)安装上httpd
  # yum -y install httpd
  # yum -y install httpd
  
  (2).配置维护页面
  # vim /var/www/html/index.html
  Website is currently under maintenance, please come back later!
  # vim /var/www/html/index.html
  Website is currently under maintenance, please come back later!
  
  (3).启动httpd服务并测试
  # service httpd start
  Starting httpd:                                          
  # service httpd start
  Starting httpd:                                             


  (4).修改配置文件
  master(node17):
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  
  vrrp_instance VI_1 {
      state MASTER   #配置模式
      interface eth0
      virtual_router_id 51
      priority 101   #配置优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80#增加一行sorry_server
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  
  
  
  slave(node18):
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  
  vrrp_instance VI_1 {
      state BACKUP   #配置模式#修改为BACKUP
      interface eth0
      virtual_router_id 51
      priority 100   #配置优先级#修改优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  
  (5).关闭所有的real server并重新启动一下master与slave的keepalived
  # service httpd stop
  Stopping httpd:                                          
  # service httpd stop
  Stopping httpd:                                          
  #service keepalived restart
  Stopping keepalived:                                       
  Starting keepalived:                                       
  #service keepalived restart
  Stopping keepalived:                                       
  Starting keepalived:                                       
  (6).查看一下lvs
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.21.100:80 rr
  -> 127.0.0.1:80               Local   1      0          0   
  (7).测试

  
  注,sorry_server测试成功,下面我们继续。
  10.怎么完成维护模式keepalived切换?
  问题:我们一般进行主从切换测试时都是关闭keepalived或关闭网卡接口,有没有一种方法能实现在不关闭keepalived下或网卡接口来实现维护呢?方法肯定是有的,在keepalived新版本中,支持脚本vrrp_srcipt,具体如何使用大家可以man keepalived.conf查看。下面我们来演示一下具体怎么实现。
  (1).定义脚本
      vrrp_srcipt chk_schedown { 
     script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"  
     interval 1 #监控间隔  
     weight -5 #减小优先级  
     fall 2 #监控失败次数  
     rise 1 #监控成功次数  
  }
  
  (2).执行脚本
      track_script {
     chk_schedown #执行chk_schedown脚本
         
  }
  
  (3).修改配置文件
  
  master(node17):只需在原来的配置上增加两处代码,是标记绿色的
      # cat /etc/keepalived/keepalived.conf   
  ! Configuration File for keepalived
  
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  
  
  vrrp_script chk_schedown { #定义vrrp执行脚本
     script "[ -e /etc/keepalived/down ] && exit 1 || exit 0" #查看是否有down文件,有就进入维护模式
     interval 1 #监控间隔时间
     weight -5 #降低优先级
     fall 2 #失败次数
     rise 1 #成功数次
  }
  
  vrrp_instance VI_1 {
      state MASTER   #配置模式
      interface eth0
      virtual_router_id 51
      priority 101   #配置优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
   track_script { #执行脚本
        chk_schedown
  
      }
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server   
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  slave(node18):只需在原来的配置上增加三处代码,是标记绿色的
  
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  
  global_defs {
  notification_email {
  root@node17.stu21.com
  root@node18.stu21.com   #配置管理员邮箱   
  }
  notification_email_from kaadmin@stu21.com#配置发件人
  smtp_server 127.0.0.1   #配置邮件服务器   
  smtp_connect_timeout 30
  router_id LVS_DEVEL
  }
  vrrp_script chk_schedown {
     script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
     interval 1
     weight -5
     fall 2
     rise 1
  }
  
  vrrp_instance VI_1 {
  state BACKUP   #配置模式#修改为BACKUP
  interface eth0
  virtual_router_id 51
  priority 100   #配置优先级#修改优先级   
  advert_int 1
  authentication {
  auth_type PASS
  auth_pass 1111
  }
  virtual_ipaddress {
  172.16.21.100   #配置虚拟IP地址   
  }
  track_script {
  chk_schedown
  }
  
  }
  
  virtual_server 172.16.21.100 80 {
  delay_loop 6
  lb_algo rr
  lb_kind DR
  nat_mask 255.255.255.0
  #persistence_timeout 50
  protocol TCP
  
  real_server 172.16.21.15 80 { #配置realaserver
  weight 1
  HTTP_GET {#监控配置
  url {
  path /
  #digest ff20ad2481f97b1754ef3e12ecd3a9cc
  status_code 200
  }
  
  connect_timeout 3
  nb_get_retry 3
  delay_before_retry 1
  }
  }
  real_server 172.16.21.16 80 { #配置realaserver
  weight 1
  HTTP_GET {#监控配置
  url {
  path /
  #digest ff20ad2481f97b1754ef3e12ecd3a9cc
  status_code 200
  }
  
  connect_timeout 3
  nb_get_retry 3
  delay_before_retry 1
  }
  }
  sorry_server 127.0.0.1 80   #增加一行sorry_server   
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  
  (4).测试
  # cd /etc/keepalived/
  # touch down
  # ll
  total 8
  -rw-r--r-- 1 root root    0 Jan 16 15:14 down
  -rw-r--r-- 1 root root 4330 Jan 16 15:10 keepalived.conf
  # ip add show #查看VIP
  
  
  # ip addr show #查看一下VIP已转移到slave上 

  
  测试:我再把 /etc/keepalived/ 目录下的down 文件移除或是改变
  # mv down down.bak
  # ll
  total 8
  -rw-r--r-- 1 root root    0 Jan 16 15:14 down.bak
  -rw-r--r-- 1 root root 4330 Jan 16 15:10 keepalived.conf
  
  # ip addr show #查看一下VIP又回到master上 

  好了,自写监测脚本,完成维护模式切换,到这里就演示成功,下面我们来解决最后一个问题,就是keepalived主从切换的邮件通告。
  
  
  
  
  11.如何在keepalived故障时(或主备切换时),发送警告邮件给指定的管理员?
  (1).keepalived通知脚本进阶示例
  下面的脚本可以接受选项,其中

[*]-s, --service SERVICE,...:指定服务脚本名称,当状态切换时可自动启动、重启或关闭此服务;
[*]-a, --address VIP: 指定相关虚拟路由器的VIP地址;
[*]-m, --mode {mm|mb}:指定虚拟路由的模型,mm表示主主,mb表示主备;它们表示相对于同一种服务而方,其VIP的工作类型;
[*]-n, --notify {master|backup|fault}:指定通知的类型,即vrrp角色切换的目标角色;
[*]-h, --help:获取脚本的使用帮助;
  ------------------------------------------------------------------------------------------------------------------------
  #!/bin/bash 
  # Author: freeloda   
  # description: An example of notify script  
  # Usage: notify.sh -m|--mode {mm|mb} -s|--service SERVICE1,... -a|--address VIP  -n|--notify {master|backup|falut} -h|--help
  contact='1521076067@163.com'    #设置管理员的邮箱
  helpflag=0  
  serviceflag=0  
  modeflag=0  
  addressflag=0  
  notifyflag=0
  Usage() { 
    echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP>  <-n|--notify {master|backup|falut}>"   
    echo "Usage: notify.sh -h|--help"  
  }
  ParseOptions() { 
    local I=1;  
    if [ $# -gt 0 ]; then  
      while [ $I -le $# ]; do  
        case $1 in  
        -s|--service)  
          [ $# -lt 2 ] && return 3  
           serviceflag=1  
           services=(`echo $2|awk -F"," '{for(i=1;i<=NF;i++) print $i}'`)  
          shift 2 ;;  
        -h|--help)  
           helpflag=1  
          return 0  
          shift  
          ;;  
        -a|--address)  
          [ $# -lt 2 ] && return 3  
          addressflag=1  
          vip=$2  
          shift 2  
          ;;  
        -m|--mode)  
          [ $# -lt 2 ] && return 3  
          mode=$2  
          shift 2  
          ;;  
        -n|--notify)  
          [ $# -lt 2 ] && return 3  
          notifyflag=1  
          notify=$2  
          shift 2  
          ;;  
        *)  
          echo "Wrong options..."  
          Usage  
          return 7  
          ;;  
         esac  
      done  
      return 0  
    fi  
  }
  #workspace=$(dirname $0)
  RestartService() { 
    if [ ${#@} -gt 0 ]; then  
      for I in $@; do  
        if [ -x /etc/rc.d/init.d/$I ]; then  
          /etc/rc.d/init.d/$I restart  
        else  
          echo "$I is not a valid service..."  
        fi  
      done  
    fi  
  }
  StopService() { 
    if [ ${#@} -gt 0 ]; then  
      for I in $@; do  
        if [ -x /etc/rc.d/init.d/$I ]; then  
          /etc/rc.d/init.d/$I stop  
        else  
          echo "$I is not a valid service..."  
        fi  
      done  
    fi  
  }
  Notify() {  
      mailsubject="`hostname` to be $1: $vip floating"  
      mailbody="`date '+%F %H:%M:%S'`, vrrp transition, `hostname` changed to be $1."  
      echo $mailbody | mail -s "$mailsubject" $contact  
  }
  # Main Function  
  ParseOptions $@  
  [ $? -ne 0 ] && Usage && exit 5
  [ $helpflag -eq 1 ] && Usage && exit 0
  if [ $addressflag -ne 1 -o $notifyflag -ne 1 ]; then 
    Usage  
    exit 2  
  fi
  mode=${mode:-mb}
  case $notify in 
  'master')  
    if [ $serviceflag -eq 1 ]; then  
        RestartService ${services
[*]}  
    fi  
    Notify master  
    ;;  
  'backup')  
    if [ $serviceflag -eq 1 ]; then  
      if [ "$mode" == 'mb' ]; then  
        StopService ${services
[*]}  
      else  
        RestartService ${services
[*]}  
      fi  
    fi  
    Notify backup  
    ;;  
  'fault')  
    Notify fault  
    ;;  
  *)  
    Usage  
    exit 4  
    ;;  
  esac
  
  
  (2).在keepalived.conf配置文件中,其调用方法如下所示:

[*]notify_master "/etc/keepalived/notify.sh -n master -a 172.16.21.100"  
[*]notify_backup "/etc/keepalived/notify.sh -n backup -a 172.16.21.100"  
[*]notify_fault "/etc/keepalived/notify.sh -n fault -a 172.16.21.100"
  (3).修改配置文件
  master(node17):只需要在原配置基础上加上绿色着色出的代码
      # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  vrrp_script chk_schedown { #定义vrrp执行脚本
     script "[ -e /etc/keepalived/down ] && exit 1 || exit 0" #查看是否有down文件,有就进入维护模式
     interval 1 #监控间隔时间
     weight -5 #降低优先级
     fall 2 #失败次数
     rise 1 #成功数次
  }
  
  vrrp_instance VI_1 {
      state MASTER   #配置模式
      interface eth0
      virtual_router_id 51
      priority 101   #配置优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
     track_script { #执行脚本
        chk_schedown
      }   
     #增加以下三行
      notify_master "/etc/keepalived/notify.sh -n master -a 172.16.21.100"
      notify_backup "/etc/keepalived/notify.sh -n backup -a 172.16.21.100"
      notify_fault "/etc/keepalived/notify.sh -n fault -a 172.16.21.100"
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server   
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #} 
  
  slave(node18):只需要在原配置的基础上增加下面绿色着色处的代码
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  
  global_defs {
     notification_email {
      root@node17.stu21.com
      root@node18.stu21.com   #配置管理员邮箱
     }
     notification_email_from kaadmin@stu21.com#配置发件人
     smtp_server 127.0.0.1   #配置邮件服务器
     smtp_connect_timeout 30
     router_id LVS_DEVEL
  }
  vrrp_script chk_schedown {
     script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
     interval 1
     weight -5
     fall 2
     rise 1
  }
  vrrp_instance VI_1 {
      state BACKUP   #配置模式#修改为BACKUP
      interface eth0
      virtual_router_id 51
      priority 100   #配置优先级#修改优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.100   #配置虚拟IP地址
      }
  track_script {
      chk_schedown
      }
  #增加以下三行
      notify_master "/etc/keepalived/notify.sh -n master -a 172.16.21.100"
      notify_backup "/etc/keepalived/notify.sh -n backup -a 172.16.21.100"
      notify_fault "/etc/keepalived/notify.sh -n fault -a 172.16.21.100"
  }
  
  virtual_server 172.16.21.100 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
            status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server   
  }
  
  #virtual_server#10.10.10.2 1358 {
  #   delay_loop 6
  #   lb_algo rr
  #   lb_kind NAT
  #   persistence_timeout 50
  #   protocol TCP
  
  #   sorry_server 192.168.200.200 1358
  
  #   real_server 192.168.200.2 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.3 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334c
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  #virtual_server#10.10.10.3 1358 {
  #   delay_loop 3
  #   lb_algo rr
  #   lb_kind NAT
  #   nat_mask 255.255.255.0
  #   persistence_timeout 50
  #   protocol TCP
  
  #   real_server 192.168.200.4 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  
  #   real_server 192.168.200.5 1358 {
  #       weight 1
  #       HTTP_GET {
  #         url {
  #             path /testurl/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl2/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         url {
  #             path /testurl3/test.jsp
  #             digest 640205b7b0fc66c1ea91c463fac6334d
  #         }
  #         connect_timeout 3
  #         nb_get_retry 3
  #         delay_before_retry 3
  #       }
  #   }
  #}
  
  
  (4).增加脚本
  # pwd
  /etc/keepalived
  # vim notify.sh
  # cat notify.sh
  #!/bin/bash
  # Author: freeloda   
  # description: An example of notify script
  # Usage: notify.sh -m|--mode {mm|mb} -s|--service SERVICE1,... -a|--address VIP-n|--notify {master|backup|falut} -h|--help
  contact=' root@node17.stu21.com'
  contact=' root@node18.stu21.com'
  helpflag=0
  serviceflag=0
  modeflag=0
  addressflag=0
  notifyflag=0
  Usage() {
  echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP><-n|--notify {master|backup|falut}>"   
  echo "Usage: notify.sh -h|--help"
  }
  ParseOptions() {
  local I=1;
  if [ $# -gt 0 ]; then
      while [ $I -le $# ]; do
        case $1 in
        -s|--service)
        [ $# -lt 2 ] && return 3
           serviceflag=1
           services=(`echo $2|awk -F"," '{for(i=1;i<=NF;i++) print $i}'`)
        shift 2 ;;
        -h|--help)
           helpflag=1
        return 0
        shift
        ;;
        -a|--address)
        [ $# -lt 2 ] && return 3
        addressflag=1
        vip=$2
        shift 2
        ;;
        -m|--mode)
        [ $# -lt 2 ] && return 3
        mode=$2
        shift 2
        ;;
        -n|--notify)
        [ $# -lt 2 ] && return 3
        notifyflag=1
        notify=$2
        shift 2
        ;;
        *)
        echo "Wrong options..."
        Usage
        return 7
        ;;
         esac
      done
      return 0
  fi
  }
  #workspace=$(dirname $0)
  RestartService() {
  if [ ${#@} -gt 0 ]; then
      for I in $@; do
        if [ -x /etc/rc.d/init.d/$I ]; then
        /etc/rc.d/init.d/$I restart
        else
        echo "$I is not a valid service..."
        fi
      done
  fi
  }
  StopService() {
  if [ ${#@} -gt 0 ]; then
      for I in $@; do
        if [ -x /etc/rc.d/init.d/$I ]; then
        /etc/rc.d/init.d/$I stop
        else
        echo "$I is not a valid service..."
        fi
      done
  fi
  }
  Notify() {
      mailsubject="`hostname` to be $1: $vip floating"
      mailbody="`date '+%F %H:%M:%S'`, vrrp transition, `hostname` changed to be $1."
      echo $mailbody | mail -s "$mailsubject" $contact
  }
  # Main Function
  ParseOptions $@
  [ $? -ne 0 ] && Usage && exit 5
  [ $helpflag -eq 1 ] && Usage && exit 0
  if [ $addressflag -ne 1 -o $notifyflag -ne 1 ]; then
  Usage
  exit 2
  fi
  mode=${mode:-mb}
  case $notify in
  'master')
  if [ $serviceflag -eq 1 ]; then
        RestartService ${services
[*]}
  fi
  Notify master
  ;;
  'backup')
  if [ $serviceflag -eq 1 ]; then
      if [ "$mode" == 'mb' ]; then
        StopService ${services
[*]}
      else
        RestartService ${services
[*]}
      fi
  fi
  Notify backup
  ;;
  'fault')
  Notify fault
  ;;
  *)
  Usage
  exit 4
  ;;
  esac
  
  
  # chmod +x notify.sh
  
  (6).将slave(node18)上脚本复制到master(node17)上
  # scp -rp notify.shnode17:/etc/keepalived/
  notify.sh   
  
  
  (7).测试一下脚本
  
  # ./notify.sh -h
  Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP><-n|--notify {master|backup|falut}>
  Usage: notify.sh -h|--help
  #./notify.sh --help
  Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP><-n|--notify {master|backup|falut}>
  Usage: notify.sh -h|--help
  #./notify.sh -m mb -a 1.1.1.1 -n master
  
  
  (9).模拟故障,切记在模拟故障时先重启一下keepalived服务。
  # ip addr show#查看一下VIP 

  
  #touch down #进入维护模式  

  
  
  
  # ip addr show   #大家可以看到VIP成功移动到slave上 

  
  在有vip的节点上查看一下邮件:
  # mail

  
  
  主备切换时,会发送邮件报警,好了到这里所有演示全部完成。
  
  思考题一:
  还有个小问题是:如果两个装有keepalived 的节点,在/etc/keepalived/keepalived.conf 中都是主模型,且优先级都是一样的,那么vip 会在哪个节点上?
  答案:会根据节点ip最后一个字节大些来确定。vip会在大的字节上。
  
  思考题二:
  设置双主模型,即两个vip,同样只需要两台服务器(node17,node18):每个节点既是主又是从。
  只需对两个配置文件各自添加vrrp_instance VI_2 ,virtual_server 两段
  node17:
  ---------------------------------------------------------------------------------------------------------------
      vrrp_instance VI_2 {
      state BACKUP   #配置模式#修改为BACKUP
      #state MASTER   #测试配置模式
      interface eth0
      virtual_router_id 52
  
     priority 99   #配置优先级#修改优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.101   #配置虚拟IP地址
      }
  track_script {
      chk_schedown
      }
     #增加以下三行
      notify_master "/etc/keepalived/notify.sh -n master -a 172.16.21.101"
      notify_backup "/etc/keepalived/notify.sh -n backup -a 172.16.21.101"
      notify_fault "/etc/keepalived/notify.sh -n fault -a 172.16.21.101"
  }
  
  ----------------------------------------------------------------------------------------------------------------------
  
  virtual_server 172.16.21.101 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server
  }
  
  --------------------------------------------------------------------------------------------------------------------
  node18:
  
  vrrp_instance VI_2 {
      #state BACKUP   #配置模式#修改为BACKUP
      state MASTER   #测试配置模式
      interface eth0
      virtual_router_id 52
  
     priority 101   #配置优先级#修改优先级
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1111
      }
      virtual_ipaddress {
        172.16.21.101   #配置虚拟IP地址
      }
  track_script {
      chk_schedown
      }
     #增加以下三行
      notify_master "/etc/keepalived/notify.sh -n master -a 172.16.21.101"
     #增加以下三行
      notify_master "/etc/keepalived/notify.sh -n master -a 172.16.21.101"
      notify_backup "/etc/keepalived/notify.sh -n backup -a 172.16.21.101"
      notify_fault "/etc/keepalived/notify.sh -n fault -a 172.16.21.101"
  }
  
  
  
  virtual_server 172.16.21.101 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      #persistence_timeout 50
      protocol TCP
  
      real_server 172.16.21.15 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
      real_server 172.16.21.16 80 { #配置realaserver
        weight 1
        HTTP_GET {#监控配置
              url {
              path /
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server
  }
  
  
              #digest ff20ad2481f97b1754ef3e12ecd3a9cc
              status_code 200
              }
  
              connect_timeout 3
              nb_get_retry 3
              delay_before_retry 1
        }
      }
  sorry_server 127.0.0.1 80   #增加一行sorry_server
  }
  
  
  ----------------------------------------------------------------------------------------------------------------------
  
  到这里思考题2 还没有结束,因为我们通过前面LVS-DR在节点node15,node16上只设置了一个vip=172.16.21.100   所以keepalived的双主模型(节点node17,node18)上无法实现RS1(node15),RS2(node16)高可用。
  此时我们分别设置节点node15,node16上的/root/src/ realserver.sh的脚本配置(文章前面已经创建过)
  
  node15:只需要添加我着色的代码
  # pwd
  /root/src
  # ls
  realserver.sh
  # vim realserver.sh
  
  #!/bin/bash
  #   
  # Script to start LVS DR real server.   
  # description: LVS DR real server   
  #   
  ./etc/rc.d/init.d/functions
  VIP=172.16.21.100
  VIP1=172.16.21.101    #添加增加的VIP,双主模型用到
  host=`/bin/hostname`
  case "$1" in
  start)
         # Start LVS-DR real server on this machine.   
        /sbin/ifconfig lo down
        /sbin/ifconfig lo 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
        /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
   /sbin/ifconfig lo:1 $VIP1 broadcast $VIP1 netmask 255.255.255.255 up
        /sbin/route add -host $VIP dev lo:0
   /sbin/route add -host $VIP1 dev lo:1
  ;;
  stop)
        # Stop LVS-DR real server loopback device(s).
        /sbin/ifconfig lo:0 down
   /sbin/ifconfig lo:1 down
        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
  ;;
  status)
        # Status of LVS-DR real server.
        islothere=`/sbin/ifconfig lo:0 | grep $VIP`
     islothere=`/sbin/ifconfig lo:1 | grep $VIP1`
        isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
   isrothere=`netstat -rn | grep "lo:1" | grep $VIP1`
        if [ ! "$islothere" -o ! "isrothere" ];then
              # Either the route or the lo:0 device   
              # not found.   
              echo "LVS-DR real server Stopped."   
        else
              echo "LVS-DR real server Running."   
        fi
  ;;
  *)
              # Invalid entry.   
              echo "$0: Usage: $0 {start|status|stop}"   
              exit 1
  ;;
  esac
  
  
  
  node16:
  只需要node15上的/root/src/ realserver.sh的脚本配置复制一份给node16:
  # scp realserver.shnode16:/root/src/
  realserver.sh                                                                        100% 1881   1.8KB/s   00:00
  
  
  
  
  接下来测试一下:
  VIP=172.16.21.100 实现高可用


  
  VIP=172.16.21.101 实现高可用
  


  
  
  
  
页: [1]
查看完整版本: Apache+lvs高可用+keepalive(主从+双主模型)