keepalived nopreempt的应用场景及说明

 更新时间:2026年01月24日 10:49:16   作者:云计算-Security  
文章详细介绍了keepalived高可用模式下`nopreempt`非抢占模式的应用场景,并探讨了不同配置下的VIP故障转移行为,同时,文章还解释了`notify`脚本的作用,包括触发时机和典型用途

背景

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅谈Spark RDD API中的Map和Reduce

    浅谈Spark RDD API中的Map和Reduce

    rdd是什么?如何创建?什么是map和reduce?本文就这些问题向大家作了一些分析,供大家参考,如有不足,欢迎指出。
    2017-10-10
  • K8s Service服务发布方式

    K8s Service服务发布方式

    文章介绍了Kubernetes中标签(Label)用于资源分组,标签选择器(Selector)用于精准匹配;Service作为服务抽象,通过标签选择器关联Pod,提供稳定访问入口(ClusterIP/NodePort);Endpoint记录Pod网络信息,实现服务发现与流量分发
    2025-08-08
  • k8s部署rabbitmq集群的方式

    k8s部署rabbitmq集群的方式

    本次部署方式为setafulset的方式部署rabbitmq集群,使用svc的无头服务,本次涉及使用到的服务有setafulset、secret、configmap、service、pv、pvc、sa,在rabbitmq的官网中使用的是operator的方式,感兴趣的朋友一起看看吧
    2024-03-03
  • 浅析kubernetes的控制器和标签

    浅析kubernetes的控制器和标签

    这篇文章主要介绍了kubernetes的控制器和标签的相关资料,帮助大家更好的理解和学习使用k8s,感兴趣的朋友可以了解下
    2021-04-04
  • 2022最新青龙面板对接机器人的详细过程(傻妞对接onebot(oicq)协议实现机器人功能)

    2022最新青龙面板对接机器人的详细过程(傻妞对接onebot(oicq)协议实现机器人功能)

    这篇文章主要介绍了2022最新青龙面板对接机器人的详细过程(傻妞对接onebot(oicq)协议实现机器人功能),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • K8s如何拉取habor镜像

    K8s如何拉取habor镜像

    这篇文章主要介绍了K8s如何拉取habor镜像,在daemon.json中添加仓库地址,需要在创建资源对象所在的节点进行添加,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-04-04
  • K8S部署rocketmq5全过程

    K8S部署rocketmq5全过程

    在开发环境中部署RocketMQ 5并验证新版本代理特性,遇到一系列问题,包括存储权限、主从副本配置和命名空间问题,通过修改配置文件和PV设置,最终解决了这些问题,成功部署了RocketMQ集群
    2025-01-01
  • helmfile声明式部署Helm Chart使用详解

    helmfile声明式部署Helm Chart使用详解

    这篇文章主要为大家介绍了helmfile声明式部署Helm Chart使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • k8s中如何实现pod自动扩缩容详解

    k8s中如何实现pod自动扩缩容详解

    在实际生产系统中,经常会遇到某个服务需要扩容的场景,可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景,下面这篇文章主要给大家介绍了关于k8s中如何实现pod自动扩缩容的相关资料,需要的朋友可以参考下
    2022-08-08
  • kubernetes调度之NodeSelector使用解读

    kubernetes调度之NodeSelector使用解读

    本文介绍Kubernetes中两种简单调度策略:NodeName通过指定节点名称强制调度,跳过调度器;NodeSelector基于节点标签匹配,需为节点打标签并在Pod定义中配置,两者均为强制约束机制
    2025-08-08

最新评论