一.keepalived 简介
vrrp 协议的软件实现,原生设计目的为了高可用 ipvs服务;
- 基于vrrp协议完成地址流动
- 为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
- 为ipvs集群的各RS做健康状态检测
- 基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务
用户空间核心组件:
- vrrp stack:VIP消息通告
- checkers:监测real server
- system call:实现 vrrp 协议状态转换时调用脚本的功能
- SMTP:邮件组件
- IPVS wrapper:生成IPVS规则
- Netlink Reflector:网络接口
- WatchDog:监控进程
- 控制组件:提供keepalived.conf 的解析器,完成Keepalived配置
- IO复用器:针对网络目的而优化的自己的线程抽象
- 内存管理组件:为某些通用的内存管理功能(例如分配,重新分配,发布等)提供访问权限
二.Keepalived 环境准备
1.时间服务器同步
bash
#在ka1中开启时间同步服务
[root@KA1 ~]# vim /etc/chrony.conf
26 allow 0.0.0.0/0
29 local stratum 10
#在ka2中使用ka1的时间同步服务
[root@KA2 ~]# vim /etc/chrony.conf
pool 172.25.254.50 iburst
[root@KA2 ~]# systemctl restart chronyd
[root@KA2 ~]# systemctl enable --now chronyd
[root@KA2 ~]# chronyc sources -v

2.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
配置文件/etc/keepalived/keepalived.conf组成:
- GLOBAL CONFIGURATION Global definitions: 定义邮件配置,route_id,vrrp配置,多播地址等
- VRRP CONFIGURATION VRRP instance(s):定义每个vrrp虚拟路由器
- LVS CONFIGURATION Virtual server group(s) Virtual server(s):LVS集群的VS和RS
bash
#全局配置
! Configuration File for keepalived
global_defs {
notification_email {
timiniglee-zln@163.com #keepalived 发生故障切换时邮件发送的目标邮箱,可以按行区分写多个
}
notification_email_from keepalived@KA1.timinglee.org #发邮件的地址
smtp_server 127.0.0.1 #邮件服务器地址
smtp_connect_timeout 30 #邮件服务器连接timeout
router_id KA1.timinglee.org #每个keepalived主机唯一标识
#建议使用当前主机名,但多节点重名不影响
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地址范围:
}
bash
#配置虚拟路由器
vrrp_instance VI_1 {
state MASTER
interface eth0 #绑定为当前虚拟路由器使用的物理接口,如:eth0,可以和VIP不在一个网卡
virtual_router_id 51 #每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一
#否则服务无法启动
#同属一个虚拟路由器的多个keepalived节点必须相同
#务必要确认在同一网络中此值必须唯一
priority 100 #当前物理节点在此虚拟路由器的优先级,范围:1-254
#值越大优先级越高,每个keepalived主机节点此值不同
advert_int 1 #vrrp通告的时间间隔,默认1s
authentication { #认证机制
auth_type AH|PASS #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
uth_pass 1111 #预共享密钥,仅前8位有效
#同一个虚拟路由器的多个keepalived节点必须一样
}
virtual_ipaddress { #虚拟IP,生产环境可能指定上百个IP地址
<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
172.25.254.100 #指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认32
172.25.254.101/24 dev eth1
172.25.254.102/24 dev eth2 label eth2:1
}
accept #开启vip 对外响应ping包,注意此处功能需要关闭vrrp_strict
#默认使用nftab策略禁用ping包响应,nft list ruleset 显示策略中即可看到
}
3.Keepalived 安装并配置虚拟路由:
bash
[root@KA1 ~]# dnf install keepalived -y
[root@KA1 ~]# systemctl start keepalived
[root@KA1 ~]# ps axf | grep keepalived
#在master
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
1233456@qq.com
}
notification_email_from timinglee_zln@163.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id KA1
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 1
vrrp_gna_interval 1
vrrp_mcast_group4 224.0.0.44
}
vrrp_instance WEB_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
#在KA2中设定
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
timinglee_zln@163.com
}
notification_email_from timinglee_zln@163.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id KA1
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 1
vrrp_gna_interval 1
vrrp_mcast_group4 224.0.0.44
}
vrrp_instance WEB_VIP {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}


