高可用集群Keeplived
一,高可用集群
1.1 集群类型
- LB(Load Balance 负载均衡)
LVS/Haproxy/Nginx
- HA(High Availability 高可用集群)
数据库 Redis
-
Spof(Single Point of Failure 解决单点故障)
HPC(High Performance Computing 高性能集群)
1.2 系统可用性
SLA:Service-Level Agreement 服务等级协议(提供服务的企业与客户之间就服务的品质、水准、性能
等方面所达成的双方共同认可的协议或契约)
A = MTBF / (MTBF+MTTR)
bash
99.95%:(60*24*30)*(1-0.9995)=21.6分钟 #一般按一个月停机时间统计
指标 :99.9%, 99.99%, 99.999%,99.9999%
1.3 系统故障
硬件故障:设计缺陷、wear out(损耗)、非人为不可抗拒因素
软件故障:设计缺陷 bug
1.4 实现高可用
提升系统高用性的解决方案:降低MTTR- Mean Time To Repair(平均故障时间)
解决方案就是冗余备份
- active/passive 主/备
- active/active 双主
- active <--> HEARTBEAT <--> active
心脏检测
- active --> HEARTBEAT --> passive
1.5 VRRP:Virtual Router Redundancy Protocol
虚拟路由冗余协议
- 物理层:三层交换机 路由器
- 软件层:keepalived

相关术语
⛵️
虚拟路由器(Virtual Router)
虚拟路由器标识(VRID 0-255)唯一标识虚拟路由器
VIP(Virtual IP)
VMAC(Virtual MAC)(0100-5e00-01VRID)
物理路由器
master(主设备)
backup(备设备)
priority(优先级)
VRRP相关技术
通告相关:心跳 优先级 周期性
工作方式:抢占性 非抢占性
安全认证:
无认证
简单字符认证
MD5
工作方式:
主/备:单虚拟路由器
主/主:互为备份
二,Keeplived部署

2.1 Keeplived简介
VRRP协议的软件实现,目的是为了高可用IPVS服务
功能
-
基于VRRP协议完成地址流动
-
为VIP地址所在的节点生成IPVS规则
-
为IPVS集群的各RS做健康状态检测
-
基于脚本调用接口完成脚本中定义的功能
2.2 Keeplived架构
官方文档

- 用户空间核心组件:
VRRP Stack:VIP消息通告
checkers:监测real server
system call:实现vrrp协议状态转化时调用的脚本功能
SMTP:邮件组件
IPVS wrapper:生成IPVS规则
Netlink Reflector:网络接口
WatchDog:监控进程
- 控制组件:提供keeplived.conf的解析器,完成keeplived配置
- IO复用器:针对网络目的而优化的自己的线程抽象
- 内存管理器:为某些通用的内存管理功能(如分配,重新分配等)提供访问权限
2.3 Keeplived环境准备

