Nginx+Keepalived实现站点高可用
Keepalived是以VRRP协议为实现基础的集群高可用方案,因此在介绍keepalived之前,因此在介绍keepalived之前,有必要先了解VRRP的原理。
VRRP介绍
VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。可以认为它是实现路由器高可用的容错协议。即将N台提供相同功能的路由器组成一个路由器组(Router Group),这个组里面有一个master和多个backup,但是在外界看来就像一台一样,构成虚拟路由器拥有一个虚拟IP(vip,也就是路由器所在局域网内其他机器的默认路由)。占有这个IP的master实际负责ARP响应和转发IP数据包,组中的其他路由器作为备份的角色处于待命状态。master会发组播消息在(组播地址:224.0.0.18),当backup在超时时间内收不到vrrp包时就认为master宕机了,组中的其他处于待命状态的备份服务器会根据vrrp的优先级来选举出一个backup服务器来当master,保证路由器的高可用。
在VRRP协议实现里,虚拟路由器使用的是一个周知的MAC地址:00-00-5E-00-01-{VIRD}。所以在一个虚拟路由器中,不管谁是master,对外都是相同的MAC和IP(VIP)。 每个Router都有一个1-255之间的优先级别,级别最高的将成为master路由器。通过降低master的优先权可以让处于backup状态的路由器抢占为主路由的状态,两个backup优先级相同的IP地址较大者为master,接管虚拟IP。
keepalived可以认为是VRRP协议在linux上的实现,主要有三个模块,分别是core、check和vrrp。
core模块是keepalived的核心程序,比如全局配置的解析和加载,进程启动等等;
check模块是keepalived的healthchecker子进程的目录,包括了所有的健康检查方式以及对应的配置的解析;
vrrp模块是keepalived的vrrp子进程以及相关的代码,来实现VRRP协议的。
试验环境:
node-1:192.168.5.81
node-2:192.168.5.82
VIP:192.168.5.222
keepalived实现nginx高可用
我的环境是:CentOS 6.6 x86_64,直接yum安装就行。
# yum install -y keepalived # # keepalived -v Keepalived v1.2.13 (03/19,2015)
nginx监控脚本
该脚本检测nginx的运行状态,并在nginx进程不存在时尝试重启nginx,如果启动失败则停止keepalived,准备让其它机器接管。
# cat /etc/keepalived/nginx_check.sh #!/bin/bash nginx_status=`ps -C nginx --no-header |wc -l` if [ ${nginx_status} -eq 0 ];then /usr/local/nginx/sbin/nginx sleep 2 if [`ps -C nginx --no-header |wc -l` -eq 0 ];then /etc/init.d/keepalived stop fi fi
keepalived配置文件
# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id node-1 } vrrp_script nginx_check { script "/etc/keepalived/nginx_check.sh" interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 146 mcast_src_ip 192.168.5.81 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } track_script { nginx_check } virtual_ipaddress { 192.168.5.222 } }
在其它备机BACKUP上,只需要改变state MASTER-> state BACKUP,priority 101 ->priority 100,mcast_src_ip MASTER IP -> mcast_src_ip BACKUP IP即可。
配置选项说明:
global_defs
notification_email : keepalived在发生诸如切换操作时需要发送email通知地址,后面的 smtp_server 相比也都知道是邮件服务器地址。也可以通过其它方式报警,毕竟邮件不是实时通知的。故障发生时,邮件通知会用到。
router_id : 机器标识,通常可设为hostname。
vrrp_instance
state:指定instance的初始状态,在两台router都启动后马上会发生竞选,高priority的会竞选为Master,所以这里的state并不表示这台就一直是Master。
interface:实例绑定的网卡。
mcast_src_ip:发送组播数据包是的IP地址,这里实际上就是在那个地址上发送vrrp通告,这个非常重要,一定要选择稳定的网卡端口来发送。如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址。
virtual_router_id:VRID标记(0-255),相同的VRID为一个组,决定组播的mac地址。
priority:设置本节点的优先级,优先级高的为master
advert_int:检查间隔,默认为1秒。这就是VRRP的定时器,MASTER每隔这样一个时间间隔,就会发送一个advertisement报文用来通知组内其它路由器自己工作正常。
authentication:定义认证方式和密码,主从必须一样
auth_type:认证方式
auth_pass:认证密码
virtual_ipaddress:设置VIP,也就是虚拟IP地址,它随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候而删除。由优先级来决定,和state设置的值没有多大关系,这里可以设置多个IP地址。
track_script:引用VRRP脚本,即在vrrp_script部分指定的名字。定期运行它们来改变优先级,并最终引发准备切换。
vrrp_script
告诉keepalived在什么情况下切换,尤为重要。可以有多个vrrp_script
script:自己写的检测脚本。也可以是一行命令。
interval 2:每2s检测一次
weight -5:检测失败(脚本返回非0),优先级-5
fail 2:检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rase 1:检测1次成功就算成功。但不修改优先级
这里要提示一下script一般有2中写法:
1.通过脚本执行的返回结果,改变优先级,keepalived继续发送通告信息,backup比较优先级再决定。
2.脚本里面检测到异常,直接关闭keepalived进程,backup机器接收不到advertisement会抢占ip。
上文 vrrp_script 配置部分,命令行属于第1种情况,/etc/keepalived/check_nginx.sh属于第2种情况(脚本中关闭keepalived)。个人更倾向于通过shell脚本判断,但有异常时exit 1,正常退出exit 0,然后keepalived根据动态调整的 vrrp_instance 优先级选举决定是否抢占VIP:
如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加
如果脚本执行结果非0,并且weight配置的值小于0,则优先级相应的减少
其他情况,原本配置的优先级不变,即配置文件中priority对应的值。
提示:
1.优先级不会不断的提高或者降低
2.可以编写多个检测脚本并为每个检测脚本设置不同的weight(在配置中列出就行)
3.不管提高优先级还是降低优先级,最终优先级的范围是在[1,254],不会出现优先级小于等于0或者优先级大于等于255的情况
4.以上可以做到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换。
nginx配置
nginx没有什么可配置的,它与keepalived没有什么联系。但是为了让演示结果更加直观,修改index.html文件就行。
测试
启动nginx,启动keepalived,使用ip add分别查看两台服务器当前网卡信息,ifconfig查看不了。node-1配置的优先级高,vip此时在node-1上。
node-1: # ip addr eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:a5:66:e9 brd ff:ff:ff:ff:ff:ff inet 192.168.5.81/21 brd 192.168.7.255 scope global eth0 inet 192.168.5.222/32 scope global eth0 inet6 fe80::5054:ff:fea5:66e9/64 scope link node-2 # ip addr eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:d8:6b:39 brd ff:ff:ff:ff:ff:ff inet 192.168.5.82/21 brd 192.168.7.255 scope global eth0 inet6 fe80::5054:ff:fed8:6b39/64 scope link valid_lft forever preferred_lft forever
浏览器访问192.168.5.222,可以访问。
关闭node-1的nginx测试。killall nginx,再次查看网卡信息,vip漂移到node-2上。
node-1 # ip addr eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:a5:66:e9 brd ff:ff:ff:ff:ff:ff inet 192.168.5.81/21 brd 192.168.7.255 scope global eth0 inet6 fe80::5054:ff:fea5:66e9/64 scope link valid_lft forever preferred_lft forever node-2 # ip addr eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:d8:6b:39 brd ff:ff:ff:ff:ff:ff inet 192.168.5.82/21 brd 192.168.7.255 scope global eth0
inet 192.168.5.222/32 scope global eth0 inet6 fe80::5054:ff:fed8:6b39/64 scope link valid_lft forever preferred_lft forever
通常如果master服务死掉后backup会变成master,但是当master服务又好了的时候 master此时会抢占VIP,这样就会发生两次切换对业务繁忙的网站来说是不好的。所以我们要在配置文件加入nopreempt非抢占,但是这个参数只能用于state为backup,故我们在用HA的时候最好master和backup的state都设置成backup让其通过priority来竞争。
注意:这样配置后,我们要注意启动keepalived服务的顺序,假设我想让A成为backup那就不能先启动A的keepalived服务。
为keepalived指定日志文件
一般安装完keepalived服务后,默认日志文件是/var/log/messages,这个文件里面显示的日志有点多,可以自己单独给keepalived指定日志文件。修改方法如下:
# vim /etc/sysconfig/keepalived KEEPALIVED_OPTIONS="-D" #修改为 KEEPALIVED_OPTIONS="-D -d -S 0" # vim /etc/rsyslog.conf local0.* /var/log/keepalived.log #在末尾添加此行 # /etc/init.d/rsyslog restart Shutting down system logger: [ OK ] Starting system logger: [ OK ] # /etc/init.d/keepalived restart Stopping keepalived: [ OK ] Starting keepalived: [ OK ] # tail -5 /var/log/keepalived.log Jul 24 11:13:50 node-2 Keepalived_healthcheckers[17498]: SNMP Trap disabled Jul 24 11:13:50 node-2 Keepalived_healthcheckers[17498]: ------< SSL definitions >------ Jul 24 11:13:50 node-2 Keepalived_healthcheckers[17498]: Using autogen SSL context Jul 24 11:13:50 node-2 Keepalived_healthcheckers[17498]: Using LinkWatch kernel netlink reflector... Jul 24 11:13:50 node-2 Keepalived_vrrp[17499]: VRRP_Script(chk_nginx) succeeded
到此keepalived日志文件修改完成。