keepalived+nginx之监测脚本无法停止keepalived服务

  keepalived+nginx这样的负载均衡配置,很多环境都用到,搭建配置都很简单。

  但是在最近的一次搭建过程中,出现了一种情况,就是nginx进程宕掉后,在监测脚本不能将进程拉起来的情况下,keepalived服务没有被终止,从而导致VIP一直漂在这台nginx已经宕掉的服务器上面,出现这样的情况,一般要么是配置错了,或者监测脚本错了,然而情况并非如此;

  下面这个是keepalived+nginx的基本配置

环境信息

Ngx-Web1
虚拟IP:1.10
物理IP:1.1    Centos7.8    8080    Keepalived master
keepalived-2.0.20
Nginx1.18.0

Ngx-Web2
物理IP:1.2    Centos7.8    8080    Keepalived backup
keepalived-2.0.20
Nginx1.18.0

web1的keepalived配置

! Configuration File for Keepalived
global_defs {
  router_id 1.1 ##指定本机物理主机IP
}
vrrp_script chk_nginx {
   script "/data/keepalived/nginx_check.sh" ## 检测 nginx服务状态
   interval 2 ## 检测时间间隔
   weight -20 ## 如果条件成立,权重-20
}
vrrp_instance VI_1 {
   state MASTER      ##指定这台主机keepalived为主节点
   interface eth0  ##指定物理网卡接口
   virtual_router_id 11 ## 虚拟路由的ID号,两个节点设置必须一样,建议用IP最后段
   mcast_src_ip 1.1  ##指定本机物理主机IP
   priority 100 ## 节点优先级,值范围0-254,MASTER要比BACKUP高
   nopreempt ## 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样,默认 1s
   ## 设置验证信息,两个节点必须一致
   authentication {
      auth_type PASS
      auth_pass 1111
   }
   ## 将 track_script 块加入 instance 配置块
      track_script {
      chk_nginx ## 执行 Nginx 监控的服务
   }
   ## 虚拟 IP 池, 两个节点设置必须一样
   virtual_ipaddress {
      1.10  ## 虚拟ip,可以定义多个
   }
}

web2的keepalived配置

! Configuration File for Keepalived
global_defs {
  router_id 1.2 ##指定本机物理主机IP
}
vrrp_script chk_nginx {
   script "/data/keepalived/nginx_check.sh" ## 检测 nginx服务状态
   interval 2 ## 检测时间间隔
   weight -20 ## 如果条件成立,权重-20
}
vrrp_instance VI_1 {
   state MASTER      ##指定这台主机keepalived为主节点
   interface eth0  ##指定物理网卡接口
   virtual_router_id 11 ## 虚拟路由的ID号,两个节点设置必须一样,建议用IP最后段
   mcast_src_ip 1.2  ##指定本机物理主机IP
   priority 80 ## 节点优先级,值范围0-254,MASTER要比BACKUP高
   nopreempt ## 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样,默认 1s
   ## 设置验证信息,两个节点必须一致
   authentication {
      auth_type PASS
      auth_pass 1111
   }
   ## 将 track_script 块加入 instance 配置块
      track_script {
      chk_nginx ## 执行 Nginx 监控的服务
   }
   ## 虚拟 IP 池, 两个节点设置必须一样
   virtual_ipaddress {
     1.10  ## 虚拟ip,可以定义多个
   }
}

监测脚本/data/keepalived/nginx_check.sh,权限给777就可以了

#!/bin/bash
C=`ps -C nginx --no-header |wc -l`
if [ $C -eq 0 ]
then
su - nginx -c /data/nginx-1.18.0/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ]
then
ps -C keepalived --no-header | awk '{print $1}' | xargs kill
fi
fi

正常情况下,上面的配置可以满足下面的负载条件:

测试用例1    节点nginx服务进程停止
测试方法    手工模拟停止nginx服务,检查nginx进程是否正常拉起
预计结果    Keepalived自动拉起nginx服务,业务访问VIP正常
实际结果    Keepalived自动拉起nginx服务,业务访问VIP正常

测试用例2    主节点宕机
测试方法    手工模拟将keepalived进程或是主机重启
预计结果    VIP自动漂移到备节点,业务访问VIP正常
实际结果    VIP自动漂移到备节点,业务访问VIP正常

