首页 > 基础资料 博客日记

Keepalived 学习总结

2026-05-29 19:00:02基础资料围观5

文章Keepalived 学习总结分享给大家,欢迎收藏极客资料网,专注分享技术知识

有志不在年高,无志空长百岁。

导航


1、工具介绍

Keepalived 是一个运行在 Linux 上的 高可用(HA)负载均衡辅助 服务,最初主要是为 Linux Virtual Server(LVS)设计的,但现在也常被用来搭建服务的高可用,以防止业务核心设备出现单点故障。虽然说它也 间接具备负载均衡 的能力,但在配置和使用上,个人觉得它比 HAProxy 更为复杂不好用。故本文的重点只关注其高可用的能力,不对其负载均衡的能力做过多探讨。

注:为什么上面说 Keepalived 是间接具备负载均衡的能力呢?是因为 Keepalived 与 LVS 是高度集成的组合,LVS 才是实际具备负载均衡能力的服务,而 Keepalived 仅是支持配置负载均衡的规则,然后调用 LVS 实现。具体过程如下:

  • 你编写配置:在 /etc/keepalived/keepalived.conf 中写好 virtual_server 相关的所有规则(IP、端口、算法、后端服务器列表等)。
  • Keepalived 启动:Keepalived 服务启动后,会读取自己的配置文件。
  • 自动调用 IPVS:Keepalived 内部包含了操作 LVS 的代码。它会直接调用 Linux 内核的 IPVS 接口,把你配置文件里的规则,自动转换成 ipvsadm 命令才能创建的规则。
  • 验证结果:你可以随时运行 ipvsadm -L -n 来查看。你会看到,只要 Keepalived 在运行,这里就已经有规则了,而你完全没有动过 ipvsadm 命令。

Keepalived 可以与 HAProxy/LVS/Nginx 组合以实现业务的 高可用+负载均衡 的功能,以下是关于 Keepalived + HAProxy 组合的架构图:

jiagou

2、协议介绍

Keepalived 底层主要依赖 VRRP 协议(Virtual Router Redundancy Protocol 虚拟路由冗余协议),而协议的主要作用就是在多个节点之间选举出一个 MASTER 角色,等协议选举出 MASTER 之后,再由 Keepalived 到 MASTER 所处的服务器上去实现 VIP(虚拟 IP) 的功能(就是在指定的物理网卡上再制作出一个虚拟的网络适配器)。

注:VIP 即虚拟 IP,就是一个未分配给真实主机的 IP,也就是说对外提供服务的主机除了有一个真实 IP 外还有一个虚 IP,使用这两个 IP 中的任意一个都可以连接到这台主机。

注意:这个 VIP 一般都是取的和服务器 IP 同网段的地址,这样它虚拟出来之后,客户端在原有基础不变动的情况下便可直接访问;而若是使用其它网段的 IP,客户端要想访问到这个虚拟 IP,网络管理员还需要对路由器交换机这些网络设备进行路由调整,待调整之后客户端才能够顺利访问。

VRRP 协议选举 MASTER 的工作过程:

  1. 所有服务器在开启 VRRP 功能后,都会根据优先级确定自己在服务器池中的角色。优先级高的服务器成为 Master,优先级低的成为 Backup。【全部成员都在进行选举
  2. 成为 Master 的服务器会定期发送 VRRP 通告报文(即心跳/广播包), 通知服务器池内的其他服务器自己工作正常;而成为 Backup 的服务器则会启动定时器等待通告报文的到来。同时 MASTER 也会通过 ARP 协议对外(VIP 所在网段之内的所有机器)通告该 VIP 的虚拟 IP 以及 MAC 地址,以让客户端能够及时了解当前 VIP 对应的 MAC 地址(其实就是让客户端知道 VIP 当前所在的具体服务器是哪个)。
  3. 如果 Backup 们的定时器在超时之后仍未收到 Master 发送来的 VRRP 通告报文,此时 Backup 们便会认为 Master 已经无法正常工作,于是 Backup 们就会认为自己才是 Master,并纷纷对外发送 VRRP 通告报文。于是新一轮的选举便再次展开,此时 Backup 们就又会根据优先级再次选举出 Master,让其承担报文的转发功能。【除了故障机器之外的剩余成员都在进行选举
  4. 在默认的抢占模式下】如果不久之后,原来故障的 MASER 又恢复了正常,此时它便会将自己的优先级数值与当前 MASTER 通告报文中的优先级数值进行比较,如果自己大,则直接抢夺 MASTER,并恢复自己原来的转发功能。【仅恢复机器与当前 MASTER 成员在进行选举
  5. 在非抢占模式下】如果不久之后,原来故障的 MASER 又恢复了正常,此时即便它的优先级大于当前 MASTER 的优先级,它也不会去抢夺 MASTER,而是等当前的 MASTER 故障之后它才会在下一轮的选举中进行 MASTER 的抢夺。