测试故障迁移:




4.日志分离和配置子配置文件
日志分离:
默认情况下。keepalived的日志会被保存在/var/log/messages文件中,这个文件中除了含有keepalived的日志外,还有其他服务的日志信息,这样不利于对于keepalived的日志进行查看
bash
#配置日志
[root@KA1 ~]# vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6"
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA1 ~]# vim /etc/rsyslog.conf
local6.* /var/log/keepalived.log
[root@KA1 ~]# systemctl restart rsyslog.service


测试查看日志:

实现独立子配置文件:
当生产环境复杂时, /etc/keepalived/keepalived.conf 文件中内容过多,不易管理 将不同集群的配置,比如:不同集群的VIP配置放在独立的子配置文件中利用include 指令可以实现包含 子配置文件
bash
#实现独立子配置文件
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
......
}
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 20
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}


5.邮件告警设置
bash
#安装邮件软件
[root@KA1 + KA2 ~]# dnf install s-nail postfix -y
#启动邮件代理
[root@KA1 + KA2 ~]# systemctl start postfix.service
在Linux主机中配置mailrc(KA1+KA2):
bash
[root@KA1+KA2 ~]# vim /etc/mail.rc
set smtp=smtp.163.com
set smtp-auth=login
set smtp-auth-user=11111@163.com
set smtp-auth-password=DDDDDD
set from=111111@163.com
set ssl-verify=ignore
测试邮箱:
bash
[root@KA1 mail]# echo hello | mailx -s test 1122334455@qq.com
[root@KA1 mail]# mailq #查看邮件队列


创建通知脚本:

bash
#在KA1和KA2中设定配置文件
! Configuration File for keepalived
global_defs {
......
}
vrrp_instance WEB_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
# unicast_src_ip 172.25.254.50
# unicast_peer {
# 172.25.254.60
# }
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
notify_master "/etc/keepalived/scripts/waring.sh master"
notify_backup "/etc/keepalived/scripts/waring.sh backup"
notify_fault "/etc/keepalived/scripts/waring.sh fault"
}

bash
#测试
[root@KA1 ~]# systemctl stop keepalived.service #停止服务后查看邮件
[root@KA1 ~]# systemctl start keepalived.service #开启服务后查看邮件

