keepalived+nginx实现高可用负载均衡

集群 struggling 2211次浏览 0个评论

一,keepalived简介

keepalived

keepalived是集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障。keepalived起初是专为 LVS设计的,专门用来监控集群系统中各个服务节点的状态。后来又加入了VRRP(Virtual Router Redundancy Protocol)功能。

VRRP协议是用于实现路由器冗余的协议,VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个),而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,或者是通过算法选举产生,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等;其他设备不拥有该IP,状态是BACKUP,除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。

VRRP的优势:

<code>
冗余:可以使用多个路由器设备作为LAN客户端的默认网关,大大降低了默认网关成为单点故障的可能性;

负载共享:允许来自LAN客户端的流量由多个路由器设备所共享;

多VRRP组:在一个路由器物理接口上可配置多达255个VRRP组;

多IP地址:基于接口别名在同一个物理接口上配置多个IP地址,从而支持在同一个物理接口上接入多个子网;

抢占:在master故障时允许优先级更高的backup成为master;

通告协议:使用IANA所指定的组播地址224.0.0.18进行VRRP通告;

VRRP追踪:基于接口状态来改变其VRRP优先级来确定最佳的VRRP路由器成为master;
</code>

VRRP分为主从模式和双主模式。

二,实现keepalived+nginx高可用

<code>
规划:

环境: CentOS 6.6  32位

Master:192.168.1.111   

Backup:192.168.1.112  

nginx1:192.168.1.113

nginx2:192.168.1.114  

VIP1:192.168.1.88
:
VIP2:192.168.1.99
</code>

首先配置好双机互信,使用hosts文件进行解析,时间同步!

<code>

[root@node1 ~]# yum install keepalived -y   #直接使用yum源进行安装,两个节点都要安装

[root@node1 keepalived]# vim keepalived.conf    #修改配置文件,以下先测试keepalived
global_defs {
   notification_email {
        root@localhost      ----->故障发生时给谁发邮件通知,此处使用本机
   }
   notification_email_from  keepalived@localhost
   smtp_server 127.0.0.1          ----------->通知邮件的smtp地址
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_script chk_maintainace {
        script "[[ -e /etc/keepalived/down ]] && exit 1 || exit 0"     #定义监控脚本,script  可以是脚本路径也可以是定义的脚本
        interval 1         ----------->每隔1秒检测一次
        weight -2        ----------->权重减2
}
vrrp_instance VI_1 {
    state MASTER       ----------->本机所处状态
    interface eth1
    virtual_router_id 51
    priority 100      ------->权重
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.88
    }
    track_script {
        chk_maintainace      #必须要追踪脚本chk_mantaince_down
    }
}
</code>

配置文件中其他的先注释掉,在末行模式下,使用“ :.,$s/^/#”。

注意:

1、上面的state为当前节点的起始状态,通常在master/slave的双节点模型中,其一个默认为MASTER,而别一个默认为BACKUP。

2、priority为当关节点在当前虚拟路由器中的优先级,master的优先级应该大于slave的;

复制配置文件到节点2,在节点2中将配置文件作以下修改:

<code>
[root@node2 keepalived]# vim keepalived.conf   #只需修改以下两处
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_script chk_maintainace {
        script "[[ -e /etc/keepalived/down ]] && exit 1 || exit 0"     
        interval 1
        weight -2
}
vrrp_instance VI_1 {
    state BACKUP      ---------->修改为BACKUP
    interface eth1       ---------->定义网卡
    virtual_router_id 51
    priority 99      ------->权重要小于MASTER
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.88
    }
    track_script {
        chk_maintainace    
    }
}
</code>

说明:chk_maintainace 脚本得含义是当检测到/etc/keepalived/下有down文件时,权重减2,此时MASTER节点的权重变为98小于BACKUP的99权重,服务会移动到BACKUP节点,删除down文件后,权重又会变为100,服务又会移动到MASTER节点。

keepalived的所有配置都在一个配置文件里,但是所有的配置分为3大部分,包括这几个配置区域,分别是global_defs、static_ipaddress、static_routes、vrrp_script、vrrp_instance和virtual_server。

1、全局配置(Global Configuration)

全局配置是对整个keepalived都起效的配置。

2、VRRPD配置

VRRPD配置是keepalived的核心配置

3、LVS配置

只有当使用keepalived来配置和管理LVS,才需要配置LVS这部分。否则,如果使用keepalived来做HA,LVS的配置完全不需要。

keepalived配置文件详解:

<code>
notify_master/backup/fault 分别表示切换为主/备/出错时所执行的脚本。

