keepalived
1.概念
集群类型
- LB负载均衡:LVS、haproxy、nginx
- HA高可用集群:mysql、redis
- SPoF解决单点故障
- HPC高性能集群
系统高可用性
SLA:Service-Level Agreement 服务等级协议(提供服务的企业与客户之间就服务的品质、水准、性能等方面所达成的双方共同认可的协议或契约)
A = MTBF / (MTBF+MTTR)
系统故障
硬件故障:设计缺陷、wear out(损耗)、非人为不可抗拒因素
软件故障:设计缺陷 bug
高可用类型
提升系统高用性的解决方案:降低MTTR- Mean Time To Repair(平均故障时间)
解决方案:建立冗余机制
- active/passive 主/备
- active/active 双主
- active --> HEARTBEAT --> passive
- active <–> HEARTBEAT <–> active
VRRP
虚拟路由冗余协议,解决静态网关单点风险
运用:
- 物理层:路由器、三层交换机
- 软件层:keepalived
VRRP 相关术语
- 虚拟路由器:Virtual Router
- 虚拟路由器标识:VRID(0-255),唯一标识虚拟路由器
- VIP:Virtual IP
- VMAC:Virutal MAC (00-00-5e-00-01-VRID)
- master:主设备
- backup:备用设备
- priority:优先级
VRRP 相关技术
- 通告:心跳,优先级等;周期性
- 工作方式:抢占式,非抢占式
安全认证:无认证、简单字符认证:预共享密钥、MD5
工作模式:主/备、主/主
2.keepalived部署
功能
- 基于vrrp协议完成地址流动
- 为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
- 为ipvs集群的各RS做健康状态检测
- 基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务
2.1keepalived架构
2.2keepalived环境准备
- 各节点时间必须同步:ntp, chrony
- 关闭防火墙及SELinux
- 各节点之间可通过主机名互相通信:非必须
- 建议使用/etc/hosts文件实现:非必须
- 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信:非必须
2.4 keepalived安装
相关文件
- 软件包名:keepalived
- 主程序文件:/usr/sbin/keepalived
- 主配置文件:/etc/keepalived/keepalived.conf
- 配置文件示例:/usr/share/doc/keepalived/
- Unit File:/lib/systemd/system/keepalived.service
- Unit File的环境配置文件:/etc/sysconfig/keepalived
dnf install keepalived -y
systemctl start keeplived
systemctl enable --now keepalived
2.5 keepalived配置
/etc/keepalived/keepalived.conf配置文件组成部分
Global definitions :定义邮件配置,route_id,vrrp配置,多播地址等
VRRP instance(s):定义每个vrrp虚拟路由器
Virtual server group(s)
Virtual server(s) :LVS集群的VS和RS
#Global Definitions 全局定义段
global_defs {notification_email {admin@example.com #告警接收邮箱(需配置SMTP)backup@example.com}notification_email_from keepalived@hostname #发件人标识smtp_server 192.168.1.1 #SMTP服务器地址smtp_connect_timeout 30 #SMTP连接超时(秒)router_id LVS_DEVEL #节点唯一标识(重要!)script_user root #检查脚本执行用户enable_script_security #禁止脚本中变量传递vrrp_skip_check_adv_addr #对所有通告报文都检查,会比较消耗性能;#用此配置后,如果收到的通告报文和上一个报文是同个路由器,则跳过检查,默认值为全检查vrrp_strict #严格遵循vrrp协议#启用此项后以下状况将无法启动服务:1.无VIP地址;2.配置了单播邻居;3.在VRRP版本2中有IPv6地址#建议不加此项配置vrrp_garp_interval 1 #免费 ARP(Gratuitous ARP)报文时间间隔#免费 ARP用于通知网络中其他设备,某 IP 地址对应的 MAC 地址发生了变化#帮助网络设备更新 ARP 缓存,确保数据能正确转发到新的主节点vrrp_gna_interval 1 #用于配置发送 Gratuitous NA(免费邻居通告)报文的时间间隔#通知网络中其他设备,某 IPv6 地址对应的链路层地址(MAC 地址)发生了变化#帮助网络设备更新邻居缓存(Neighbor Cache)#确保 IPv6 数据包能正确转发到新的主节点vrrp_mcast_group4 224.0.0.44 #指定组播IP地址范围
}
#VRRP Instance VRRP实例段
vrrp_instance VI_1 {state MASTER # 初始状态(MASTER/BACKUP)interface eth0 # 绑定VRRP的物理网卡virtual_router_id 51 # 虚拟路由ID(0-255,集群内一致)# 同属一个虚拟路由器的多个keepalived节点必须相同 priority 100 # 选举优先级(MASTER需>BACKUP)advert_int 1 # 通告间隔(秒)unicast_src_ip 192.168.1.2 # 单播模式下的源IP(可选)unicast_peer {192.168.1.3 # 对端IP(替代组播)}authentication #认证机制{auth_type PASS # 认证类型(PASS/AH)auth_pass 1111 # 密码(明文,建议8字符)}virtual_ipaddress #虚拟IP,生产环境可能指定上百个IP地址{#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>192.168.1.100/24 dev eth0 label eth0:0 # 虚拟IP配置2001:db8::1/64 # 支持IPv6}track_script {chk_nginx # 关联的健康检查脚本(见下文)}notify_master "/path/to/script.sh master" # 状态切换触发脚本notify_backup "/path/to/script.sh backup"
}#检查配置文件语法
keepalived -t -f /etc/keepalived/keepalived.conf
例:
#master
global_defs {router_id KA1.timinglee.org # 唯一标识vrrp_garp_interval 1 # 免费ARP广播间隔vrrp_mcast_group4 224.0.0.18 # VRRP组播地址
}vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 20 # 集群ID需一致priority 100 # 高优先级virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0 # VIP配置}
}
#backup
global_defs {router_id KA2.timinglee.org # 唯一标识vrrp_mcast_group4 224.0.0.18 # 与Master相同组播地址
}vrrp_instance VI_1 {state BACKUPinterface eth0virtual_router_id 20 # 与Master相同的集群IDpriority 80 # 低优先级virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0 # 相同的VIP}
}
22:48:23.294894 IP 172.25.254.50 > 224.0.0.18: VRRPv2, Advertisement, vrid 20, prio 100 # Master通告
22:48:24.084793 IP 172.25.254.60 > 224.0.0.18: VRRPv2, Advertisement, vrid 20, prio 80 # Backup监听
2.5.1 keepalived日志功能
vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6" #日志级别为0-7
vim /etc/rsyslog.conf
local6.* /var/log/keepalived.log
systemctl restart keepalived.service rsyslog.service
#测试
tail -f /var/log/keepalived.log
2.5.2实现独立子配置文件
mkdir /etc/keepalived/conf.d
vim /etc/keepalived/keepalived.conf
#在global下面添加
include /etc/keepalived/conf.d/*.conf #相关子配置文件
vim /etc/keepalived/conf.d/router.conf
vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 20priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0}
}
3.keepalived示例
3.1master/slave的单主架构
master配置
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {lllll@lllll.com}notification_email_from keepalived@KA1.li.orgsmtp_server 127.0.0.1smtp_connect_timeout 30router_id KA1.li.orgvrrp_skip_check_adv_addr#vrrp_strict #添加此选项无法访问vip,可以用nft list ruleset查看vrrp_garp_interval 1vrrp_gna_interval 1vrrp_mcast_group4 224.0.0.18
}vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 20priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0}
}
backup配置
#只修改
vrrp_instance VI_1 {state BACKUPinterface eth0virtual_router_id 20 #相同id管理同一个虚拟路由priority 80 #低优先级advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0}
}
#测试
tcpdump -i eth0 -nn host 224.0.0.18
3.2抢占模式和非抢占模式
抢占模式工作流程
3.2.1非抢占模式
特点:
- 原 Master 节点恢复后不会自动抢回 VIP,保持 Backup 状态
- 需显式配置 nopreempt 参数
- 适合避免频繁切换导致服务波动的场景
- 所有节点都要设置backup
工作流程
配置
vrrp_instance VI_1 {state BACKUP # 所有节点均设为BACKUPpriority 100 # 优先级仍可不同advert_int 1nopreempt # 显式声明非抢占模式
}
3.2.2 延迟抢占模式
作用
- 立即检测到恢复,但不立即抢回 VIP
- 等待延迟时间(preempt_delay) 确认节点稳定性
- 延迟结束后,若节点仍健康,则执行 VIP 抢占
工作流程
配置
vrrp_instance VI_1 {state MASTERpriority 100preempt # 显式启用抢占模式(默认已启用)preempt_delay 300 # 抢占延迟时间(秒,建议5-300秒)advert_int 1 # 心跳间隔需小于preempt_delay
}
3.3VIP单播配置
启用 vrrp_strict 时,不能启用单播
unicast_src_ip <IPADDR> #指定发送单播的源IP
unicast_peer {<IPADDR> #指定接收单播的对方目标主机IP
}
3.4Keepalived 通知脚本配置
默认以用户keepalived_script身份执行脚本,如果此用户不存在,以root执行脚本可以用 script_user <USER> 指定脚本执行用户的身份
global_defs {......script_user <USER>......
}
通知脚本类型
notify_master <STRING>|<QUOTED-STRING> #当前节点成为主节点时触发的脚本
notify_backup <STRING>|<QUOTED-STRING> #当前节点转为备节点时触发的脚本
notify_fault <STRING>|<QUOTED-STRING> #当前节点转为“失败”状态时触发的脚本
脚本的调用
#在vrrp_instance VI_1 语句块下面加
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"#创建通知脚本
vim /etc/keepalived/mail.sh
#!/bin/bash
mail_dest='llll@llll.com'mail_send()
{mail_subj="$HOSTNAME to be $1 vip 转移"mail_mess="`date +%F\ %T`: vrrp 转移,$HOSTNAME 变为 $1"echo "$mail_mess" | mail -s "$mail_subj" $mail_dest
}
case $1 inmaster)mail_send master;;backup)mail_send backup;;fault)mail_send fault;;*)exit 1;;
esac#邮件配置
dnf install s-nail sendmail -y
vim /etc/mail.rc
#######mail set##########
set smtp=smtp.163.com
set smtp-auth=login
set smtp-auth-user=lllll@163.com
set smtp-auth-password=
set from=lllll@163.com
set ssl-verify=ignore
systemctl enable --now sendmail.service
3.4.1Keepalived 状态切换的通知脚本
vim /etc/keepalived/mail.sh
#!/bin/bash
mail_dest='llll@llll.com'mail_send()
{mail_subj="$HOSTNAME to be $1 vip 转移"mail_mess="`date +%F\ %T`: vrrp 转移,$HOSTNAME 变为 $1"echo "$mail_mess" | mail -s "$mail_subj" $mail_dest
}
case $1 inmaster)mail_send master;;backup)mail_send backup;;fault)mail_send fault;;*)exit 1;;
esacchmod +x /etc/keepalived/mail.sh
vim /etc/keepalived/keepalived.conf
global_defs {enable_script_security #开启keepalived执行脚本功能script_user root #指定脚本执行用户身份
}
vrrp_instance VI_1 {……notify_master "/etc/keepalived/mail.sh master"notify_backup "/etc/keepalived/mail.sh backup"notify_fault "/etc/keepalived/mail.sh fault"
}
3.5master/master的双主架构
双master分别走不同的业务,互为主备
vim /etc/keepalived/keepalived.conf
#KA1
vrrp_instance VI_1 {state MASTER #主interface ens33virtual_router_id 50priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.50 dev ens33 label ens33:0}
}vrrp_instance VI_60 {state BACKUP #备interface ens33virtual_router_id 60priority 80advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.60 dev ens33 label ens33:1}
}
#KA2
vrrp_instance VI_1 {state BACKUP #备interface ens33virtual_router_id 50priority 80advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.50 dev ens33 label ens33:0}
}vrrp_instance VI_60 {state MASTER #主interface ens33virtual_router_id 60priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.60 dev eth0 label eth0:1}
}
3.6实现IPVS的高可用性
实现 IPVS (IP Virtual Server) 的高可用性需要结合 Keepalived 和 LVS 技术,通过 VIP 漂移和健康检查确保服务持续可用。
virtual_server IP port {...real_server {...}real_server {...}…
}virtual_server IP port #定义虚拟主机IP地址及其端口
virtual_server fwmark int #ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string #使用虚拟服务器组
配置
virtual_server IP port { #VIP和PORTdelay_loop <INT> #检查后端服务器的时间间隔lb_algo rr|wrr|lc|wlc|lblc|sh|dh #定义调度方法lb_kind NAT|DR|TUN #集群的类型,注意要大写persistence_timeout <INT> #持久连接时长protocol TCP|UDP|SCTP #指定服务协议,一般为TCPsorry_server <IPADDR> <PORT> #所有RS故障时,备用服务器地址real_server <IPADDR> <PORT> { #RS的IP和PORTweight <INT> #RS权重notify_up <STRING>|<QUOTED-STRING> #RS上线通知脚本notify_down <STRING>|<QUOTED-STRING> #RS下线通知脚本HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... } #定义当前主机健康状态检测方法}
}
#应用层检测:HTTP_GET|SSL_GET
HTTP_GET|SSL_GET {url {path <URL_PATH> #定义要监控的URLstatus_code <INT> #判断上述检测机制为健康状态的响应码,一般为 200}connect_timeout <INTEGER> #客户端请求的超时时长, 相当于haproxy的timeout servernb_get_retry <INT> #重试次数delay_before_retry <INT> #重试之前的延迟时长connect_ip <IP ADDRESS> #向当前RS哪个IP地址发起健康状态检测请求connect_port <PORT> #向当前RS的哪个PORT发起健康状态检测请求bindto <IP ADDRESS> #向当前RS发出健康状态检测请求时使用的源地址bind_port <PORT> #向当前RS发出健康状态检测请求时使用的源端口
}
#传输层检测:TCP_CHECK
TCP_CHECK {connect_ip <IP ADDRESS> #向当前RS的哪个IP地址发起健康状态检测请求connect_port <PORT> #向当前RS的哪个PORT发起健康状态检测请求bindto <IP ADDRESS> #发出健康状态检测请求时使用的源地址bind_port <PORT> #发出健康状态检测请求时使用的源端口connect_timeout <INTEGER> #客户端请求的超时时长#等于haproxy的timeout server
}
3.7实现其它应用的高可用性 VRRP Script
keepalived利用 VRRP Script 技术,可以调用外部的辅助脚本进行资源监控,并根据监控的结果实现优先动态调整,从而实现其它应用的高可用性功能
建议配置文件路径:/usr/share/doc/keepalived/keepalived.conf.vrrp.localcheck
#配置模板
#定义脚本
vrrp_script <SCRIPT_NAME> {script <STRING>|<QUOTED-STRING> #此脚本返回值为非0时,会触发下面OPTIONS执行OPTIONS
}
#调用脚本
track_script {SCRIPT_NAME_1SCRIPT_NAME_2
}
#定义脚本
vrrp_script <SCRIPT_NAME> { #定义一个检测脚本,在global_defs 之外配置script <STRING>|<QUOTED-STRING> #shell命令或脚本路径interval <INTEGER> #间隔时间,单位为秒,默认1秒timeout <INTEGER> #超时时间weight <INTEGER:-254..254> #默认为0,如果设置此值为负数,#当上面脚本返回值为非0时#会将此值与本节点权重相加可以降低本节点权重, #即表示fall. #如果是正数,当脚本返回值为0,#会将此值与本节点权重相加可以提高本节点权重#即表示 rise.通常使用负值fall <INTEGER> #执行脚本连续几次都失败,则转换为失败,建议设为2以上rise <INTEGER> #执行脚本连续几次都成功,把服务器从失败标记为成功user USERNAME [GROUPNAME] #执行监测脚本的用户或组init_fail #设置默认标记为失败状态,监测成功之后再转换为成功状态
}
#调用脚本
vrrp_instance test {
... ...track_script {check_down}
}