目录

keepalived

将一个虚拟的ip映射到2多台服务器上。服务器有主之分,当主服务器宕机时,备用服务器会选举出一个替代主服务器(接替那个虚拟ip)。用于服务器的冗余。

VRRP全称 Virtual Router Redundancy Protocol,即 虚拟路由冗余协议。可以认为它是实现路由器高可用的容错协议,即将N台提供相同功能的路由器组成一个路由器组(Router Group),这个组里面有一个master和多个backup,但在外界看来就像一台一样,构成虚拟路由器,拥有一个虚拟IP(vip,也就是路由器所在局域网内其他机器的默认路由),占有这个IP的master实际负责ARP相应和转发IP数据包,组中的其它路由器作为备份的角色处于待命状态。master会发组播消息,当backup在超时时间内收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master,保证路由器的高可用。

keepalived 常常跟lvs,nginx一起用。lvs用于做主机的负载均衡,keepalived用于做lvs的冗余。

安装

配置

如果只用lvs的话,这份配置文件已经够用了

global_defs {
   notification_email {
     qiang.fang@xxx.cn
   }
   notification_email_from qiang.fang@xxx.cn
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER   # 备是 BACKUP
    # nopreempt    # 如果backup现在是master,虽然我优先级高,但也不去强master
    interface eth0
    virtual_router_id 51 #该实例属于哪个VRRP组,主,备 这个字段要一致
    priority 100    # 主的要比备的高
    advert_int 1
    authentication {
        auth_type PASS  #主,备 这个字段要一致
        auth_pass 1111  #主,备 这个字段要一致
    }
    virtual_ipaddress {
        10.211.55.200/24 dev eth0 label eth0:0  #要虚拟的ip以及要绑定的网卡
    }
}

这是主配置文件,备用lvs的keepalived,只需要将state MASTER 改为state BACKUP,降低priority 100 的值

测试:当主keepalived被kill时,备keepalived会接替vip继续服务

高级用法

禁止抢占

通常情况下,利用keepalived做热备,其中一台设置为master,一台设置为backup。当master出现异常后,backup自动切换为master。当backup成为master后,master恢复正常后会再次抢占成为master,导致不必要的主备切换。

我们可以这么做

脚本检测

然而keepalived只能做到对网络故障和keepalived本身的监控,即当出现网络故障或者keepalived本身出现问题时,进行切换。但是这些还不够,我们还需要监控keepalived所在服务器上的其他业务进程,根据业务进程的运行状态决定是否需要进行主备切换。这个时候,我们可以通过编写脚本对业务进程进行检测监控

使用脚本配置

global_defs {
   notification_email {
     qiang.fang@tongdun.cn
   }
   notification_email_from qiang.fang@tongdun.cn
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}
vrrp_script checkhaproxy   # checkhaproxy 为脚本名称
{
    script "/home/hadoop/check.sh"  # 脚本功能为,当出现特定情况,重启keepalived。
                                    # 非抢占模式下,每重启一次,vip就会切换,非常实用
    interval 3  # 每3秒执行一次脚本
}

vrrp_instance VI_1 {
    state BACKUP  #  建议使用非抢占模式(主,被都设置成BACKUP,且优先级高的设置nopreempt)
    nopreempt     #  即使自己的优先级高,也不去抢占其他机器的master
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.211.55.200/24 dev eth0 label eth0:0
    }
    track_script
    {
        checkhaproxy  # 调用checkhaproxy脚本
    }
}
global_defs {
   notification_email {
     qiang.fang@tongdun.cn
   }
   notification_email_from qiang.fang@tongdun.cn
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}
vrrp_script checkhaproxy
{
    script "/home/hadoop/check.sh"
    interval 3
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0              # 和主配置相比,少了nopreempt
    virtual_router_id 51
    priority 99                 # 和主配置相比,优先级低,其他配置都一样
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.211.55.200/24 dev eth0 label eth0:0
    }
    track_script
    {
        checkhaproxy
    }
}

keepalived + LVS配置

global_defs {
   notification_email {
     acassen@firewall.loc # 发生故障时发送的邮箱
     failover@firewall.loc 
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc # 使用哪个邮箱发送
   smtp_server 192.168.200.1 # 发件服务器
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER # 标示为主lvs
    interface eth2 # HA检测接口
    virtual_router_id 53  #主,备 这个字段要一致,这里不要使用默认值(默认值是51),
#如果默认值,日志会报一个警告:receive an invalid ip number count associated with VRID!
    priority 100 # 优先级,备lvs要比主lvs小
    advert_int 1 # VRRP Multicast 广播周期秒数
    authentication {
        auth_type PASS  # 认证方式为口令认证(主备一致)
        auth_pass 1111  # 定义口令(主备一致)
    }
    virtual_ipaddress {
        10.0.1.250 # 多个vip可换行添加
    }
}
virtual_server 10.0.1.250 80 {
    delay_loop 6 # 每隔6秒查看realserver状态
    lb_algo wrr  # 调度算法为加权轮寻
    lb_kind DR # lvs工作模式为DR(直接路由)模式
    nat_mask 255.255.255.255
    persistence_timeout 0 # 同一IP 的连接x秒内被分配到同一台realserver(测试时建议改为0)
    protocol TCP
    real_server 10.0.2.178 80 {
        weight 1 # 定义权重
        TCP_CHECK {
        connect_timeout 8 # 8秒无响应超时
        nb_get_retry 3 
        delay_before_retry 3
        connect_port 80
        }
    }
    real_server 10.0.1.179 80 {
        weight 1
        TCP_CHECK {
        connect_timeout 8
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
}