keepalived


keepalived 主要实现功能包括1.vip的失败接管 2.管理配置lvs 3.对realserver的健康检查

同类软件 heartbeat
硬件设备:F5 netscaler radware

安装

yum install openssl openssl-devel popt popt-devel –y
./configure 
make && make install 

keepalived.conf格式

  • 各层级使用 '{' 和 '}' 进行分割;

  • 使用 '#' or '!' 开头 作为注释

  • include 引用其他配置文件

  • 脚本

    • 对于keepalived 要有可执行权限
      1. 通知脚本(当virrp实例状态发生变更时触发)
      2. vrrp 的探测脚本(通过脚本的返回状态0|1判断weigth值的变更)
      3. LVS 探测realserver的脚本(如果返回状态部位0,将realserver 标记down

keepalived.conf 的配置层级结构

  • GLOBAL CONFIGURATION
  • BFD CONFIGURATION
  • VRRPD CONFIGURATION
  • LVS CONFIGURATION

全局配置

! Configuration File for keepalived

##########################################################
global_defs {
	notification_email {
		wangendao@.crv.com.cn
		email2
	}
	notification_email_from wangendao@.crv.com.cn
	smtp_server 218.13.52.193
	smtp_connect_timeout 30
	router_id LVS_7 # specify the name of the lvs director,master and backend use different name

}

VRRP探测脚本

# 探测脚本。当脚本退出状态码不为0 ,vrrp 实例状态变为down或权重上升或下降。使用时在高可用实例中调用
vrrp_script check_port {
	script "/etc/keepalived/check_port.sh 6443"
	interval 2
	weight -20
}

高可用

master 通过组播224.0.0.18 方式通知 backup

#################### Vrrp instance #########################

vrrp_instance VI_1 {     
    state MASTER 			# MASTER|BACKUP
    interface ens33			
    virtual_router_id 51    #vrid,same vrrp have to same vrid
    priority 150            #master and backup have to diffent value 
    advert_int 1
    vrrp_garp_master_delay 2	# 成功收到免费ARP应答后间,隔2s发送下一组arp
    nopreempt   # 在master 端设置不抢占
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.124/24 dev eth0 label eth0:0
        192.168.0.125/24 dev eth0 label eth0:1
    }
    
    track_script {
    	check_port
    }
    
    # 当前角色变为 master 时 执行对应脚本
    notify_master "/etc/keepalived/notify.sh master"
    # 当前角色变为 backup 时 执行对应脚本
    notify_backup "/etc/keepalived/notify.sh backup"
    # 当前主机故障 时 执行对应脚本
    notify_fault "/etc/keepalived/notify.sh fault"
}

管理LVS

########################manager lvs########################

virtual_server 192.168.0.125 80 {	#virtual_server (@IP PORT)|(fwmark num)
    delay_loop 6  # 指定每次健康检查的间隔秒
    lb_algo rr	#rr|wrr|lc|w1c|sh|dh|1b1c 
    lb_kind DR	#NAT|DR|TUN
    persistence_timeout 50	#指定会话保持的时间
    protocol TCP
    persistence_granularity @IP  # specify a granularity mask for persisten connections
    virtualhost string  # specify a http virtualhost to use for http|ssl_get

    # 
    real_server 192.168.0.123 80 {
        weight 1
    }

    real_server 192.168.0.124 80 {
        weight 1
        # if check's result is false ,keepalived only set weight=0 
        inhibit_on_failure
        # TCP health check
        TCP_CHECK {
            connect_timeout 8
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }

    }
    sorry_server @IP PORT 

}

健康检查的方式

TCP CHECK 在osi模型的第四层工作,如果指定时间没有响应tcp探测的包则从负载集群中移除

HTTP GET 在osi模型的第五层,通过获取指定uri,并通过md5 验证,如果不一致或无响应则视为失败并移除负载集群

SSL GET

MISC CHECK 自定义脚本检查返回结果必须时0 或 1

TCP_CHECK

TCP_CHECK {
	connect_port num
	connect_timeout num
}

MISC CHECK

MISC_CHECK { 
	# check real server availability using user defined script
	misc_path /path_to_script/script.sh
	(or misc_path "/path_to_script/scripts.sh <arg_list>")
}

HTTP_GET|SSL_GET

SSL_GET {
	url {
		path /
		digest ff20ad2481f97b1754ef3e12ecd3a9cc
	}
	url {
		path /mrtg/
		digest 9b3a0c85a887a256d6939da88aabd8cd
	}
	connect_timeout 3
	nb_get_retry 3
	delay_before_retry 3
}
        
        
HTTP_GET {
	url {
		path /testurl/test.jsp
        digest 640205b7b0fc66c1ea91c463fac6334d
	}
	url {
        path /testurl2/test.jsp
        digest 640205b7b0fc66c1ea91c463fac6334d
	}
	connect_timeout 3
	nb_get_retry 3
	delay_before_retry 3
	}
}

裂脑

1.增加专用的心跳线

2.如果BACKUP 发现MASTER 无法通讯,连接到MASTER 执行命令关闭服务或主机

启动命令

keepalived -D -S 0 -l -d -f /tmp/keepalived.conf
kill -HUP `cat /var/run/keepalived.pid `
kill -INT `cat /var/run/keepalived.pid `

