keepalived nopreempt 的应用场景

keepalived

Author:Arsen
Date:2025/11/11



背景

keepalived 高可用模式下 “nopreempt(非抢占模式)” 的应用场景。

配置

环境

主节点:

  • VIP:192.168.11.235

  • 主节点IP:192.168.11.201

  • 主节点心跳IP:172.16.11.11

备节点:

  • 备节点IP:192.168.11.202
  • 备节点心跳IP:172.16.11.12

配置

主节点:

! Configuration File for keepalived
  
global_defs {
   router_id arsen-master # 主备须唯一
}

vrrp_script chk_net {
    script "/data/keepalived/check/chk_net.sh"
    interval 15
    # weight 15 # 权重是否需要配置请看“实测”部分看你是属于哪种场景
    fall 2
    rise 2
}
vrrp_script chk_acgw {
    script "/data/keepalived/check/chk_nginx.sh"
    interval 15
    # weight 15 # 权重是否需要配置请看“实测”部分看你是属于哪种场景
    fall 2
    rise 2
}

vrrp_instance VI_1 { # vrrp实例名称,可自定义
    state BACKUP  # 状态(非抢占模式下主备保持一致,均为BACKUP)
    interface enp125s0f2 # 心跳网卡,VRRP探测网卡
    virtual_router_id 91 # 虚拟路由,主备保持一致
    priority 50 # 节点权重
    advert_int 1 # VRRP报文探测间隔(1秒)
    nopreempt # 配置非抢占
    unicast_src_ip 172.16.11.11 # 当前节点心跳IP(即心跳网卡enp125s0f2的IP)
    unicast_peer {
        172.16.11.12 # 对端节点心跳IP
    }
    authentication { # VRRP报文认证
        auth_type PASS # 认证类型:密码认证
        auth_pass HelloArsen # 认证密码:HelloArsen
    }
    virtual_ipaddress { # 虚拟IP绑定
        192.168.11.235/24 dev enp125s0f0 # 指定VIP及绑定的物理网卡
    }
    track_script { # 脚本检测(用于触发故障转移)
        chk_net # 网络连通性检测脚本
        chk_nginx # nginx服务健康状态检测脚本
    }
    notify /data/keepalived/notify/notify.sh # 看 notify 应用部分
}

备节点:

! Configuration File for keepalived
  
global_defs {
   router_id arsen-slave # 主备须唯一
}

vrrp_script chk_net {
    script "/data/keepalived/check/chk_net.sh"
    interval 15
    # weight 15 # 权重是否需要配置请看“实测”部分看你是属于哪种场景
    fall 2
    rise 2
}
vrrp_script chk_acgw {
    script "/data/keepalived/check/chk_nginx.sh"
    interval 15
    # weight 15 # 权重是否需要配置请看“实测”部分看你是属于哪种场景
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP  # 状态(非抢占模式下主备保持一致,均为BACKUP)
    interface enp125s0f2 # 心跳网卡,VRRP探测网卡
    virtual_router_id 91 # 虚拟路由,主备保持一致
    priority 50 # 节点权重
    advert_int 1 # VRRP报文探测间隔(1秒)
    nopreempt # 配置非抢占
    unicast_src_ip 172.16.11.12 # 当前节点心跳IP(即心跳网卡enp125s0f2的IP)
    unicast_peer {
        172.16.11.11 # 对端节点心跳IP
    }
    authentication { # VRRP报文认证
        auth_type PASS # 认证类型:密码认证
        auth_pass HelloArsen # 认证密码:HelloArsen
    }
    virtual_ipaddress { # 虚拟IP绑定
        192.168.11.235/24 dev enp125s0f0 # 指定VIP及绑定的物理网卡
    }
    track_script { # 脚本检测(用于触发故障转移)
        chk_net # 网络连通性检测脚本
        chk_nginx # nginx服务健康状态检测脚本
    }
    notify /data/keepalived/notify/notify.sh # 看 notify 应用部分
}

实测

场景1

主备都设置 nopreempt,state 主为 MASTER 备为 BACKUP,且启用 track_script 权重(正/负权重)。

这种场景下,即便是主的权重小于备的权重也是无法进行 VIP 故障转移,因为此时 nopreempt 和权重产生了冲突。

场景2

主备都设置 nopreempt,state 主为 MASTER 备为 BACKUP,且没启用 track_script 权重(正/负权重)。

