Skip to content

keepalived

1 安装

bash
yum install keepalived -y

2 配置说明

  • 配置文件默认位于 /etc/keepalived/keepalived.conf

  • keepalive .conf 是描述所有 keepalive 关键字的配置文件。关键字被置于块和子块的层次结构中,每一层都由{}对分隔。

  • 注释以 # 或者 ! 可以从队伍的任何地方开始。

  • 关键字 include 和变体允许从主配置文件中包含其他配置文件,或从随后包含的文件中包含其他配置文件。

    • include指令的格式是: include $FILENAME:
    • FILENAME 可以是绝对路径名或相对路径名,并且可以包含通配符,包括csh风格的花括号表达式,如 {foo/{,cat,dog},bar},如果glob()支持的话。
  • 打开包含的文件后,当前目录被设置为文件本身的目录,因此任何包含的文件的相对路径都是相对于包含文件本身的目录的。

常用参数语法:

BOOL :取值: on|off|true|false|yes|no

TIMER: 是以秒为单位的时间值,包括小数秒,例如2.71828或3; 定时器单位为微秒。

SCRIPTS: 有三类脚本可以被配置来执行。

(a)通知当vrrp实例或vrrp组状态发生变化,或虚拟服务器仲裁在up和down之间发生变化时运行的脚本。

(b) VRRP跟踪脚本,使VRRP实例退出非零存在状态,或者如果指定了权重,则会增加或减去该VRRP实例优先级的权重。

(c) LVS检查器杂项脚本,如果它们以非零状态退出,将导致实服务器被配置down。

3 模块说明

一个功能比较完整的常用的 keepalived 配置文件,主要包含以下三块:

yaml
#全局定义块
global_defs {
   ...
}
#VRRP 实例定义块
vrrp_instance VI_1 {
   ...
}
#LVS服务器定义块
virtual_server 10.10.10.2 1358 {
   ...
}

cat /etc/keepalived/keep配置文件内容

yaml
global_defs {                        ###全局定义块
    router_id node01             ###用户标识本节点的名称,主备节点要不一致
}

vrrp_instance VI_1 {                 ###定义一个vrrp_install实例,名称为VI_1
    state BACKUP                     ###表示该实例的角色状态,有MASTER和BACKUP两种主备状态。
    interface ens160                 ###对外提供服务的网络接口,如eth0,ens33,ens192
    virtual_router_id 160     ###虚拟路由ID标识,主备服务器配置中相同实例的ID必须一致,否则将出现脑裂问题。
    priority 100              ###priority表示实例优先级。数字越大,优先级越高。
    # advert_int 1                  ###advert_int为同步通知间隔。主备之间通信检查的时间间隔,默认为1秒。
    # nopreempt               ###nopreempt允许一个priority比较低的节点作为master,即使有priority更高的节点启动。
    
    # notify scripts, alert as above
    notify_master "/etc/keepalived/mail.sh master"
    notify_backup "/etc/keepalived/mail.sh backup"
    notify_fault "/etc/keepalived/mail.sh fault"
    # 停止VRRP时执行
    # notify_stop <STRING>|<QUOTED-STRING> [username [groupname]]
    # VRRP 任何状态变化时执行
    # notify <STRING>|<QUOTED-STRING> [username [groupname]]
    
    authentication {    ###权限认证配置,下方2行参数。
        auth_type PASS
        auth_pass f@sQ@4TAC#9AM_pI
    }
    
    virtual_ipaddress {  
        ###虚拟IP地址;可以配置多个IP,每个IP占一行。注意,这里的IP就是在工作中需要和域名绑定的ip,即可配置的高可用服务监听的ip保持一致。
        172.16.1.200 dev ens160 
    }

}

3.1 配置邮件

低版本Linux使用mailx,高版本已经被s-nail替代了

shell
yum install s-nail -y

添加配置文件 /etc/s-nail.rc

shell
set v15-compat
set from="moujunmore@163.com"
set mta=smtps://moujunmore:PASS@smtp.163.com:465
set smtp-auth=login

发送邮件测试

shell
echo "test mail" |s-nail -s "test" xxxx@163.com

3.2 告警邮件脚本配置

vi /etc/keepalived/mail.sh 完成之后添加可执行权限 chmod +x /etc/keepalived/mail.sh

