11. 前言 2 3VRRP(Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议,最新协议在RFC3768中定义,原来的定义RFC2338被废除,新协议相对还简化了一些功能。 4 52. 协议说明 6 72.1 协议 8 9VRRP协议是为消除在静态缺省路由环境下的缺省路由器单点故障引起的网络失效而设计的主备模式的协议,使得在发生故障而进行设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。VRRP协议需要具有IP地址备份,优先路由选择,减少不必要的路由器间通信等功能。 10 11VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个),而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,或者是通过算法选举产生,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等;其他设备不拥有该IP,状态是BACKUP,除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。 12 13配置VRRP协议时需要配置每个路由器的虚拟路由器ID(VRID)和优先权值,使用VRID将路由器进行分组,具有相同VRID值的路由器为同一个组,VRID是一个0~255的正整数;同一组中的路由器通过使用优先权值来选举MASTER,优先权大者为MASTER,优先权也是一个0~255的正整数。 14 15VRRP协议使用多播数据来传输VRRP数据,VRRP数据使用特殊的虚拟源MAC地址发送数据而不是自身网卡的MAC地址,VRRP运行时只有MASTER路由器定时发送VRRP通告信息,表示MASTER工作正常以及虚拟路由器IP(组),BACKUP只接收VRRP数据,不发送数据,如果一定时间内没有接收到MASTER的通告信息,各BACKUP将宣告自己成为MASTER,发送通告信息,重新进行MASTER选举状态。 16 172.2 MASTER选举 18如果对外的虚拟路由器IP就是路由器本身配置的IP地址的话,该路由器始终都是MASTER; 19否则如果不具备虚拟IP的话,将进行MASTER选举,各路由器都宣告自己是MASTER,发送VRRP通告信息; 20如果收到其他机器的发来的通告信息的优先级比自己高,将转回BACKUP状态; 21如果优先级相等的话,将比较路由器的实际IP,IP值较大的优先权高; 22不过如果对外的虚拟路由器IP就是路由器本身的IP的话,该路由器始终将是MASTER,这时的优先级值为255。 23 242.3 协议状态机 25 26VRRP协议状态比较简单,就三种状态,初始化,主机,备份机。 27 +---------------+ 28 +--------->| |<-------------+ 29 | | Initialize | | 30 | +------| |----------+ | 31 | | +---------------+ | | 32 | | | | 33 | V V | 34 +---------------+ +---------------+ 35 | |---------------------->| | 36 | Master | | Backup | 37 | |<----------------------| | 38 +---------------+ +---------------+ 39复制代码 40 41初始化: 42路由器启动时,如果路由器的优先级是255(最高优先级,路由器拥有路由器地址),要发送VRRP通告信息,并发送广播ARP信息通告路由器IP地址对应的MAC地址为路由虚拟MAC,设置通告信息定时器准备定时发送VRRP通告信息,转为MASTER状态; 43否则进入BACKUP状态,设置定时器检查定时检查是否收到MASTER的通告信息。 44 45主机: 46主机状态下的路由器要完成如下功能: 47设置定时通告定时器; 48用VRRP虚拟MAC地址响应路由器IP地址的ARP请求; 49转发目的MAC是VRRP虚拟MAC的数据包; 50如果是虚拟路由器IP的拥有者,将接受目的地址是虚拟路由器IP的数据包,否则丢弃; 51当收到shutdown的事件时删除定时通告定时器,发送优先权级为0的通告包,转初始化状态; 52如果定时通告定时器超时时,发送VRRP通告信息; 53收到VRRP通告信息时,如果优先权为0,发送VRRP通告信息;否则判断数据的优先级是否高于本机,或相等而且实际IP地址大于本地实际IP,设置定时通告定时器,复位主机超时定时器,转BACKUP状态;否则的话,丢弃该通告包; 54 55备机: 56备机状态下的路由器要实现以下功能: 57设置主机超时定时器; 58不能响应针对虚拟路由器IP的ARP请求信息; 59丢弃所有目的MAC地址是虚拟路由器MAC地址的数据包; 60不接受目的是虚拟路由器IP的所有数据包; 61当收到shutdown的事件时删除主机超时定时器,转初始化状态; 62主机超时定时器超时的时候,发送VRRP通告信息,广播ARP地址信息,转MASTER状态; 63收到VRRP通告信息时,如果优先权为0,表示进入MASTER选举;否则判断数据的优先级是否高于本机,如果高的话承认MASTER有效,复位主机超时定时器;否则的话,丢弃该通告包; 64 652.4 ARP查询处理 66 67当内部主机通过ARP查询虚拟路由器IP地址对应的MAC地址时,MASTER路由器回复的MAC地址为虚拟的VRRP的MAC地址,而不是实际网卡的MAC地址,这样在路由器切换时让内网机器觉察不到;而在路由器重新启动时,不能主动发送本机网卡的实际MAC地址。如果虚拟路由器开启的ARP代理(proxy_arp)功能,代理的ARP回应也回应VRRP虚拟MAC地址; 68 692.5 VRRP应用举例 70 71 +-----------+ +-----------+ 72 | Rtr1 | | Rtr2 | 73 |(MR VRID=1)| |(BR VRID=1)| 74 |(BR VRID=2)| |(MR VRID=2)| 75 VRID=1 +-----------+ +-----------+ VRID=2 76 IP A ---------->* *<---------- IP B 77 | | 78 | | 79 ------------------+------------+-----+--------+--------+--------+-- 80 ^ ^ ^ ^ 81 | | | | 82 (IP A) (IP A) (IP B) (IP B) 83 | | | | 84 +--+--+ +--+--+ +--+--+ +--+--+ 85 | H1 | | H2 | | H3 | | H4 | 86 +-----+ +-----+ +--+--+ +--+--+ 87 Legend: 88 ---+---+---+-- = Ethernet, Token Ring, or FDDI 89 H = Host computer 90 MR = Master Router 91 BR = Backup Router 92 * = IP Address 93 (IP) = default router for hosts 94复制代码 95 96这是通常VRRP使用拓扑,两台路由器运行VRRP互为备份,路由器1作为VRID组1的MASTER,IP地址A,VRID组2的BACKUP,路由器2作为VRID组2的MASTER,IP地址B,VRID组1的BACKUP,内部网络中一部分机器的缺省网关地址是IP地址A,一部分是IP地址B,正常情况下以A为网关的数据将走路由器1,以B为网关的数据将走路由器2,如果一台路由器发生故障,所有数据将走另一台路由器。 97 983. 协议定义 99 1003.1 以太头 101 102源MAC地址必须为虚拟MAC地址:00-00-5E-00-01-{VRID},VRID为虚拟路由器ID值,16进制格式,所以同一网段中最多有255个VRRP路由器;目的MAC为多播类型的MAC。 103 104这里可以看出VRID非常重要 105 106 1073.2 IP头参数 108 109VRRP包的源地址是本机地址,目的地址必须为224.0.0.18,为一多播地址;IP协议号为112;IP包的TTL值必须为255。 110 1113.3 VRRP协议数据格式 112 0 1 2 3 113 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 114 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 115 |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| 116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 117 | Auth Type | Adver Int | Checksum | 118 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 119 | IP Address (1) | 120 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 121 | . | 122 | . | 123 | . | 124 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 125 | IP Address (n) | 126 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 127 | Authentication Data (1) | 128 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 129 | Authentication Data (2) | 130 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 131复制代码 132 133 134 135其中: 136version:版本,4位,在RFC3768中定义为2; 137Type:类型,4位,目前只定义一种类类型:通告数据,取值为1; 138Virtual Rtr ID:虚拟路由器ID,8位 139Priority:优先级,8位,具备冗余IP地址的设备的优先级为255; 140Count IP Addrs:VRRP包中的IP地址数量,8位; 141Auth Type:认证类型,8位,RFC3768中认证功能已经取消,此字段值定义0(不认证),为1,2只作为对老版本的兼容; 142Adver Int:通告包的发送间隔时间,8位,单位是秒,缺省是1秒; 143Checksum:校验和,16位,校验数据范围只是VRRP数据,即从VRRP的版本字段开始的数据,不包括IP头; 144IP Address(es):和虚拟路由器相关的IP地址,数量由Count IP Addrs决定 145Authentication Data:RFC3768中定义该字段只是为了和老版本兼容,必须置0。 146 1473.4 接收数据时的必须检查 148 149收到VRRP数据包时要进行以下验证,不满足的数据包将被丢弃: 150 - TTL必须为255; 151 - VRRP版本号必须为2; 152 - 一个包中数据字段必须完整; 153 - 校验和必须正确; 154 - 必须验证在接收的网卡上配置了VRID值,而且本地路由器不是路由IP地址的拥有者 155 - 必须验证VVRP认证类型和配置的一致; 156 157 1584. 结论 159 160VRRP实现了对路由器IP地址的冗余功能,防止了单点故障造成的网络失效,VRRP本身是热备形式的,但可以通过互相热备实现路由器的均衡处理,新版的VRRP较老版简化了认证处理,实际不再进行数据的认证,这是因为在实际应用中经常出现认证成为造成多个MASTER同时使用的异常情况。 161 162 163 164 165Keepalived原理与实战精讲 166 167什么是Keepalived呢,keepalived观其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发生,那说到keepalived时不得不说的一个协议就是VRRP协议,可以说这个协议就是keepalived实现的基础,那么首先我们来看看VRRP协议 168 169注:搞运维的要有足够的耐心哦,不理解协议就很难透彻的掌握keepalived的了 170 171一,VRRP协议 172VRRP协议 173学过网络的朋友都知道,网络在设计的时候必须考虑到冗余容灾,包括线路冗余,设备冗余等,防止网络存在单点故障,那在路由器或三层交换机处实现冗余就显得尤为重要,在网络里面有个协议就是来做这事的,这个协议就是VRRP协议,Keepalived就是巧用VRRP协议来实现高可用性(HA)的 174 175VRRP协议有一篇文章写的非常好,大家可以直接看这里(记得认真看看哦,后面基本都已这个为基础的了) 176帖子地址:http://bbs.ywlm.net/thread-790-1-1.html 177只需要把服务器当作路由器即可! 178 179在《VRRP协议》里讲到了虚拟路由器的ID也就是VRID在这里比较重要 180 181keepalived完全遵守VRRP协议,包括竞选机制等等 182 183二,Keepalived原理 184 185Keepalived原理 186keepalived也是模块化设计,不同模块复杂不同的功能,下面是keepalived的组件 187core check vrrp libipfwc libipvs-2.4 libipvs-2.6 188 189core:是keepalived的核心,复杂主进程的启动和维护,全局配置文件的加载解析等 190check:负责healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置的解析包括LVS的配置解析 191vrrp:VRRPD子进程,VRRPD子进程就是来实现VRRP协议的 192libipfwc:iptables(ipchains)库,配置LVS会用到 193libipvs*:配置LVS会用到 194注意,keepalived和LVS完全是两码事,只不过他们各负其责相互配合而已 195 196 197 198keepalived启动后会有三个进程 199父进程:内存管理,子进程管理等等 200子进程:VRRP子进程 201子进程:healthchecker子进程 202 203有图可知,两个子进程都被系统WatchDog看管,两个子进程各自复杂自己的事,healthchecker子进程复杂检查各自服务器的健康程度,例如HTTP,LVS等等,如果healthchecker子进程检查到MASTER上服务不可用了,就会通知本机上的兄弟VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态 204 205三,Keepalived配置文件详解 206 207 208keepalived配置详解 209keepalived有三类配置区域(姑且就叫区域吧),注意不是三种配置文件,是一个配置文件里面三种不同类别的配置区域 210 211 全局配置(Global Configuration) 212VRRPD配置 213LVS配置 214 215一,全局配置 216全局配置又包括两个子配置: 217全局定义(global definition) 218静态路由配置(static ipaddress/routes) 219 2201,全局定义(global definition)配置范例 221global_defs 222{ 223notification_email 224{ 225admin@example.com 226} 227notification_email_from admin@example.com 228smtp_server 127.0.0.1 229stmp_connect_timeout 30 230router_id node1 231} 232复制代码 233全局配置解析 234global_defs全局配置标识,表面这个区域{}是全局配置 235notification_email 236 237{ 238 239admin@example.com 240admin@ywlm.net 241 242} 243复制代码 244表示keepalived在发生诸如切换操作时需要发送email通知,以及email发送给哪些邮件地址,邮件地址可以多个,每行一个 245 246notification_email_from admin@example.com 247表示发送通知邮件时邮件源地址是谁 248 249smtp_server 127.0.0.1 250表示发送email时使用的smtp服务器地址,这里可以用本地的sendmail来实现 251 252smtp_connect_timeout 30 253连接smtp连接超时时间 254 255router_id node1 256机器标识 257 2582,静态地址和路由配置范例 259static_ipaddress 260{ 261192.168.1.1/24 brd + dev eth0 scope global 262192.168.1.2/24 brd + dev eth1 scope global 263} 264static_routes 265{ 266src $SRC_IP to $DST_IP dev $SRC_DEVICE 267src $SRC_IP to $DST_IP via $GW dev $SRC_DEVICE 268} 269复制代码 270 271这里实际上和系统里面命令配置IP地址和路由一样例如: 272192.168.1.1/24 brd + dev eth0 scope global 相当于: ip addr add 192.168.1.1/24 brd + dev eth0 scope global 273就是给eth0配置IP地址 274路由同理 275一般这个区域不需要配置 276这里实际上就是给服务器配置真实的IP地址和路由的,在复杂的环境下可能需要配置,一般不会用这个来配置,我们可以直接用vi /etc/sysconfig/network-script/ifcfg-eth1来配置,切记这里可不是VIP哦,不要搞混淆了,切记切记! 277 278二,VRRPD配置 279VRRPD配置包括三个类 280VRRP同步组(synchroization group) 281VRRP实例(VRRP Instance)VRRP脚本 282 2831,VRRP同步组(synchroization group)配置范例 284vrrp_sync_group VG_1 { 285group { 286http 287mysql 288} 289notify_master /path/to/to_master.sh 290notify_backup /path_to/to_backup.sh 291notify_fault "/path/fault.sh VG_1" 292notify /path/to/notify.sh 293smtp_alert 294} 295复制代码 296其中: 297group { 298http 299mysql 300} 301复制代码 302http和mysql是实例名和下面的实例名一致 303 304notify_master /path/to/to_master.sh:表示当切换到master状态时,要执行的脚本 305 306notify_backup /path_to/to_backup.sh:表示当切换到backup状态时,要执行的脚本 307 308notify_fault "/path/fault.sh VG_1" 309复制代码 310notify /path/to/notify.sh: 311 312smtp alter表示切换时给global defs中定义的邮件地址发送邮件通知(在这里我们可以利用一款非常小巧的邮件发送工具mailx来进行邮件的发送工作) 313 3142,VRRP实例(instance)配置范例 315vrrp_instance http { 316state MASTER 317interface eth0 318dont_track_primary 319track_interface { 320eth0 321eth1 322} 323mcast_src_ip <IPADDR> 324garp_master_delay 10 325virtual_router_id 51 326priority 100 327advert_int 1 328authentication { 329auth_type PASS 330autp_pass 1234 331} 332virtual_ipaddress { 333#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> 334192.168.200.17/24 dev eth1 335192.168.200.18/24 dev eth2 label eth2:1 336} 337virtual_routes { 338# src <IPADDR> [to] <IPADDR>/<MASK> via|gw <IPADDR> dev <STRING> scope <SCOPE> tab 339src 192.168.100.1 to 192.168.109.0/24 via 192.168.200.254 dev eth1 340192.168.110.0/24 via 192.168.200.254 dev eth1 341192.168.111.0/24 dev eth2 342192.168.112.0/24 via 192.168.100.254 343} 344nopreempt 345preemtp_delay 300 346debug 347} 348复制代码 349 350state:state指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定,里如果这里设置为master,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为master 351 352interface:实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的 353 354dont track primary:忽略VRRP的interface错误 355 356track interface:跟踪接口,设置额外的监控,里面任意一块网卡出现问题,都会进入故障(FAULT)状态,例如,用nginx做均衡器的时候,内网必须正常工作,如果内网出问题了,这个均衡器也就无法运作了,所以必须对内外网同时做健康检查 357 358mcast src ip:发送多播数据包时的源IP地址,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址 359 360garp master delay:在切换到master状态后,延迟进行免费的ARP(gratuitous ARP)请求 361 362virtual router id:这里设置VRID,这里非常重要,相同的VRID为一个组,他将决定多播的MAC地址 363 364priority 100:设置本节点的优先级,优先级高的为master 365 366advert int:检查间隔,默认为1秒 367 368virtual ipaddress:这里设置的就是VIP,也就是虚拟IP地址,他随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系,这里可以设置多个IP地址 369 370virtual routes:原理和virtual ipaddress一样,只不过这里是增加和删除路由 371 372lvs sync daemon interface:lvs syncd绑定的网卡 373 374authentication:这里设置认证 375 376auth type:认证方式,可以是PASS或AH两种认证方式 377 378auth pass:认证密码 379 380nopreempt:设置不抢占,这里只能设置在state为backup的节点上,而且这个节点的优先级必须别另外的高。当主mysql恢复后不抢占资源 381 382preempt delay:抢占延迟 383 384debug:debug级别 385 386notify master:和sync group这里设置的含义一样,可以单独设置,例如不同的实例通知不同的管理人员,http实例发给网站管理员,mysql的就发邮件给DBA 387 3883,VRRP脚本 389 390vrrp_script check_running { 391 script "/usr/local/bin/check_running" 392 interval 10 393 weight 10 394} 395 396vrrp_instance http { 397 state BACKUP 398 smtp_alert 399 interface eth0 400 virtual_router_id 101 401 priority 90 402 advert_int 3 403 authentication { 404 auth_type PASS 405 auth_pass whatever 406 } 407 virtual_ipaddress { 408 1.1.1.1 409 } 410 track_script { 411 check_running weight 20 412 } 413} 414复制代码 415 416首先在vrrp_script区域定义脚本名字和脚本执行的间隔和脚本执行的优先级变更 417vrrp_script check_running { 418script "/usr/local/bin/check_running" 419interval 10 #脚本执行间隔 420weight 10 #脚本结果导致的优先级变更:10表示优先级+10;-10则表示优先级-10 421} 422然后在实例(vrrp_instance)里面引用,有点类似脚本里面的函数引用一样:先定义,后引用函数名 423track_script { 424check_running weight 20 425} 426 427注意:VRRP脚本(vrrp_script)和VRRP实例(vrrp_instance)属于同一个级别 428LVS配置 429 430如果你没有配置LVS+keepalived那么无需配置这段区域,里如果你用的是nginx来代替LVS,这无限配置这款,这里的LVS配置是专门为keepalived+LVS集成准备的。 431注意了,这里LVS配置并不是指真的安装LVS然后用ipvsadm来配置他,而是用keepalived的配置文件来代替ipvsadm来配置LVS,这样会方便很多,一个配置文件搞定这些,维护方便,配置方便是也! 432 433这里LVS配置也有两个配置 434一个是虚拟主机组配置 435一个是虚拟主机配置 436 4371,虚拟主机组配置文件详解 438这个配置是可选的,根据需求来配置吧,这里配置主要是为了让一台realserver上的某个服务可以属于多个Virtual Server,并且只做一次健康检查 439 440virtual_server_group <STRING> { 441# VIP port 442<IPADDR> <PORT> 443<IPADDR> <PORT> 444fwmark <INT> 445} 446 4472,虚拟主机配置 448 449virtual server可以以下面三种的任意一种来配置 4501. virtual server IP port 4512. virtual server fwmark int 4523. virtual server group string 453复制代码 454下面以第一种比较常用的方式来配详细解说一下 455 456virtual_server 192.168.1.2 80 { #设置一个virtual server: VIP:Vport 457delay_loop 3 # service polling的delay时间,即服务轮询的时间间隔 458 459lb_algo rr|wrr|lc|wlc|lblc|sh|dh #LVS调度算法 460lb_kind NAT|DR|TUN #LVS集群模式 461persistence_timeout 120 #会话保持时间(秒为单位),即以用户在120秒内被分配到同一个后端realserver 462persistence_granularity <NETMASK> #LVS会话保持粒度,ipvsadm中的-M参数,默认是0xffffffff,即每个客户端都做会话保持 463protocol TCP #健康检查用的是TCP还是UDP 464ha_suspend #suspendhealthchecker’s activity 465virtualhost <string> #HTTP_GET做健康检查时,检查的web服务器的虚拟主机(即host:头) 466 467sorry_server <IPADDR> <PORT> #备用机,就是当所有后端realserver节点都不可用时,就用这里设置的,也就是临时把所有的请求都发送到这里啦 468 469real_server <IPADDR> <PORT> #后端真实节点主机的权重等设置,主要,后端有几台这里就要设置几个 470{ 471weight 1 #给每台的权重,0表示失效(不知给他转发请求知道他恢复正常),默认是1 472inhibit_on_failure #表示在节点失败后,把他权重设置成0,而不是冲IPVS中删除 473 474notify_up <STRING> | <QUOTED-STRING> #检查服务器正常(UP)后,要执行的脚本 475notify_down <STRING> | <QUOTED-STRING> #检查服务器失败(down)后,要执行的脚本 476 477HTTP_GET #健康检查方式 478{ 479url { #要坚持的URL,可以有多个 480path / #具体路径 481digest <STRING> 482status_code 200 #返回状态码 483} 484connect_port 80 #监控检查的端口 485 486bindto <IPADD> #健康检查的IP地址 487connect_timeout 3 #连接超时时间 488nb_get_retry 3 #重连次数 489delay_before_retry 2 #重连间隔 490} # END OF HTTP_GET|SSL_GET 491 492 493#下面是常用的健康检查方式,健康检查方式一共有HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK这些 494#TCP方式 495TCP_CHECK { 496connect_port 80 497bindto 192.168.1.1 498connect_timeout 4 499} # TCP_CHECK 500 501# SMTP方式,这个可以用来给邮件服务器做集群 502SMTP_CHECK 503host { 504connect_ip <IP ADDRESS> 505connect_port <PORT> #默认检查25端口 50614 KEEPALIVED 507bindto <IP ADDRESS> 508} 509connect_timeout <INTEGER> 510retry <INTEGER> 511delay_before_retry <INTEGER> 512# "smtp HELO"ž|·- ëê§Œà " 513helo_name <STRING>|<QUOTED-STRING> 514} #SMTP_CHECK 515 516#MISC方式,这个可以用来检查很多服务器只需要自己会些脚本即可 517MISC_CHECK 518{ 519misc_path <STRING>|<QUOTED-STRING> #外部程序或脚本 520misc_timeout <INT> #脚本或程序执行超时时间 521 522misc_dynamic #这个就很好用了,可以非常精确的来调整权重,是后端每天服务器的压力都能均衡调配,这个主要是通过执行的程序或脚本返回的状态代码来动态调整weight值,使权重根据真实的后端压力来适当调整,不过这需要有过硬的脚本功夫才行哦 523#返回0:健康检查没问题,不修改权重 524#返回1:健康检查失败,权重设置为0 525#返回2-255:健康检查没问题,但是权重却要根据返回代码修改为返回码-2,例如如果程序或脚本执行后返回的代码为200,#那么权重这回被修改为 200-2 526} 527} # Realserver 528} # Virtual Server 529 530配置文件到此就讲完了,下面是一份未加备注的完整配置文件 531global_defs 532{ 533notification_email 534{ 535admin@example.com 536} 537notification_email_from admin@example.com 538smtp_server 127.0.0.1 539stmp_connect_timeout 30 540router_id node1 541} 542notification_email 543{ 544admin@example.com 545admin@ywlm.net 546} 547 548static_ipaddress 549{ 550192.168.1.1/24 brd + dev eth0 scope global 551192.168.1.2/24 brd + dev eth1 scope global 552} 553static_routes 554{ 555src $SRC_IP to $DST_IP dev $SRC_DEVICE 556src $SRC_IP to $DST_IP via $GW dev $SRC_DEVICE 557} 558 559vrrp_sync_group VG_1 { 560group { 561http 562mysql 563} 564notify_master /path/to/to_master.sh 565notify_backup /path_to/to_backup.sh 566notify_fault "/path/fault.sh VG_1" 567notify /path/to/notify.sh 568smtp_alert 569} 570group { 571http 572mysql 573} 574 575 576vrrp_script check_running { 577 script "/usr/local/bin/check_running" 578 interval 10 579 weight 10 580} 581 582 583vrrp_instance http { 584state MASTER 585interface eth0 586dont_track_primary 587track_interface { 588eth0 589eth1 590} 591mcast_src_ip <IPADDR> 592garp_master_delay 10 593virtual_router_id 51 594priority 100 595advert_int 1 596authentication { 597auth_type PASS 598autp_pass 1234 599} 600virtual_ipaddress { 601#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> 602192.168.200.17/24 dev eth1 603192.168.200.18/24 dev eth2 label eth2:1 604} 605virtual_routes { 606# src <IPADDR> [to] <IPADDR>/<MASK> via|gw <IPADDR> dev <STRING> scope <SCOPE> tab 607src 192.168.100.1 to 192.168.109.0/24 via 192.168.200.254 dev eth1 608192.168.110.0/24 via 192.168.200.254 dev eth1 609192.168.111.0/24 dev eth2 610192.168.112.0/24 via 192.168.100.254 611} 612track_script { 613check_running weight 20 614} 615 616nopreempt 617preemtp_delay 300 618debug 619} 620 621virtual_server_group <STRING> { 622# VIP port 623<IPADDR> <PORT> 624<IPADDR> <PORT> 625fwmark <INT> 626} 627 628virtual_server 192.168.1.2 80 { 629delay_loop 3 630 631lb_algo rr|wrr|lc|wlc|lblc|sh|dh 632lb_kind NAT|DR|TUN 633persistence_timeout 120 634persistence_granularity <NETMASK> 635protocol TCP 636ha_suspend 637virtualhost <string> 638 639sorry_server <IPADDR> <PORT> 640 641real_server <IPADDR> <PORT> 642{ 643weight 1 644inhibit_on_failure 645notify_up <STRING> | <QUOTED-STRING> 646notify_down <STRING> | <QUOTED-STRING> 647 648#HTTP_GET方式 649HTTP_GET | SSL_GET 650{ 651url { 652path / 653digest <STRING> 654status_code 200 655} 656connect_port 80 657 658bindto <IPADD> 659connect_timeout 3 660nb_get_retry 3 661delay_before_retry 2 662} 663} 664} 665复制代码 666 667Keepalived双机热备 668 669这里我们仅仅只利用Keepalive做双机热备,也就是保证服务器的高可用性,其他的不用管。可能您会说这样在实际应用中很少会这样用,这您可就错了,Keepalived仅仅做双机热备的情况还是有的,我就碰到过几次这样的案例,下面就我碰到的几个案例做个小结 670 671一,Keepalived双机热备的应用场景 672 6731,网站流量不高,压力不大,但是对服务器的可靠性要求极其高,例如实时在线OA系统,政府部门网站系统,医院实时报医系统,公安局在线报案系统,股市后台网站系统等等,他们的压力不是很大,但是对可靠性要求是非常高的 674 6752,有钱没地方花的,典型的政府企业,公办学校等等 676 677二,Keepalived双机热备的特性以及优缺点 678 679特性: 6801,至少需要两台服务器,其中一台为master始终提供服务,另外一台作为backup始终处于空闲状态,只有在主服务器挂掉的时候他就来帮忙了,这是典型的双击热备 681 6822,能根据需求判断服务是否可用,在不可用的时候要即使切换 683优缺点: 684 685优点:数据同步非常简单,不像负载均衡对数据一致性要求非常高,实现起来相对复杂维护也颇为不便,双机热备用rsync就可以实现了操作和维护非常简单 686 687缺点:服务器有点浪费,始终有一台处于空闲状态 688 689 690三,Keepalived双机热备的配置 691首先画个双机热备拓扑图吧: 692 693 694 695 696这里我只写最终实现的配置,至于Keepalived的理论知识请参考《Keepalived原理与实战精讲》 697 6981,本例通过Keepalived来实现两台LNMP(也就是linux+nginx+mysql+php)架构服务器的双机热备 699 700LNMP的配置请参考:《Lnmp配置精讲第一版》 701 7022,Keepalived配置双机安装配置 703 7041》Keepalived安装 705 706keepalived官方地址:http://www.keepalived.org/download.html,大家可以到这里下载最新版本的keepalived 707 708操作系统:centos 5.5 32bit 709系统安装:最小化安装,也就是去掉所有组件 710环境配置:安装make 和 gcc openssl openssl-devel等等 711yum -y install gcc make openssl openssl-devel wget kernel-devel 712mkdir -p /usr/local/src/hasoft 713cd /usr/local/src/hasoft 714wget http://www.keepalived.org/software/keepalived-1.2.2.tar.gz 715tar -zxvf keepalived-1.2.2.tar.gz 716cd keepalived-1.2.2 717./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-238.19.1.el5-i686/ 718复制代码 719预编译后出现: 720Keepalived configuration 721------------------------ 722Keepalived version : 1.2.2 723Compiler : gcc 724Compiler flags : -g -O2 -DETHERTYPE_IPV6=0x86dd 725Extra Lib : -lpopt -lssl -lcrypto 726Use IPVS Framework : Yes 727IPVS sync daemon support : Yes 728IPVS use libnl : No 729Use VRRP Framework : Yes 730Use Debug flags : No 731复制代码 732make && make install 733复制代码 734这里注意哦,我上面是指通用的安装方法,如果你没有用到LVS可以把lvs去掉即 735./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-238.19.1.el5-i686/ --disable-lvs-syncd --disable-lvs 736 737但这个没有影响,就按照我的来配置吧,不过如果你要是集成了LVS,那么就不可加这两个参数了哦 738 739整理管理文件: 740cp /usr/local/keepalived/sbin/keepalived /usr/sbin/ 741cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ 742cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/ 743 744 745建立配置文件目录(注意:keepalived的配置文件默认在/etc/keepalived/目录) 746mkdir -p /etc/etc/keepalived/ 747 748两台服务器(两个节点)都这样安装即可 749 7502》配置 751 752节点A配置如下: 753vi /etc/keepalived/keepalived.conf 754global_defs 755{ 756notification_email 757{ 758admin@example.com 759admin@ywlm.net 760} 761notification_email_from admin@example.com 762smtp_server 127.0.0.1 763stmp_connect_timeout 30 764router_id lnmp_node1 765} 766 767vrrp_instance lnmp { 768state MASTER 769interface eth0 770virtual_router_id 100 771priority 200 772advert_int 5 773track_interface { 774eth0 775eth1 776} 777authentication { 778auth_type PASS 779auth_pass 123456 780} 781virtual_ipaddress { 782192.168.17.200 783} 784} 785复制代码 786 787节点B配置如下: 788vi /etc/keepalived/keepalived.conf 789 790global_defs 791{ 792notification_email 793{ 794admin@example.com 795admin@ywlm.net 796} 797notification_email_from admin@example.com 798smtp_server 127.0.0.1 799stmp_connect_timeout 30 800router_id lnmp_node1 801} 802 803vrrp_instance lnmp { 804state MASTER 805interface eth0 806virtual_router_id 100 807priority 150 808advert_int 5 809track_interface { 810eth0 811eth1 812} 813authentication { 814auth_type PASS 815auth_pass 123456 816} 817virtual_ipaddress { 818192.168.17.200 819} 820} 821复制代码 822四,启动调试 823在节点A上启动 824/usr/local/keepalived/sbin/keepalived 825 826启动日志: 827Sep 8 18:26:02 centosa Keepalived_vrrp: Registering Kernel netlink reflector 828Sep 8 18:26:02 centosa Keepalived_vrrp: Registering Kernel netlink command channel 829Sep 8 18:26:02 centosa Keepalived_vrrp: Registering gratutious ARP shared channel 830Sep 8 18:26:02 centosa Keepalived_vrrp: Opening file '/etc/keepalived/keepalived.conf'. 831Sep 8 18:26:02 centosa Keepalived_vrrp: Configuration is using : 36076 Bytes 832Sep 8 18:26:02 centosa Keepalived_vrrp: Using LinkWatch kernel netlink reflector... 833Sep 8 18:26:02 centosa Keepalived: Starting VRRP child process, pid=5606 834Sep 8 18:26:07 centosa Keepalived_vrrp: VRRP_Instance(lnmp) Transition to MASTER STATE 835Sep 8 18:26:12 centosa Keepalived_vrrp: VRRP_Instance(lnmp) Entering MASTER STATE 836Sep 8 18:26:12 centosa avahi-daemon[2528]: Registering new address record for 192.168.17.200 on eth0. 837 838 839在节点B上启动 840/usr/local/keepalived/sbin/keepalived 841 842开机自动启动 843echo /usr/local/keepalived/sbin/keepalived >> /etc/rc.local 844 845启动日志: 846Sep 8 18:30:02 centosb Keepalived: Starting Keepalived v1.2.2 (09/08,2011) 847Sep 8 18:30:02 centosb Keepalived: Starting Healthcheck child process, pid=5837 848Sep 8 18:30:02 centosb Keepalived_vrrp: Registering Kernel netlink reflector 849Sep 8 18:30:02 centosb Keepalived_vrrp: Registering Kernel netlink command channel 850Sep 8 18:30:02 centosb Keepalived_vrrp: Registering gratutious ARP shared channel 851Sep 8 18:30:02 centosb Keepalived: Starting VRRP child process, pid=5839 852Sep 8 18:30:02 centosb kernel: IPVS: Registered protocols (TCP, UDP, AH, ESP) 853Sep 8 18:30:02 centosb kernel: IPVS: Connection hash table configured (size=4096, memory=32Kbytes) 854Sep 8 18:30:02 centosb kernel: IPVS: ipvs loaded. 855Sep 8 18:30:02 centosb Keepalived_healthcheckers: Registering Kernel netlink reflector 856Sep 8 18:30:02 centosb Keepalived_healthcheckers: Registering Kernel netlink command channel 857Sep 8 18:30:02 centosb Keepalived_healthcheckers: Opening file '/etc/keepalived/keepalived.conf'. 858Sep 8 18:30:02 centosb Keepalived_vrrp: Opening file '/etc/keepalived/keepalived.conf'. 859Sep 8 18:30:02 centosb Keepalived_vrrp: Configuration is using : 36252 Bytes 860Sep 8 18:30:02 centosb Keepalived_vrrp: Using LinkWatch kernel netlink reflector... 861Sep 8 18:30:02 centosb Keepalived_healthcheckers: Configuration is using : 6271 Bytes 862Sep 8 18:30:02 centosb Keepalived_healthcheckers: Using LinkWatch kernel netlink reflector... 863Sep 8 18:30:02 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Entering BACKUP STATE 864 865从日志可以看出,启动都没有问题,并且安装我给的优先级完成了竞选,各自成就了各自的状态 866 867关闭节点A的网卡测试切换是否正常 868ifdown eth0 869 870观察节点B的日志: 871Sep 8 18:32:55 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Transition to MASTER STATE 872Sep 8 18:33:00 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Entering MASTER STATE 873Sep 8 18:33:00 centosb avahi-daemon[2531]: Registering new address record for 192.168.17.200 on eth0. 874 875 876启动节点A的网卡测试切换是否正常 877ifup eth0 878观察节点B的日志: 879Sep 8 18:33:31 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Received higher prio advert 880Sep 8 18:33:31 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Entering BACKUP STATE 881Sep 8 18:33:31 centosb avahi-daemon[2531]: Withdrawing address record for 192.168.17.200 on eth0. 882 883Received higher prio advert:表示接收到更高优先级的公告(advert公告的意思) 884Withdrawing:撤回的意思,可以看出切换过程一目了然 885 886 887OK,到这里我们的安装部分完成,下面我们来看看如何监控服务吧,我们这里仅仅是监控了网络故障和keepalived本身进程,在网络或者keepalived进程出现问题的时候会切换,但是我的节点A里面还有很多服务呢,例如nginx,PHP,mysql进程出问题或高负载的时候相应过慢怎么办,怎么切换的呢,这时就要用到脚本了,下面我们来看看keepalived是如何控制脚本来实现对服务器的监控和切换的 888 889写个脚本来实时监控三个服务,若有一个出现问题遍切换mkdir /root/shell/ 890cd /root/shell 891vi keepcheck.sh 892#!/bin/bash 893while : 894do 895mysqlcheck=`/usr/local/lnmp/mysql/bin/mysqladmin -uroot ping 2>&1` 896mysqlcode=`echo $?` 897phpcheck=`ps -C php-fpm --no-header | wc -l` 898nginxcheck=`ps -C nginx --no-header | wc -l` 899keepalivedcheck=`ps -C keepalived --no-header | wc -l` 900if [ $nginxcheck -eq 0 ]|| [ $phpcheck -eq 0 ]||[ $mysqlcode -ne 0 ];then 901 if [ $keepalivedcheck -ne 0 ];then 902 killall -TERM keepalived 903 else 904 echo "keepalived is stoped" 905 fi 906 else 907 if [ $keepalivedcheck -eq 0 ];then 908 /etc/init.d/keepalived start 909 else 910 echo "keepalived is running" 911 fi 912fi 913sleep 5 914done 915 916复制代码 917注意,用/etc/init.d/keepalived start如果起不来,可以用/usr/local/keepalived/sbin/keepalived二进制文件直接执行启动即可 918启动脚本: 919chmod +x /root/shell/keepcheck.sh 920nohup sh /root/shell/keepcheck.sh & 921复制代码 922节点B也用这个脚本 923 924写入/etc/rc.local开机自动启动 925 926echo "nohup sh /root/shell/keepcheck.sh &" >> /etc/rc.loal 927复制代码 928*****************************以下为个人总结的高可用问题分析**************************** 929 930 931 9321.“脑裂问题” 933 934两台真实主机A和B,A为MASTER,B为BACKUP,通过keepalived虚拟出VIP。A服务器的iptables是开启的规则为iptables -L -n --line-numbers 935Chain INPUT (policy ACCEPT) 936num target prot opt source destination 9371 DROP all -- 0.0.0.0/0 224.0.0.18 9382 DROP all -- 224.0.0.18 0.0.0.0/0 939 940Chain FORWARD (policy ACCEPT) 941num target prot opt source destination 942 943Chain OUTPUT (policy ACCEPT) 944num target prot opt source destination 9451 ACCEPT all -- 0.0.0.0/0 224.0.0.18 9462 ACCEPT all -- 224.0.0.18 0.0.0.0/0 947 948B服务器的规则为 949 950iptables -L -n --line-numbers 951Chain INPUT (policy ACCEPT) 952num target prot opt source destination 9531 DROP all -- 0.0.0.0/0 224.0.0.18 9542 DROP all -- 224.0.0.18 0.0.0.0/0 955 956Chain FORWARD (policy ACCEPT) 957num target prot opt source destination 958 959Chain OUTPUT (policy ACCEPT) 960num target prot opt source destination 9611 ACCEPT all -- 0.0.0.0/0 224.0.0.18 9622 ACCEPT all -- 224.0.0.18 0.0.0.0/0 963 964 965那么我们通过日志看到B会将自己也提升为MASTER,同时A也是MASTER,这样就会出现VIP争抢现象。如果我将B的iptables停止,那么一切都正常。以下为争抢日志 966LVS-slave :Sep 1 10:39:20 localhost Keepalived_vrrp[127534]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 192.168.1.233 967Sep 1 10:39:20 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 968Sep 1 10:39:20 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 969Sep 1 10:39:20 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 970Sep 1 10:39:20 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 971Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.222 972Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: VRRP_Instance(VI_2) Sending/queueing gratuitous ARPs on eth0 for 192.168.1.222 973Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.222 974Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.222 975Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.222 976Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.222 977Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 978Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 192.168.1.233 979Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 980Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 981Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 982Sep 1 10:39:25 localhost Keepalived_vrrp[127534]: Sending gratuitous ARP on eth0 for 192.168.1.233 983 984**************************************************************************************************************************************************** 985 986LVS-master: Sep 1 10:39:15 localhost Keepalived_healthcheckers[5431]: Netlink reflector reports IP 192.168.1.222 added 987Sep 1 10:39:15 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 988Sep 1 10:39:15 localhost Keepalived_vrrp[5432]: VRRP_Instance(VI_2) Sending/queueing gratuitous ARPs on eth0 for 192.168.1.222 989Sep 1 10:39:15 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 990Sep 1 10:39:15 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 991Sep 1 10:39:15 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 992Sep 1 10:39:15 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 993Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.233 994Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 192.168.1.233 995Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.233 996Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.233 997Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.233 998Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.233 999Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 1000Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: VRRP_Instance(VI_2) Sending/queueing gratuitous ARPs on eth0 for 192.168.1.222 1001Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 1002Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 1003Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222 1004Sep 1 10:39:20 localhost Keepalived_vrrp[5432]: Sending gratuitous ARP on eth0 for 192.168.1.222
Keepalived原理与实战精讲
Stella981
2021-10-11
1074 0 0
点赞
收藏
评论区
加载中...