Keepalived 是一款用C语言编写的开源路由软件,目前仍处于活跃开发的状态,其主要目标是基于 Linux 系统提供一款配置简单且功能强大的负载均衡和高可用的软件应用。负载均衡是基于 LVS(IPVS)实现的,Keepalived 在 LVS 的基础上增加了多种主动健康检测机制,可以根据后端真实服务器的运行状态,自动对虚拟服务器负载的真实服务器进行维护和管理。
高可用性是通过虚拟冗余路由协议(Virtual Reduntant Routing Protocol,VRRP)实现的。VRRP 是工作在网络层的一种路由容错协议,通过组播的通告机制进行网络路由快速转移,以实现网络设备的高可用。
Keepalived相关术语如下:
Keepalived 为 LVS 提供了文件形式的配置方式,并为真实服务器提供了多种主动健康检测机制,通过 VRRP 协议为 LVS 提供了高可用的负载集群解决方案。Keepalived 的工作模式如下图所示。
Keepalived 设计了多种主动健康检测机制,每个健康检测机制都注册在全局调度框架中,通过检测真实服务器的运行状态,自动对服务池中的真实服务器进行维护和管理。常用的健康检测机制有以下 4 种。
Keepalived 配置文件可以分为 3 个部分,分别为全局配置、VRRP 配置和虚拟服务配置。各部分的常用配置关键字及其功能如下。
Keepalived 全局配置关键字实现邮件告警的 SMTP 配置及自身 VRRP 路由相关的全局配置,配置关键字如下表所示。
配置关键字 | 功能描述 |
---|---|
global_defs | 全局配置区域标识 |
notification_email | 设置接收告警邮件的地址列表 |
notification_email_from | 设置发送邮件的地址列表 |
smtp_server | 设置用于发送邮件的 SMTP 服务器地址 |
smtp_connection_timeout | 设置 SMTP 服务器连接超时时间 |
router_id | 设置当前设备的路由 ID,每个设备均不相同 |
vrrp_version | VRRP 协议版本 |
nopreempt | 是否启用非抢占模式,即不参与 MASTER 的选举,默认为抢占模式 |
配置样例如下:
global_defs{
notification_email {
monitor@nginxbar.org # 接收邮件的邮箱为monitor@nginxbar.org
}
smtp_server smtp.nginxbar.org # SMTP服务器地址为smtp.nginxbar.org
smtp_connect_timeout 30 # SMTP服务器连接超时时间为30秒
router_id LVS_Nginx1 # 当前设备路由ID为LVS_Nginx1
}
Keepalived 的 VRRP 配置关键字用于创建 VRRP 路由器,并为其配置运行参数。配置文件中可以创建多个不同名称的 VRRP 路由器实例,每个 VRRP 路由器实例都需要通过设定虚拟路由 ID 加入虚拟路由器中。VRRP 路由器接收组播的 VRRP 通告,并根据 VRRP 通告切换自身状态。当切换状态时会触发配置中对应状态的 shell 脚本,并根据配置参数判断是否发送告警邮件。VRRP 配置关键字如下表所示。
配置关键字 | 功能描述 |
---|---|
vrrp_instance | VRRP 实例配置区域标识 |
state | 设置当前 VRRP 路由的初始状态 |
interface | 设置 VRRP 绑定的设备网络接口 |
virtual_router_id | 设置当前设备所属的虚拟路由 ID |
priority | 设置当前 VRRP 路由的初始优先级,优先级最高的会被选举为 MASTER,优先级取值范围为 1~254 |
advert_int | 发送组播包的间隔时间,默认为 1 秒 |
nopreempt | 是否启用非抢占模式,即不参与 MASTER 的选举,默认为抢占模式 |
preempt_delay | 设置抢占延时,取值范围为 0~1000,默认为 0,单位为秒。即等待多少秒才参与 MASTER 选举 |
authentication | VRRP 通信认证配置区域标识 |
auth_type | 指定 VRRP 通信的认证类型,有 PASS 简单密码认证和 AH:IPSEC 认证两种类型 |
auth_pass | 指定 VRRP 通信密码字符串,最大为 8 位 |
virtual_ipaddress | VIP 地址配置区域标识 |
notify_master | 指定一个转换为 MASTER 状态后执行的 shell 脚本 |
notify_backup | 指定一个转换为 BACKUP 状态后执行的 shell 脚本 |
notify_fault | 指定一个转换为 FAULT 状态后执行的 shell 脚本 |
smtp_alert | 使用 SMTP 的配置发送邮件告警通知 |
配置样例如下:
vrrp_instance VI_1 {
state MASTER # 初始路由状态为MASTER
interface eth0 # VRRP绑定接口为eth0
virtual_router_id 51 # 虚拟路由器的VRID为51
priority 100 # 当前设备的优先级是100
nopreempt # 不参与MASTER的选举
advert_int 5 # VRRP组播的间隔时间是5秒
authentication {
auth_type PASS # 认证类型为PASS
auth_pass 2222 # 认证密码为2222
}
virtual_ipaddress {
192.168.2.155 # 虚拟服务器的VIP是192.168.2.155
}
}
VRRP 本身是通过 VRRP 通告机制实现路由器状态切换判断的,但在实际的应用场景中会存在因网络抖动等原因影响 VRRP 的通告传递的情况,为提高状态切换的准确性,Keepalived 还提供了一种脚本检测机制,可以让用户通过自定义脚本更精准地进行路由状态切换。相关配置关键字如下表所示。
配置关键字 | 功能描述 |
---|---|
vrrp_script | VRRP 脚本配置区域标识 |
scrip | 指定要执行的脚本路径 |
weight | 用于调整 VRRP 路由器优先级的权重值,如果脚本执行成功且 weight 为正时,则优先级增力相应值;如果脚本执行失败且 weight 为负,则优先级减少相应值。优先级的取值范围为 1~254 |
interval | 设置检测脚本的执行间隔。单位是 s。默认为 1s |
timeout | 脚本执行返回结果超时时间,超过指定时间则认为检测失败 |
rise | 连续检测成功次数为设定值时才确认为成功状态 |
fall | 连续检测失败次数为设定值时才确认为失败状态 |
init_fail | 设置脚本初始检测状态为失败状态 |
Keepalived 通过 VRRP 通告判断虚拟路由器中其他 VRRP 路由状态并确保路由的转移,对于业务层的高可用,则需要用户单独对应用进程进行同步检测。例如,Nginx 与 Keepalived 部署在同一台设备上,可以通过脚本检测 Nginx 进程的状态,如果 Nginx 检测失败并无法自动恢复,则降低 VRRP 的优先级。要尽量避免在切换为 MASTER 状态时,因自身业务层故障导致业务高可用切换失败。也可用多个脚本组合实现 VRRP 路由优先级的动态调整。配置样例如下:
vrrp_script checknginx {
script "/opt/data/scripts/checknginx.sh"
interval 3 # 检测脚本执行时间间隔
weight -20 # 当检测失败时,VRRP路由优先级降低20
rise 3 # 连续监测3次成功才确认为成功
fall 3 # 连续监测3次失败才确认为失败
}
检测脚本内容如下:
#!/bin/bash
# 检测脚本查询Nginx进程是否存在,若存在则返回0,若检测失败则返回1
check = `ps aux | grep -v grep | grep nginx | wc -l`
if [ $check > 0 ]; then
exit 0
else
systemctl start nginx
exit 1
fi
Keepalived 的虚拟服务器是负载均衡的外部访问点,通过配置关键字实现对 LVS 运行参数的配置,配置文件中可以为 VIP 绑定不同的端口创建多个虚拟服务器。虚拟服务器配置关键字如下表所示。
配置关键字 | 功能描述 |
---|---|
virtual_server | 虚拟服务器配置区域标识 |
delay_loop | 设置健康检测的间隔时间 |
lb_algo | LVS 调度算法 |
lb_kind | LVS 转模式(NAT、DR、TUN) |
persistence_timeout | 设置保持连接的超时时间,在设定时间内会把同一个客户端的连接全部转发给同一真实服务器 |
persistence_granularity | 对启用保持连接的客户端 IP 进行掩码调整,当 IP 为 255.255.255.255 时,则仅限这个 IP 的客户端;当 IP 为 255.255.255.0 时,则为这个客户端所在子网网段内 IP 的所有客户端 |
virtualhost | 为 HTTP_GET 或 SSL_GET 设置执行要检测的虚拟主机 |
protocol | 转发协议类型(TCP、UDP、SCTP) |
sorry_server | 设置一个服务池中所有真实服务器都无法访问时的备用服务器 |
真实服务器相关关键字如下表所示。
配置关键字 | 功能描述 |
---|---|
real_server | 配置真实服务器 IP 及端口 |
weight | 设置真实服务器的权重,默认为 1 |
inhibit_on_failure | 当健康检测失败时,将当前服务器权重设置为 0,而不将其从服务器池中移除 |
notify_up | 当前服务器健康检查成功时执行的脚本 |
notify_down | 当前服务器健康检查失败时执行的脚本 |
uthreshold | 当前服务器的最大连接数 |
lthreshold | 当前服务器的最小连接数 |
TCP_CHECK | TCP 检测设置区域标识 |
MISC_CHECK | 自定义检测脚本设置区域标识 |
HTTP_GET | HTTP 检测设置区域标识 |
SSL_GET | SSL HTTP 检测设置区域标识 |
通过 Keepalived 为真实服务器配置关键字不仅可以实现 LVS 真实服务器的运行参数配置,还可以对自身增加的真实服务器的主动健康检测进行配置。真实服务器健康检测配置关键字如下表所示。
配置关键字 | 功能描述 |
---|---|
url | HTTP_GET 和 SSL_GET 的 URL 检测标识 |
path | HTTP_GET 和 SSL_GET 的 URL 检测路径 |
digest | HTTP_GET 和 SSL_GET 的返回结果的 MD5 计算值 |
status_code | HTTP_GET 和 SSL_GET 的健康检测返回状态码 |
connect_ip | 检测的 IP 地址,默认为真实服务器的 IP 地址 |
connect_port | 检测的端口,默认为真实服务器的端口 |
bindto | 发起检测连接的接口地址,默认为本地 IP 地址 |
bind_port | 发起检测连接的源端口,默认为随机端口 |
connect_timeout | 检测连接的超时时间,默认为 5s |
fwmark | 使用 fwmark 对所有发出去的检查数据包进行标记 |
warmup | 指定一个随机延迟时间用于防止网络阻塞,如果为 0,则表示关闭该功能 |
nb_get_retry | GET 尝试次数,仅 HTTP_GET 和 SSL_GET 有效 |
retry | 重试次数,默认是 1 次,仅 TCP_CHECK 有效 |
delay_before_retry | 设置在重试之前延迟的秒数 |
配置样例如下:
virtual_server 192.168.2.155 80 { # 虚拟服务器IP及端口
delay_loop 6 # 健康检测间隔时间为6s
lb_algo wrr # 负载均衡调度算法为加权轮询
lb_kind DR # 转发模式为DR
persistence_timeout 60 # 保持连接的超时时间为60s
protocol TCP # 负载均衡转发协议为TCP
real_server 192.168.2.109 80 { # 真实服务器IP及端口
weight 100 # 真实服务器权重为100
notify_down /etc/keepalived/scripts/stop.sh # 当真实服务器健康检测失败时执
# 行stop.sh脚本
HTTP_GET {
url {
path "/healthcheck" # 指定要检查的URL的路径
digest bfaa324fdd71444e43eca3b7a1679a1a # 检测URL返回值的MD5计算值
status_code 200 # 健康检测返回状态码
}
connect_timeout 10 # 连接超时时间为10s
nb_get_retry 3 # 重试3次确认失败
delay_before_retry 3 # 失败重试的时间间隔为3s
}
}
}
# digest值的计算方法
genhash -s 192.168.2.109 -p 80 -u /healthcheck
Keepalived 的其他配置关键字此处并未列出,更多配置关键字可以通过 man 命令获取。
man keepalived.conf