shell
#!/bin/bash
recv_addr='moujunmore@163.com'
notify(){
    mailsubject="$(cat /proc/sys/kernel/hostname) 变更为 $1 ,vip 发生浮动"
    mailbody="$(date +'%Y-%m-%d %H:%M:%S'): vrrp 发生浮动, $(cat /proc/sys/kernel/hostname) 变为 $1"
    echo "$mailbody" |s-nail -s "$mailsubject" $recv_addr
}

case $1 in
master)
  notify master
  # 如果是主机就启动服务
  ;;
backup)
  notify backup
  # 如果需要主机起来作为备机,可以将服务停掉
  ;;
fault)
  notify fault
  ;;
*)
  echo "错误的入参,请调用: $(basename $0) {master|backup|fault}"
  exit 1
  ;;
esac

3.3 检测脚本配置

keepalived只能做到对网络故障和keepalived本身的监控,我们还需要监控keepalived所在服务器上的其他业务进程,比如说nginxkeepalived+nginx实现nginx的负载均衡高可用,如果nginx异常,仅仅keepalived保持正常,是无法完成系统的正常工作的,因此需要根据业务进程的运行状态决定是否需要进行主备切换。这个时候,我们可以通过编写脚本对业务进程进行检测监控。

nginx检查脚本 /etc/keepalived/check_service.sh

shell
#!/bin/bash
count=`ps aux | grep -v grep | grep nginx | wc -l`
if [ $count -gt 0 ]; then
    exit 0
else
    exit 1
fi

在配置文件中新增检测

yaml
global_defs {                        ###全局定义块
    router_id node01             ###用户标识本节点的名称,主备节点要不一致
}

vrrp_script check_nginx {            ###应用状态检查
    script "/etc/keepalived/check_service.sh"   ###nginx状态检查脚本
    interval 5                          ###检查间隔时间
    fall 2 								### 连续检测失败次数
    rise 2 								### 连续检测成功次数
    weight -40
} 

vrrp_instance VI_1 {                 ###定义一个vrrp_install实例,名称为VI_1
    state BACKUP                     ###表示该实例的角色状态,有MASTER和BACKUP两种主备状态。
    interface ens160                 ###对外提供服务的网络接口,如eth0,ens33,ens192
    virtual_router_id 160     ###虚拟路由ID标识,主备服务器配置中相同实例的ID必须一致,否则将出现脑裂问题。
    priority 100              ###priority表示实例优先级。数字越大,优先级越高。
    # advert_int 1                  ###advert_int为同步通知间隔。主备之间通信检查的时间间隔,默认为1秒。
    # nopreempt               ###nopreempt允许一个priority比较低的节点作为master,即使有priority更高的节点启动。
    
    # notify scripts, alert as above
    notify_master "/etc/keepalived/mail.sh master"
    notify_backup "/etc/keepalived/mail.sh backup"
    notify_fault "/etc/keepalived/mail.sh fault"
    # 停止VRRP时执行
    # notify_stop <STRING>|<QUOTED-STRING> [username [groupname]]
    # notify <STRING>|<QUOTED-STRING> [username [groupname]]
    
    authentication {    ###权限认证配置,下方2行参数。
        auth_type PASS
        auth_pass f@sQ@4TAC#9AM_pI
    }
    virtual_ipaddress {  
        ###虚拟IP地址;可以配置多个IP,每个IP占一行。注意,这里的IP就是在工作中需要和域名绑定的ip,即可配置的高可用服务监听的ip保持一致。
        172.16.1.200 dev ens160 
    }
    
    track_script {     ###可以在keepalived.conf文件中定义的脚本,用以实现某个检测功能;
       check_nginx    ###此处调用check_nginx中的脚本。
    } 

}

3.4 非抢占模式

默认情况下,主节点宕机,备节点接管业务后,一般来说是不希望切换回去的,因为多一次业务的切换会多一分不稳定的因素,实际场景中更希望业务稳定运行

可在脚本中添加服务的启停实现 也可以通过 nopreempt 来实现

3.5 组播变单播

为什么需要设置单播呢,由于一个网段中,可能存在多个高可用的情况,虽然情况比较少见,万一配置id一直并且认证方式也一致,就有可能导致高可用故障

配置单播以后也有效提高网络数据包传输效率