vrrp

注:(1)VRRP 协议的实现有 VRRPv2 和 VRRPv3 两个版本。其中,VRRPv2 基于 IPv4,VRRPv3 基于 IPv6。 VRRPv2 和 VRRPv3 在功能实现上并没有区别,仅仅只是应用的网络环境不同而已。(2)Keepalived 允许服务器池中只有个别机器开启了非抢占模式,而其它机器仍旧是抢占模式这样的用法。但建议均保持一致。

3、配置结构

Keepalived 默认的配置文件是 /etc/keepalived/keepalived.conf,它整体的语法结构如下:

# 全局参数
global_defs {
    # 定义 router_id、邮箱通知等参数
}

# VIP 绑定组
vrrp_sync_group VG1 {
    group {
        # 配置 VIP 漂移实例名称
    }
}

# 健康检查脚本
vrrp_script chk_mt {
    # 定义检查脚本的位置、定时间隔、权重变化值等参数
}

# VIP 漂移实例1
vrrp_instance VI_1 {
    # 定义状态、优先级、接口等参数
    track_script {
        chk_mt
    }
    virtual_ipaddress {
        # 指定 VIP 的 IP 地址
    }
}

# VIP 漂移实例2
vrrp_instance VI_2 {
    # 定义状态、优先级、接口等参数
    virtual_ipaddress {
        # 指定 VIP 的 IP 地址
    }
}

# LVS 负载均衡
virtual_server 192.168.200.12 443 {
    # 定义负载均衡的模式、算法、协议等参数
    real_server 192.168.100.2 443 {
        # 指定后台实际提供服务的地址
    }
    real_server 192.168.100.3 443 {
        # 指定后台实际提供服务的地址
    }
}

注:以上功能块都不是必须要出现的,例如我们只使用 keepalived 的高可用功能,那么只需要 vrrp_instance 块存在即可,其它块可有可无。

4、应用场景

以下实验的环境状况如下:

  • 实验环境总共两台服务器 A 和 B(均未开启 SELinux、iptables 安全设置 )
  • A 网卡 ens33,IP 地址 192.168.98.120
  • B 网卡 ens33,IP 地址 192.168.98.130
  • 定义的 VIP 地址 192.168.98.200、192.168.98.250。

4.1、VIP 漂移

实验目的:聚合两台服务器形成一个虚拟 ip,使得只要服务器池中还有一台机器存活,那么这个虚拟 ip 便仍旧可以正常访问。

# 服务器 A 的 keepalived 配置
#global_defs {
#    router_id test-name           # 本机名称,可随便自定义
#    vrrp_strict                   # 对 VRRP 配置进行严格校验。建议关闭,否则可能会出现一些奇怪的问题。
#    enable_script_security        # 开启脚本执行环境的安全模式,此时脚本相关的文件权限、内容规范、所属人都会被严格检查,检查通过脚本才会被执行。所以,一般还是把它关闭掉,否则疑点会很多。
#    script_user root              # 指定执行脚本的用户,不指定的话,默认是 keepalived_script 用户,而该用户默认不存在,还需要手动去创建。 
#}

vrrp_instance VI_1 {
    state MASTER            # 设置起始状态为 MASTER 角色,但片刻之后,这个角色能否保持还是取决于 priority。
    interface ens33          # 指定 VIP 绑定的网卡接口
    virtual_router_id 50    # 类似群组的功能,要求同一个服务器池的机器的此值都保持一致,否则会出现脑裂现象,即同时出现多个 MASTER 角色。
    priority 150            # 指定优先级,值越大优先级越高。取值范围:0~255
    advert_int 1            # 心跳发包间隔时间,1秒
#    nopreempt              # 开启非抢占模式
    virtual_ipaddress {
        192.168.98.200      # 定义虚拟 IP
    }
}
# 服务器 B 的 keepalived 配置
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 50
    priority 100
    advert_int 1
    virtual_ipaddress {
        192.168.98.200
    }
}