-D, --log-detail
-S, --log-facility=[0-7]
-l, --log-console
-d, --dump-conf
-HUP reload its configuration
-INT keepalived will shutdown.
修改日志
vi /etc/sysconfig/keepalived
#注释掉原有的KEEPALIVED_OPTIONS="-D"
KEEPALIVED_OPTIONS="-D -d -S 0"
vi /etc/rsyslog.conf
#在结尾添加如下内容,意思在local0设备上把所有级别的日志都打印到/var/log/keepalived.log
local0.*	 /var/log/keepalived.log
keepalived通知脚本进阶示例:

下面的脚本可以接受选项,其中:
-s, --service SERVICE,...:指定服务脚本名称,当状态切换时可自动启动、重启或关闭此服务;
-a, --address VIP: 指定相关虚拟路由器的VIP地址;
-m, --mode {mm|mb}:指定虚拟路由的模型,mm表示主主,mb表示主备;它们表示相对于同一种服务而方,其VIP的工作类型;
-n, --notify {master|backup|fault}:指定通知的类型,即vrrp角色切换的目标角色;
-h, --help:获取脚本的使用帮助;

#!/bin/bash
# Author: MageEdu <linuxedu@foxmail.com>
# description: An example of notify script
# Usage: notify.sh -m|--mode {mm|mb} -s|--service SERVICE1,... -a|--address VIP  -n|--notify {master|backup|falut} -h|--help 

#contact='linuxedu@foxmail.com'
helpflag=0
serviceflag=0
modeflag=0
addressflag=0
notifyflag=0

contact='root@localhost'

Usage() {
  echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP>  <-n|--notify {master|backup|falut}>" 
  echo "Usage: notify.sh -h|--help"
}

ParseOptions() {
  local I=1;
  if [ $# -gt 0 ]; then
    while [ $I -le $# ]; do
      case $1 in
	  -s|--service)
		[ $# -lt 2 ] && return 3
 	    serviceflag=1
 		services=(`echo $2|awk -F"," '{for(i=1;i<=NF;i++) print $i}'`)
		shift 2 ;;
	  -h|--help)
 		helpflag=1
		return 0
        shift
		;;
	  -a|--address)
		[ $# -lt 2 ] && return 3
	    addressflag=1
		vip=$2
		shift 2
		;;
	  -m|--mode)
		[ $# -lt 2 ] && return 3
		mode=$2
		shift 2
		;;
	  -n|--notify)
		[ $# -lt 2 ] && return 3
		notifyflag=1
		notify=$2
		shift 2
		;;
	  *)
		echo "Wrong options..."
		Usage
		return 7
		;;
       esac
    done
    return 0
  fi
}

#workspace=$(dirname $0)

RestartService() {
  if [ ${#@} -gt 0 ]; then
    for I in $@; do
      if [ -x /etc/rc.d/init.d/$I ]; then
        /etc/rc.d/init.d/$I restart
      else
        echo "$I is not a valid service..."
      fi
    done
  fi
}

StopService() {
  if [ ${#@} -gt 0 ]; then
    for I in $@; do
      if [ -x /etc/rc.d/init.d/$I ]; then
        /etc/rc.d/init.d/$I stop
      else
        echo "$I is not a valid service..."
      fi
    done
  fi
}


Notify() {
    mailsubject="`hostname` to be $1: $vip floating"
    mailbody="`date '+%F %H:%M:%S'`, vrrp transition, `hostname` changed to be $1."
    echo $mailbody | mail -s "$mailsubject" $contact
}


# Main Function
ParseOptions $@
[ $? -ne 0 ] && Usage && exit 5

[ $helpflag -eq 1 ] && Usage && exit 0

if [ $addressflag -ne 1 -o $notifyflag -ne 1 ]; then
  Usage
  exit 2
fi

mode=${mode:-mb}

case $notify in
'master')
  if [ $serviceflag -eq 1 ]; then
      RestartService ${services[*]}
  fi
  Notify master
  ;;
'backup')
  if [ $serviceflag -eq 1 ]; then
    if [ "$mode" == 'mb' ]; then
      StopService ${services[*]}
    else
      RestartService ${services[*]}
    fi
  fi
  Notify backup
  ;;
'fault')
  Notify fault
  ;;
*)
  Usage
  exit 4
  ;;
esac



在keepalived.conf配置文件中,其调用方法如下所示:
    notify_master "/etc/keepalived/notify.sh -n master -a 172.16.100.1"  
    notify_backup "/etc/keepalived/notify.sh -n backup -a 172.16.100.1"  
    notify_fault "/etc/keepalived/notify.sh -n fault -a 172.16.100.1"  
#!/bin/bash
# Author: MageEdu <linuxedu@foxmail.com>
# description: An example of notify script
# 

vip=172.16.100.1
contact='root@localhost'

Notify() {
    mailsubject="`hostname` to be $1: $vip floating"
    mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"
    echo $mailbody | mail -s "$mailsubject" $contact
}

case "$1" in
    master)
        echo "now i am master `hostname -i`">/tmp/1.log
        exit 0
    ;;
    backup)
        printf "%s" `hostname` >/tmp/2.log
        exit 0
    ;;
    fault)
        exit 0
    ;;
    *)
        echo 'Usage: `basename $0` {master|backup|fault}'
        exit 1
    ;;
esac
posted @ 2022-01-30 11:59  mingtian是吧  阅读(168)  评论(0)    收藏  举报