link 发表于 2018-12-29 08:23:32

V 7 keepalived

V 7 keepalived
  一、相关概念:
  keepalived(c语言编写的路由软件,是LVS的扩展项目,主要实现后端RS的loadbalance和healthcheck及两director的HA(masterbackup的failover),实现VIP在高可用的director间流转,keepalived是在linux上实现了vrrp协议的服务软件,依赖协议vrrp(virtual router redundance protocol,虚拟路由冗余协议,可将多个物理设备虚拟成一个设备),内部的一个配置文件足以完成所有功能,但严重依赖脚本实现其扩展功能,比corosync更轻量级,地址转移非常快,若不需要多个node又不需要共享存储,keepalived足以满足我们需求)
  vrrp
  本身与keepalived没关系,设计初衷是为内网LAN中的主机(client)连接外部网络时,指定网关的连接方式(动态、静态)
  动态方式一(proxy arp,前提要提供arp-server、arp-client,arp-client要连接外网时需请求,arp-server予以响应,这样arp-client会动态获得一个网关地址;这种方式的好处,可以配置多个网关,哪个网关响应快就使用哪个路由,由此实现冗余的功能(路由冗余或网关冗余),使得不能因为某一个路由设备故障导致内网主机连接外网中断;不好的地方,需要client安装arp的client工具,配置复杂)
  动态方式二(routing protocol,使用动态路由协议RIP2或OSPF,在client上实现一种服务,能提供RIP2或OSPF协议,并能实现与前端网关交互并生成动态路由表的功能,同样配置复杂)
  动态方式三(IRDP client,ICMP router discovery protocol)
  注:以上动态方式,client配置复杂及系统有额外开销,若某路由器故障,切换过程会比较慢
  静态方式(client通过静态方式指定默认网关,这将简化客户端的处理过程,但会带来单点故障问题)
  由此vrrp诞生,在静态方式的基础上,让网关本身能实现冗余的功能,将两台路由器(或是主机的两个物理接口)虚拟成一个路由器,虚拟出的这个路由器对外提供服务,同一时刻后端的两个路由器仅一台对外连接,client指定的默认网关为虚拟出的路由器的地址,这个指定的地址通过vrrp内部选举或配置使用哪台路由设备,当某一路由器node故障自动转移至备用node)
  1个master,n个backup(通常1主1从,从要处于空闲状态);也能多主模型
  多主模型(多主是在一组物理设备上虚拟出多个虚拟路由组(虚拟出多个虚拟路由设备),因为在同一网卡上可配置多个地址,如两个物理设备的eth0:0对应虚拟路由器1、两个物理设备的eth1:1对应虚拟路由器2)
  注:vrrp是一个选举协议,它能够动态地将一个虚拟路由器的责任指定到同一个vrrp组中的其它路由器上,从而消除了静态路由配置的单点故障
  VRRP的优势:
  冗余:可以使用多个路由器设备作为LAN客户端的默认网关,大大降低了默认网关成为单点故障的可能性;
  负载共享:允许来自LAN客户端的流量由多个路由器设备所共享;
  多VRRP组:在一个路由器物理接口上可配置多达255个VRRP组;
  多IP地址:基于接口别名在同一个物理接口上配置多个IP地址,从而支持在同一个物理接口上接入多个子网;
  抢占:在master故障时允许优先级更高的backup成为master;
  通告协议:使用IANA所指定的组播地址224.0.0.18进行VRRP通告;
  VRRP追踪:基于接口状态来改变其VRRP优先级来确定最佳的VRRP路由器成为master
  keepalived是在linux上实现了vrrp协议的服务软件,这个软件可让linux主机用户配置虚拟路由的功能,通过vrrp选举某一node使用当前的VIP,并在活动node故障时转移到其它node(转移到哪个node要看优先级)
  keepalived提供服务的高可用功能(仅有IP的转移还不够,还要有服务的转移),以LVS为例,ipvs的内核功能不用转移,VIP在哪个node工作,哪个 node就是active-node,另一个non-action-node就算配置了ipvs规则起不了作用,平时就让高可用集群中各node的ipvs功能启用并配置好规则(万一IP要飘移过来,规则未配置上那飘移过来的IP也没用),所以要实现对高可用集群服务的health_check,keepalived提供脚本或命令的检测方式,让飘移后的高可用服务所依赖的除IP外其它服务(或功能),只有检测成功才飘移,检测不成功很可能不飘移
  注:可用一script检测当前active-node的服务,active-node通过vrrp不停向外通告自己所处的状态,若服务故障则降低这个node的优先级,vrrp会在内部比较各node的优先级,active-node一旦发现自己的优先级比从的低,IP会飘移到从,从这时就成了active-node(优先级高的会把IP抢过来,会有主从角色转换,masterbackup),VIP飘移到从,从上的其它服务要启动(两种方式,要么在飘移的过程中启动依赖的其它服务;要么在检测这些服务正常运行后再飘移过来(active-node在故障后优先级降低时就通过script就将服务启动好,这样node在转换时会很快))
  双主模型(两个IP,服务是同一个;例如node1故障(M-->M),node2上是两个主(压力较大),通常不这样做;若node1故障时降低优先级,vrrp向外通告按优先级转移至node2,通过script重启node1上的服务(script要一直检测服务是否正常),若重启后正常,vrrp向外通告按优先级再转移回来继续提供服务)
  注:script要一直检测active-node服务是否正常,若检测不到状态或检测到服务故障就降低优先级,IP就向外飘,同时让故障node的服务重启,重启后正常按优先级再转移回来
  在服务刚启动时#service keepalived start,双方向对方传递通告信息,比较优先级,这个过程是初始化状态,从而按优先级确认主备关系
  keepalived只能做到对网络故障和keepalived自身的监控(它自身出问题或网络故障时才自动切换),要监控keepalived所在服务的的其它服务进程,则要依赖脚本实现vrrp_script或notify_master|notify_backup|notify_fault
  注:keepalived+nginx、keepalived+haproxy(这两种模型作为高可用的前端非常常见;nginx是轻量级的web,同时又是轻量级的web反向代理;haproxy是超轻量级的高性能的反向代理;这两个组件作为反向代理不需用共享存储,工作机制同ipvs类似)
  sorry_serverIPPORT(若所有后端RS都挂掉,这个功能可在另一服务器(通常是前端作为高可用的服务器)上提供报错页面,如服务器正在维护等信息)
  二、操作:
  环境:
  # uname -a
  Linux node1.magedu.com 2.6.18-308.el5 #1SMP Fri Jan 27 17:21:15 EST 2012 i686 i686 i386 GNU/Linux
  软件包:keepalived-1.2.19.tar.gz,ipvsadm-1.24-13.el5.i386.rpm(ipvsadm仅作查询用)
  node{1,2}作为高可用node,安装keepalived和ipvsadm;node{3,4}作为后端RS,仅需提供httpd服务即可;node5供测试用
  (1)安装及配置
  node{1,2}-side:
  # grep -i ip_vs/boot/config-2.6.18-308.el5
  CONFIG_IP_VS=m
  ……
  CONFIG_IP_VS_TAB_BITS=12
  CONFIG_IP_VS_PROTO_TCP=y
  ……
  # cd /mnt/cdrom/Cluster
  # rpm -ivh ipvsadm-1.24-13.el5.i386.rpm
  # cd
  # tar xf keepalived-1.2.19.tar.gz
  # ./configure --prefix=/usr/local/keepalived --disable-fwmark(若不使用--disable-fwmark在编译时会报错,如configure: error: No SO_MARK declaration in headers)
  # make
  # make install
  # cd /usr/local/keepalived/
  # ls
  bin etcsbinshare
  # cp bin/genhash /bin
  # cp etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
  # cp etc/sysconfig/keepalived /etc/sysconfig/
  # mkdir /etc/keepalived
  # cp -r etc/keepalived/* /etc/keepalived/
  # cp sbin/keepalived /sbin/
  # vim /etc/man.config(添加一行,这样可以直接使用#mankeepalived.conf,否则要指定路径#man-M /usr/local/keepalived/share/man keepalived.conf)
  MANPATH /usr/local/keepalived/share/man
  # chkconfig --add keepalived
  # chkconfig keepalived on
  # chkconfig --list keepalived
  keepalived         0:off 1:off 2:on 3:on 4:on 5:on 6:off
  # sed -i 's@net.ipv4.ip_forward = 0@net.ipv4.ip_forward = 1@g' /etc/sysctl.conf
  node1-side:
  # cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
  # vim /etc/keepalived/keepalived.conf(前端director的ipvs规则均在配置文件中设置,不需手动添加规则)
  global_defs {
  notification_email {(故障或监控信息向指定邮箱发邮件告知)
  root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id LVS_DEVEL
  }
  vrrp_instance VI_1 {(定义VIP虚拟路由)
  state MASTER(初始状态这端为MASTER,另一端为BACKUP)
  interface eth0(通告信息基于哪个物理接口发送,虚拟路由工作的接口)
  virtual_router_id 51(两端要一样,used to differentiate multiple instances of vrrpd running on thesame NIC and hence same socket,arbitary unique number 0-255)
  priority 101(主端要比备端大点,但降低优先级后要比备端的优先级要小(priority的数减去降低的数要比备端的priority的数要小,for electing MASTER, highest priority wins,to be MASTER, make 50 more than other machines)
  advert_int 1(每隔多长时间发送一次通告信息,VRRP Advert interval, secs (use default))
  authentication {(发送的通告信息要认证,若认证失败就不接收,防止相同配置的机器自动加入或误加入这个集群中)
  auth_type PASS(PASS表示简单字符认证,PASS - Simple Passwd (suggested))
  auth_pass 1111
  }
  virtual_ipaddress {(VIP,设置格式可参考#mankeepalived.conf)
  192.168.41.222/32deveth0 labeleth0:0
}
  }
  virtual_server 192.168.41.222 80 {
  delay_loop 6(delay timer for service polling)
  lb_algo rr(LVS scheduler)
  lb_kind DR(LVS forwarding method)
  nat_mask 255.255.255.0
  persistence_timeout 50(LVS persistence timeout, sec)
  protocol TCP(Only TCP is implemented)
  real_server 192.168.41.133 80 {
  weight 1(relative weight to use, default: 1)
  HTTP_GET {(常用的有HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK)
  url {(检测一个RS,可同时检测多个url)
  path /(获取主页面)
  status_code 200(状态响应码,或用digest状态响应码的摘要码)
  }
  connect_timeout 3
  nb_get_retry 3(number of get retry)
  delay_before_retry 3
  }
  }
  real_server 192.168.41.134 80 {
  weight 1
  HTTP_GET {
  url {
  path /
  status_code 200
  }
  connect_timeout 3
  nb_get_retry 3
  delay_before_retry 3
  }
  }
  }
  # scp /etc/keepalived/keepalived.conf node2:/etc/keepalived/
  node2-side:
  # vim /etc/keepalived/keepalived.conf(仅需更改两项,其它均相同)
  state BACKUP
  priority 100
  node{3,4}-side:
  使用脚本开启相关设置:
  # vim rs.sh
  #!/bin/bash
  #use RS-side
  # chkconfig: - 90 10
  # description: LVS DR real server
  #
  . /etc/rc.d/init.d/functions
  VIP=192.168.41.222
  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
  ---------以上是script content----------
  # chmod 755 rs.sh
  # ./rs.sh start
  # service httpd start(node{3,4}准备不同的页面,分别是RS1.magedu.com和RS2.magedu.com)
  node{1,2}-side:
  # service keepalived start
  Starting keepalived:                                       
  # ipvsadm -L -n(可通过查看网卡的别名知道哪个node在提供调度,或查看日志#tail /var/log/messages,或查看邮件)
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port          Forward Weight ActiveConn InActConn
  TCP 192.168.41.222:80 rr persistent 50
  -> 192.168.41.133:80         Route   1      0         0
  -> 192.168.41.134:80         Route   1      0         0
  (2)测试:
  node5-side:
  # elinks -dump 192.168.41.222
  RS1.magedu.com
  node3-side:
  # service httpd stop
  Stopping httpd:                                          [ OK]
  node1-side:
  # ipvsadm -L -n(RS1上的服务停掉后,在前端director上就将出问题的RS-node剔除掉,服务若正常后则又会加回来)
  ……
  TCP 192.168.41.222:80 rr persistent 50
  -> 192.168.41.134:80         Route   1      0         1
  node5-side:
  # elinks -dump 192.168.41.222
  RS2.magedu.com
  node3-side:
  # service httpd start
  Starting httpd:                                          
  node1-side:
  # ipvsadm -L -n(再次查看时会提示有邮件,任意一个node故障到恢复都有邮件通知)
  ……
  TCP 192.168.41.222:80 rr persistent 50
  -> 192.168.41.133:80         Route   1      0         0
  -> 192.168.41.134:80         Route   1      0         0
  You have new mail in /var/spool/mail/root
  # mail
  ……
  N 13 keepalived@node1.magThu Dec 10 17:3613/550" Realserver 192.168.41.133:80 - DOWN"
  N 14keepalived@node1.magThu Dec 1017:4113/530   " Realserver192.168.41.133:80 - UP"
  (3)当后端所有RS挂掉,在director(node1,node2两个节点)上提供报错页面(事先启动httpd)
  node{1,2}-side:
  # vim /etc/keepalived/keepalived.conf
  virtual_server 192.168.41.222 80 {
  ……
sorry_server 127.0.0.1 80
  ……
  }
  # yum -y install httpd(安装并准备报错页面内容theserver is maintaing)
  # echo "the server is maintaining" > /var/www/html/index.html
  # service httpd start
  node{3,4}-side(将后端两个RS的服务停掉或模拟将网卡禁用):
  # service httpd stop
  Stopping httpd:                                          
  node{1,2}-side(前端两个director的keepalived服务重启):
  # service keepalived restart
  Stopping keepalived:                                       
  Starting keepalived:                                       
  You have new mail in /var/spool/mail/root
  # ipvsadm -L -n(已将本机的web服务添加进来)
  ……
  TCP192.168.41.222:80 rr persistent 50
  -> 127.0.0.1:80                Local   1      0         1
  node5-side(测试,后端RS全挂掉,正常跳转至当前director的报错页面):
  # elinks -dump 192.168.41.222
  the server is maintaining
  node{3,4}-side:测试完将这两个node的httpd服务开启,继续下面
  (4)自写脚本,完成维护模式切换(高可用的两个director切换)
  node{1,2}-side:
  # vim/etc/keepalived/keepalived.conf
  global_defs {
  ……
  }
  vrrp_script chk_schedown{
     script "[[ -e /etc/keepalived/down ]]&& exit 1 || exit 0"(引号内写要执行的语句,或者单独将语句放在一脚本文件中,引号内写脚本路径)
     interval 1(多长时间运行这个脚本一次)
     weight -5(脚本执行结果为0且weight值大于0,则优先级增加;脚本执行结果非0,且weight值小于0,则优先级减少;其它情况优先级均不变按原本配置的来;无论提高优先级还是降低优先级,范围总是在1-254之间,不会==255)
     fall 2(检测失败两次才认为失败,避免误伤)
     rise 1(检测1次成功则认为成功)
  }
  vrrp_instance VI_1 {
  ……
     track_script {(定义什么时候执行)
      chk_schedown
  }
  ……
  }
  node1-side:
  # ifconfig | grep -A 1 eth0:0(当前node1提供调度)
  eth0:0   Link encap:EthernetHWaddr00:0C:29:E5:92:E1
  inet addr:192.168.41.222 Bcast:0.0.0.0 Mask:255.255.255.255
  # touch /etc/keepalived/down
  # ifconfig | grep -A 1 eth0:0(查不到内容,由此可知director已切换至node2)
  node2-side:
  # ifconfig | grep -A 1 eth0:0(已在node2提供调度)
  eth0:0   Link encap:EthernetHWaddr00:0C:29:69:51:EC
  inet addr:192.168.41.222 Bcast:0.0.0.0 Mask:255.255.255.255
  node5-side:
  # elinks -dump 192.168.41.222(正常)
  RS1.magedu.com
  node{3,4}-side:将RS的httpd停掉,测试报错页面是否正常
  # elinks -dump 192.168.41.222(报错页面也正常)
  the server is maintaing
  (5)在vrrp事务发生时,发送警告邮件给指定的管理员
  node{1,2}-side:
  # cd /etc/keepalived
  # vim new_notify.sh
  #!/bin/bash
  #
  contact='root@localhost'
  Usage() {
  echo "Usage:`basename $0` master|backup|fault VIP"
  }
  Notify() {
  subject="`hostname`'s status changed to $1"
  mailbody="`date "+%F %T"`;`hostname`'s status changed to$1,$VIP floating"
  echo $mailbody | mail -s "$subject" $contact
  }
  [ $# -lt 2 ] && Usage &&exit
  VIP=$2
  case $1 in
  master)
  Notify master
  ;;
  backup)
  Notify backup
  ;;
  fault)
  Notify fault
  ;;
  *)
  Usage
  exit 1
  ;;
  esac
  # chmod 755 new_notify.sh
  # vim keepalived.conf
  ……
  vrrp_instance VI_1 {
  ……
     notify_master"/etc/keepalived/new_notify.sh master 192.168.41.222"
     notify_backup"/etc/keepalived/new_notify.sh backup 192.168.41.222"
     notify_fault"/etc/keepalived/new_notify.sh fault 192.168.41.222"
  }
  ……
  在node1-side测试查看:
  # rm -rf /etc/keepalived/down
  # ifconfig | grep -A 1 eth0:0
  eth0:0   Link encap:EthernetHWaddr00:0C:29:E5:92:E1
  inet addr:192.168.41.222 Bcast:0.0.0.0 Mask:255.255.255.255
  You have new mail in /var/spool/mail/root
  # mail
  ……
  N 10 root@node1.magedu.coFri Dec 18 12:1716/734"node1.magedu.com's status changed to master"
  & 10
  ……
  2015-12-18 12:17:56;node1.magedu.com'sstatus changed to master,192.168.41.222 floating
  在node2-side查看:
  # mail
  ……
  N8root@node2.magedu.coFri Dec 1812:1716/734   "node2.magedu.com's status changed to backup"
  & 8
  ……
  2015-12-18 12:17:54;node2.magedu.com'sstatus changed to backup,192.168.41.222 floating
  注:测试时注意确保sendmail服务正常,本次测试时由于时间问题sendmail服务重启提示来自未来的时间,一直收不到邮件
  (6)通过脚本完成,主备模型(在主备node转换时(vrrp发生事务时),重启或停止相关服务且以邮件形式通知管理员,例如master-->backup停止master的相关服务,backup-->master重启backup上的相关服务);主主模型(切换时均重启设置的相关服务)
  # vim notify.sh(此脚本属马哥所写,未作修改,不过确实好用)
  #!/bin/bash
  # Author: MageEdu
  # 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='linuxedu@foxmail.com'
  helpflag=0
  serviceflag=0
  modeflag=0
  addressflag=0
  notifyflag=0
  contact='root@localhost'
  Usage() {
  echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--serviceSERVICE1,...]"
  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
页: [1]
查看完整版本: V 7 keepalived