notify 表示任何一状态切换时都会调用该脚本,并且该脚本在以上三个脚本执行完成之后进行调用,keepalived会自动传递三个参数($1 = "GROUP"|"INSTANCE",$2 = name of group or instance,$3 = target state of transition(MASTER/BACKUP/FAULT))。

smtp_alert 表示是否开启邮件通知(用全局区域的邮件设置来发通知)。

state 可以是MASTER或BACKUP,不过当其他节点keepalived启动时会将priority比较大的节点选举为MASTER,因此该项其实没有实质用途。

interface 节点固有IP(非VIP)的网卡,用来发VRRP包。

use_vmac 是否使用VRRP的虚拟MAC地址。

dont_track_primary 忽略VRRP网卡错误。(默认未设置)

track_interface 监控以下网卡,如果任何一个不通就会切换到FALT状态。(可选项)

mcast_src_ip 修改vrrp组播包的源地址,默认源地址为master的IP。(由于是组播,因此即使修改了源地址,该master还是能收到回应的)

lvs_sync_daemon_interface 绑定lvs syncd的网卡。

garp_master_delay 当切为主状态后多久更新ARP缓存,默认5秒。

virtual_router_id 取值在0-255之间,用来区分多个instance的VRRP组播。

priority 用来选举master的,要成为master,那么这个选项的值最好高于其他机器50个点,该项取值范围是1-255(在此范围之外会被识别成默认值100)。

advert_int 发VRRP包的时间间隔,即多久进行一次master选举(可以认为是健康查检时间间隔)。

authentication 认证区域,认证类型有PASS和HA(IPSEC),推荐使用PASS(密码只识别前8位)。

virtual_ipaddress vip,不解释了。

virtual_routes 虚拟路由,当IP漂过来之后需要添加的路由信息。

virtual_ipaddress_excluded 发送的VRRP包里不包含的IP地址,为减少回应VRRP包的个数。在网卡上绑定的IP地址比较多的时候用。

nopreempt 允许一个priority比较低的节点作为master,即使有priority更高的节点启动。

delay_loop 延迟轮询时间(单位秒)。

lb_algo 后端调试算法(load balancing algorithm)。

lb_kind LVS调度类型NAT/DR/TUN。

virtualhost 用来给HTTP_GET和SSL_GET配置请求header的。

sorry_server 当所有real server全都宕掉时,sorry server顶替,可以讲sorry server定义为本机。

real_server 真正提供服务的服务器。

weight 权重。

notify_up/down 当real server宕掉或启动时执行的脚本。

健康检查的方式,N多种方式。

path 请求real serserver上的路径。

digest/status_code 分别表示用genhash算出的结果和http状态码。

connect_port 健康检查,如果端口通则认为服务器正常。

connect_timeout,nb_get_retry,delay_before_retry分别表示超时时长、重试次数,下次重试的时间延迟。

[root@node1 keepalived]# service keepalived  start   #启动两个节点的服务

[root@node1 keepalived]# ssh node2 'service keepalived  start'
</code>

在日志文件中查看是否启动成功:

<code>
[root@node1 keepalived]# tail /var/log/messages   
Aug 27 20:34:21 node1 Keepalived_vrrp[8827]: VRRP_Instance(VI_1) Transition to MASTER STATE
Aug 27 20:34:22 node1 Keepalived_vrrp[8827]: VRRP_Instance(VI_1) Entering MASTER STATE
Aug 27 20:34:22 node1 Keepalived_vrrp[8827]: VRRP_Instance(VI_1) setting protocol VIPs.
Aug 27 20:34:22 node1 Keepalived_vrrp[8827]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth1 for 192.168.1.88
Aug 27 20:34:22 node1 Keepalived_healthcheckers[8826]: Netlink reflector reports IP 192.168.1.88 added
Aug 27 20:34:27 node1 Keepalived_vrrp[8827]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth1 for 192.168.1.88

[root@node1 keepalived]# ip  addr  show   #查看VIP
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: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:3c:59:f9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.111/24 brd 192.168.1.255 scope global eth1
    inet 192.168.1.88/32 scope global eth1                    ------->此处为VIP
    inet6 fe80::20c:29ff:fe3c:59f9/64 scope link 
       valid_lft forever preferred_lft forever
</code>

然后在/etc/keepalived/下创建down文件后,服务会转移到BACKUP节点,删除down文件后,服务又会转移回来的,说明已经测试成功了!

然后配置nginx,首先在192.168.1.113和192.168.1.114上上安装nginx:

<code>
[root@node3 nginx]# rpm -ibh nginx-1.8.0-1.gf.el6.i686.rpm