yaml
global_defs {                        ###全局定义块
    router_id node01             ###用户标识本节点的名称,主备节点要不一致
    #vrrp_strict			#单播必须关闭这个参数
}

vrrp_script check_nginx {            ###应用状态检查
    script "/etc/keepalived/check_service.sh"   ###nginx状态检查脚本
    interval 5                          ###检查间隔时间
    fall 2 								### 连续检测失败次数
    rise 2 								### 连续检测成功次数
    weight -40
}

vrrp_instance VI_1 {                 ###定义一个vrrp_install实例,名称为VI_1
    state BACKUP                     ###表示该实例的角色状态,有MASTER和BACKUP两种主备状态。
    interface ens160                 ###对外提供服务的网络接口,如eth0,ens33,ens192
    virtual_router_id 160     ###虚拟路由ID标识,主备服务器配置中相同实例的ID必须一致,否则将出现脑裂问题。
    priority 100              ###priority表示实例优先级。数字越大,优先级越高。
    # advert_int 1                  ###advert_int为同步通知间隔。主备之间通信检查的时间间隔,默认为1秒。
    # nopreempt               ###nopreempt允许一个priority比较低的节点作为master,即使有priority更高的节点启动。
    
    # notify scripts, alert as above
    notify_master "/etc/keepalived/mail.sh master"
    notify_backup "/etc/keepalived/mail.sh backup"
    notify_fault "/etc/keepalived/mail.sh fault"
    # 停止VRRP时执行
    # notify_stop <STRING>|<QUOTED-STRING> [username [groupname]]
    # notify <STRING>|<QUOTED-STRING> [username [groupname]]
    
    authentication {    ###权限认证配置,下方2行参数。
        auth_type PASS
        auth_pass f@sQ@4TAC#9AM_pI
    }
    
    unicast_src_ip 172.16.1.21		 #配置单播的源地址,即本机地址
    unicast_peer {
      172.16.1.22                    #配置单播的目标地址,即对方节点地址,备有多台就配置多个地址
    } 
    
    virtual_ipaddress {  
        ###虚拟IP地址;可以配置多个IP,每个IP占一行。注意,这里的IP就是在工作中需要和域名绑定的ip,即可配置的高可用服务监听的ip保持一致。
        172.16.1.200 dev ens160 
    }
    
    track_script {     ###可以在keepalived.conf文件中定义的脚本,用以实现某个检测功能;
       check_nginx    ###此处调用check_nginx中的脚本。
    }

}

4. 配合LVS

yaml
# LVS 配置模块 可以配置多个集群
virtual_server 172.16.1.100 80 {
    delay_loop 6 # 健康检查间隔 默认60s
    lvs_sched rr # 调度模式 rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq|twos
    lvs_method TUN type ipip # 集群模式 DR NAT | TUN [type {ipip|gue port NUM|gre} [nocsum|csum|remcsum]]
    # persistence_timeout 50 # LVS 持久化时间 这段时间内 ip调度会想同一个real server负载
    protocol TCP # TCP|UDP|SCTP
    real_server 192.168.132.3 80 {     # 第一个节点服务器
        weight 1
        # notify_up <STRING> # 服务为up时执行的脚本
        # notify_down <STRING> # 服务为down时执行的脚本
        
        # HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|DNS_CHECK|MISC_CHECK|BFD_CHECK|UDP_CHECK|PING_CHECK|FILE_CHECK
        TCP_CHECK {
            connect_port 80 # 检测端口
            connect_timeout 3 # 超时时间
            retry 1 # 失败重试次数 默认1
            delay_before_retry 3 # 失败后重试间隔时间
        }
    }
 
    real_server 192.168.1.26 80 {     # 第二个节点服务器
        weight 1
        # notify_up <STRING> # 服务为up时执行的脚本
        # notify_down <STRING> # 服务为down时执行的脚本
        
        # HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|DNS_CHECK|MISC_CHECK|BFD_CHECK|UDP_CHECK|PING_CHECK|FILE_CHECK
        MISC_CHECK { # 对于一些http的复杂检测,可以使用自定义脚本来检测
           # 默认重试次数为 0
           # 脚本执行路径
           misc_path "/etc/keepalived/httpcheck.sh 192.168.1.26"
           # 脚本执行超时时间
           misc_timeout <INTEGER>
       }
    }
}

5. 配合HAProxy