- 各个节点的时间必须同步
- 关闭防火墙及SElinux
- 各节点之间可互相通信(非必须)
- 建议使用/etc/hosts文件实现(非必须)
- 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信(非必须)
2.4 Keeplived 相关文件
- 软件包:keeplived
- 主程序文件:/usr/sbin/keeplived
- 主配置文件:/etc/keeplived/keeplived.conf
2.5 Keeplived 安装
安装keeplived
bash
[root@KA1 ~]# dnf install keepalived -y
[root@KA1 ~]# systemctl enable --now keepalived.service
Created symlink /etc/systemd/system/multi-user.target.wants/keepalived.service → /usr/lib/systemd/system/keepalived.service.
[root@KA1 ~]# ps axf | grep keeplived
31024 pts/1 S+ 0:00 | | \_ grep --color=auto keeplived
2.6 Keeplived 配置说明
2.6.1 配置文件组成部分
配置文件:/etc/keeplived/keeplived.conf
配置文件组成:
- Global Configuration
Global definitions:定义邮件配置 round_id vrrp配置 多播地址
- VRRP Configuration
VRRP instance:定义每个vrrp虚拟路由器
- LVS Configuration
Virtual server groups
Virtual server:LVS集群的VS和RS
2.6.2 配置语法说明
bash
[root@KA1 ~]# man keepalived.conf
2.6.2.1 全局配置
bash
global_defs {
notification_email {
acassen@firewall.loc # keeplived发生故障切换时邮件发送的目标邮箱,可以按行区分多个
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc # 发邮件的地址
smtp_server 192.168.200.1 # 邮件服务器地址
smtp_connect_timeout 30 # SMTP服务器连接的超时时间
router_id LVS_DEVEL # Keeplived的唯一标识
vrrp_skip_check_adv_addr # 跳过VRRP通告包的源IP地址
vrrp_strict # 启用VRRP严格模式,严格遵循VRRP协议规范
vrrp_garp_interval 0 # 0表示禁用VRRP切换时的ARP广播刷新
vrrp_gna_interval 0 # 0表示禁止VRRP相关的邻居公告
}
2.6.2.2 配置虚拟路由器
bash
vrrp_instance VI_1 {
state MASTER
interface eth0 # 绑定为当前虚拟路由器使用的物理接口
virtual_router_id 51 # 每个虚拟路由器唯一标识(0-255),此值必须唯一
priority 100 # 当前物理节点在此虚拟路由器的优先级(1-254)
advert_int 1 # VRRP通告的时间间隔
authentication { # 认证机制
auth_type PASS # PASS为简单密码,AH为IPSEC认证
auth_pass 1111 # 预共享密钥,仅前8位有效
}
virtual_ipaddress { # 虚拟IP,生产环境可能有上百个IP
192.168.200.16 # 指定VIP,不指定网卡,默认为eth0(不指定/prefix,默认为32)
192.168.200.17
192.168.200.18
}
accept # 开启VIP对外响应ping包(此处需要关闭vrrp_strict)
}
示例
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from Onepiece@KA1
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id RS1
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from KA2
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id KA2
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
[root@KA2 ~]# systemctl restart keepalived.service
测试
bash
[root@KA2 ~]# tcpdump -i eth0 -nn host 224.0.0.18
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:21:06.155771 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:07.169746 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:08.172674 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:09.176428 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:10.179124 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:11.181872 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:12.187884 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:13.190818 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:14.191588 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:15.194601 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:16.198297 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:17.198504 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:21:18.203500 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20

2.6.2.3 启用keeplived日志功能
示例
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from Onepiece@KA1
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id RS1
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
KEEPALIVED_OPTIONS="-D -S 6"
}
[root@KA1 ~]# systemctl restart keepalived.service
测试
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
KEEPALIVED_OPTIONS="-D -S 6"
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from Onepiece@KA1
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id RS1
vrrp_skip_check_adv_addr
# vrrp_strict
}
[root@KA1 ~]# vim /etc/rsyslog.conf
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
local6.* /var/log/keepalived.log
# ### sample forwarding rule ###
#action(type="omfwd"
# # An on-disk queue is created for this action. If the remote host is
# # down, messages are spooled to disk and sent when it is up again.
#queue.filename="fwdRule1" # unique name prefix for spool files
[root@KA1 ~]# systemctl restart keepalived.service rsyslog.service
[root@KA1 ~]# tail /var/log/keepalived.log
Feb 21 21:44:56 KA1 Keepalived_healthcheckers[91920]: smtp fd 11 returned write error
Feb 21 21:45:00 KA1 Keepalived[91919]: Stopping
Feb 21 21:45:00 KA1 Keepalived_healthcheckers[91920]: Shutting down service [192.168.201.100]:tcp:443 from VS [192.168.200.100]:tcp:443
Feb 21 21:45:00 KA1 Keepalived_healthcheckers[91920]: Shutting down service [192.168.200.2]:tcp:1358 from VS [10.10.10.2]:tcp:1358
Feb 21 21:45:00 KA1 Keepalived_healthcheckers[91920]: Shutting down service [192.168.200.3]:tcp:1358 from VS [10.10.10.2]:tcp:1358
Feb 21 21:45:00 KA1 Keepalived_healthcheckers[91920]: Shutting down service [192.168.200.4]:tcp:1358 from VS [10.10.10.3]:tcp:1358
Feb 21 21:45:00 KA1 Keepalived_healthcheckers[91920]: Shutting down service [192.168.200.5]:tcp:1358 from VS [10.10.10.3]:tcp:1358
Feb 21 21:45:00 KA1 Keepalived_healthcheckers[91920]: Stopped
Feb 21 21:45:01 KA1 Keepalived_vrrp[91921]: Stopped
Feb 21 21:45:01 KA1 Keepalived[91919]: Stopped Keepalived v2.2.8 (04/04,2023), git commit v2.2.7-154-g292b299e+

