Keepalived 介绍
Keepalived 是由 c 语言编写的一个路径选择软件,是 IPVS 的一个扩展性项目,为 IPVS 提供高可用性(故障转移)特性,它的高可用性是通过 VRRP 协议实现的,并实现了对负载均衡服务器池中的 real server 进行健康状态检测,当 real server 不可用时,自身实现了故障的隔离,这弥补了 IPVS 不能对 real server 服务器进行健康检测的不足,这也是 keepalived 运用最广泛的场景,当然 keepalived 不只限于实现 IPVS 的高可用。
Keepalived 软件架构
Keepalived 是一个模块化设计的软件,其有多个组件共同组成,每个组件各司其职共同完成 Keepalived 的各项功能。
Checkers
:对后端服务器节点(RS)进行健康状态监测和故障隔离,我们知道,LVS 本身是没有健康状态监测功能,keepalived 起初就是为 LVS 生成 IPVS 规则和增加健康状态检测功能而设计的。
VRRP Stack
:这是 keepalived 实现 VRRP 功能的模块,VRRP 功能可以实现对前端调度器集群的故障切换(failover)。
SMTP
:Checkers 和 VRRP Stack 都是对节点进行状态监测,不同的是监测前端调度器和监测后端RS,但是这两个模块都可以通过SMTP通知管理员故障信息的邮件。
System Call
:Checkers 和 VRRP Stack 同样都可以调用系统内核功能完成故障隔离和故障切换。
IPVS wrapper
:Checkers 通过监测后端 RS 的工作状态得出信息,IPVS wrapper 通过这些信息添加 IPVS 规则,内核中的 IPVS 则通过这些规则进行工作。
Netlink Reflector
:在调度器发生故障切换的时候,该模块充当调用内核 NETLINK 的接口,完成虚拟 IP 的设置和切换。
Watch Dog
:keepalived 的核心模块就是 Checkers 和 VRRP Stack,当这两个模块发生故障的时候怎么办呢,这时候 Watch Dog 就发生了作用,它是一个检测工具,周期性的去检测 Checkers 和 VRRP Stack 的运行状态,一旦 Checkers 和 VRRP Stack 发生故障,Watch Dog 就能够检测到并采取恢复措施(重启)。
Keepalived 的主要功能
① 实现 IP 漂移
② 生成 IPVS 规则
③ 状态切换后执行某个动作
Keepalived 应用场景
Keepalived 起初是专门为 LVS 所开发的一款集后端服务器监控检查、生成 IPVS 规则的高可用软件。其目的是简化 LVS 的配置和通过IP 漂移实现两个或多个 LVS 高可用功能。后来被各路开发和运维人员拿来做各种各样的用途,只要是有 IP 漂移需求的场景,都能看到有 Keepalived 的身影。最常用且通用的用法就是以下的几种。
- Keepalived + LVS
- Keepalived + haproxy
- Keepalived + nginx
Keepalived 工作原理
本小结探讨 Keepalived 的 IP 漂移过程的原理,IPVS 规则的生成不在此节讨论。
要理解 Keepalived 的原理,首先要了解 VRRP 协议,理解了 VRRP,Keepalived 的工作原理也就一目了然了。
VRRP 协议
虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP)是由IETF提出的解决局域网中配置静态网关出现单点失效现象的路由协议,1998年已推出正式的RFC2338协议标准。VRRP广泛应用在边缘网络中,它的设计目标是支持特定情况下IP数据流量失败转移不会引起混乱,允许主机使用单路由器,以及及时在实际第一跳路由器使用失败的情形下仍能够维护路由器间的连通性。
简而言之,VRRP 即是多个路由器绑定为一个虚拟路由器组,期间通过选举得出一个主路由器,其余路由器作为备用路由器。当主路由器宕机后,由 VRRP 协议再次进行选举出新的主路由器,替代原来的主路由器的工作。如下图所示,VRRP 路由器的工作示意图。
VRRP 状态
VRRP路由器在运行过程中有三种状态:
- Initialize 状态: 系统启动后就进入 Initialize,此状态下路由器不对 VRRP 报文做任何处理,可以理解为初始化
Master 状态: 路由器会发送 VRRP 通告,发送免费 ARP 报文1。
这里使用免费 ARP 的目的有:- 检测 IP 是否已经被使用
- 更新其他主机设备的 ARP 表
Backup 状态: 接收 VRRP 通告。
一般主路由器处于Master状态,备份路由器处于Backup状态。
VRRP 选举机制
VRRP 使用选举机制来确定路由器的状态,运行 VRRP 的一组路由器对外构成了一个虚拟路由器,其中一台路由器处于 Master 状态,其他处于 Backup 状态。所以主路由器又叫做 Master 路由器,备份路由器又叫做 Backup 路由器。
优先级选举:
- VRRP 组中 IP 拥有者。如果虚拟 IP 地址与 VRRP 组中的某台 VRRP 路由器 IP 地址相同,则此路由器为 IP 地址拥有者,这台路由器将被定位主路由器。
- 比较优先级。如果没有 IP 地址拥有者,则比较路由器的优先级,优先级的范围是0~255,大的作为主路由器。
- 比较IP地址。在没有 IP 地址拥有者和优先级相同的情况下,IP 地址大的作为主路由器。
VRRP 定时器
VRRP通告报文时间间隔定时器
- VRRP 备份组中的 Master 路由器会定时发送 VRRP 通告报文,通知备份组内的路由器自己工作正常
- 用户可以通过设置 VRRP 定时器来调整 Master 路由器发送 VRRP 通告报文的时间间隔
- 如果 Backup 路由器在等待了 3 个间隔时间后,依然没有收到 VRRP 通告报文,则认为自己是 Master 路由器,并对外发送 VRRP 通告报文,重新进行 Master 路由器的选举
VRRP抢占延迟时间定时器
- 为了避免备份组内的成员频繁进行主备状态转换,让 Backup 路由器有足够的时间搜集必要的信息(如路由信息),Backup 路由器接收到优先级低于本地优 先级的通告报文后,不会立即抢占成为 Master
- 而是等待一定时间——抢占延迟时间后,才会对外发送 VRRP 通告报文取代原来的 Master 路由器
VRRP 报文格式
- VRRP 通告报文使用 IP 组播数据包进行封装,组播地址为 223.0.0.18,IANA 给其分配的协议号为 112。
- VRRP 通告报文的 TTL 值必须是 255,如果 VRRP 路由器接受到 TTL 值不为 255 的 VRRP 通告报文,必须丢弃。
- VRRP 组中的主路由器会定期发送通告报文,备份路由器接收,他们通过这种方式来交流选举。
Keepalived 工作原理
Keepalived 是 VRRP 协议的具体实现,有了以上的 VRRP 基础知识,对 Keepalived 的工作原理也就一目了然了。当然了,我们回顾一下 Keepalived 的软件架构,除了 VRRP 之外,还有一个重要组件 Checkers。Checkers 的主要功能有:后端服务器进行健康检查、执行自定义脚本、通知等。
后端服务器监控检查
Keepalived 提供以下几种对后端服务器监控检查的接口,我们可以选择合适和方式对后端服务器进行检查。
方法 | 说明 | 示例 |
---|---|---|
HTTP_GET/SSL_GET | HTTP(S) GET请求对WEB服务器进行检查 | HTTP_GET{ url { path /index.html digest 9b3a0...d8cd status_code 200 } connect_port 80 connect_timeout 3 nb_get_retry 3 delay_before_retry 2 } |
TCP_CHECK | 检查后端服务器TCP端口 | TCP_CHECK { connect_port 80 connect_timeout 5 nb_get_retry 3 delay_before_retry 3 } |
SMTP_CHECK | 检查SMTP服务器 | SMTP_CHECK { host { connect_ip 192.168.1.1 connect_port 25 } connect_timeout 5 retry 2 delay_before_retry 3 hello_name "mail.domain.com" } |
MISC_CHECK | 自定义检查脚本,命令执行返回0或1 | MISC_CHECK { misc_path /path/to/check.sh misc_timeout 3 warmup 5 misc_dynamic } |
Keepalived 状态通知
Keepalived 为什么提供了两类状态通知功能,一类是当 VRRP 状态发生变化时触发,另一类是当虚拟服务器监控状态发生变化时触发。
VRRP 状态通知
状态 | 触发钩子 | 说明 |
---|---|---|
master | notify_master | 当节点从其他状态变成master状态时触发 |
backup | notify_backup | 当节点从其他状态变成backup状态时触发 |
fault2 | notify_fault | 当节点从其他状态变成fault状态时触发 |
stop | noify_stop | 当Keepalived停止时触发 |
虚拟服务器状态通知
状态 | 触发钩子 | 说明 |
---|---|---|
up | notify_up | 当节点从其他状态变成up状态时触发 |
down | notify_down | 当节点从其他状态变成down状态时触发 |
Keepalived 的扩展接口
除了以上的状态通知机制之外,Keepalived 还提供了一些钩子,使得我们可以很方便地控制 Keepalived (VRRP)的优先级。
钩子 | 功能 | 定义 |
---|---|---|
vrrp_script track_script | 执行自定义命令。 当weight为负数: 1.命令返回值为0:优先级不变 2.命令返回值为1:优先级+weight 当weight为正数: 1.命令返回值为0:优先级+weight 2.命令返回值为1:优先级不变 | vrrp_script <SCRIPT_NAME> { script \<STRING\>|\<QUOTED-STRING\> interval \<INTEGER\> weight \<INTEGER:-253..253\> fall \<INTEGER> rise \<INTEGER> } track_script { <SCRIPT_NAME> [weight <-253..253>] } |
vrrp_track_file track_file | 2.0版本新增的功能,监视文件变化, 当文件变化时,读取文件的内容。 文件内容为数值。 当weight为0:文件内容不为0时, VRRP状态变成fault状态 当weight不为0:文件内容不为0时, 改变其优先级。 优先级=默认优先级+(weight*文件中的数值) | vrrp_track_file \<STRING\> { file <QUOTED_STRING> weight <-254..254> init_file [VALUE][overwrite] } vrrp_instance \<STRING\> { track_file { \<STRING\> } } |
track_interface | 监视网卡状态,当网卡down掉时会变成fault状态 | track_interface { \<INTERFACE\> } |