三.Keepalived 企业应用示例
1.抢占模式和非抢占模式
抢占模式( 默认的,谁优先级高就把vip放到哪里)
非抢占模式 nopreempt:
- 默认为抢占模式preempt,即当高优先级的主机恢复在线后,会抢占低先级的主机的master角色, 这样会使vip在KA主机中来回漂移,造成网络抖动,
- 建议设置为非抢占模式 nopreempt ,即高优先级主机恢复后,并不会抢占低优先级主机的master角色,
- 非抢占模块下,如果原主机down机, VIP迁移至的新主机, 后续也发生down时,仍会将VIP迁移回原主机。
注:要关闭 VIP抢占,必须将各 keepalived 服务器state配置为BACKUP。
bash
#ka1主机配置
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 20
priority 100 #优先级高
nopreempt #非抢占模式
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
#KA2主机配置
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 20
priority 80 #优先级低
advert_int 1
nopreempt #非抢占模式
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
抢占延迟模式 preempt_delay:
- 抢占延迟模式,即优先级高的主机恢复后,不会立即抢回VIP,而是延迟一段时间(默认300s)再抢回 VIP。
注:需要各keepalived服务器state为BACKUP,并且不要启用 vrrp_strict。
bash
#kA1中
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance WEB_VIP {
state BACKUP #非抢占模式互为backup
interface eth0
virtual_router_id 51
preempt_delay 10 #启动延迟抢占,延迟10s抢占
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
#关闭服务测试vip是否10s后迁移
[root@KA1 ~]# systemctl stop keepalived.service
#KA2中
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance WEB_VIP {
state BACKUP
interface eth0
virtual_router_id 51
preempt_delay 10 #启动延迟抢占,延迟10s抢占
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
[root@KA2 ~]# systemctl stop keepalived.service
配置文件:

测试:
启动观察ka1:

关闭服务,vip转移到ka2:

等待10s后才会拿回vip。

2.keepalived的单播模式
默认keepalived主机之间利用多播相互通告消息,不能跨网络通信,如果需要跨网络实现主备需要启用单播模式实现vrrp通告 。
bash
#在KA1中
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
......
#vrrp_mcast_group4 224.0.0.44 #关闭组播
}
vrrp_instance WEB_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
unicast_src_ip 172.25.254.50 #指定单播源地址,通常是本机IP
unicast_peer {
172.25.254.60 #指定单播接收地址
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
#在KA2中
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
......
#vrrp_mcast_group4 224.0.0.44 #关闭组播
}
vrrp_instance WEB_VIP {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
unicast_src_ip 172.25.254.60 #指定单播源地址,通常是本机IP
unicast_peer {
172.25.254.50 #指定单播接收地址
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
配置文件:


测试:
50--->60,中途50关闭服务,vip转移给60;

60--->50;
50重启服务,拿回vip。

3.Keepalived双主模式
bash
#在KA1中
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance WEB_VIP { #第一个虚拟路由,以master身份设定
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
vrrp_instance DB_VIP { #第二个虚拟路由。以backup身份设定
state BACKUP
interface eth0
virtual_router_id 52
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.200/24 dev eth0 label eth0:1
}
}
#KA2中
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance WEB_VIP { #第一个虚拟路由,以backup身份设定
state BACKUP
interface eth0
virtual_router_id 51
preempt_delay 10
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
}
vrrp_instance DB_VIP { #第二个虚拟路由,以master身份设定
state MASTER
interface eth0
virtual_router_id 52
preempt_delay 10
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.200/24 dev eth0 label eth0:1
}
}
#重启服务
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# systemctl restart keepalived.service
配置文件:


查看vip:


测试vip转移:

4.实现IPVS的高可用性
bash
#1.配置RS
[root@rs1+2 ~]# cd /etc/NetworkManager/system-connections/
[root@rs1+2 system-connections]# ls
eth0.nmconnection
#创建回环来承载vip
[root@rs1+2 system-connections]# cp eth0.nmconnection lo.nmconnection -p
[root@rs1+2 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ipv4]
method=manual
address1=127.0.0.1/8
address2=172.25.254.100/32
#启用回环
[root@rs1+2 system-connections]# nmcli connection reload
[root@rs1+2 system-connections]# nmcli connection up lo
[root@rs1+2 system-connections]# ip a
[root@rs1+2 system-connections]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
[root@rs1+2 system-connections]# sysctl -p
#安装ipvsadm
[root@KA1+KA2 ~]# dnf install ipvsadm -y
RS1和RS2的IP配置:


配置内核参数用于 LVS-DR 后端节点,抑制 RS 争抢 VIP 的 ARP 应答与广播,确保 VIP 仅由调度器对外响应 ARP,保障集群正常转发。

bash
#在keepalived的所有主机中
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 172.25.254.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 172.25.254.10 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
real_server 172.25.254.20 80 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 80
}
}
}
[root@KA1 ~]# systemctl restart keepalived.service
配置方式:
测试:

5.利用VRRP Script 实现全能高可用
bash
#在KA1和KA2中安装haproxy
[root@KA1+2 ~]# dnf install haproxy-2.4.22-4.el9.x86_64 -y
[root@KA1 ~]# vim /etc/sysctl.conf
[root@KA1+2 ~]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
sysctl -p
[root@KA1+2 ~]# vim /etc/haproxy/haproxy.cfg
listen webserver
bind 172.25.254.100:80
mode http
server web1 172.25.254.10:80 check
server web2 172.25.254.20:80 check
[root@KA1+2 ~]# systemctl enable --now haproxy.service
bash
#在KA1主机中
[root@KA1 ~]# vim /etc/keepalived/scripts/test.sh
#!/bin/bash
[ ! -f "/mnt/lee" ] #检测文件是否存在,存在时返回1,不存在时返回0。
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_script check_lee {
script "/etc/keepalived/scripts/test.sh" # 检测脚本路径
interval 1 # 每隔1秒执行一次检测
weight -30 # 默认为0,如果设置此值为负数,当上面脚本返回值为非0时,会将此值与本节点权重相加可以降低本节点权重,
# 如果是正数,当脚本返回值为0,会将此值与本节点权重相加可以提高本节点权重。 # 连续2次检测异常,标记节点故障
rise 2 # 连续2次检测恢复正常,标记节点健康
timeout 2 # 脚本执行超时2秒,直接判定故障
user root # 以root身份运行脚本
}
vrrp_instance DB_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:1
}
track_script {
check_lee
}
}
[root@KA1 ~]# systemctl restart keepalived.service
编写的脚本:

vrrp_script 健康检测块:

测试:

bash
# keepalived + haproxy
[root@KA1 ~]# vim /etc/keepalived/scripts/haproxy_check.sh
#!/bin/bash
killall -0 haproxy &> /dev/null #只检测进程是否存在,不会杀死进程,进程正常运行,命令返回退出码0;进程挂掉,返回非 0;
[root@KA1 ~]# chmod +x /etc/keepalived/scripts/haproxy_check.sh
vrrp_script haporxy_check {
script "/etc/keepalived/scripts/haproxy_check.sh"
interval 1
weight -30
fall 2
rise 2
timeout 2
user root
}
vrrp_instance WEB_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:0
}
track_script {
haporxy_check
}
}
[root@KA1 ~]# systemctl restart keepalived.service
环境准备:


更改了脚本里的内容为检测haporxy程序是否正常运行;


测试:

6.双主模式代理不同业务实现高可用
bash
#在rs中设定lo添加vip2 172.25.254.200/32
#在rs中搭建数据库
[root@rs1+2 ~]# dnf install mariadb-server -y
[root@rs1+2 ~]# systemctl enable --now mariadb
[root@rs1+2 ~]# mysql
MariaDB [(none)]> CREATE USER lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> GRANT ALL ON *.* TO lee@'%';
Query OK, 0 rows affected (0.001 sec)
#测试
[root@rs1 ~]# mysql -ulee -plee -h172.25.254.10
[root@rs1 ~]# mysql -ulee -plee -h172.25.254.20
在RS1和RS2上添加vip200:


在RS1和RS2上创建更改id:

创建数据库远程登陆用户:


bash
#KA1和KA2
[root@KA1+2 ~]# vim /etc/keepalived/keepalived.conf
include /etc/keepalived/conf.d/webserver.conf
include /etc/keepalived/conf.d/datebase.conf
[root@KA1+2 ~]# vim /etc/keepalived/conf.d/webserver.conf
virtual_server 172.25.254.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 172.25.254.10 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
retry 3
delay_before_retry 1
}
}
real_server 172.25.254.20 80 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 80
}
}
}
[root@KA1+2 ~]# vim /etc/keepalived/conf.d/datebase.conf
virtual_server 172.25.254.200 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 172.25.254.10 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 172.25.254.20 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 3306
}
}
}
[root@KA1+2 ~]# systemctl restart keepalived.service
配置文件:


bash
[root@rs2 ~]# mysql -ulee -plee -h172.25.254.200
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 89
Server version: 10.5.27-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
[Administrator.DESKTOP-VJ307M3] ➤ curl 172.25.254.100
RS1 - 172.25.254.10
[2026-01-29 11:58.55] ~
[Administrator.DESKTOP-VJ307M3] ➤ curl 172.25.254.100
RS2 - 172.25.254.20
结果测试:



