分享

Keepalived原理

 阅知人生百态 2018-03-10

简介

Keepalived:高可用或热备软件,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构不可用)的发生,keepalived就是VRRP协议的实现。
 

Keepalived原理

原理

Keepalived采用是模块化设计,不同模块实现不同的功能,keepalived主要有三个模块,分别是core、check和vrrp。 core是keepalived的核心,负责主进程的启动和维护,全局配置文件的加载解析等 check 负责healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置的解析包括LVS的配置解析;
可基于脚本检查对IPVS后端服务器健康状况进行检查。 vrrpVRRPD子进程,VRRPD子进程就是来实现VRRP协议的
以上是主要组件;下面是其他库: libipfwc:iptables/ipchains库,配置LVS会用到 libipvs*:配置LVS会用到
注意,keepalived和LVS完全是两码事,各司其职相互配合。
架构图 Keepalived原理-很简单  
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
{

  1. 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)
 
  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多