keepalived

一、keepalived基础

1.1 HA实现

上述演示中,不管是lvs-nat还是lvs-nat模型,都会有2个遗留问题:

(1) 如果调度器服务器挂了,如何对调度器做高可用

(2) 如果RS中某台服务器挂了,如何对RS做集群的健探测

健康监测的方式有很多种,比如网络层可以使用icmp ping监测主机的存活状态,传输层可以使用tcp端口监测工具探测端口的可用性,比如nmap,应用层,比如可以对关键服务发起请求。

而实现高可用的方案一般有2种,一种是vrrp协议的实现,比如keepalived,一种是ais的实现方案,比如heartbeat, corosync, pacemaker。其中ais是非常完备,非常重量级的实现。

首先,这里以非常简单的方式描述下ais方案,首先假设这样一种场景,由多台服务器提供相同的服务,比如是httpd服务,此时集群中每台机器需要知道对方的生存状况,比如机器A持续的向其他机器发送信息表示自己存活(假如连续3次失败则会被判定为非存活状态),这种方式被称为心跳检测,但是可能会有这样一种网络原因造成的故障,A认为自己是存活的,但是信息没有成功被其他服务器接收,比如B和C都认为A是非存活状态,此时会造成分裂现象,解决这个问题需要一个仲裁方案,比如最简单的少数服从多数原则,这也是一般推荐奇数台机器构建集群的原因,有时候只有2台,可以使用比如网关服务器当观察者凑够3台也可以,总之必须有一个仲裁机制。假设此时多数的认为机器B可以当做Master向外提供服务,需要一个机制可以停止掉机器A的服务,并且剥夺他的ip使用权,最简单的方式,就是停掉A,然后在机器B上配置的接口上配置一个别名。而实际上ais的实现非常复杂,分为三层,最底层是集群事务层,还有资源管理层和资源代理层,它是一个非常完备的实现,基本上可以满足一切的高可用方案,后面会详细介绍。

这里我们关注的是vrrp协议,,Virtual Redundant Routing Protocol,vrrp协议是非常老的一个协议,是一个虚拟的路由器协议,而keepalived则是vrrp协议的实现。

1.2 VRRP与keepalived

关于VRRP的协议详情可以参考华为等公司一些vrrp协议白皮书,因为vrrp协议原本就是用来做虚拟路由之类的。

VRRP中术语说明:

  • 虚拟路由器:由一个Master路由器和多个Backup组成。主机将虚拟路由器当做默认网关。
  • VRID:虚拟路由器的标识
  • Master路由器:虚拟路由器中承担报文转发任务的路由器。
  • Backup路由器:Master路由器出现故障时,能够代替Master路由器工作的路由器。
  • 虚拟IP地址:虚拟路由器的IP地址。一个虚拟路由器可以有一个或者多个IP地址
  • IP地址拥有者:接口IP地址和虚拟IP地址相同的路由器被称为IP地址拥有者。
  • 虚拟MAC地址:一个虚拟路由器拥有一个虚拟MAC地址。虚拟MAC地址的格式为00-00-5E-00-01-{VRID}。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址。
  • 优先级:VRRP根据优先级来确定虚拟路由器中每台路由器的地位。
  •  抢占模式:在抢占模式下,如果Backup设备的优先级更高,则自己主动自己切换成Master
  • 非抢占模式:在非抢占式模式下,只要Master设备没有出现故障,Backup设备即使随后被配置了更高的优先级,也不会成为Master设备

VRRP的工作过程:

(1) 虚拟路由器根据优先级选举Master。Master通过发送免费ARP报文,将自己的虚拟MAC地址通知给与它连接的设备或者主机,从而承担报文转发任务。

(2) Master路由器周期性发送VRRP报文,以公布其配置信息和工作状态

(3)如果Master出现故障,根据优先级从Backup中选举

(4)虚拟路由器状态切换时,Master路由器由一台设备切换为另一台,新的Master路由器只是简单地发送一个携带虚拟路由器的MAC地址和虚拟IP地址信息的免费ARP报文,这样就可以更新与它相连接的主机或者设备中的ARP相关信息。网络上的主机感知不到Master路由器已经切换为另外一个台设备

(5)Backup路由器的优先级高于Master时,根据工作方式决定是否重新选举

 

VRRP的工作模式

  • 主备模式,一台Master,多台为Backup
  • 主/主模式,其实是互为主备模式

 

keepalived

 

