keepalive基础知识
一、LVS负载均衡集群的缺点
二、Keepalived介绍
三、Keepalived的功能
四、Keepalived工作原理
五、Keepalived组件框架
六、Keepalived的安装
6.1 高可用集群配置的前提
6.2 Keepalived配置
6.3 Keepalived高可用其它服务
一、LVS负载均衡集群的缺点
在之前的一篇博客中介绍了有关LVS的工作原理,详情可参考《LVS工作原理》。LVS能够实现四层负载,能够支持足够大的并发量,但使用LVS负载均衡集群有以下两个缺点。
① 如果调度器(Director)挂了(不可用),将会导致整个系统不可用,从而调度器成为了单点故障(SPOF)。
② 调度器(Director)无法对后端RealServer做健康状态检测。因此,如果后端的某一台RealServer挂了,前端调度器将无法得知,仍然会向该RealServer调度请求,导致服务不可用;另外,如果某一台挂了的RealServer但已经恢复正常并重新提供服务时,前端调度器也无法得知,并将其加入调度队列。
因此,为了能够使前端调度器(Director)能够冗余、使Director能够对后端各RS做健康状态检测,并按需增删RS,需要引入高可用集群的解决方案。以下介绍的是Keepalived高可用软件。
二、Keepalived介绍
Keepalived是VRRP协议的实现,原生设计目的是高可用IPVS服务。此外,Keepalived能够根据配置文件的规则生成IPVS规则,并能够对各RealServer的健康状态进行检测。
Keepalived的高可用功能是通过VRRP协议实现的,VRRP是Virtual Router Redundancy Protocol(虚拟路由器冗余协议)的缩写。VRRP的出现是为了解决静态路由单点故障的问题,当某一节点出现故障时,可以防止导致整个网络不可用。Keepalived除了可以高可用LVS之外,还可以作为其他系统网络服务(Nginx、Haproxy等)的高可用解决方案(Keepalived可通过调用vrrp_script来高可用其它服务,并通过调用vrrp_track来追踪每一个服务)。
三、Keepalived的功能
Keepalived有三个重要功能,如下。
(1) 高可用系统网络服务。
Keepalived可以实现在两台或多台主机之间的故障切换转移。如果在两台主机中都安装了Keepalived,当正常工作时,有一台主机工作为Master角色,另一台主机工作为Backup角色。角色为Master的主机获得所有资源(VIP资源、服务资源)并向用户提供服务,角色为Backup的主机不提供服务而仅作为Master主机的热备。当角色为Master的主机出现故障时,角色为Backup的主机将自动接管Master主机的所有资源(VIP资源、服务资源)并开始工作。当Master主机故障修复完成时,将重新接管原来的资源和工作,而Backup主机则释放Master主机故障时它接管的资源和工作,各自恢复原来的角色。
(2) 实现对LVS集群中各RealServer的健康状态进行检测。
Keepalived可以通过在自身配置文件keepalived.conf中配置LVS集群服务中各台RealServer的IP地址和相关参数,并可以通过网络层、传输层和应用层这三层进行探测各RealServer的健康状态。当有一台或多台RealServer出现故障而无法提供服务时,Keepalived服务可以把出现故障的RealServer从LVS的正常转发队列中移除,保证不影响用户的访问。而当有RealServer故障修复完成时,Keepalived服务可以将其重新加入LVS的正常转发队列中,向用户提供服务。
(3) 管理LVS负载均衡软件。
Keepalived可以读取配置文件,并通过一个更为底层的接口来管理IPVS并生成IPVS规则,这使得LVS的使用更为方便。
四、Keepalived工作原理
前面提到,Keepalived的高可用功能是通过VRRP协议实现的,要了解Keepalived的工作原理,需要先了解VRRP协议的工作原理。
4.1 VRRP工作原理
VRRP,是Virtual Router Redundancy Protocol的缩写,中文名为虚拟路由器冗余协议。VRRP的出现是为了解决静态路由的单点故障问题,早期应用于交换机、路由器等设备中。VRRP协议是通过竞选机制来实现将路由任务交给某一台VRRP路由器的。
在一组VRRP路由器中,可以有多台物理路由器,但只有一台称为Master的路由器负责路由任务(响应ARP请求、转发发送给网关的数据包),而其他路由器都是Backup角色。Master和Backup是通过竞选机制选举出来的,这种竞选机制是根据优先级的高低来选举,在这一组VRRP路由器中优先级最高的路由器就是Master,其他路由器为Backup。Master路由器需要基于IP组播(默认组播地址为224.0.0.18)的方式发送心跳消息给其它的Backup路由器,告诉其它路由器自己还活着,同时告知Master自己的优先级。而当Master路由器发生故障时,就没法发送心跳消息,这样Backup路由器就检测不到Master的心跳消息了,这时多台Backup路由器就会再通过同样的竞选机制,选举出优先级最高的一台作为新的Master路由器,并接管路由任务(响应ARP请求、转发发送给网关的数据包)。
虚拟路由器由VRID(虚拟路由器标识,0-255),对外部则表现为一个VMAC(Virtual MAC)地址:00-00-5E-00-01-{VRID}和一个VIP(Virtual IP)。
4.2 Keepalived工作原理
Keepalived服务的高可用对之间的通信是基于VRRP协议进行通信的,VRRP是通过竞选机制来确定主、备节点的,主节点的优先级高于备节点。当Keepalived服务正常工作时,主Master节点接管IP资源和服务资源,向用户提供服务,并不断地向备Backup节点发送心跳消息(以组播的方式),用以告知备节点自己还活着,而备节点收到心跳消息后,一方面得知主节点还活着,另一方面得知主节点的优先级仍高于自己,因此不敢“犯上”。当主Master节点出现故障时,就无法发送心跳消息,所以备Backup节点就收不到主节点发来的心跳消息,这时所有备节点就会再此互相发送协议报文进行协商(再次进行竞选),各备节点将自己的优先级通告给所有其他备节点,最后优先级高的备节点则为新的主Master节点,由其调用自身的接管程序接管之前主节点的IP资源和服务资源,向用户提供服务。当先前的主Master节点故障修复完成时,则会再次接管IP资源和服务资源(如果Keepalived工作于抢占模式的话),继续向用户提供服务,而后来接管IP资源和服务资源的备Backup节点会释放接管的资源,再次成为备节点。
导致主、备节点切换的原因不仅仅是主节点发生了故障,也有可能是主Master节点被人为降低优先级(降到比备节点还低),这时备Backup节点会发现主节点的优先级比自己还低,同样会抢占资源并成为主节点。
前面提到,Keepalived主要由三个功能,此处介绍的原理只是其中之一,另外两个功能较为简单,其原理可以参考前面第三点。
五、Keepalived的组件框架
Keepalived的框架可以参考下图(图片来自Keepalived官网)。
Keepalived的组件有控制组件(配置文件分析器)、内存管理、I/O复用和核心组件。其中,核心组件包括VRRP Stack、Checkers、IPVS wrapper、WatchDog和SMTP等,各部分功能如下。
VRRP Stack ==> 是VRRP协议的实现,能够实现Keepalived的高可用性。
Checkers ==> 能够基于网络层(IP)、传输层(TCP)、应用层(HTTP、SSL等)对RealServer进行健康状态检查。
IPVS Checkers ==> 根据配置文件生成IPVS规则并送往IPVS使之生效。
WatchDog ==> 用于监控VRRP Stack和Checkers这两个Keepalived关键组件是否正常工作。
SMTP ==> 是一个SMTP接口,主要用于当VRRP Stack中发生地址流动时,或者当Checkers发现服务上下线并增删服务节点时,能够以邮件方式通知管理员。
六、Keepalived的安装
对于CentOS 6.4+的系统版本,Keepalived程序包已经在base源提供。在CentOS 7.x上使用yum工具安装如下:
# yum -y install keepalived
6.1 高可用集群配置的前提
① 确保各节点时间同步 ==> 基于NTP协议或Chrony协议
② 确保iptables和selinux不会阻碍
③ 各节点之间可通过主机名互相通信(对Keepalived并非必须) ==> 名称解析服务的解析结果必须与"uname -n"命令的执行结果相同。
④ 各节点之间的root用户可以基于密钥认证的SSH进行通信(对Keepalived并非必须)
6.2 Keepalived配置
主配置文件 ==> /etc/keepalived/keepalived.conf
Unit File ==> /usr/lib/systemd/system/keepalived.service
Unit File的配置文件 ==> /etc/sysconfig/keepalived
Keepalived配置内容块:
GLOBAL CONFIGURATION(全局配置)
VRRPD CONFIGURATION(VRRP配置)
LVS CONFIGURATION(LVS配置)
(1) GLOBAL CONFIGURATION(全局配置)
全局配置框架:
global_defs {
...
}
常用配置:
global_defs {
notification_email # 邮件通告的收件人(如果有多个收件人须用花括号'{}'括起来)
{
admin@example1.com # postfix服务只能由本机用户发给本机用户
... # 如果要发送给其它主机上的用户可借助于有提供smtp服务的主机,
} 但一般smtp服务器需要申请有互联网的公网IP地址
notification_email_from admin@example.com # 邮件通告的发送人
smtp_server 127.0.0.1 # smtp服务器的IP地址。如果是向外提供服务的smtp服务器,则需要
支持正反解
smtp_connect_timeout 30 # 发送邮件的超时时长
router_id my_hostname # 定义当前路由器设备的ID号(不一定要使用主机名)
vrrp_mcast_group4 224.0.0.18 # 基于VRRP协议的多个虚拟路由器使用的组播地址
group4表示使用ipv4格式地址
}
全局配置示例:
global_defs {
notification_email {
root@localhost
}
notification_email_from kaadmin@itab.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.100.18
}
(2) VRRPD CONFIGURATION(VRRP配置)
虚拟路由配置框架:
vrrp_sync_group GRP_NAME { # 规定所有的虚拟路由器的主Master节点都必须在同一台主机上
...
}
vrrp_instance INST_NAME { # 配置虚拟路由器实例,可配置多个实例
...
}
常用配置:
vrrp_instance <string> { # 配置虚拟路由器实例
state MASTER | BACKUP # 当前节点在此虚拟路由器中的初始状态
interface ETHERCARD # VRRP实例工作(绑定)的网络接口
virtual_router_id 51 # 虚拟路由器ID,范围是0-255
priority 100 # 当前物理节点在此虚拟路由器中的优先级
advert_int # # VRRP通告的时间间隔
authentication { # 认证机制
# PASS||AH
# PASS - Simple Passwd (suggested)
# AH - IPSEC (not recommended))
auth_type PASS # 认证类型,推荐使用简单字符串认证(PASS类型)
# Password for accessing vrrpd.
# should be the same for all machines.
# Only the first eight (8) characters are used. ==> 以下认证密码仅前8位字符有效
auth_pass 1234 # 认证密码(建议使用随机数作为认证密码)
}
virtual_ipaddress { # 定义虚拟IP
<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
192.168.200.17/24 dev eth1
192.168.200.18/24 dev eth2 label eth2:1
192.168.200.18/32
}
track_interface { # 定义要监控的接口
eth0
eth1
...
}
nopreempt # 工作于非抢占模式(不指定时默认为抢占模式),如果两台路由器
性能相差不大时可以考虑工作于非抢占模式
preempt_delay 300 # 工作于抢占模式时,设定再次上线的节点(原来为主Master节点)
应该延迟多长时间再抢占
# 通告脚本定义
notify_master <STRING>|<QUOTED-STRING> # 当前节点变成主Master节点时使用的通告脚本
notify_backup <STRING>|<QUOTED-STRING> # 当前节点变成备Backup节点时使用的通告脚本
notify_fault <STRING>|<QUOTED-STRING> # 当前节点故障时使用的通告脚本
notify <STRING>|<QUOTED-STRING> # 以上无论哪一个状态发生变化,都使用的通告脚本
}
虚拟路由器实例配置示例:
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 6
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 5FfZnxFm
}
virtual_ipaddress {
192.168.100.66 # VIP地址
}
notify_master "/etc/keepalived/notify.sh master" # 注意要使用双引号
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
通知脚本示例:
# vim /etc/keepalived/notify.sh
#!/bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(hostname) to be $1: vip floating"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) change to be $1"
echo $mailbody | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
;;
esac
注意:通告脚本需要有执行权限。
# chmod +x /etc/keepalived/notify.sh
(3) LVS CONFIGURATION(LVS配置)
LVS集群配置框架:
virtual_server_group VSG_NAME {
...
}
virtual_server IP port |
virtual_server fwmark int {
protocol TCP
...
real_server <IPADDR> <PORT> {
...
}
real_server <IPADDR> <PORT> {
...
}
...
}
常用配置:
virtual_server IP port | #==> 通过请求报文的目标IP和目标PORT定义集群服务
virtual_server fwmark # { #==> 通过防火墙标记定义集群服务
lb_algo rr|wrr|lc|wlc|lblc|sh|dh # 定义负载均衡调度算法
delay_loop <INT> # 定义服务轮询时间间隔,即对后端服务的检测时间间隔
lb_kind NAT|DR|TUN # 集群的类型
persistence_timeout <INT> # 持久连接时长
protocol TCP # 服务协议
virtualhost <STRING> # 当后端Web服务器上有多台虚拟主机时,可使用此项来指明要检测
的虚拟主机(带上Host首部)。否则,则只向RIP发出请求,并只
由后端Web服务器上的默认虚拟主机响应
sorry_server <IPADDR> <PORT> # 所有RS均故障时,提供say sorry的服务器
real_server <IPADDR> <PORT> { # 定义RS
weight <INT> # 权重
notify_up <STRING>|<QUOTED-STRING> # 节点上线时调用的通知脚本
notify_down <STRING>|<QUOTED-STRING> # 节点离线时调用的通知脚本
# HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK
# 支持所有的健康状态检测方式
HTTP_GET|SSL_GET {
url {
path <STRING> # 健康状态检测时请求的资源的URL
digest <STRING> # 基于获取的内容摘要码进行健康状态判定
status_code <INT> # 基于要求返回的状态码进行健康状态判定
}
nb_get_retry <INT> # 尝试的次数
delay_before_retry <INT> # 两次尝试之间的时间间隔
connect_timeout <INTEGER> # 连接的超时时长
connect_ip <IP ADDRESS> # 向此处指定的地址发测试请求(不指定时则向此前指定的RIP发测试请求)
connect_port <PORT> # 项此处指定的PORT发测试请求(不指定时则向此前指定的RS的PORT发测试请求)
bindto <IP ADDRESS> # 指定测试请求报文的源IP
bind_port <PORT> # 指定测试请求报文的源PORT
}
TCP_CHECK {
# 除了不能定义url,其它的配置同HTTP_GET|SSL_GET
}
}
}
LVS集群配置示例:
virtual_server 192.168.10.7 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
sorry_server 127.0.0.1 80
real_server 192.168.10.11 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.10.12 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
6.2 Keepalived高可用其它服务
(1) vrrp_script、track_script
vrrp_script ==> 用于自定义一个资源(或服务)监控脚本;vrrp实例能够将脚本的状态返回值作为判断一个资源(或服务)是否可用的依据。需要公共定义,可被多个vrrp实例调用,因此要定义在vrrp实例之外。
track_script ==> 用于调用vrrp_script定义的脚本去监控资源(或服务),并能够在监控过程中,一旦发现脚本状态返回值为成功时,则使节点的优先级不变或升高,当发现脚本状态返回值为是失败时,则使节点的优先级降低。而当前节点就可以通过向外通告自身优先级来完成节点角色(主或备)的切换。
(2) 使用示例1 ==> 当检测到/etc/keepalived/down文件存在时,则进行地址漂移
vrrp_script chk_down {
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
# 当检测到down文件存在时(成功),定义为失败(状态码为1);而将检测不到down文件存在时(失败),反而定义为成功(状态码为0)
interval 2 # 每隔2秒执行脚本检测一次
weight -5 # 一旦脚本运行失败,则执行该项(将优先级降低5)
}
vrrp_instance INST_NAME {
...
track_script {
chk_down # 调用已定义的vrrp_script
}
...
}
(3) 使用示例2 ==> 监控具体的服务进程
vrrp_script chk_httpd {
script "killall -0 httpd" # 当httpd进程运行不正常时,则脚本运行失败(状态码为1);
当httpd进程运行正常时,则脚本运行成功(状态码为0)
interval 2
weight -5 # 一旦脚本运行失败,则执行该项(将优先级降低5)
}
vrrp_instance VI_1 {
...
track_script {
chk_httpd
}
...
}
注意:
(1) killall命令使用-0选项时只起探测作用,不会真正杀死进程。
(2) 调用的脚本中使用的命令必须为已经安装的命令。本示例中的vrrp脚本只有在主机上必须有killall命令时才能执行,如果没有killall命令,则可使用yum安装psmisc。
问题:如何改进该脚本?
vrrp_script所实现的监控功能应该更为完整,例如可以在检测不到资源(或服务)时,不要立即调低优先级,而先尝试重启服务,并规定尝试几次,两次尝试之间的时间间隔。当然,在vrrp_script中所实现的功能也可由前面所提到的通告脚本来实现,也就是可以将前面的通告脚本示例再改进一下。改进后的脚本如下。
#!/bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(hostname) to be $1: vip floating"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) change to be $1"
echo $mailbody | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
systemctl start httpd.service # 保证服务是启动的
;;
backup)
notify backup
systemctl restart httpd.service # 当切换为备节点时,重启一次服务
;;
fault)
notify fault
systemctl restart httpd.service # 当节点发生错误时,重启一次服务
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
;;
esac
keepalive基础知识的更多相关文章
- JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)
本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...
- SpringCloud(1) 架构演进和基础知识简介
一.传统架构演进到分布式架构 简介:讲解单机应用和分布式应用架构演进基础知识 (画图) 高可用 LVS+keepalive 1.单体应用:开发速度慢.启动时间长.依赖庞大.等等 2.微服务:易开发.理 ...
- JavaWeb基础知识总结
JavaWeb基础知识总结. 1.web服务器与HTTP协议 Web服务器 l WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. l Internet上供 ...
- linux web服务基础知识,dns
#web服务基础知识c/s 客户端/服务器b/s 浏览器/服务器 nginx > web server 服务端浏览器 > web client 客户端 #dns解析 ...
- java第九节 网络编程的基础知识
/** * * 网络编程的基础知识 * 网络协议与TCP/IP * IP地址和Port(端口号) * 本地回路的IP地址:127.0.0.1 * 端口号的范围为0-65535之间,0-1023之间的端 ...
- Vue基础知识简介
基础知识: vue的生命周期: beforeCreate/created.beforeMount/mounted.beforeUpdate/updated.beforeDestory/destorye ...
- vue基础知识之vue-resource/axios
Vue基础知识之vue-resource和axios(三) vue-resource Vue.js是数据驱动的,这使得我们并不需要直接操作DOM,如果我们不需要使用jQuery的DOM选择器,就没 ...
- Vue基础知识之vue-resource和axios
Vue基础知识之vue-resource和axios 原文链接:http://www.cnblogs.com/Juphy/p/7073027.html vue-resource Vue.js是数据驱 ...
- Nginx基础知识介绍
Nginx基础知识介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx概述 Nginx是免费的.开源的.高性能的HTTP和正向/反向代理服务器.邮件代理服务器.以及T ...
随机推荐
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- Python列表推导式中使用if-else
data_list=[] col=["a", "b", "c", "d"] jdata={"a":1 ...
- selinux与kernel 0day
selinux与kernel 0day kernel NULL pointer的利用需要把shellcode映射到内存0处, 大家在测试exp的时候,总能发现一个规律, 开着selinux就能溢出成功 ...
- rookit入門
来源:rootkit_com 作者:Clandestiny 翻译:fqh “Help!我是一名新手!我需要一款rootkit入侵朋友的机器…我想编写自己的rootkit…我想开始开发代码… 该从哪里入 ...
- Pytest---yield
场景:你已经可以将测试方法前要执行的或依赖的解决了,测试 方法后销毁清除数据的要如何进行呢?范围是模块级别的.类似 setupClass 解决:通过在同一模块中加入 yield关键字,yield是调用 ...
- css 深入理解
场景一.边框半透明,背景绿色 默认情况下背景会延伸到边框所在的下边 css2 中我们只能接受 css3 中我们可以通过 background-clip 属性来实现 border: 10px soli ...
- 面试题: nodejs 的事件轮询机制
setTimeout(function(){ console.log('setTimeout()执行了') },0) setImmediate(function(){ console.log('set ...
- PHP 工厂模式浅析
//抽象出一个人的接口interface Person{ public function showInfo();}//继承于人的学生类class Student implements Person{ ...
- 整合mybatis时报错:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Una ...
- http(python)
1.client 1) httpie http -f POST example.org hello=World http POST http://192.168.200.251:55101/Api/C ...