Keepalived是一个基于VRRP协议来实现的服务高可用方案,能够利用其来避免IP单点故障,相似的工具还有heartbeat、corosync、pacemaker。nginx
可是它通常不会单独出现,而是与其它负载均衡技术(如lvs、haproxy、nginx)一块儿工做来达到集群的高可用。web
Keepalived的做用是检测服务器的状态,若是有一台web服务器死机,或工做出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其余服务器代替该服务器的工做;当服务器工做正常后Keepalived自动将服务器加入到服务器群中,这些工做所有自动完成,不须要人工干涉,须要人工作的只是修复故障的服务器。shell
wget http://www.keepalived.org/software/keepalived-1.2.23.tar.gz #解压 tar -zxvf keepalived-1.2.23.tar.gz cd keepalived-1.2.23 #安装 ./configure --prefix=/usr/local/keepalived #prefix指定安装目录 make make install
#配置启动
cp keepalived/etc/init.d/keepalived.init /etc/init.d/keepalived
chmod +x /etc/init.d/keepalived
cp keepalived/etc/init.d/keepalived.sysconfig /etc/sysconfig/keepalived
cp keepalived/etc/keepalived/keepalived.conf /etc
keepalived.confbash
global_defs { notification_email { #指定keepalived在发生事情的时候,发送邮件告知,能够有多个地址,每行一个。 acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from root@firewall.loc #指定发件人 smtp_server 127.0.0.1 #发送email的smtp地址 smtp_connect_timeout 30 #超时时间 router_id LVS_DEVEL #运行keepalived的机器的一个标识,多个节点标识能够相同,也能够不一样 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER #指定当前节点为主节点 备用节点上设置为BACKUP便可 interface eth0 #绑定虚拟IP的网络接口 virtual_router_id 51 #VRRP组名,两个节点的设置必须同样,以指明各个节点属于同一VRRP组 priority 100 #主节点的优先级(1-254之间),备用节点必须比主节点优先级低 advert_int 1 authentication { #设置验证信息,两个节点必须一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { #指定虚拟IP, 两个节点设置必须同样 192.168.1.21/24 } }
service keepalived start|stop|restart
chkconfig keepalived on
验证虚拟ip 可以使用 ip addr 验证服务器
两种模式:网络
master服务器 keepalived.conf负载均衡
global_defs { notification_email { #指定keepalived在发生事情的时候,发送邮件告知,能够有多个地址,每行一个。 acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc #指定发件人 smtp_server 127.0.0.1 #发送email的smtp地址 smtp_connect_timeout 30 #超时时间 router_id LVS_DEVEL #运行keepalived的机器的一个标识,多个节点标识能够相同,也能够不一样 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER #指定当前节点为主节点 备用节点上设置为BACKUP便可 interface eth0 #绑定虚拟IP的网络接口 virtual_router_id 51 #VRRP组名,两个节点的设置必须同样,以指明各个节点属于同一VRRP组 priority 100 #主节点的优先级(1-254之间),备用节点必须比主节点优先级低 advert_int 1 authentication { #设置验证信息,两个节点必须一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { #指定虚拟IP, 两个节点设置必须同样 192.168.1.21/24 } }
Backup服务器 keepalived.conf工具
global_defs { notification_email { #指定keepalived在发生事情的时候,发送邮件告知,能够有多个地址,每行一个。 acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc #指定发件人 smtp_server 127.0.0.1 #发送email的smtp地址 smtp_connect_timeout 30 #超时时间 router_id LVS_DEVEL #运行keepalived的机器的一个标识,多个节点标识能够相同,也能够不一样 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state BACKUP #指定当前节点为主节点 备用节点上设置为BACKUP便可 interface eth0 #绑定虚拟IP的网络接口 virtual_router_id 51 #VRRP组名,两个节点的设置必须同样,以指明各个节点属于同一VRRP组 priority 99 #主节点的优先级(1-254之间),备用节点必须比主节点优先级低 advert_int 1 authentication { #设置验证信息,两个节点必须一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { #指定虚拟IP, 两个节点设置必须同样 192.168.1.21/24 } }
主备模式的缺点就是始终只有一台机器位于工做状态,另一台机器永远是备用状态,存在资源浪费之问题。测试
双主模式容许两台机器均处于工做状态并互相做为备份。搭建keepalived双主模式的要素:spa
master1配置文件keepalived.conf
global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc #指定发件人 smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 #本机两个vrrp_instance组的此值不能相同,但对应备用节点的此值必须相同 priority 100 #对应备用节点值应该比此值小 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.21/24 } } vrrp_instance VI_2 { state BACKUP interface eth0 virtual_router_id 52 #本机两个vrrp_instance组的此值不能相同,但对应备用节点的此值必须相同 priority 99 #主节点的值应该比此值大 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.22/24 } }
master2节点keepalived.conf
global_defs { notification_email { #指定keepalived在发生事情的时候,发送邮件告知,能够有多个地址,每行一个。 acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc #指定发件人 smtp_server 127.0.0.1 #发送email的smtp地址 smtp_connect_timeout 30 #超时时间 router_id LVS_DEVEL #运行keepalived的机器的一个标识,多个节点标识能够相同,也能够不一样 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 #本机两个vrrp_instance组的此值不能相同,但对应备用节点的此值必须相同 priority 99 #对应主节点值应该比此值大 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.21/24 } } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 #本机两个vrrp_instance组的此值不能相同,但对应备用节点的此值必须相同 priority 100 #对应备用节点的值应该比此值小 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.22/24 } }
两个节点实际都处于正常工做状态,可是没法接收到彼此的组播通知,这时两个节点均强行绑定虚拟IP,致使不可预料的后果。
这时就须要设置仲裁,即每一个节点必须判断自身的状态(应用服务状态及自身网络状态),要实现这两点可以使用自定义shell脚本实现,经过周期性地检查自身应用服务状态,并不断ping网关(或其它可靠的参考IP)都可。当自身服务异常、或没法ping通网关,则认为自身出现故障,就应该移除掉虚拟IP(中止keepalived服务便可)。
主要借助keepalived提供的vrrp_script及track_script实现:
在keepalived的配置文件最前面加入如下代码,定义一个跟踪脚本:
vrrp_script check_local { #定义一个名称为check_local的检查脚本 script "/usr/local/keepalived/bin/check_local.sh" #shell脚本的路径 interval 5 #运行间隔 }
再在vrrp_instance配置中加入如下代码使用上面定义的检测脚本:
track_script {
check_local
}
咱们在/usr/local/keepalived/bin/check_local.sh定义的检测规则是:
但这里有个小问题,若是本机或是网关偶尔出现一次故障,那么咱们不能认为是服务故障。更好的作法是若是连续N次检测本机服务不正常或链接N次没法ping通网关,才认为是故障产生,才须要进行故障转移。
但这么作的缺点是,若是脚本检测到故障产生,并中止掉了keepalived服务,那么当故障恢复后,keepalived是没法自动恢复的。
还能够利用独立的脚本以秒级的间隔检查自身服务及网关链接性,再根据故障状况控制keepalived的运行或是中止。
在每一个节点运行shell脚本(check_service.sh)检测本机的服务是否正常,一旦检测到服务异常时,中止掉本机的keepalived, 如此虚拟IP自动转移到备用机器之上,如每隔3秒检测一次本机服务状态,若是链接3次检测失败,则中止掉keepalived实例。同时若是本机服务是正常的,可是keepalived没有启动(故障恢复以后),则启动keepalived,以达到故障恢复之目的。
check_service.sh文件的内容
#!/bin/bash pidfile=/var/lock/subsys/`basename $0`.pid if [ -f $pidfile ] && [ -e /proc/`cat $pidfile` ] ; then exit 1 fi trap "rm -fr $pidfile ; exit 0" 1 2 3 15 echo $$ > $pidfile maxfails=3 fails=0 success=0 while [ 1 ] do /usr/bin/wget --timeout=3 --tries=1 http://127.0.0.1/ -q -O /dev/null if [ $? -ne 0 ] ; then let fails=$[$fails+1] success=0 else fails=0 let success=$[$success+1] fi if [ $fails -ge $maxfails ] ; then fails=0 success=0 #check keepalived is running ? try to stop it service keepalived status | grep running if [ $? -eq 0 ] ; then logger -is "local service fails $maxfails times ... try to stop keepalived." service keepalived stop 2>&1 | logger fi fi if [ $success -gt $maxfails ] ; then #check keepalived is stopped ? try to start it service keepalived status | grep stopped if [ $? -eq 0 ] ; then logger -is "service changes normal, try to start keepalived ." service keepalived start fi success=0 fi sleep 3 done
两个节点上均应运行此脚本,请将此脚本加入到cron任务中(此程序已经做了单实例运行机制,加入计划任务的做用就是防止脚本意外中断后检测功能失效),可实现的功能:
执行crontab -e , 加入如下内容:
*/1 * * * * /root/check_service.sh
测试