Keepalived 配置示例

满足基本 HA 功能的配置

global_defs {
   notification_email {
        root@localhost
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   script_user root
}
vrrp_script chk_haproxy {
   script “killall -0 haproxy”
   interval 1
   weight -2
}
vrrp_instance VI_1 {
    state MASTER #备节点改成BACKUP
    interface ens33
    virtual_router_id 51
    priority 101 #倍节点改成100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.75
    }
    track_script {
        chk_haproxy
    }
    notify_master "/etc/keepalived/notify master" root
    notify_backup "/etc/keepalived/notify backup" root
    notify_fault "/etc/keepalived/notify fault" root
}
include /etc/keepalived/include/*

基本 LVS 的配置

virtual_server 192.168.0.63 80 {
  delay_loop 6
  lvs_sched rr
  lvs_method DR
  protocol TCP
  real_server 192.168.1.71 80 {
    TCP_CHECK {
     connect_timeout 10
    }
  }
  real_server 192.168.0.72 80 {
    TCP_CHECK {
      connect_timout 10
    }
  }
}

keepalive 双主模型

global_defs {
   notification_email {
         linuxedu@foxmail.com
   }
   notification_email_from kanotify@magedu.com
   smtp_connect_timeout 3
   smtp_server 127.0.0.1
   router_id LVS_DEVEL
}

vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 1
    weight -2
}

vrrp_instance VI_1 {
    interface eth0
    state MASTER  # BACKUP for slave routers
    priority 101  # 100 for BACKUP
    virtual_router_id 51
    garp_master_delay 1

    authentication {
        auth_type PASS
        auth_pass password
    }
    track_interface {
       eth0
    }
    virtual_ipaddress {
        192.168.0.75
    }
    track_script {
        chk_haproxy
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

vrrp_instance VI_2 {
    interface eth0
    state BACKUP  # BACKUP for slave routers
    priority 100  # 100 for BACKUP
    virtual_router_id 52
    garp_master_delay 1

    authentication {
        auth_type PASS
        auth_pass password
    }
    track_interface {
       eth0
    }
    virtual_ipaddress {
        192.168.0.75
    }
    track_script {
        chk_haproxy
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

keepalived 所用到的脚本示例

下面是一个 notify.sh 脚本的简单示例:

#!/bin/bash
# Author: MageEdu <linuxedu@foxmail.com>
# description: An example of notify script
vip=192.168.0.75
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)
        notify master
        systemctl start haproxy.service
        exit 0
    ;;
    backup)
        notify backup
       systemctl stop haproxy.service
        exit 0
    ;;
    fault)
        notify fault
        /etc/rc.d/init.d/haproxy stop
        exit 0
    ;;
    *)
        echo 'Usage: `basename $0` {master|backup|fault}'
        exit 1
    ;;
esac

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"

keepalived 日志配置

建议使用 local2 级别日志,因为 keepalived_healthcheckers 默认为 local2 级别,新版 keepalived 已不用改该配置

修改启动参数,将 -D 改为 -D -d -S 0

sed -i 's/\(KEEPALIVED_OPTIONS=\)"-D"/\1"-D -d -S 0"/' /etc/sysconfig/keepalived

修改 rsyslog 配置

cat > /etc/rsyslog.d/keepalived-log.conf << EOF
local0.*        /var/log/keepalived/keepalived.log
& stop
EOF

配置日志轮替

cat > /etc/logrotate.d/keepalived << \EOF
/var/log/keepalived/keepalived.log {
    daily
    copytruncate
    rotate 10
    missingok
    dateext
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        /bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}
EOF
systemctl restart rsyslog

最后修改 March 23, 2023: 整理,减少顶级目录 (8b75fa89)