[root@node1 keepalived]# vim keepalived.conf  #修改配置文件
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 {
    state MASTER          
    interface eth1          
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.88       
    }
}

vrrp_script chk_nginx {        #删除之前定义的测试脚本,添加nginx检测脚本
        script "killall -0 nginx "   ----->监控nginx是否在线,此方法是所有方法中资源消耗最少的
        interval 1
        weight -2
        fall 2              ---------->失败检测次数
        raise 1           ----------->成功检测次数
}
vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.88
    }
    track_script {       
        chk_nginx          ----------->检测nginx脚本
    }
    notify_master "/etc/keepalived/notify.sh master"      #定义在状态转移时进行通知
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

virtual_server 192.168.1.88 80 {            #定义virtual server
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.0.0
    persistence_timeout 0
   protocol TCP

    real_server 192.168.1.113 80 {      #real server1
        weight 1
        HTTP_GET {                       #使用HTTP_GET检测,也可以使用TCP_CHECK检测
            url {
              path /
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 192.168.1.114 80 {      #real server2
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

[root@node1 keepalived]# vim notify.sh     # notify脚本
#!/bin/bash
# Author: MageEdu <linuxedu@foxmail.com>
# description: An example of notify script
# 

vip=192.168.1.88
contact='root@localhost'

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
}

case "$1" in
    master)
        notify master
        /etc/init.d/nginx  start
        exit 0
    ;;
    backup)
        notify backup
        /etc/init.d/nginx  stop
        exit 0
    ;;
    fault)
        notify fault
        /etc/init.d/nginx  stop
        exit 0
    ;;
    *)
        echo 'Usage: `basename $0` {master|backup|fault}'
        exit 1
    ;;
esac

</code>

将配置文件及脚本复制到node2,并修改配置文件如上所述的,修改state 为BACKUP,priority 为99.

<code>
[root@node1 keepalived]# service keepalived  restart   #重新启动两个节点的服务

[root@node1 keepalived]# ssh node2 'service keepalived  restart'

[root@node1 keepalived]# ss -tln |grep  80    #查看服务是否启动
LISTEN     0      128                       *:80                       *:*  
</code>

关闭master节点的nginx服务后,服务将转移到BACKUP节点,说明测试成功!

三,实现基于虚拟路由的 master/master 模型

master/master 模型就是使用两个VRRP,两个中都定义一个主服务器,但都分别为另一个的从服务器,此设置要基于DNS实现,在DNS中要添加两条A记录,分别指向两个VRRP!

此步只需要再定一个vrrp_instance ,在配置文件中添加以下配置:

<code>
[root@node1 keepalived]# vim keepalived.conf

vrrp_instance VI_2 {
    state BACKUP              #VI_1为MASTER,则此处为BACKUP
    interface eth1
    virtual_router_id 55     #修改id,不能与VI_1相同
    priority 99                   #权重要小于VI_1
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 2111     ------->修改此处
    }
    virtual_ipaddress {
        192.168.1.99       ---------->再定义一个virtual_ipaddress
    }
    track_script {
        chk_nginx
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
</code>

将此配置添加到node2的配置文件中,并作如下修改:

<code>
vrrp_instance VI_2 {
    state MASTER     #此处为MASTER
    interface eth1
    virtual_router_id 55   
    priority 100      #权重大于VI_1
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 2111
    }
    virtual_ipaddress {
        192.168.1.99
    }
    track_script {
        chk_maintainace
        chk_nginx
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
</code>
<code>
[root@node1 keepalived]# service keepalived  restart   #重新启动两个节点的服务

[root@node1 keepalived]# ssh node2 'service keepalived  restart'

[root@node1 keepalived]# ip  addr  show    #node1
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: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:3c:59:f9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.111/24 brd 192.168.1.255 scope global eth1
    inet 192.168.1.88/32 scope global eth1                            --------->VIP1
    inet6 fe80::20c:29ff:fe3c:59f9/64 scope link 
       valid_lft forever preferred_lft forever

[root@node2 keepalived]# ip  addr  show   #node2
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: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:3c:59:f9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.111/24 brd 192.168.1.255 scope global eth1
    inet 192.168.1.99/32 scope global eth1                          --------->VIP2
    inet6 fe80::20c:29ff:fe3c:59f9/64 scope link 
       valid_lft forever preferred_lft forever
</code>




DevOps-田飞雨 》》转载请注明源地址
喜欢 (0)or分享 (0)
发表我的评论
取消评论
*

表情 贴图 加粗 链接 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址