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

总结

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

相关文章

  • 教你在k8s上部署HADOOP-3.2.2(HDFS)的方法

    教你在k8s上部署HADOOP-3.2.2(HDFS)的方法

    这篇文章主要介绍了k8s-部署HADOOP-3.2.2(HDFS)的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • K8s基本单元Pod解读

    K8s基本单元Pod解读

    Kubernetes中Pod是调度单元,包含多个容器及Pause容器,提供共享网络、存储等资源,状态分为Pending、Running、Failed等,支持存活、就绪、启动探针检测容器健康
    2025-08-08
  • 虚拟化和云计算的区别分析

    虚拟化和云计算的区别分析

    这篇文章主要介绍了虚拟化和云计算的区别,深入浅出的列举分析了虚拟化与云计算的几点常见区别,需要的朋友可以参考下
    2016-10-10
  • Kubernetes中crictl的详细用法教程与应用实战记录

    Kubernetes中crictl的详细用法教程与应用实战记录

    crictl作为Kubernetes的容器运行时接口(CRI)的命令行工具,为Kubernetes的调试和管理提供了强大的支持,通过本文的详细介绍,你应该已经掌握了crictl的基本安装、配置、常用命令以及高级用法,需要的朋友可以参考下
    2024-07-07
  • Kubernetes(k8s 1.23))安装与卸载详细教程

    Kubernetes(k8s 1.23))安装与卸载详细教程

    这篇文章主要介绍了Kubernetes(k8s 1.23))安装与卸载,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • 解决k8s namespace 一直处于 Terminating 状态的问题

    解决k8s namespace 一直处于 Terminating 状态的问题

    这篇文章主要介绍了k8s namespace 一直处于 Terminating 状态的解决方法,以下的 tool 为 Terminating 状态的 namespace,下面相关的一些操作记得将 tool 修改成自己的 namespace 名称,需要的朋友可以参考下
    2022-10-10
  • 再分享6个可无限激活阿里云盘邀请码,不信你不能激活阿里云盘

    再分享6个可无限激活阿里云盘邀请码,不信你不能激活阿里云盘

    这篇文章主要分享6个可无限激活的阿里云盘邀请码,不信你不能激活阿里云盘,需要的朋友可以参考下
    2020-11-11
  • k8s容器状态Terminating无法删除的问题及解决

    k8s容器状态Terminating无法删除的问题及解决

    这篇文章主要介绍了k8s容器状态Terminating无法删除的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-07-07
  • 关于k8s中subpath的使用详解

    关于k8s中subpath的使用详解

    这篇文章主要介绍了k8s中subpath的使用,文章介绍分为两种情况给大家详细讲解,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • Kubernetes中创建命名空间实现方法

    Kubernetes中创建命名空间实现方法

    这篇文章主要为大家介绍了Kubernetes中创建命名空间实现方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11

最新评论