keepalived 是 Linux 一个轻量级的高可用解决方案,提供了心跳检测和资源接管、检测集群中的系统服务,在集群节点间转移共享IP 地址的所有者等。
工作原理
keepalived 通过 VRRP(virtual router redundancy protocol)虚拟路由冗余协议来实现高可用。在这个协议里会将多态功能相同的路由组成一个小组,这个小组会有一个 master 角色 和 N(N >=1)个 backup 角色。
Keepalived 有三个模块:core、check、vrrp。
其中:
core 模块 为 Keepalived 的核心,负责主进程启动、维护以及全局配置文件的加载和解析;
check 模块负责 健康检查;
vrrp 负责实现 vrrp 协议。
keepalived 的体系结构
keepalived 的体系 结构从整体上分为 两层,分别是用户层 (User Space)和 内核空间层(Kernel Space)。
内核空间层处于最底层,它包括 IPVS 和 NETLINK 两个模块。IPVS 模块是 Keepalived 引入 的一个第三方模块,通过 IPVS 可以实现基于 IP 的负载均衡集群。IPVS 默认包含在 LVS 集群软件中。而对于 LVS 集群软件,在 LVS 集群中, IPVS 安装在 一台叫 Director Server 的服务器上,同时在 Director Server 上虚拟出一个 IP 地址对外提供服务,而用户必须通过这个虚拟 IP 地址才能访问服务。这个虚拟 IP 一般成为 LVS 的 VIP,即 Virtual IP。访问的请求首先经过 VIP 到达 Director Server ,然后有 Director Server 从服务器集群节点中选取一个 服务节点响应用户的请求。
Keepalived的配置文件解析
Keepalived的核心组件,包含了一系列功能模块,主要有WatchDog、Checkers、VRRP Stack、IPVS wrapper 和Netlink Reflector,下面介绍每个模块所实现的功能如下:
1、WatchDog
WatchDog是计算机可靠性领域中一个极为简单又非常有效的检测工具,它的工作原理是针对被监视的目标设置一个计数器和一个阈值,WatchDog会自己增加此计数值,然后等待被监视的目标周期性地重置该计数值。一旦被监控目标发生错误,就无法重置此计数值,WatchDog就会检测到,于是采取对应的恢复措施,例如重启或关闭。
在linux中很早就引入了WatchDog功能,而Keepalived正是通过WatchDog的运行机制来监控Checkers和VRRP进程的。
2、 Checkers
这是Keepalived最基础的功能,也是最主要的功能,可实现对服务器运行状态检测和故障隔离。
3、 VRRP Stack
这是Keepalived后来引入的VRRP功能,可以实现HA集群中失败切换(Failover)功能。Keepalived通过VRRP功能再结合LVS负载均衡软件即可部署一个高性能的负载均衡集群系统。
4、 IPVS wrapper
这是IPVS功能的一个实现。IPVS wrapper模块可以将设置好的IPVS规则发送到内核空间并提交给IPVS模块,最终实现IPVS模块的负载均衡功能。
5、 Netlink Reflector
用来实现高可用集群中Failover时虚拟IP(VIP)的设置和切换。Netlink Reflector的所有请求最后都发送到内核空间层的NETLINK模块来完成。
配置文件说明
keepalived配置文件按层级和模块划分的,每层由"{ }"来界定。 在主配置文件中可以通过include来涵盖多个子配置文件。 语法说明:
BOOL: on|off|true|false|yes|no
TIMER: 以秒为单位的时间值,包括小数秒,如3,2.71828。计时器的分辨率是微妙。
关于脚本引用:
双引号"字符串中嵌入其他双引号或空格,那么字符串将仅在带引号的字符串之后结束(如:“abcd” efg h jkl “mnop” 等同于 “abcd efg h jkl mnop”;)。
对于使用参数指定脚本,不带引号的空格将分隔参数。如果参数需要包含空格,则应将其括在单引号(')中
配置文件结构
! Configuration File for keepalived
# 全局定义
global_defs {
# 指定接收通知的邮箱地址列表
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 指定发件人的邮箱地址
notification_email_from Alexandre.Cassen@firewall.loc
# SMTP 服务器地址,用于发送邮箱通知
smtp_server 192.168.200.1
# SMTP 连接超时时间
smtp_connect_timeout 30
# 标识当前节点的唯一 ID
router_id LVS_DEVEL
# 跳过检查 VRRP 广播地址
vrrp_skip_check_adv_addr
# 其余严格的 VRRP 模式
vrrp_strict
# 设置 GARP 的时间间隔
vrrp_garp_interval 0
# 设置 GNA 的时间间隔
vrrp_gna_interval 0
}
# VRRP 实例
vrrp_instance VI_1 {
# 当前节点的角色 (MASTER 或 BACKUP)。主节点设置为 MASTER,从节点设置为 BACKUP
state MASTER
# 绑定的网络接口(如 eth0)
interface eth0
# 虚拟路由的 ID(范围0 - 255),同一组中的所有节点必须使用相同的值
virtual_router_id 51
# 节点的优先级(范围1 - 254),数值越高优先级越高
priority 100
# VRRP 广播间隔时间(秒)
advert_int 1
# VRRP 认证信息
authentication {
# 认证类型(PASS 表示简单密码认证)
auth_type PASS
# 认证密码
auth_pass 1111
}
# 虚拟 IP 地址列表,这些 IP 将绑定在当前节点的网络接口上
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
}
# 虚拟服务器
# 定义一个虚拟服务器,监听指定的IP 和端口(如:192.168.200.100 443)
virtual_server 192.168.200.100 443 {
# 健康检查的间隔时间(秒)
delay_loop 6
# 负载均衡算法(如 rr 表示轮训)
lb_algo rr
# 负载均衡模式(如 NAT 表示网络地址转换)
lb_kind NAT
# 会话保持时间(秒)
persistence_timeout 50
# 协议类型(TCP)
protocol TCP
# 定义真实后端服务器
real_server 192.168.201.100 443 {
# 权重值,用于分配流量的比例
weight 1
# 使用 SSL 请求进行健康检查
SSL_GET {
# 检查的目标 URL 及其 MD5 摘要值
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
# 连接超时时间
connect_timeout 3
# 失败后重试时间
retry 3
# 重试前的延迟时间
delay_before_retry 3
}
}
}
配置文件包括以下几个模块:
1.GLOBAL CONFIGURATION
包含配置文件中的global_defs、static_ipaddress、static_route区域,负责定义邮件的相关配置、route_id、vrrp配置、多播地址、节点的ip和路由信息等
global_defs 全局配置
vrrpd
1. vrrp_script添加一个周期性执行的脚本。脚本的退出状态码会被调用它的所有的VRRP Instance记录。
2. vrrp_sync_group将所有相关的VRRP实例定义在一起,作为一个VRRP Group,如果组内的任意一个实例出现问题,都可以实现Failover
3. garp_group
4. vrrp_instance
LVS配置
virtual_server
real_server
real_server中的健康检查
HTTP_GET or SSL_GET
TCP_CHECK
TCP_CHECK
DNS_CHECK
DNS_CHECK
全局配置模块
! Configuration File for keepalived
global_defs { #全局定义部分
notification_email { #设置报警邮件地址,可设置多个
acassen@firewall.loc #接收通知的邮件地址
failover@firewall.loc
}
notification_email_from test0@163.com #设置 发送邮件通知的地址
smtp_server smtp.163.com #设置 smtp server 地址,可是ip或域名.可选端口号 (默认25)
smtp_connect_timeout 30 #设置 连接 smtp server的超时时间
router_id LVS_DEVEL #主机标识,用于邮件通知
vrrp_strict #严格执行VRRP协议规范,此模式不支持节点单播
script_user keepalived_script #指定运行脚本的用户名和组。默认使用用户的默认组。如未指定,默认为keepalived_script 用户,如无此用户,则使用root
enable_script_security #如过路径为非root可写,不要配置脚本为root用户执行。
}
2.BFD CONFIGURATION
用于快速检测系统之间的通信故障,并在出现故障时通知上层应用。
它具有两优点:
对网络设备间任意类型的双向转发路径提供快速、轻负荷的故障检测
用单一的机制对任何介质、任何协议层进行实时检测,并支持不同的检测时间与开销
3. VRRPD CONFIGURATION
包含配置文件中的vrrp_script、vrrp_instance、vrrp_sync_group、garp_group区域,负责定义每个vrrp虚拟路由器
vrrp_script配置
作用:添加一个周期性执行的脚本。脚本的退出状态码会被调用它的所有的VRRP Instance记录。
注意:至少有一个VRRP实例调用它并且优先级不能为0.优先级范围是1-254.
vrrp_script <SCRIPT_NAME> {
...
}
选项说明:
script "/path/to/somewhere":指定要执行的脚本的路径。
interval <INTEGER>:指定脚本执行的间隔。单位是秒。默认为1s。
timeout <INTEGER>:指定在多少秒后,脚本被认为执行失败。
weight <-254 --- 254>:调整优先级。默认为2.
rise <INTEGER>:执行成功多少次才认为是成功。
fall <INTEGER>:执行失败多少次才认为失败。
user <USERNAME> [GROUPNAME]:运行脚本的用户和组。
init_fail:假设脚本初始状态是失败状态。
解释:
weight:
1. 如果脚本执行成功(退出状态码为0),weight大于0,则priority增加。
2. 如果脚本执行失败(退出状态码为非0),weight小于0,则priority减少。
3. 其他情况下,priority不变
vrrp_instance
命令说明:
state MASTER|BACKUP:指定该keepalived节点的初始状态。
interface eth0:vrrp实例绑定的接口,用于发送VRRP包。
use_vmac [<VMAC_INTERFACE>]:在指定的接口产生一个子接口,如vrrp.51,该接口的MAC地址为组播地址,通过该接口向外发送和接收VRRP包。
vmac_xmit_base:通过基本接口向外发送和接收VRRP数据包,而不是通过VMAC接口。
native_ipv6:强制VRRP实例使用IPV6.(当同时配置了IPV4和IPV6的时候)
dont_track_primary:忽略VRRP接口的错误,默认是没有配置的。
track_interface {
eth0
eth1 weight <-254-254>
...
}:如果track的接口有任何一个出现故障,都会进入FAULT状态。
track_script {
<SCRIPT_NAME>
<SCRIPT_NAME> weight <-254-254>
}:添加一个track脚本(vrrp_script配置的脚本。)
mcast_src_ip <IPADDR>:指定发送组播数据包的源IP地址。默认是绑定VRRP实例的接口的主IP地址。
unicast_src_ip <IPADDR>:指定发送单薄数据包的源IP地址。默认是绑定VRRP实例的接口的主IP地址。
version 2|3:指定该实例所使用的VRRP版本。
unicast_peer {
<IPADDR>
...
}:采用单播的方式发送VRRP通告,指定单播邻居的IP地址。
virtual_router_id 51:指定VRRP实例ID,范围是0-255.
priority 100:指定优先级,优先级高的将成为MASTER。
advert_int 1:指定发送VRRP通告的间隔。单位是秒。
authentication {
auth_type PASS|AH:指定认证方式。PASS简单密码认证(推荐),AH:IPSEC认证(不推荐)。
auth_pass 1234:指定认证所使用的密码。最多8位。
}
virtual_ipaddress {
<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
}:指定VIP地址。
nopreempt:设置为不抢占。默认是抢占的,当高优先级的机器恢复后,会抢占低优先级的机器成为MASTER,而不抢占,则允许低优先级的机器继续成为MASTER,即使高优先级的机器已经上线。如果要使用这个功能,则初始化状态必须为BACKUP。
preempt_delay:设置抢占延迟。单位是秒,范围是0---1000,默认是0.发现低优先级的MASTER后多少秒开始抢占。
通知脚本:
notify_master <STRING>|<QUOTED-STRING> [username [groupname]]
notify_backup <STRING>|<QUOTED-STRING> [username [groupname]]
notify_fault <STRING>|<QUOTED-STRING> [username [groupname]]
notify <STRING>|<QUOTED-STRING> [username [groupname]]
# 当停止VRRP时执行的脚本。
notify_stop <STRING>|<QUOTED-STRING> [username [groupname]]
smtp_alert
vrrp_sync_group
作用:将所有相关的VRRP实例定义在一起,作为一个VRRP Group,如果组内的任意一个实例出现问题,都可以实现Failover。
vrrp_sync_group VG_1 {
group {
inside_network # vrrp instance name
outside_network # vrrp instance name
...
}
...
}
说明:
如果username和groupname没有指定,则以默认的script_user所指定的用户和组。
1. notify_master /path/to_master.sh [username [groupname]]
作用:当成为MASTER时,以指定的用户和组执行脚本。
2. notify_backup /path/to_backup.sh [username [groupname]]
作用:当成为BACKUP时,以指定的用户和组执行脚本。
3. notify_fault "/path/fault.sh VG_1" [username [groupname]]
作用:当该同步组Fault时,以指定的用户和组执行脚本。
4. notify /path/notify.sh [username [groupname]]
作用:在任何状态都会以指定的用户和组执行脚本。
说明:该脚本会在notify_*脚本后执行。
notify可以使用3个参数,如下:
$1:可以是GROUP或INTANCE,表明后面是组还是实例。
$2:组名或实例名。
$3:转换后的目标状态。有:MASTER、BACKUP、FAULT。
5. smtp_alert:当状态发生改变时,发送邮件。
6. global_tracking:所有的VRRP实例共享相同的tracking配置。
注意:脚本文件要加上x权限,同时指令最好写绝对路径。
4.LVS CONFIGURATION
包含配置文件中的virtual_server_group、virtual_server区域,负责lvs集群配置
LVS模块结构:
virtual_server{
… ...
real_server{
… ...
}
}
virtual_server
virtual_server IP Port | virtual_server fwmark int | virtual_server group string {
delay_loop <INT>:健康检查的时间间隔。
lb_argo rr|wrr|lc|wlc|lblc|sh|dh:LVS调度算法。
lb_kind NAT|DR|TUN:LVS模式。
persistence_timeout 360:持久化超时时间,单位是秒。默认是6分钟。
persistence_granularity:持久化连接的颗粒度。
protocol TCP|UDP|SCTP:4层协议。
ha_suspend:如果virtual server的IP地址没有设置,则不进行后端服务器的健康检查。
virtualhost <STRING>:为HTTP_GET和SSL_GET执行要检查的虚拟主机。如virtualhost www.felix.com
sorry_server <IPADDR> <PORT>:添加一个备用服务器。当所有的RS都故障时。
sorry_server_inhibit:将inhibit_on_failure指令应用于sorry_server指令。
alpha:在keepalived启动时,假设所有的RS都是down,以及健康检查是失败的。有助于防止启动时的误报。默认是禁用的。
omega:在keepalived终止时,会执行quorum_down指令所定义的脚本。
quorum <INT>:默认值1. 所有的存活的服务器的总的最小权重。
quorum_up <STRING>:当quorum增长到满足quorum所定义的值时,执行该脚本。
quorum_down <STRING>:当quorum减少到不满足quorum所定义的值时,执行该脚本。
}
real_server
real_server IP Port {
weight <INT>:给服务器指定权重。默认是1.
inhibit_on_failure:当服务器健康检查失败时,将其weight设置为0,而不是从Virtual Server中移除。
notify_up <STRING>:当服务器健康检查成功时,执行的脚本。
notify_down <STRING>:当服务器健康检查失败时,执行的脚本。
uthreshold <INT>:到这台服务器的最大连接数。
lthreshold <INT>:到这台服务器的最小连接数。
}