这种场景下,会进行 VIP 故障转移,与权重无关,主中 track_script 的服务恢复后(注意是监测的所有服务都恢复)VIP 自动转移回来。

场景3

主备都设置 nopreempt,state 主备均为 BACKUP,且启用 track_script 权重(正/负权重)。

这种场景下,即便是主的权重小于备的权重也是无法进行 VIP 故障转移,因为此时 nopreempt 和权重产生了冲突。

场景4

主备都设置 nopreempt,state 主备均为 BACKUP,且没启用 track_script 权重(正/负权重)。

这种场景下,会进行 VIP 故障转移,与权重无关,主中 track_script 的服务恢复后(注意是监测的所有服务都恢复),VIP 不会自动转移回来,只有备中的服务异常后VIP才会自动转移回来。但是要注意,比如主的 nginx 异常,备的 nginx 正常,VIP 会漂移至备,如果过段时间备的 nginx 异常,而主的 nginx 仍然没有恢复正常,则主备都无法持有 VIP,整个业务将异常。

场景5

主备都没设置 nopreempt,state 主为 MASTER 备为 BACKUP,且启用 track_script 权重(正/负权重)。

这种场景下,会根据权重进行 VIP 故障转移,主中 track_script 的服务恢复后且权重高于备,则 VIP 自动转移回来。

场景6

主备都没设置 nopreempt,state 主为 MASTER 备为 BACKUP,且没启用 track_script 权重(正/负权重)。

这种场景下,会进行 VIP 故障转移,与权重无关,主中 track_script 的服务恢复后(注意是监测的所有服务都恢复)VIP自动转移回来。

notify 应用

notify 有什么用?notify 会根据 keepalived 的状态变化去执行相关动作(如执行某个脚本),notify 共有三种状态,分别为 MASTER、BACKUP、FAULT,除了案例中配置的 notify_master 外,还有如下几项配置。

  • notify_master

    notify_master /data/keepalived/notify/notify_master.sh

    触发时机:当节点转换到 MASTER 状态时

    典型用途:

    • 重启服务(如 Nginx、Java)
    • 节点状态切换通知
  • notify_backup

    notify_backup /data/keepalived/notify/notify_master.sh

    触发时机:当节点转换到 BACKUP 状态时

    典型用途:

    • 节点状态切换通知
  • notify_fault

    /data/keepalived/notify/notify_fault.sh

    触发时机:当节点转换到 FAULT 状态时(即检测到故障)

    典型用途:

    • 发送故障告警
    • 执行紧急恢复操作
  • notify_stop

    notify_stop /data/keepalived/notify/notify_stop.sh

    触发时机:当 Keepalived进程停止时(如服务关闭、重启)

    典型用途:

    • 停止相关服务
    • 发送维护通知
  • notify

    notify_stop /data/keepalived/notify/notify.sh

    触发时机:任何状态变化时都会调用

    参数传递:

    • 脚本会收到状态参数:$1 = "MASTER"|"BACKUP"|"FAULT"
    • VRRP 实例名称:$2
    • 状态名称:$3

    典型用途:

    • 统一的日志记录
    • 通用处理逻辑(如下案例)

实际上,我们只需配置 notify 即可,然后在脚本中捕获 keepalived 实例状态后执行对应的逻辑即可,如:

#!/bin/bash

TYPE=$1
NAME=$2
STATE=$3

case $STATE in
    "MASTER")
        # 成为 Master 时的操作
        echo "$(date): $NAME 切换为 MASTER 状态" >> /var/log/keepalived-notify.log
        echo "$(date): $NAME 开始重启 nginx 服务..." >> /var/log/keepalived-notify.log
        systemctl restart nginx
        ;;
    "BACKUP") 
        # 成为 Backup 时的操作
        echo "$(date): $NAME 切换为 BACKUP 状态" >> /var/log/keepalived-notify.log
        ;;
    "FAULT")
        # 故障时的操作
        echo "$(date): $NAME 切换为 FAULT 状态" >> /var/log/keepalived-notify.log
        # 发送告警邮件或通知
        ;;
    "STOP")
        # Keepalived 停止时的操作
        echo "$(date): $NAME Keepalived 服务停止" >> /var/log/keepalived-notify.log
        ;;
esac

exit 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值