keepalived作为vrrp协议的实现,设计目的是为了高可用ipvs服务器,他能够在配置文件定义ipvs规则,并能对RS的健康状态进行探测;vrrp_script,vrrp_track

keepalivedz中包含多个组件:

  控制组件:配置文件分析器

  内存管理

  IO复用

  核心组件

  vrrp stack

  checker

  ipvs wrapper

  watch dog

 

HA集群配置的前提,一般Linux都需要以下配置

(1)各节点时间同步,Centos上可以基于ntp协议,Centos7上可以是chrony

(2)确保iptables以及selinux不会阻碍;

(3)各节点之间通过主机名互相铜线,即名称解析服务器的解析结果必须和"uname -n"命令的结果一致;

(4)各个节点之root用户基于密钥认证的ssh通信;

yum -y install keepalived

同步下时间:

ntpdate time.windows.com 

hwclock -w 

二、 keepalived配置文件说明

通过命令rpm -qc keepalived发现配置文件只需要关注keepalived.conf即可,详情使用man keepalived.conf观察,下面简要说明一下,Keepavlived分为多个配置段,global配置段,vppr配置段,lvs配置段

global_defs:定义全局配置

global_defs {
   notification_email {
        root@localhost
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ysz202
   vrrp_mcast_group4 224.0.100.18
}

说明

  • root@localhost直接使用本地用户当做收件地址
  • router_id可以使用主机名
  • vrrp_mcast_group4表示的ipv4协议下的组播地址,举个例子,因为集群中的心跳通信用单播每个服务器都要单独发送,用广播会给局域网内所有的服务器都发送信息,因此此处使用组播,向拥有同一组播地址的服务器发送心跳信息比较合适。


vrrp_instance : vrrp实例配置

定义一个虚拟路由实例

state MASTER|BACKUP:在当前VRRP实例中此节点的初始状态;
interface IFACE_NAME:vrrp用于绑定vip的接口;
virtual_router_id #:当前VRRP实例的VRID,可用范围为0-255,默认为51;
priority #:当前节点的优先级,可用范围0-255;
advert_int 1:通告时间间隔;
authentication { #认证机制
  # PASS||AH
  # PASS - Simple Passwd (suggested)
  # AH - IPSEC (not recommended))
  auth_type PASS
  # Password for accessing vrrpd.
  # should be the same for all machines.
  # Only the first eight (8) characters are used.
  auth_pass 1234
}

# 最关键的。定义vip
virtual_ipaddress {
  <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>

  192.168.200.17/24 dev eth1

  192.168.200.18.24 dev eth2 label eth2:1

}

# 一个主机上可能有多个接口,定义要监控的接口

trace_interface {

  eth0

  eth1

  ...

}  

nopreempt #非抢占模式,默认是抢占模式,如果2个服务器性能有优劣之别,可以抢占..

#通告脚本定义

notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"

 

其中的脚本notify.sh可以大致如下

#!/bin/bash
#
contact='root@localhost'
notify() {
        subject="$(hostname) to be $1 :vip floating"
        body="$(date +'%F %T'): vrrp transition, $(hostname) change to be $1"
        echo $body | mail -s "$subject" $contact
}

case $1 in
        master)
                notify master
                ;;
        backup)
                notify backup
                ;;
        fault)
                notify fault
                ;;
        *)
                echo "Usage:$(basename $0) {master|backup|fault}"
                ;;
esac

 virtual_server : 虚拟服务器

功能描述:

f
virtual server IP port或者vitual server FWM #

virtual_server 192.168.200.100 443 {
    delay_loop 6 #
    lb_algo rr #负载均衡调度算法
    lb_kind NAT #调度类型
    nat_mask 255.255.255.0 #
    persistence_timeout 50 #持久连接时长
    protocol TCP #只支持TCP协议
    # quality regression. Defaults to 1.
    quorum 1
   sorry_server 192.168.1.202 80
    real_server 192.168.201.100 443 {
        weight 1
        #notify_up <STRING>|<QUOTED-STRING>
        #notify_down <STRING>|<QUOTED-STRING>
         
        #应用层检测
        SSL_GET {
            url {
                  path /
                  digest ff20ad2481f97b1754ef3e12ecd3a9cc #特征码
            }
            url {
                  path /mrtg/
                  status_code 200 #基于状态码判定
            }
            connect_timeout 3 #连接的超时时长
            nb_get_retry 3 #连接的重试次数
            delay_before_retry 3 #连接的重试间隔
            
        }
    }
}

总结:

  如果只是需要vip服务,可以只配置vrrp实例,如果需要keepalived来帮助完成lvs负载均衡才需要配置Vitual Server

 vrrp_script和track_script

vrrp_script: 资源脚本

track_script: 调用vrrp_script脚本去监控资源;

vrrp_script chk_httpd {
   script "killall -0 httpd"
   interval 2
   weight -5
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 98
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0
    }
    track_script {
        chk_httpd
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

说明:上述配置中命令killall -0 httpd 用来检测当前httpd进程是否存活,假如没有的话返回失败,当前服务器的优先级会降低,在抢占工作模式下由Master->Backup实现地址漂移,这种方式可以为任何服务做高可用,比如说这里的httpd可以改成Nginx。

 

三、使用keepalived+lvs集群httpd

设计如下:

ysz211(192.168.1.211)和ysz214(192.168.1.214)作为VS提供ipvsadm服务,使用keepalived做ha实现高可用,虚拟ip为192.168.1.204在ysz211和ysz214上地址漂移

ysz212(192.168.1.212)和ysz213(192.168.1.213)作为RS提供httpd服务

第一步,ysz211和ysz214安装ipvsadm

yum install ipvsadm
yum install keepalived

keepalived的配置文件keepalived.conf大致如下:

ysz211为MASTER,ysz214为BACKUP,另外一台只需要将state设置为BACKUP且优先级调低为98即可

global_defs {
   notification_email {
        root@localhost
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_mcast_group4 224.0.100.18
}

vrrp_instance VI_1 {
    state MASTER
    interface eno16777736
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    192.168.1.204 dev eno16777736 label eno16777736:0
    }
}
virtual_server 192.168.1.204 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP
    
    real_server 192.168.1.212 80 {
        weight 1
        HTTP_GET {
            url {
                  path /
                  status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    
    real_server 192.168.1.213 80 {
        weight 1
        HTTP_GET {
            url {
                  path /
                  status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

第二步 ysz212和ysz213启动httpd服务

第三步 ysz211启动keepalived

使用tail -f /var/log/messages发现成功启动,信息如下:

Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Configuration is using : 17026 Bytes
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Using LinkWatch kernel netlink reflector...
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Activating healthchecker for service [192.168.1.212]:80
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Activating healthchecker for service [192.168.1.213]:80
Nov 14 21:38:06 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Transition to MASTER STATE
Nov 14 21:38:07 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Entering MASTER STATE
Nov 14 21:38:07 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) setting protocol VIPs.
Nov 14 21:38:07 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eno16777736 for 192.168.1.204
Nov 14 21:38:07 www Keepalived_healthcheckers[5180]: Netlink reflector reports IP 192.168.1.204 added
Nov 14 21:38:12 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eno16777736 for 192.168.1.204

且ipvsadm也成功启动,截图如下

第四步,ysz214上启动备用keepalived

搭建成功,可以模拟ysz211 keepalived 故障和ysz213 httpd服务故障,对外服务均可用,从而同时实现了负载均衡和高可用的目的。

四、演示:使用keepalived完成双主模型

双主模型实际上也是主备模型,2个实例互为主备,比如一个httpd服务,一个nginx服务,尽可能减少资源浪费,注意下面是2个不同的ip地址,因此还可以在DNS解析服务器上再做一次负载均衡,使得请求分散到2个ip中,使得前端2个调度器都不会空闲。

ysz202配置文件

global_defs {
   notification_email {
    root@localhost
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ysz202
   vrrp_mcast_group4 224.0.100.18
}

vrrp_script chk_httpd {
   script "killall -0 httpd"
   interval 2
   weight -5
}

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.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0
    }
    track_script {
    chk_httpd
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

vrrp_instance VI_2 {
    state BACKUP
    interface eth0
    virtual_router_id 52
    priority 98
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.112/32 brd 192.168.1.111 dev eth0 label eth0:1
    }
    track_script {
    chk_httpd
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

 

ysz204上配置文件

global_defs {
   notification_email {
    root@localhost
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ysz202
   vrrp_mcast_group4 224.0.100.18
}

vrrp_script chk_httpd {
   script "killall -0 httpd"
   interval 2
   weight -5
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 98
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0
    }
    track_script {
    chk_httpd
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

vrrp_instance VI_2 {
    state MASTER
    interface eth0
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.112/32 brd 192.168.1.111 dev eth0 label eth0:1
    }
    track_script {
    chk_httpd
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

 

posted @ 2016-10-12 00:37  carl_ysz  阅读(1863)  评论(0编辑  收藏  举报