keepalived介绍及使用

622 阅读6分钟

中文在线文档

介绍:

负载平衡是一种跨真实服务器集群分配IP流量的方法,提供一个或多个高度可用的虚拟服务。在设计负载平衡拓扑时,必须考虑负载平衡器本身以及其背后的真实服务器的可用性。

Keepalive为负载平衡和高可用性提供了框架。负载平衡框架依赖于众所周知且广泛使用的Linux虚拟服务器(IPVS)内核模块,该模块提供第4层负载平衡。Keepalive实现了一组健康检查程序,以根据服务器池的健康状况动态、自适应地维护和管理负载平衡的服务器池。通过虚拟冗余路由协议(VRRP)实现高可用性。VRRP是路由器故障切换的基础砖。此外,keepalive实现了一组到VRRP有限状态机的钩子,提供低级别和高速协议交互。每个Keepalive框架都可以单独使用或一起使用,以提供弹性基础设施。

在这种情况下,负载平衡器也可以称为控制器或LVS路由器。
简而言之,Keepalive提供了两个主要功能:

  • LVS系统的健康检查
  • VRRPv2堆栈的实现以处理负载平衡器故障切换

软件设计:

Keepalive是纯ANSI/ISO C编写的。该软件围绕一个中央I/O多路复用器,提供实时网络设计。主要设计重点是在所有元素之间提供同质的模块化。这就是为什么创建了一个核心库来消除代码重复。目标是生成安全可靠的代码,确保生产的健壮性和稳定性。

为了确保健壮性和稳定性,守护进程分为3个不同的进程:

  • 极简型父进程负责下属子线程的监控。
  • 两个子进程,一个负责VRRP框架,另一个负责健康检查。

每个子进程都有自己的调度I/O多路复用器,这样VRRP调度抖动就得到了优化,因为VRRP调度比健康检查更合理/更关键。这种分离设计最小化了对外部库使用情况的健康检查,并最小化了其自身的操作,以避免其自身造成的故障。

父进程监控框架称为看门狗,其设计是每个子进程打开一个接受unix域套接字,然后在守护进程引导时,父进程连接到这些unix域套接字并向子进程发送周期性(5s)hello数据包。若父级无法将hello数据包发送到远程连接的unix域套接字,则只需重新启动子级进程。

这种看门狗设计提供了两个好处,首先,从父进程向远程连接的子进程发送的hello数据包是通过I/O多路复用器调度器完成的,这样它可以检测子进程调度框架中的死循环。第二个好处是使用sysV信号检测死亡子进程。运行时,您将在进程列表中看到:

PID 111 Keepalived <-- Parent process monitoring children
    112 \_ Keepalived <-- VRRP child
    113 \_ Keepalived <-- Healthchecking child

内核组件

Keepalive使用四个Linux内核组件:

  1. LVS框架:使用getsockopt和setsockopt调用获取和设置套接字上的选项。
  2. Netfilter框架:支持NAT和伪装的IPVS代码。
  3. Netlink接口:设置和删除网络接口上的VRRP虚拟IP。
  4. 多播:VRRP广播被发送到持有的VRRP Multicast组(224.0.0.18)。

原子元素

依赖软件安装

centos安装以下先决条件:

yum install curl gcc openssl-devel libnl3-devel net-snmp-devel

安装方式1-yum 方式

#安装
yum install -y keepalived

初始化及启动

systemctl enable keepalived  #加入开机启动 keepalived
systemctl start keepalived   #启动 keepalived
systemctl restart keepalived  #重新启动 keepalived
systemctl status keepalived   #查看 keepalived 状态

安装方式2-源码包

cenntos

#下载源码
wget https://www.keepalived.org/software/keepalived-2.2.7.tar.gz
#解压源码包
tar -zxvf keepalived-2.2.7.tar.gz
#进入源码目录
cd keepalived-2.2.7
#执行配置
./configure --prefix=/usr/local/keepalived-2.2.7
#编译安装
make && make install

源码位置:

编译后的文件:

初始化及启动:

# keepalived 启动脚本变量引用文件,默认文件路径是 /etc/sysconfig/,也可以不做软链接,直接修改启动脚本中文件路径即可(安装目录下)
cp /usr/local/keepalived-2.2.7/etc/sysconfig/keepalived  /etc/sysconfig/keepalived
# 将keepalived 主程序加入到环境变量(安装目录下)
cp /usr/local/keepalived-2.2.7/sbin/keepalived /usr/sbin/keepalived
# keepalived 启动脚本(源码目录下),放到 /etc/init.d/ 目录下就可以使用 service 命令便捷调用
cp /home/solft/keepalived-2.2.7/keepalived/etc/init.d/keepalived  /etc/init.d/keepalived
# 将配置文件放到默认路径下
mkdir /etc/keepalived
cp /usr/local/keepalived-2.2.7/etc/keepalived/keepalived.conf.sample /etc/keepalived/keepalived.conf
加为系统服务:chkconfig –add keepalived
开机启动:chkconfig keepalived on
查看开机启动的服务:chkconfig –list
启动、关闭、重启 service keepalived start|stop|restart

ubuntu

#系统版本
lsb_release -a 
#安装前环境准备
sudo apt-get install libssl-dev
sudo apt-get install libpopt-dev
sudo apt-get install daemon
sudo apt-get install build-essential
sudo apt-get install libssl-dev 
sudo apt-get install openssl 
sudo apt-get install libpopt-dev
# 软连
ln -s /usr/local/keepalived-2.2.7/sbin/keepalived /sbin/
 
# 拷贝配置文件,默认路径为/etc/keepalived
mkdir /etc/keepalived
cp -rf /usr/local/keepalived-2.2.7/etc/keepalived/keepalived.conf /etc/keepalived/
 
# 添加环境变量 (环境变量在 /etc/profile 在最后一行添加即可
echo "export KEEPALIVED_HOME=/usr/local/keepalived-2.2.7" >> ~/.bashrc
. ~/.bashrc

Keepalived配置简介

配置文件参考说明

