keepalived与dr模式结合
keepalived介绍
keepalived可提供vrrp以及health-check功能,可以只用它提供双机浮动的vip(vrrp虚拟路由功能),
这样可以简单实现一个双机热备高可用功能;
keepalived是以VRRP虚拟路由冗余协议为基础实现高可用的,
可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,
这个组里面有一个master和多个backup,
master上面有一个对外提供服务的vip
(该路由器所在局域网内其他机器的默认路由为该vip),
master会发组播,当backup收不到VRRP包时就认为master宕掉了,
这时就需要根据VRRP的优先级来选举一个backup当master。
这样的话就可以保证路由器的高可用了。
keepalived可提供vrrp以及health-check功能,可以只用它提供双机浮动的vip(vrrp虚拟路由功能),
这样可以简单实现一个双机热备高可用功能;
keepalived是以VRRP虚拟路由冗余协议为基础实现高可用的,
可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,
这个组里面有一个master和多个backup,
master上面有一个对外提供服务的vip
(该路由器所在局域网内其他机器的默认路由为该vip),
master会发组播,当backup收不到VRRP包时就认为master宕掉了,
这时就需要根据VRRP的优先级来选举一个backup当master。
这样的话就可以保证路由器的高可用了。
keepalived实验
实验环境 4台虚拟机
dr1 192.168.1.135
dr2 192.168.1.106
rs1 192.168.1.190
rs2 192.168.1.187
VIP 192.168.1.180
为方便实验,建议关闭iptables,或者开通80端口
dr1和dr2安装ipvsadm和keepalived
yum install -y ipvsadm keepalived
real_server1和real_server2上安装nginx
开启80端口访问,区分两个real_server
实验操作
- 修改配置文件
1.修改dr1的keepalived配置文件
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email { # 配置邮箱报警
acassen@firewall.loc # (如果要开启邮件报警,需要开启相应的sendmail服务)
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 # 表示keepalived服务器的一个标识,是发邮件时显示在邮件主题中的信息
}
vrrp_instance VI_1 { #定义一个vrrp组,组名唯一
state MASTER #定义改主机为keepalived的master主机
interface eth0 #监控eth0号端口
virtual_router_id 58 #虚拟路由id号为58,id号唯一,这个id决定了多播的MAC地址
# (一组keepalived相同,多组不能相同)
priority 150 #设置本节点的优先级,master的优先级 要比backup的优先级别高,数值要大
# (一组中keepalived会检查此选项然后选举出一台服务器作为路由,配置vip)
advert_int 1 #检查间隔,默认为1秒
authentication {
auth_type PASS #认证方式,密码认证
auth_pass 1111 #认证的密码,这个密码必须和backup上的一致
}
virtual_ipaddress { #设置虚拟的ip, 这个ip是以后对外提供服务的ip。如果有多个VIP,继续换行填写.
192.168.1.180
}
}
virtual_server 192.168.1.180 80 { #虚拟主机设置,ip同上。
delay_loop 2 #每隔2秒查询realserver状态
lb_algo rr #lvs的调度算法
lb_kind DR #lvs的集群模式
nat_mask 255.255.255.0
# persistence_timeout 50 #同一IP的连接50秒内被分配到同一台realserver
# 测试的时候可以不用开
protocol TCP #用TCP协议检查realserver状态
real_server 192.168.1.187 80 { #后端真实主机1
weight 100 #每台机器的权重,0表示不给该机器转发请求,直到它恢复正常。
TCP_CHECK { #健康检查项目,以下
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.1.190 80 { #后端真实主机2
weight 100 #每台机器的权重,0表示不给该机器转发请求,直到它恢复正常。
TCP_CHECK { #健康检查项目,以下
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
2.修改dr2上的keepalived配置文件
vim /etc/keepalived/keepalived.conf
只要修改dr1上的配置内容
backup主机的配置和master的基本一样,只有以下地方需要修改。
state BACKUP #定义改主机为keepalived的backup主机,监控主master
priority 100 #设置本节点的优先级,数值要比master主机上的小
3.配置real_server的dr脚本(同dr模式脚本)
vim /usr/local/sbin/lvs_dr.sh
#!/bin/bash
vip=192.168.1.180
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
/sbin/route add -host $vip lo:0
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/eth0/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/default/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/default/arp_announce
- 启动执行
1.将2台dr上的keepalived启动
/etc/init.d/keepalived start
2.执行脚本
sh /usr/local/sbin/lvs_dr.sh
- 检查是否搭建成功
查看VIP和ipvsadm
通过检查网卡信息看vip绑定在哪台机器的网卡上
ip addr
[root@localhost ~]# ip a
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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:46:c8:ae brd ff:ff:ff:ff:ff:ff
inet 192.168.1.106/24 brd 192.168.1.255 scope global eth0
inet 192.168.1.180/32 scope global eth0
inet6 fe80::20c:29ff:fe46:c8ae/64 scope link
valid_lft forever preferred_lft forever
不要跟dr模式混乱,这里启动keepalived后不需要再执行dr模式下的lvs_dr.sh脚本
- 测试
(注:如果发现rs没有轮询,注释掉keepalived.conf中persistence_timeout 50即可)
A:dr1存活(正常轮询)
[root@151 ~]# curl 192.168.1.180
rs2 nginx
[root@151 ~]# curl 192.168.1.180
rs1 nginx
[root@151 ~]# curl 192.168.1.180
rs2 nginx
此时vip在135上
[root@localhost ~]# ip a
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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:46:c8:ae brd ff:ff:ff:ff:ff:ff
inet 192.168.1.106/24 brd 192.168.1.255 scope global eth0
inet 192.168.1.180/32 scope global eth0
inet6 fe80::20c:29ff:fe46:c8ae/64 scope link
valid_lft forever preferred_lft forever
B:dr1挂掉
停掉dr1的keepalived,vip自动绑定到dr2,keepalived搭建完成
[root@localhost ~]# ip a
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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:5a:c3:48 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.135/24 brd 192.168.1.255 scope global eth1
inet 192.168.1.180/32 scope global eth0
inet6 fe80::20c:29ff:fe5a:c348/64 scope link
valid_lft forever preferred_lft forever
因为给192.168.1.106配置的priority优先级为150
而192.168.1.135的优先级是100
所以,当keepalived连接通信时(主从同时存在时),vip会在106上
而当106宕机时,vip会飘到135上
当重新启动106(启动106上的keepalived)等于重新做了keepalived主从
106因为优先级为150,所以又会重新获得vip
脑裂问题(主从模式)
上述主从配置方式存在脑裂的可能,
即两个节点实际都处于正常工作状态,但是无法接收到彼此的组播通知,
这时两个节点均强行绑定虚拟IP,导致不可预料的后果。
这就是我刚刚实验中说不需要执行dr模式下的lvs_dr.sh脚本,因为执行脚本后,主从同时获得vip
这时就需要设置仲裁,即每个节点必须判断自身的状态(应用服务状态及自身网络状态),
要实现这两点可使用自定义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定义的检测规则可以是:
(以上的路径及文件是自己定义的。)
a.自身web服务故障(超时,http返回状态不是200)
b.无法ping通网关
c.产生以上任何一个问题,均应该移除本机的虚拟IP(停止keepalived实例即可)
但这里有个小问题,如果本机或是网关偶尔出现一次故障,那么我们不能认为是服务故障。
更好的做法是如果连续N次检测本机服务不正常或连接N次无法ping通网关,
才认为是故障产生,才需要进行故障转移。
另一方面,如果脚本检测到故障产生,并停止掉了keepalived服务,
那么当故障恢复后,keepalived是无法自动恢复的。
我觉得利用独立的脚本以秒级的间隔检查自身服务及网关连接性,
再根据故障情况控制keepalived的运行或是停止。
这里提供一个思路,具体脚本内容请大家根据自己的需要编写即可。
脚本 /usr/local/nginx/check_nginx.sh”内容:
#!/bin/bash
if [ "$(ps -ef | grep "nginx: master process"| grep -v grep )" == "" ]
then
/usr/local/nginx/sbin/nginx
sleep 5
if [ "$(ps -ef | grep "nginx: master process"| grep -v grep )" == "" ]
then
killall keepalived
fi
fi
vi /etc/keepalived/keepalived.conf
global_defs {
router_id nginx_backup
}
#监控服务.NGINX mysql等
vrrp_script chk_nginx {
script "/usr/local/nginx/check_nginx.sh"
interval 2
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.xx.xx #VIP(虚拟ip)
192.168.xx.xx #主服务器IP
192.168.xx.xx #从服务器IP
}
track_script {
chk_nginx #检测脚本 上面配置的
}
}
keepalived健康检查方式
keepalived对后端realserver的健康检查方式主要有以下几种
TCP_CHECK:工作在第4层,keepalived向后端服务器发起一个tcp连接请求,
如果后端服务器没有响应或超时,那么这个后端将从服务器池中移除。
HTTP_GET:工作在第5层,向指定的URL执行http请求,
将得到的结果用md5加密并与指定的md5值比较看是否匹配,不匹配则从服务器池中移除;
此外还可以指定http返回码来判断检测是否成功。
HTTP_GET可以指定多个URL用于检测,这个一台服务器有多个虚拟主机的情况下比较好用。
SSL_GET:跟上面的HTTP_GET相似,不同的只是用SSL连接
MISC_CHECK:用脚本来检测,脚本如果带有参数,
需将脚本和参数放入双引号内。脚本的返回值需为:
0) 检测成功
1) 检测失败,将从服务器池中移除
2-255)检测成功;如果有设置misc_dynamic,权重自动调整为 退出码-2,
如退出码为200,权重自动调整为198=200-2。
SMTP_CHECK:用来检测邮件服务的smtp的
当把nginx与keepalived部署在同一台服务器上时
nginx做反向代理,keepalived做vip(重点还是nginx的反向代理)
同时配置BACKUP文件,重新做主从不替换
当keepalived的MASTER宕掉,BACKUP启动。再恢复MASTER会再次抢走vip,
但此时并不需要更换vip,如果业务量大的话,反而会对业务有影响。
此时将两台机器的keepalived同时设置为BACKUP,priority相同
两台服务器使用相同的keepalived的BACKUP配置文件
两台机器会抢vip,因为优先权相同。当谁先启动谁就拥有了vip
避免了更换从主的问题
nginx+keepalived双主模式
双主模式与普通主从模式的最大区别,充分使用两台服务器,不会有闲置BACKUP机器
注意:
配置中的虚拟路由标识virtual_router_id在MASTER和BACKUP处配置不能一样(但在主从模式下配置是一样的)
1)master负载机上的keepalived配置:
(注意,这里是双主配置,MASTER-BACKUP和BACKUP-MASTER;
如果是多主,比如三主,
就是MATER-BACKUP-BACKUP、BACKUP-MASTER-BACKUP和BACKUP-BACKUP-MASTER)
双主模式就是设置两个vrrp_instance VI_1和VI_2
vrrp_instance VI_1 {
state MASTER
virtual_router_id 51
priority 101
}
vrrp_instance VI_2 {
state BACKUP
virtual_router_id 52
priority 99
}
#在另一台机器上
vrrp_instance VI_1 {
state BACKUP
virtual_router_id 51
priority 99
}
vrrp_instance VI_2 {
state MASTER
virtual_router_id 52
priority 101
}
主要就是这三项的变化
同一个虚拟的vrrp_instance相同
然后互为主从,权限不同
将nginx中配置的域名解析到这两个VIP地址上:(万网DNS解析配置)
103.110.98.20 www.chenhaoran.com
103.110.98.21 www.chenhaoran.com
参考链接
http://blog.chinaunix.net/uid-10480699-id-5179873.html
http://blog.csdn.net/qiandublog/article/details/52474450
http://www.keepalived.org/doc/introduction.html
推荐阅读
http://www.361way.com/keepalived-health-check/5218.html
https://www.cnblogs.com/kevingrace/p/6248941.html