2.6.2.4 实现独立子配置文件
生产环境复杂时,主配置文件内容过多。不宜管理
格式
include /path/file
示例
bash
[root@KA1 ~]# mkdir /etc/keepalived/conf.d
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
KEEPALIVED_OPTIONS="-D -S 6"
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from Onepiece@KA1
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id RS1
vrrp_skip_check_adv_addr
# vrrp_strict
}
include /etc/keepalived/conf.d/*.conf
[root@KA1 ~]# vim /etc/keepalived/conf.d/router.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA1 ~]# tcpdump -i eth0 -nn host 224.0.0.18
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:56:04.380402 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:56:05.382265 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:56:06.385786 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:56:07.387737 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:56:08.390935 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20

三,Keeplived 企业应用示例
3.1 实现master/slave的Keeplived 单主架构
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from Onepiece@KA1
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id RS1
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
[root@KA1 ~]# systemctl restart keepalived.service
BACKUP配置
bash
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
13571532874@163.com
}
notification_email_from KA2
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id KA2
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
[root@KA2 ~]# systemctl restart keepalived.service
抓包观察
bash
[root@KA1 ~]# tcpdump -i eth0 -nn host 224.0.0.18
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
22:00:22.749122 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
22:00:23.750605 IP 192.168.136.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20

3.2 抢占模式和非抢占模式
3.2.1 非抢占模式 nopreempt
默认为抢占模式preempt,就是在高优先级的主机恢复后,会抢占低优先级主机的master角色,这样会使VIP漂移,造成网络抖动
建议设置为nopreempt非抢占模式
配置实例
bash
# KA1
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
nopreempt #非抢占模式
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
# KA2
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
nopreempt #非抢占模式
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
3.2.2 抢占延迟模式 preempt_delay
抢占延迟模式,就是优先级高的主机恢复后,不会立刻抢回VIP,而是延长一段时间在抢回
bash
preempt_delay # 指定抢占时间,默认为300s
⛵️
不要启用vrrp_strict
配置示例
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
preempt_delay 10 # 抢占延迟时间为10s
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
preempt_delay 10 # 抢占延迟时间为10s
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
[root@KA2 ~]# systemctl restart keepalived.service
3.3 VIP单播配置
默认Keeplived主机之间利用多播互相通告信息,会造成网络问题,换为单播,减少网络流量
🗡
启用vrrp_strict时,不能启用单播
配置示例
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
priority 100
preempt_delay 10
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
unicast_src_ip 192.168.136.10 # 本机的IP
unicast_peer { # 指定对方的IP
192.168.136.20
}
}
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
unicast_src_ip 192.168.136.20
unicast_peer {
192.168.136.10
}
}
[root@KA2 ~]# systemctl restart keepalived.service
# 效果
[root@KA1 ~]# tcpdump -i eth0 -nn src host 192.168.136.10 and dst 192.168.136.20
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:51:37.368134 IP 192.168.136.10 > 192.168.136.20: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
10:51:38.368918 IP 192.168.136.10 > 192.168.136.20: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
10:51:39.369731 IP 192.168.136.10 > 192.168.136.20: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
10:51:40.370204 IP 192.168.136.10 > 192.168.136.20: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
10:51:41.370792 IP 192.168.136.10 > 192.168.136.20: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
10:51:42.371707 IP 192.168.136.10 > 192.168.136.20: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
^C

3.4 Keeplived 通知脚本设置
当keepalived状态改变时,自动触发脚本的执行,比如:发邮件给用户
默认以用户keepalived_script身份执行脚本
如果此用户不存在,以root执行脚本可以命令指定用户执行脚本
global_defs {
......
script_user <USER>
......
}
3.4.1 脚本的调用
在vrrp_strict VI_1 语句末添加下面内容
bash
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
3.4.2 创建脚本
bash
#!/bin/bash
mail_dest='13571532874@163.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 in
master)
mail_send master
;;
backup)
mail_send backup
;;
fault)
mail_send fault
;;
*)
exit 1
;;
esac
mail_dest='594233887@qq.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 in
master)
mail_send master
;;
backup)
mail_send backup
;;
fault)
mail_send fault
;;
3.4.3 邮件配置
安装邮件工具
bash
[root@KA1 ~]# yum install s-nail.x86_64 postfix -y
邮箱设置
bash
[root@KA1 ~]# vim /etc/mail.rc
set smtp=smtp.163.com
set smtp-auth=login
set smtp-auth-user=13571532874@163.com
set smtp-auth-password=PCTzSZuJswwWbZFA
set from=13571532874@163.com
set ssl-verify=ignore
[root@KA1 ~]# systemctl restart postfix.service
# 测试
[root@KA1 ~]# echo hello | mailx -s test 13571532874@163.com
3.4.4 实战案例:实现Keepalived 状态切换的通知脚本
bash
[root@KA1 ~]# vim /etc/keepalived/mail.sh
#!/bin/bash
mail_dest='13571532874@163.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 in
master)
mail_send master
;;
backup)
mail_send backup
;;
fault)
mail_send fault
;;
*)
exit 1
;;
esac
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
enable_script_security
script_user root
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
unicast_src_ip 192.168.136.10
unicast_peer {
192.168.136.20
}
notify_master "/etc/keepalived/mail.sh master"
notify_backup "/etc/keepalived/mail.sh backup"
notify_fault "/etc/keepalived/mail.sh fault"
}
测试
bash
[root@KA1 ~]# killall keepalived

3.5 实现master/master的Keeplived双主架构
master/slave的单主架构,同一时间只有一个Keepalived对外提供服务,另一台很空闲,利用率低
双主架构:
就是将两个或两个以上VIP运行在不同的Keeplived服务器上,实现服务器并行提供访问web目的,提供资源的利用率
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
preempt_delay 10
nopreempt
advert_int 1
# enable_script_security
# script_user root
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
# unicast_src_ip 192.168.136.10
# unicast_peer {
# 192.168.136.20
#}
#notify_master "/etc/keepalived/mail.sh master"
#notify_backup "/etc/keepalived/mail.sh backup"
#notify_fault "/etc/keepalived/mail.sh fault"
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 80
preempt_delay 10
nopreempt
advert_int 1
# enable_script_security
# script_user root
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
}
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
preempt_delay 10
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
unicast_src_ip 192.168.136.20
unicast_peer {
192.168.136.10
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 100
preempt_delay 10
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
unicast_src_ip 192.168.136.20
unicast_peer {
192.168.136.10
}
}
[root@KA2 ~]# systemctl restart keepalived.service
3.6 实现IPVS的高可用性
3.6.1 IPVS相关配置
3.6.1.1 虚拟服务器配置架构
bash
virtual_server IP port {
...
real_server {
...
}
real_server {
...
}
...
}
3.6.1.2 Virtual server的定义格式
bash
virtual_server IP port #定义虚拟主机IP地址及其端口
virtual_server fwmark int #ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string #使用虚拟服务器组
3.6.1.3 虚拟服务器配置
bash
virtual_server IP port { #VIP和PORT
delay_loop <INT> #检查后端服务器的时间间隔
lb_algo rr|wrr|lc|wlc|lblc|sh|dh #定义调度方法
lb_kind NAT|DR|TUN #集群的类型,注意要大写
persistence_timeout <INT> #持久连接时长
protocol TCP|UDP|SCTP #指定服务协议,一般为TCP
sorry_server <IPADDR> <PORT> #所有RS故障时,备用服务器地址
real_server <IPADDR> <PORT> { #RS的IP和PORT
weight <INT> #RS权重
notify_up <STRING>|<QUOTED-STRING> #RS上线通知脚本
notify_down <STRING>|<QUOTED-STRING> #RS下线通知脚本
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... } #定义当前主机健康状
态检测方法
}
}
#注意:括号必须分行写,两个括号写在同一行,如: }} 会出错
3.6.1.4 应用层检测
bash
HTTP_GET|SSL_GET {
url {
path <URL_PATH> #定义要监控的URL
status_code <INT> #判断上述检测机制为健康状态的响应码,一般为 200
}
connect_timeout <INTEGER> #客户端请求的超时时长, 相当于haproxy的timeout server
nb_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发出健康状态检测请求时使用的源端口
}
3.6.1.5 TCP检测
bash
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.6.2 实战案例 实现单主的LVS-DR模式
后端服务器绑定
bash
[root@RS1 ~]# ip addr add 192.168.136.100/32 dev lo
[root@RS2 ~]# ip addr add 192.168.136.100/32 dev lo
配置示例
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 192.168.136.100 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
protocol TCP
real_server 192.168.136.30 80 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.136.40 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
}
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 192.168.136.100 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
protocol TCP
real_server 192.168.136.30 80 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.136.40 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
}
[root@KA2 ~]# systemctl restart keepalived.service
# 测试
[2026-02-22 12:08.57] ~
[Administrator.WIN-G01HRFS4OB1] ⮞ for i in {1..6}; do curl 192.168.136.100; done
RS1
RS2
RS1
RS2
RS1
RS2

3.7 实现其他应用的高可用性 VRRP Script
调用外部的辅助脚本进行资源监控,并根据监控的结果实现优先动态调整,实现其他应用的高可用性功能
3.7.1 VRRP Script 配置
- 定义脚本
VRRP_Script:自定义资源监控脚本,根据脚本返回值,公共定义,可被多个实例调用,一般放在global_def设置块之后
一旦发现异常,会将master的权重低至Slave节点,实现VIP到SLAVE节点
bash
vrrp_script <SCRIPT_NAME> {
script <STRING>|<QUOTED-STRING> #此脚本返回值为非0时,会触发下面OPTIONS执行
OPTIONS
}
- 调用脚本
track_script:调用vrrp_script定义的脚本去监控资源
bash
track_script {
SCRIPT_NAME_1
SCRIPT_NAME_2
}
定义VRRP Script
bash
rrp_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 Script
bash
vrrp_instance test {
... ...
track_script {
check_down
}
}
3.7.2 实战案例 利用脚本实现主从角色切换
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_script check {
script "/etc/keepalived/check.sh"
interval 1
weight -30
fall 2
rise 2
timeout 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
preempt_delay 10
nopreempt
advert_int 1
# enable_script_security
# script_user root
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.136.100/24 dev eth0 label eth0:0
}
# unicast_src_ip 192.168.136.10
# unicast_peer {
# 192.168.136.20
#}
#notify_master "/etc/keepalived/mail.sh master"
#notify_backup "/etc/keepalived/mail.sh backup"
#notify_fault "/etc/keepalived/mail.sh fault"
track_script {
check
}
}
[root@KA1 ~]# vim /etc/keepalived/check.sh
#!/bin/bash
[ ! -f "/media/lee" ]
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA1 ~]# touch /media/lee
[root@KA1 ~]# tail -f /var/log/messages
s