注:(1)如果 AB 服务器只有一方开启了非抢占模式,那么仅为服务器 A 开启非抢占模式的选举,仅对 A 有效,B 若没有开启此功能的话,B 是会进行抢占的。(2)router_id 是“节点名字”可随便指定,virtual_router_id 是“VRRP 组编号”,服务器池中的所有主机必须保持一致。

4.2、VIP 绑定

实验目的:让多个虚拟 ip 捆绑在一台服务器上,而不是让他们各自选举随机分布在不同的服务器上。

# 服务器 A 的 keepalived 配置
global_defs {
    router_id LVS_MASTER
}

############################
# 第一个 VRRP 实例
############################
vrrp_instance VI_WEB {
    state MASTER
    interface ens33
    virtual_router_id 51            # 关注点
    priority 150                    # 关注点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.98.200/24            # 关注点
    }
}

############################
# 第二个 VRRP 实例
############################
vrrp_instance VI_DB {
    state MASTER
    interface ens33
    virtual_router_id 52            # 关注点
    priority 50                     # 关注点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.98.250/24            # 关注点
    }
}

############################
# 同步组
############################
vrrp_sync_group VG_1 {
    group {
        VI_WEB
        VI_DB
    }
}
# 服务器 B 的 keepalived 配置
global_defs {
    router_id LVS_MASTER
}

############################
# 第一个 VRRP 实例
############################
vrrp_instance VI_WEB {
    state BACKUP
    interface ens33
    virtual_router_id 51            # 关注点
    priority 100                    # 关注点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.98.200/24            # 关注点
    }
}

############################
# 第二个 VRRP 实例
############################
vrrp_instance VI_DB {
    state BACKUP
    interface ens33
    virtual_router_id 52            # 关注点
    priority 100                    # 关注点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.98.250/24            # 关注点
    }
}

############################
# 同步组
############################
vrrp_sync_group VG_1 {
    group {
        VI_WEB
        VI_DB
    }
}

注:服务器 A 的 VI_WEB 的优先级大于 服务器 B 的 VI_WEB,A 的 VI_DB 的优先级又小于 B 的 VI_DB,在不绑定 VIP 组的情况下,A 服务器上存在一个 VIP,B 服务器存在一个 VIP;当绑定 VIP 组之后,这两个 VIP 要么都在 A 服务器上,要么都在 B 服务器上,此时优先级似乎没有什么作用了, VIP 在哪个服务器上完全取决于服务启动的先后顺序了。

4.3、健康检查

实验目的:让服务器的优先级可以随着外部环境的一些可变因素而发生变化,而不是一成不变或者只能在 keepalived 服务挂掉或服务器宕机的情况下,优先级才会改变,伴随着 MASTER 角色才能发生改变。

# 服务器 A 的 keepalived 配置
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 50
    priority 150
    advert_int 1
    virtual_ipaddress {
        192.168.98.200
    }
}
# 服务器 B 的 keepalived 配置
#global_defs {
#    vrrp_strict                   # 对 VRRP 配置进行严格校验。建议关闭,否则可能会出现一些奇怪的问题。
#    enable_script_security        # 开启脚本执行环境的安全模式,此时脚本相关的文件权限、内容规范、所属人都会被严格检查,检查通过脚本才会被执行。所以,一般还是把它关闭掉,否则疑点会很多。
#    script_user root              # 指定执行脚本的用户,不指定的话,默认是 keepalived_script 用户,而该用户默认不存在,还需要手动去创建。 
#}

vrrp_script chk_mt {
    script "/etc/keepalived/chk_mt.sh"        # 当脚本返回 0 时,priority(160) = priority(100) + weight(60),此时 B 的优先级会大于 A,B 会切换为 MASTER。
    interval 10                               # 脚本每 10 秒执行一次
    weight 60
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 50
    priority 100
    advert_int 1

    virtual_ipaddress {
        192.168.98.200
    }

    track_script {
      chk_mt
   }
}

测试脚本如下:

#!/bin/bash

#touch /tmp/test.txt
echo test >> /tmp/test2.txt
touch /tmp/test.txt
#exit 1

注:关于健康脚本的实验,在测试的时候坑有点多,现将注意事项整理如下。

