简介
Keepalived:高可用或热备软件,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构不可用)的发生,keepalived就是VRRP协议的实现。
Keepalived原理
原理
Keepalived采用是模块化设计,不同模块实现不同的功能,keepalived主要有三个模块,分别是core、check和vrrp。 core:是keepalived的核心,负责主进程的启动和维护,全局配置文件的加载解析等 check: 负责healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置的解析包括LVS的配置解析; 可基于脚本检查对IPVS后端服务器健康状况进行检查。 vrrp:VRRPD子进程,VRRPD子进程就是来实现VRRP协议的 以上是主要组件;下面是其他库: libipfwc:iptables/ipchains库,配置LVS会用到 libipvs*:配置LVS会用到 注意,keepalived和LVS完全是两码事,各司其职相互配合。 架构图 Keepalived启动后会有三个进程: 父进程:内存管理,子进程管理等等 子进程:vrrpd子进程 子进程:healthchecker子进程 由上图可知,两个子进程都被系统WatchDog看管,两个子进程各自实现自己的事,healthchecker子进程实现检查各自服务器的健康程度,例如HTTP,LVS等等,如果healthchecker子进程检查到MASTER上服务不可用,就会通知本机上的兄弟VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态
工作原理
keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是第3层、第4层和第5层交换,分别工作在IP/TCP协议栈的IP层、TCP层、应用层,原理分别如下: Layer3: Keepalived使用Layer3的方式工作式时,Keepalived会定期向服务器群中的服务器发送一个ICMP的数据包(既Ping),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除(这种情况的典型例子是某台服务器被非法关机)。Layer3方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。 Layer4: Layer4主要以TCP端口的状态来决定服务器工作正常与否。如web server的服务端口一般是80,如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。 Layer5: Layer5就是工作在具体的应用层了,比Layer3,Layer4要复杂,在网络上占用的带宽也要大一些。Keepalived将根据用户的设定检查服务器相应服务是否运行正常,如果没有正常运行,则Keepalived将把服务器从服务器群中剔除。
Keepalived配置文件
Keepalived配置文件为:keepalived.conf;主要有三个配置区域,分别是: 全局配置(Global Configuration) VRRPD配置 LVS配置 以下分别介绍三个配置区域
全局配置
全局配置又包括两个子配置: 全局定义(global definition) 静态IP地址/路由配置(static ipaddress/routes)
1.全局定义(global definition)
全局定义由 global_defs 来标识,并以大括号 ”{}” 来标记该区域 例: global_defs { notification_email { admin@example.com admin@abc.com } notification_email_from admin@example.com smtp_server 127.0.0.1 stmp_connect_timeout 30 enable_traps router_id node1 } 配置解析: global_defs 全局配置标识,表面这个 区域{} 是全局配置; notification_email 表示在故障发生时给谁发送邮件通知,可以有多个,每行一个; notification_email_from 表示发送通知邮件时邮件源地址是谁; smtp_server 表示发送email时使用的smtp服务器地址,例中使用本地的sendmail来实现; smtp_connect_timeout 连接smtp连接超时时间 enable_traps 开启SNMP陷阱(见Simple Network Management Protocol)。 router_id 机器标识,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到。
2.静态IP地址/路由配置(建议忽略)
由 static_ipaddress 和 static_routes 来标识,指定本节点的IP地址和路由信息。如果机器已经配置了IP地址和路由,这两个区域不用设置。一般情况下机器都会有IP地址和路由信息的,因此没必要再在这两个区域配置。 例: static_ipaddress {
0.0.1/24 brd 10.0.0.255 dev eth0
192.168.1.1/24 brd + dev eth1 scope global } static_routes { src $SRC_IP to $DST_IP dev $SRC_DEVICE src $SRC_IP to $DST_IP via $GW dev $SRC_DEVICE } } 以上分别表示启动/关闭keepalived时在本机执行的如下命令: 开启时执行: # ip addr add 10. 0.0.1/24 brd 10.0.0.255 dev eth0 # ip addr add 192.168.1.1/24 brd + dev eth1 scope global 关闭时执行: # ip addr del 10. 0.0.1/24 brd 10.0.0.255 dev eth0 # ip addr del 192.168.1.1/24 brd + dev eth1 scope global 路由同理。 注意: 请忽略这两个区域,因为我坚信你的机器肯定已经配置了IP和路由; 在复杂的环境下可能需要配置,一般不会用这个来配置,我们可以直接用vi /etc/sysconfig/network-script/ifcfg-eth1来配置,切记这里可不是VIP
VRRPD配置
VRRPD配置包括3个子配置区域: VRRP同步组(synchronization group) VRRP实例(VRRP instace) VRRP脚本(VRRP script) 其中: VRRP同步组用 vrrp_sync_group 来标识; VRRP实例用 vrrp_instance 来标识; VRRP脚本用 vrrp_script 来标识。 vrrp_instance用来定义对外提供服务的VIP区域及其相关属性。 vrrp_sync_group用来定义vrrp_intance组,使得这个组内成员动作一致。 举个例子来说明一下其功能: 两个vrrp_instance同属于一个vrrp_sync_group,那么其中一个vrrp_instance发生故障切换时,另一个vrrp_instance也会跟着切换(即使这个instance没有发生故障)。
1.VRRP同步组
用 vrrp_sync_group <同步组名> 来标识, <同步组名>指定本同步组的名字。 virtual_server_group一般在超大型的LVS中用到,普通的LVS架构不需要用该项配置。 例: vrrp_sync_group VG_1 { group { http # 实例名 mysql # 实例名 } notify_master /path/to/to_master.sh notify_backup /path_to/to_backup.sh notify_fault "/path/fault.sh VG_1" notify /path/to/notify.sh smtp_alert } 配置解析: group 定义实例,http和mysql是实例名,和下面的实例名一致 notify_master/backup/fault 分别表示切换为 主/备/出错 时所执行的脚本。 notify 表示任何状态切换时都会调用该脚本,并且该脚本在以上三个脚本执行完成之后进行调用,keepalived会自动传递三个参数($1 = "GROUP"|"INSTANCE",$2 = name of group or instance,$3 = target state of transition(MASTER/BACKUP/FAULT))。 smtp_alert 表示切换时是否开启邮件通知(用全局区域的邮件设置来发通知)。
2. VRRP实例
用 vrrp_instance <实例名> 来标识,<实例名>是由 vrrp_sync_group 中的group定义的。 例: vrrp_instance http { state MASTER interface eth0 dont_track_primary track_interface { eth0 eth1 } mcast_src_ip <IPADDR> garp_master_delay 10 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS autp_pass 1234 } virtual_ipaddress { #<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> 192.168.200.17/24 dev eth1 192.168.200.18/24 dev eth2 label eth2:1 } virtual_routes { # src <IPADDR> [to] <IPADDR>/<MASK> via|gw <IPADDR> dev <STRING> scope <SCOPE> tab src 192.168.100.1 to 192.168.109.0/24 via 192.168.200.254 dev eth1 192.168.110.0/24 via 192.168.200.254 dev eth1 192.168.111.0/24 dev eth2 192.168.112.0/24 via 192.168.100.254 } nopreempt preemtp_delay 300 debug } 配置解析: state:state指定instance(Initial)的初始状态 MASTER/BACKUP,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定,里如果这里设置为master,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为master,因此该项其实没有实质用途。 interface:实例绑定的网卡(非VIP网卡),用来发VRRP包 dont_track_primary:忽略VRRP的interface错误(默认未设置) track_interface:监控以下网卡,设置额外的监控,里面任意一块网卡出现问题,都会进入故障(FAULT)状态,例如,用nginx做均衡器的时候,内网必须正常工作,如果内网出问题了,这个均衡器也就无法运作了,所以必须对内外网同时做健康检查。(可选) mcast_src_ip:发送多播数据包时的源IP地址,默认源地址为MASTER的IP,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址. garp_master_delay:在切换到master状态后,延迟进行免费的ARP(gratuitous ARP)请求 virtual_router_id:设置VRID,取值在0~255之间,用来区分多个instance的VRRP组播,相同的VRID为一组,该值将决定多播的MAC地址(同一网段内不能重复,否则会出错). priority 100:设置本节点的优先级,优先级高的为master,取值为1~255,超过该值则默认为100。要成为MASTER,该值最好高于其他机器50个点。 advert_int:检查间隔,默认为1秒。就是发送VRRP包的时间间隔。 virtual_ipaddress:这里设置的就是VIP,也就是虚拟IP地址(可设置多个VIP),他随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系。 virtual_routes:原理和virtual ipaddress一样,只不过这里是增加和删除路由 lvs_sync_daemon_interface:lvs syncd绑定的网卡 authentication:这里设置认证 auth type:认证方式,可以是PASS或AH两种认证方式 auth pass:认证密码(pass方式密码只识别前8位) nopreempt:设置不抢占,这里只能设置在state为backup的节点上,而且这个节点的优先级必须特别的高。 preempt delay:抢占延迟 debug:debug级别 notify_master:和sync_group设置的含义一样,可以单独设置,例如不同的实例通知不同的管理人员,http实例发给网站管理员,mysql的就发邮件给DBA
3.VRRP脚本
用vrrp_script表示,在vrrp_script区域定义脚本名字和脚本执行的间隔和脚本执行的优先级变更 例: vrrp_script check_running { script "/usr/local/bin/check_running" interval 10 weight 10 } vrrp_instance http { state BACKUP smtp_alert interface eth0 virtual_router_id 101 priority 90 advert_int 3 authentication { auth_type PASS auth_pass whatever } virtual_ipaddress { 1.1.1.1 } track_script { check_running weight 20 } } 配置解析: vrrp_script check_running { script "/usr/local/bin/check_running" #指定脚本文件位置 interval 10 #脚本执行间隔 weight 10 #脚本结果导致的优先级变更:10表示优先级+10;-10则表示优先级-10 } 然后在实例(vrrp_instance)里面引用,有点类似脚本里面的函数引用一样:先定义,后引用函数名 track_script { check_running weight 20 } 注意: VRRP脚本(vrrp_script)和VRRP实例(vrrp_instance)属于同一个级别
LVS配置
这段配置是为LVS + Keepalived准备的,如果用的是nginx来代替LVS,则无需配置,这里的LVS配置是专门为keepalived + LVS集成准备的。 注意: 这里LVS配置并不是指真的安装LVS然后用 ipvsadm 来配置他,而是用keepalived的配置文件来代替ipvsadm配置LVS,这样维护,配置方便些! LVS配置包括两个子配置: 虚拟主机组配置 虚拟主机配置
1.虚拟主机组配置
该配置是可选的,根据需求来配置,该项配置主要是为了让一台realserver上的某服务可以属于多个Virtual Server,并且只做一次健康检查。 使用 virtual_server_group 来标识 例: virtual_server_group <STRING> { # VIP port <IPADDR> <PORT> <IPADDR> <PORT> fwmark <INT> }
2.虚拟主机配置
使用 virtual_server 来标识,可以使用以下三种方式的任意一种来配置: virtual_server IP port virtual_server fwmark int virtual_server group string 其中,第一种较为常见,下面使用第一种方式来解说 例: virtual_server 192.168.1.2 80 { #设置一个virtual server: ip : port delay_loop 3 # service polling的delay时间,即服务轮询的时间间隔 lb_algo rr|wrr|lc|wlc|lblc|sh|dh #LVS调度算法,也就是后端的调度算法 lb_kind NAT|DR|TUN #LVS负载均衡技术,NAT、DR、TUN persistence_timeout 120 #会话保持时间(秒),即用户在120秒内被分配到同一个后端realserver persistence_granularity <NETMASK> #LVS会话保持粒度,ipvsadm中的-M参数,默认是0xffffffff,即每个客户端都做会话保持 protocol TCP #健康检查是TCP还是UDP ha_suspend #suspendhealthchecker’s activity virtualhost <string> #HTTP_GET做健康检查时,检查的web服务器头中的host(即host:头) sorry_server <IPADDR> <PORT> #备用机,就是当所有后端realserver节点都不可用时,就用这里设置的,也就是临时把所有的请求都发送到这里啦 real_server <IPADDR> <PORT> #定义后端真实主机的权重等设置,后端有几台就设置几个 { weight 1 #给每台的权重,0表示失效(不知给他转发请求知道他恢复正常),默认是1 inhibit_on_failure #表示在节点失败后,把他权重设置成0,而不是冲IPVS中删除 notify_up <STRING> | <QUOTED-STRING> #检查服务器正常(UP)后,要执行的脚本 notify_down <STRING> | <QUOTED-STRING> #检查服务器失败(down)后,要执行的脚本 HTTP_GET #健康检查方式 { url { #要检查的URL,可以有多个 path / #具体路径 digest <STRING> status_code 200 #返回状态码 } connect_port 80 #监控检查的端口 bindto <IPADD> #健康检查的IP地址 connect_timeout 3 #连接超时时间 nb_get_retry 3 #重连次数 delay_before_retry 2 #重连间隔 } # END OF HTTP_GET|SSL_GET #下面是常用的健康检查方式,有HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK这些 #TCP方式 TCP_CHECK { connect_port 80 bindto 192.168.1.1 connect_timeout 4 } # TCP_CHECK # SMTP方式,这个可以用来给邮件服务器做集群 SMTP_CHECK { host { connect_ip <IP ADDRESS> connect_port <PORT> #默认检查25端口 14 KEEPALIVED bindto <IP ADDRESS> } connect_timeout <INTEGER> retry <INTEGER> delay_before_retry <INTEGER> helo_name <STRING>|<QUOTED-STRING> } #SMTP_CHECK #MISC方式,这个可以用来检查很多服务器只需要自己会些脚本即可 MISC_CHECK { misc_path <STRING>|<QUOTED-STRING> #外部程序或脚本 misc_timeout <INT> #脚本或程序执行超时时间 misc_dynamic #可以精确的调整权重,是后端每天服务器的压力都能均衡调配,主要是根据执行的程序或脚本返回值来动态调整weight值,使权重根据真实的后端压力来适当调整,需要有过硬的脚本 #返回0:健康检查没问题,不修改权重 #返回1:健康检查失败,权重设置为0 #返回2-255:健康检查没问题,但是权重却要根据返回代码修改为返回码-2,例如如果程序或脚本执行后返回的代码为200,#那么权重这回被修改为 200-2 } } # Realserver } # Virtual Server
其他
Keepalived主从切换
主从切换比较麻烦,需要将backup配置文件的priority选项的值调整的比master高50个点,然后reload配置文件就可以切换了。也可以将master的keepalived停止,这样也可以进行主从切换。 更多的是让keepalived根据VRRP协议自动切换不手动切换。
Keepalived仅做HA配置
请看该文档同级目录下的配置文件示例。 说明: 10.210.214.113 为keepalived的备机,其配置文件为113.keepalived.conf 10.210.214.163 为keepalived的主机,其配置文件为163.keepalived.conf 10.210.214.253 为Virtual IP,即提供服务的内网IP地址,在网卡eth0上面 192.168.1.11 为模拟的提供服务的公网IP地址,在网卡eth1上面 用tcpdump命令来捕获的结果如下: 17:20:07.919419 IP 10.210.214.163 > 224.0.0.18: VRRPv2, Advertisement, vrid 1, prio 200, authtype simple, intvl 1s, length 20
LVS+keepalived配置
Keepalived与LVS结合使用时一般还会用到一个工具ipvsadm,用来查看相关VS相关状态。 10.67.15.95为keepalived master,VIP为10.67.15.94,配置文件为95-lvs-keepalived.conf 10.67.15.96为keepalived master,VIP为10.67.15.94,配置文件为96-lvs-keepalived.conf 10.67.15.195为real server 注意: 当使用LVS+DR+Keepalived配置时,需要在real server上添加一条iptables规则(其中dport根据情况添加或缺省): # iptables -t nat -A PREROUTING -p tcp -d 10.67.15.94 --dport 80 -j REDIRECT 当使用LVS+NAT+Keepalived配置时,需要将real server的默认路由配置成Director的VIP 10.67.15.94 ,必须确保client的请求是通过 10.67.15.94 到达real server的。
安装keepalived
从keepalived下载合适的版本,解压并执行如下命令完成安装。 # cd keepalived-xxx # ./configure --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --mandir=/usr/share # make && make install 也可以打成RPM包,然后安装。 Redhat系列建议从EPEL安装,EPEL地址: Http://dl.fedoraproject.org/pub/epel
说明
我们用到的HA场景如下: 两台主机host113和host163,内网IP在eth1网卡上,分别是10.210.214.113和10.210.214.163,VIP为公网IP在eth0上,IP地址是202.102.152.253,网关为202.102.152.1。当VIP在host113上提供服务时,host113上的默认路由为202.102.152.1,提供服务的端口为202.102.152.253:443。host113发生故障需要将VIP及服务切回到host163上的时候,需要以下几步,第一将VIP接管过来,第二添加默认路由202.102.152.1,第三启动在端口202.102.152.253:443上的服务。 如此一来,keepalived需要另外的脚本来完成添加默认路由和启动服务工作,这点和heartbeat中的resources是相同的。目前我进行了测试,发现keepalived速度要比heartbeat快,也就是说效率比heartbeat高。并且,最重要的一点,keepalived支持多个backup。 不要问我为何有以上需求。要为两个不同的域名提供https服务,由于SSL证书问题,必须有两个公网IP地址分别绑定443端口。 当然,通过SNI也可以实现一个公网IP绑定443端口来为多个域名提供https服务,但是这需要浏览器支持(M$的IE浏览器不支持)。(nginx/apache)
|