测试用例3    主节点恢复
测试方法    恢复主节点keepalived与nginx服务
预计结果    备节点VIP回切主节点,业务访问VIP正常
实际结果    备节点VIP回切主节点,业务访问VIP正常
但是,经过测试,还是会出现一种情况:节点nginx服务进程停止,监测脚本无法拉起nginx的情况下,keepalived服务没有停止虚拟IP依然停留在nginx进程异常的节点上面,导致访问过来的请求出现报错。
一开始以为是脚本的问题、配置的问题,后来手动执行监测脚本,确实可以在nginx进程宕掉后,成功停止keepalived服务,然后虚拟IP漂到备节点上面,那就是脚本执行到一半就没有往下执行了,所以脚本确实是执行了,导致权重也没有减少,因此虚拟IP还是没有漂到备节点上面,配置、脚本都没有问题,百思不解之下,通过网上搜查,发现了另一个可行方案,监测脚本不变,但是web1的keepalived配置添加一个TCP监测项,监测nginx 的访问端口
! Configuration File for Keepalived
global_defs {
  router_id 1.1 ##指定本机物理主机IP
}
vrrp_script chk_nginx {
   script "/data/keepalived/nginx_check.sh" ## 检测 nginx服务状态
   interval 2 ## 检测时间间隔
   weight -20 ## 如果条件成立,权重-20
}
vrrp_instance VI_1 {
   state MASTER      ##指定这台主机keepalived为主节点
   interface eth0  ##指定物理网卡接口
   virtual_router_id 11 ## 虚拟路由的ID号,两个节点设置必须一样,建议用IP最后段
   mcast_src_ip 1.1  ##指定本机物理主机IP
   priority 100 ## 节点优先级,值范围0-254,MASTER要比BACKUP高
   nopreempt ## 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样,默认 1s
   ## 设置验证信息,两个节点必须一致
   authentication {
      auth_type PASS
      auth_pass 1111
   }
   ## 将 track_script 块加入 instance 配置块
      track_script {
      chk_nginx ## 执行 Nginx 监控的服务
   }
   ## 虚拟 IP 池, 两个节点设置必须一样
   virtual_ipaddress {
      1.10  ## 虚拟ip,可以定义多个
   }
}
virtual_server 1.10 8080 { ## 虚拟ip和nginx访问端口
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 5
    protocol TCP

    real_server 1.1 8080 { ##本机物理主机IP和nginx访问端口
        weight 1
        notify_down /data/keepalived/sbin/nginx_check.sh ##监测本地nginx进程端口宕掉后,执行脚本,停止keepalived
TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
                connect_port 8080  #监测的NGINX的访问的TCP端口
        }
    }
}

web2上面的keepalived配置跟web1一样,添加一个TCP监测
! Configuration File for Keepalived
global_defs {
  router_id 1.2 ##指定本机物理主机IP
}
vrrp_script chk_nginx {
   script "/data/keepalived/nginx_check.sh" ## 检测 nginx服务状态
   interval 2 ## 检测时间间隔
   weight -20 ## 如果条件成立,权重-20
}
vrrp_instance VI_1 {
   state MASTER      ##指定这台主机keepalived为主节点
   interface eth0  ##指定物理网卡接口
   virtual_router_id 11 ## 虚拟路由的ID号,两个节点设置必须一样,建议用IP最后段
   mcast_src_ip 1.2  ##指定本机物理主机IP
   priority 80 ## 节点优先级,值范围0-254,MASTER要比BACKUP高
   nopreempt ## 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样,默认 1s
   ## 设置验证信息,两个节点必须一致
   authentication {
      auth_type PASS
      auth_pass 1111
   }
   ## 将 track_script 块加入 instance 配置块
      track_script {
      chk_nginx ## 执行 Nginx 监控的服务
   }
   ## 虚拟 IP 池, 两个节点设置必须一样
   virtual_ipaddress {
     1.10  ## 虚拟ip,可以定义多个
   }
}
virtual_server 1.10 8080 { ## 虚拟ip和nginx访问端口
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 5
    protocol TCP

    real_server 1.2 8080 { ##本机物理主机IP和nginx访问端口
        weight 1
        notify_down /data/keepalived/sbin/nginx_check.sh ##监测本地nginx进程端口宕掉后,执行脚本,停止keepalived
TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
                connect_port 8080  #监测的NGINX的访问的TCP端口
        }
    }
}
当这个keepalived的配置改成这样后,监测脚本无法拉起nginx的情况下,keepalived服务也会因为TCP端口,就是nginx的访问端口宕掉,而触发脚本,将keepalived服务停止,而不会像前面的那样,发现nginx进程无法拉起后,一直重复执行拉起操作,但是不停止keepalived进程

 

posted @ 2021-02-02 21:15  知识,让我掌握未来  阅读(1167)  评论(0编辑  收藏  举报