(1)安全选项 enable_script_security 开启的状态下,被执行脚本的权限最好是 750,脚本所有者和 script_user 指定的要保持一致。

(2)keepalived 的脚本执行环境不是简单的 bash,脚本内容不能有类似 echo 123 >> /tmp/test.txt 这种写法,出现特殊符号,会导致脚本解析错误的问题。若是要进行判断,可在脚本中写入 /usr/bin/touch /tmp/test.txt ,然后在 shell 中不断执行 stat /tmp/test.txt 去查看文件的修改时间是否发生变化,若有变化则说明脚本是被执行了。

(3)脚本在被执行时,systemctl ststus keepalived.service 日志中并不会显示脚本每次被定时执行的事件,只会显示初次被执行时的状态。但即便显示初始化失败,也并不意味着该脚本就没有被执行,它的判断标准似乎只是根据脚本的最后一条命令的返回值进行的判断,若最后一条命令执行失败或错误,日志显示的初始化状态便也是 failed 状态,但这个状态下脚本依旧被定时执行着。

(4)脚本在每次被执行之后,它的优先级的计算并非每次都是 priority = priority + weight, 而是只有在“状态发生变化”时才会调整优先级。例如,假设 weight 等于 20,脚本被定时执行 5 次之后 优先级的状态如下:

时间 返回值 状态 priority
T1 0 OK 90
T2 1 FAIL 70
T3 1 FAIL(仍失败) 70(不变)
T4 1 FAIL(持续失败) 70(不变)
T5 0 OK 90

可见,weight 值不是让 priority 一直递减,它只是在 90 和 70 这两个值之间来回跳。

4.4、切换通知

实验目的:让服务器的角色在发生变化时,可以通过邮箱或一些其它的手段来通知管理员,或是让其可以执行一些其它什么脚本任务啥的。

#通知脚本:
#!/bin/bash
# 这里是我们的vip 地址
vip=172.16.100.104
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
        exit 0
    ;;
    backup)
        notify backup
        exit 0
    ;;
    fault)
        notify fault
        exit 0
    ;;
    *)
        echo 'Usage: `basename $0` {master|backup|fault}'
        exit 1
    ;;
esac	
 # ... 其他配置

vrrp_instance VI_1 {
    # ... 其他配置
    notify_master "/etc/keepalived/notify.sh master"        # 当当前服务器的角色切换为 MASTER 时向 root 用户发送 mail通知
	notify_backup "/etc/keepalived/notify.sh backup"        # 当当前服务器的角色切换为 BACKUP 时向 root 用户发送 mail通知
	notify_fault "/etc/keepalived/notify.sh fault"          # 当当前服务器的角色切换为 FAULT 时向 root 用户发送 mail通知
}

4.5、负载均衡

实验目的:让访问 VIP 的请求任务可以被均匀的分发给不同的后端服务器进行处理。

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 50
    priority 150
    advert_int 1
    virtual_ipaddress {
        192.168.98.200
    }
}

virtual_server 192.168.98.200 8080 {
    delay_loop 20
    lb_algo rr        # 负载均衡调度算法
    lb_kind NAT       # 负载实现的 NAT 模式
    persistence_timeout 360
    protocol TCP

# 实际处理任务的后端服务器
    real_server 192.168.98.120 8080 {
        weight 1
        TCP_CHECK {            # TCP 健康检查
            connect_timeout 3
        }
    }
    real_server 192.168.98.130 8080 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
}

注:以上仅为配置上的示例,实际上还需要在机器上进行一些系统级的功能开启,具体参考 这篇文章。仅凭以上配置,在浏览器访问 web 服务 http://192.168.98.200:8080 并不能够成功。

5、杂七杂八

(1)参考文档:中文手册木西笔记CSDN

(2)服务器之间的心跳包的防火墙放行规则如下:

# 放行广播包
iptables -A INPUT -i eth1 -d 224.0.0.0/8 -j ACCEPT

# 放行协议号 112。心跳包是一个基于 ip 协议之上的 vrrp 协议包,协议号是 112。【这条似乎可以省略,有前面一条就够了】
iptables -A INPUT -i eth1 -p 112 -j ACCEPT

(3)检查当前服务器是否是 MASTER 角色,可以使用 systemctl status keepalived.service 查看,但通过 ip a 查看更方便,VIP 是否生效一眼便知。


文章来源:https://www.cnblogs.com/kqdssheng/p/20220656
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云