一、简介
目前主流实现web网站及数据库服务高可用软件包括:keepalived、heartbeat、corosync,cman;高可用简称HA;
官方站点:https://www.keepalived.org/
1、keepalived主要功能
对RealServer进行健康状态检查,支持3层、4层、7层协议进行健康检查;并支持VRRP冗余协议,所以keepalived两个功能是监控检查,VRRP冗余协议;
2、keepalived的作用
检查web服务器的状态,如果有一台web服务器/mysql服务器宕机或故障,keepalived将故障节点从系统中剔除,当故障恢复的时候自动加入服务器集群中,非常智能化,只需要手动修复坏的节点即可。
3、keepalived的layer3、4、7层分别是IP层、传输层、应用层的实现原理如下:
1)、layer3:keepalived定期向集群中服务器发送ICMP的包,如果发现哪台ping不通,便报告这台服务器失效,并将其剔除集群;(判断标准为IP是否有效)
2)、layer4:主要以TCP端口(也可以是udp)状态来决定服务器工作是否正常,如web服务器的80端口如果没有工作,则将其剔除集群(判断标准为端口)
3)、layer7:应用层,keepalived将根据用户的设定,检查服务器程序的运行是否正常,如果不是设定值,则将其剔除集群(判断标准为程序是否正常)
二、keepalived VRRP原理
1、学习keepalived,必须了解VRRP协议的原理,因为keepalived是VRRP的完美实现,那什么是VRRP那?VRRP(虚拟路由冗余协议)最早是为了解决网关的点单故障的路由协议,在主机上如何选定到达目的的下一跳路由,这个问题通常解决方案是,动态路由协议RIP,OSPF;再有就是静态路由协议,主机中实现动态路由协议非常不实际,管理,开销,维护等诸多问题,因此通常是配置静态路由协议,但是路由器或网管就经常出现单点,VRRP就是解决此静态路由单点问题,VRRP通过竞选协议来动态交给LAN中的虚拟路由器中的某台VRRP路由器。
2、VRRP虚拟路由器集群中,由多台物理机组成,但是并不是同时工作,而是由master负载路由工作,其他都是backup,master也不是一成不变,VRRP会让每个VRRP路由参与竞选最终优先的就是master。
3、master的特权是拥有虚拟路由器的IP地址,即VIP,负责转发给网关地址的包和响应ARP请求。
4、VRRP通过竞选来实现虚拟路由器的功能,所有协议报文都是通过IP多播包(多播地址224.0.0.18)发送的,虚拟路由器有VRID(0~255)和一组IP地址组成,对外表现为一个mac地址,所以一组虚拟路由器集群中,不管谁是master,对外都是一个相同mac和VIP,客户端没有感知。
5、master的VRRP路由器会一直发送VRRP广播包,backup不会抢占master,除非优先级(priority)更高,当master不可用时(backup收不到广播包),多台backup中优先级最高的这台会抢占master,抢占是非常快速的,并且VRRP包还使用了加密协议进行传输。
6、keepalived基于VRRP将两台主机当做路由器,组成虚拟路由器集群,master高的主机产生VIP,该VIP负责转发用户发起的IP包或请求
三、keepalive架构模型
一个父进程两个子进程
为了确保健壮及稳定性,守护进程被分为3个不同的进程,父进程负责fork和监控子进程,因此父进程也称为watchdog,凉饿子进程,一个负责VRRP,另一个负责健康检查,每个进程都有自己的I/O多路复用器,这样可以优化VRRP调度抖动,因为VRRP比健康检查更重要,两个子进程开启本地套接字Unix Domain Socket,当keepalive启动后,父进程通过unix domain socket每隔5s发送一个hello消息给子进程,如果父进程无法发送消息给子进程,将认为子进程出现问题,于是重启子进程。watchdog这种设计的两个好处是,第一父进程发送给远程子进程的hello数据包是通过I/O多路复用程序完成的,这样他就可以在子调度框架中检测死循环,第二是使用sysV信号检测dead children。
架构图:
解释:
userspace 用户空间
kernelspace 内核空间
checker组件:负责RS健康状态检查,并在LVS拓扑中移除、添加,支持layer3/4/7的协议检查,该组件使用独立的子进程负责,但被父进程监控。这个组件就是实现健康检查(TCP\HTTP\SSL\MISC......)
VRRP stack:提供director的故障转移功能从而实现director的高可用,该组件可独立提供功能,无需LVS支持,也是独立的子进程负责,父进程监控,vrrp stact就是vrrp的实现,比如vrrp协议调用。
system call组件:提供抓取自定义脚本的功能,该组件在使用时,将临时产生一个子进程来执行任务,支持系统调用机制,做出管理操作。
IPVS wrapper组件:负责将配置文件中IPVS相关规则发送到内核的IPVS模块,就是生产ipvs规则的。
netlink reflector:用来设定,监控vrrp的vip地址,负责交互,VRRP借助于netlink健康网络,实现网络功能配置。
schedule-I/O Multiplexer:并发控制。
memory mngt:内存管理。
control plane configuration file parser:配置文件,分析的主控工具。
watch dog:可以理解为高可用监视器。
四、keepalived配置文件
vim /etc/keepalived/keepalived.conf
2 ! Configuration File for keepalived 3 4 global_defs { #全局部分定义邮件报警系统 5 notification_email { #定义邮件发送目标 6 [email protected] 7 [email protected] 8 [email protected] 9 } 10 notification_email_from [email protected] #定义邮件发送人 11 smtp_server 192.168.200.1 #指定smtp服务器地址 12 smtp_connect_timeout 30 #指定smtp连接超时时间 13 router_id LVS_DEVEL #表示keepalived服务器的字符串,局域网内是唯一的高可用需要使用它标识节点 14 vrrp_skip_check_adv_addr #默认是不跳过检查,检查收到的VRRP通过中的所有地址可能会比较耗时,设置此命令的意思是,如果通告于接收的上一个通过来自相同的master路由器,则不执行检查,也就是跳过检查。 15 vrrp_strict #严格嬦VRRP协议,阻止keepalived启动有几种情况,1没有vip,2单播邻居,3在VRRP版本2中有ipv6地址 16 vrrp_garp_interval 0 #在一个接口发送的两个arp之间的延迟,可以是毫米级 17 vrrp_gna_interval 0 18 } 19#定义VRRP实例,一个配置文件可以有多例,不同主机之间互为主备,实例名称应该一致。 20 vrrp_instance VI_1 { 21 state MASTER #定义角色状态,是master/backup 22 interface eth0 #定义网卡 23 virtual_router_id 51 #定义虚拟路由标识VRID,主备应该相同 24 priority 100 #定义优先级 25 advert_int 1 #心跳时间1s 26 authentication { #认证方式一个实例中必须完全一致 27 auth_type PASS 28 auth_pass 1111 #最多8个字符 29 } 30 virtual_ipaddress { #设置VIP,主备相同,可以使用dev选项来指定接口,如果需要ifconfig查看,需要在ip地址后加上label,可以是多个VIP 31 192.168.200.16 32 192.168.200.17 33 192.168.200.18 34 } 35 } 36 #定义虚拟服务部分 37 virtual_server 192.168.200.100 443 { #虚拟服务器地址和端口空格隔开地址为VIP 38 delay_loop 6 #健康检查间隔 39 lb_algo rr #定义负载均衡算法,这里是rr 40 lb_kind NAT #定义lvs模型 41 persistence_timeout 50 #持久会话保持时长 42 protocol TCP #监控服务的协议类型 43 44 real_server 192.168.201.100 443 { #定义rs部分,地址端口 45 weight 1 #lvs权重 46 SSL_GET { #监控检查的方式,常见的有HTTP_GET/SSL_GET/TCP_CHECK/MISC_CHECK 47 url { 48 path / #指定ssl——get健康检查路径 49 digest ff20ad2481f97b1754ef3e12ecd3a9cc 50 } #健康状态需要状态码,可以是status_code,digest,digest+status_code 51 url { #digest值用keepalived的genhash命令生产,一般使用status_code 52 path /mrtg/ 53 digest 9b3a0c85a887a256d6939da88aabd8cd 54 } 55 connect_timeout 3 #3s五响应就超时,就判断为realserver不健康,需要重新连接 56 nb_get_retry 3 #标识重试3次,防误伤 57 delay_before_retry 3 #重试间隔3s 58 } #总共12s才能判断故障节点,可以改小点 59 } 60 } 61 62 virtual_server 10.10.10.2 1358 { #定义所有rs宕机时,有哪台服务器提供服务 63 delay_loop 6 #一般在keepalived给一个web页面,提示维护等。 64 lb_algo rr 65 lb_kind NAT 66 persistence_timeout 50 67 protocol TCP 68 69 sorry_server 192.168.200.200 1358 70 71 real_server 192.168.200.2 1358 { 72 weight 1 73 HTTP_GET { 74 url { 75 path /testurl/test.jsp 76 digest 640205b7b0fc66c1ea91c463fac6334d 77 } 78 url { 79 path /testurl2/test.jsp 80 digest 640205b7b0fc66c1ea91c463fac6334d 81 } 82 url { 83 path /testurl3/test.jsp 84 digest 640205b7b0fc66c1ea91c463fac6334d 85 } 86 connect_timeout 3 87 nb_get_retry 3 88 delay_before_retry 3 89 } 90 } 91 92 real_server 192.168.200.3 1358 { 93 weight 1 94 HTTP_GET { 95 url { 96 path /testurl/test.jsp 97 digest 640205b7b0fc66c1ea91c463fac6334c 98 } 99 url { 100 path /testurl2/test.jsp 101 digest 640205b7b0fc66c1ea91c463fac6334c 102 } 103 connect_timeout 3 104 nb_get_retry 3 105 delay_before_retry 3 106 } 107 } 108 } 109 110 virtual_server 10.10.10.3 1358 { 111 delay_loop 3 112 lb_algo rr 113 lb_kind NAT 114 persistence_timeout 50 115 protocol TCP 116 117 real_server 192.168.200.4 1358 { 118 weight 1 119 HTTP_GET { 120 url { 121 path /testurl/test.jsp 122 digest 640205b7b0fc66c1ea91c463fac6334d 123 } 124 url { 125 path /testurl2/test.jsp 126 digest 640205b7b0fc66c1ea91c463fac6334d 127 } 128 url { 129 path /testurl3/test.jsp 130 digest 640205b7b0fc66c1ea91c463fac6334d 131 } 132 connect_timeout 3 133 nb_get_retry 3 134 delay_before_retry 3 135 } 136 } 137 138 real_server 192.168.200.5 1358 { 139 weight 1 140 HTTP_GET { 141 url { 142 path /testurl/test.jsp 143 digest 640205b7b0fc66c1ea91c463fac6334d 144 } 145 url { 146 path /testurl2/test.jsp 147 digest 640205b7b0fc66c1ea91c463fac6334d 148 } 149 url { 150 path /testurl3/test.jsp 151 digest 640205b7b0fc66c1ea91c463fac6334d 152 } 153 connect_timeout 3 154 nb_get_retry 3 155 delay_before_retry 3 156 } 157 } 158 }