[root@localhost ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {                                     #全局定义部分
    notification_email {                          #设置报警邮件地址,可设置多个
        acassen@firewall.loc                      #接收通知的邮件地址
    }
    notification_email_from test0@163.com         #设置 发送邮件通知的地址
    smtp_server smtp.163.com                      #设置 smtp server 地址,可是ip或域名.可选端口号 (默认25)
    smtp_connect_timeout 30                       #设置 连接 smtp server的超时时间
    router_id LVS_DEVEL                           #主机标识,用于邮件通知
    vrrp_skip_check_adv_addr
    vrrp_strict                                   #严格执行VRRP协议规范,此模式不支持节点单播
    vrrp_garp_interval 0
    vrrp_gna_interval 0
    script_user keepalived_script                 #指定运行脚本的用户名和组。默认使用用户的默认组。如未指定,默认为keepalived_script 用户,如无此用户,则使用root
    enable_script_security                        #如过路径为非root可写,不要配置脚本为root用户执行。
}
 
vrrp_instance VI_1 {                              #vrrp 实例部分定义,VI_1自定义名称
    state MASTER                                  #指定 keepalived 的角色,必须大写 可选值:MASTER|BACKUP
    interface ens33                               #网卡设置,lvs需要绑定在网卡上,realserver绑定在回环口。区别:lvs对访问为外,realserver为内不易暴露本机信息
    virtual_router_id 51                          #虚拟路由标识,是一个数字,同一个vrrp 实例使用唯一的标识,MASTER和BACKUP 的 同一个 vrrp_instance 下 这个标识必须保持一致
    priority 100                                  #定义优先级,数字越大,优先级越高。
    advert_int 1                                  #设定 MASTER 与 BACKUP 负载均衡之间同步检查的时间间隔,单位为秒,两个节点设置必须一样
    authentication {                              #设置验证类型和密码,两个节点必须一致
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {                           #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
        192.168.119.130
    }
    track_script {                                #脚本监控状态
        chk_nginx_service                         #可加权重,但会覆盖声明的脚本权重值。chk_nginx_service weight -20
    }
        notify_master "/etc/keepalived/start_haproxy.sh start"  #当前节点成为master时,通知脚本执行任务
        notify_backup "/etc/keepalived/start_haproxy.sh stop"   #当前节点成为backup时,通知脚本执行任务
        notify_fault  "/etc/keepalived/start_haproxy.sh stop"   #当当前节点出现故障,执行的任务;
}
 
virtual_server 192.168.119.130 80  {          #定义RealServer对应的VIP及服务端口,IP和端口之间用空格隔开
    delay_loop 6                              #每隔6秒查询realserver状态
    lb_algo rr                                #后端调试算法(load balancing algorithm)
    lb_kind DR                                #LVS调度类型NAT/DR/TUN
    #persistence_timeout 60                   同一IP的连接60秒内被分配到同一台realserver
    protocol TCP                              #用TCP协议检查realserver状态
    real_server 192.168.119.120 80 {
        weight 1                              #权重,最大越高,lvs就越优先访问
        TCP_CHECK {                           #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC
            connect_timeout 10                #10秒无响应超时
            retry 3                           #重连次数3次
            delay_before_retry 3              #重连间隔时间
            connect_port 80                   #健康检查realserver的端口
        }
    }
}
}

VRRP script脚本说明

vrrp_script <SCRIPT_NAME> { #定义一个检测脚本,在global_defs 之外配置
    script <STRING>|<QUOTED-STRING> # shell命令或脚本路径
    interval <INTEGER> # 间隔时间,单位为秒,默认1秒
    timeout <INTEGER> # 超时时间
    weight <INTEGER:-254..254> # 权重,当脚本成功或失败对当前节点的优先级是增加还是减少,这个值会与定义的优先级做加法例:-80时则为priority+(-80)
    fall <INTEGER> #脚本几次失败转换为失败
    rise <INTEGER> # 脚本连续监测成果后,把服务器从失败标记为成功的次数
    user USERNAME [GROUPNAME] # 执行监测的用户或组
    init_fail # 设置默认标记为失败状态,监测成功之后再转换为成功状态
}
  • script 脚本 执行结果判断(0为成功,非0为失败)

配置文件模块说明

详细参数说明:

keepalived-doc.readthedocs.io/zh_CN/lates…

实战

实战1

实战目的:

完成如下图的高可用架构,A节点服务挂了,自动切换到备用B节点,A起来后为备节点,降低单点故障发生;

服务准备:

类型IP系统
MASTER1.1.1.249centos
BACKUP1.1.1.254ubuntu
VIP1.1.1.253

操作文件的目录位置:

MASTER下keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL_249
   enable_script_security
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_port.sh 80"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state MASTER
    interface em1
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        1.1.1.253
    }
    track_script {
         chk_nginx
    }
}

BACKUP下keepalived.conf

! Configuration File for keepalived

global_defs {
    router_id LVS_DEVEL_gjw_254
    enable_script_security
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_port.sh 80"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state BACKUP
    interface enp0s31f6
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        1.1.1.253
    }
    track_script {
        chk_nginx
    }
}

check_port.sh:

#!/bin/bash
CHK_PORT=$1
PORT_PROCESS=`ss -nltp|grep $CHK_PORT|awk '{print $4}'|grep -x "\[::\]:$CHK_PORT"|wc -l`
if [ $PORT_PROCESS -eq 0 ];then
    echo "Port $CHK_PORT Is Not Used,End."
    exit 8
else
    echo "Port $CHK_PORT Is In Used"
    exit 0
fi

验证:

通过ip addr 查看网卡下 vip信息

本人使用docker 启动的 nginx ,分别在两天机器上启停 nginx 容器进行验证,验证通过

遇到的问题:

keepalived 脚本不执行 报SECURITY VIOLATION - scripts are being executed but script_security not enabled.

github源码仓库,issues 有人遇到过,github.com/acassen/kee…,然后根据这个线索源码查找,man5下keepalived.conf.5.in 有提及,需要在全局配置 enable_script_security 即可;

参考网址:

blog.csdn.net/weixin_4225…

juejin.cn/post/713784…

blog.csdn.net/weixin_5961… [ubuntu安装]