0%

实现高可用集群的神器 详解 Keepalived

关于 Keepalived 系列其他文章的传送门

  1. 《 实现高可用集群的神器 详解 Keepalived 》      您当前所在位置

  2. 《 LVS 小宇宙爆发! 当 Keepalived 遇上 LVS,实现集群高可用 》



logo

一、高可用集群介绍

高可用集群的类型主要有三种

  • LB:负载均衡集群;
  • HA:高可用集群;
  • HP:高性能集群。

本篇主要介绍高可用集群
高可用集群 (High Availability Cluster) 简称 HA Cluster,是一组计算机,它们作为一个整体向用户提供各种资源,集群里的 host 就是节点 (node)。
高可用集群是以减少服务中断时间为目的的服务器集群技术,它通过保护用户的业务程序对外不间断提供的服务,把因软件、硬件、人为造成的故障对业务的影响降低到最小程度,简单说就是保证服务不间断地运行。

集群可用性

集群可用性是通过系统的可靠性 (reliability) 和可维护性 (maintainability) 来衡量。
通常使用平均无故障时间 (MTTF) 来衡量系统的可靠性,用平均修复时间 (MTTR) 来衡量系统的可维护性。
计算公式HA=MTTF/(MTTF+MTTR)

高可用集群实现机制

高可用集群主要实现自动侦测 (Auto-Detect) 故障、自动切换/故障转移 (FailOver) 和自动恢复 (FailBack) 功能。简单来说就是,用高可用集群软件实现故障检查和故障转移 (故障/备份主机切换) 的自动化,当然像负载均衡、DNS 分发也可提供高可性。

自动侦测机制

自动侦测阶段由主机上的软件通过冗余侦测线,经由复杂的监听程序,逻辑判断,来相互侦测对方运行的情况。
常用的方法是:集群各节点间通过心跳信息判断节点是否出现故障。

避免集群脑裂
如果当有节点(一个或多个)和另外节点互相接收不到对方心跳信息时,如何决定哪一部分节点是正常运行的,而哪一部分是出现故障需要隔离的呢
这时候通过法定票数 (quorum) 决定,即当有节点故障时,节点间投票决定哪个节点是有问题的,票数大于半数为合法。

票数
每个节点可以设置票数,即决定节点在集群内是否合法(正常)的权限值,这个是可以有多有少的,例如有些节点的性能较好或有其他优势,可以设置较多的票数。

法定票数(quorum)
当一个节点能和另一个节点保持心跳信息,该节点就获取得了另一个节点的票数,该节点获得的所有票数就是法定票数。

比较特殊的是只有两个节点的集群,或两边票数相等。
这时候可以借助另外的参考节点,如 ping 网关(或是一个节点),可以和测试点 ping 通,但不可以和对方通,说明对方节点有问题,或本节点有问题;还有就是通过仲裁设备,如仲裁磁盘,每个节点都间隔一定时间不停往磁盘写数据,若监测到对方不再写入的时候,可能对方节点出故障。
但最好还是使得组成集群的节点数量为单数台(2n+1),当集群分区脑裂时,节点数量小于一半(>n+1)的分区自动停止对外提供服务。

Paxos 算法

关于“投票”,有必要知道著名的 Paxos 算法。

Paxos 算法解决的是保证集群中每个节点执行相同的操作序列,可以保证分布式群集中的数据一致性。
例如,通过投票来对写操作进行全局编号,同一时刻,只有一个写操作被批准,同时并发的写操作要去争取选票,只有获得过半数选票的写操作才会被批准(所以永远只会有一个写操作得到批准);而其他的写操作竞争失败只好再发起一轮投票,就这样,在日复一日年复一年的投票中,所有写操作都被严格编号排序。

编号严格递增,当一个节点接受了一个编号为 100 的写操作,之后又接受到编号为 99 的写操作(因为网络延迟等很多不可预见原因),它马上能意识到自己数据不一致了,自动停止对外服务并重启同步过程。

任何一个节点挂掉都不会影响整个集群的数据一致性(总 2n+1 台,除非挂掉大于 n 台)。

HA Cluster 的实现方案

  • 通过 vrrp 协议的实现
    • keepalived
  • 通过 ais 架构实现
    • RHCS(cman)
    • heartbeat
    • corosync

本文主要介绍 Keepalived

二、Keepalived 介绍

keepalived 的主要特性

  • vrrp 协议的软件实现,原生设计的目的为了高可用 ipvs 服务:
  • 基于 vrrp 协议完成地址浮动;
  • 为 vip 地址所在的节点生成 ipvs 规则(在配置文件中预先定义);
  • 为 ipvs 集群的各 RS 做健康状态检测;
  • 可以基于脚本调用接口通过执行脚本完成脚本中定义的功能,进而影响集群事务;

工作模式

  • 主/备:单虚拟路由器;
  • 主/主:主/备(虚拟路由器 1),备/主(虚拟路由器 2)

keepalived 的安装配置

HA Cluster 的配置前提

  • 各节点时间必须同步,使用 ntp, chrony
  • 确保 iptablesselinux 不会成为阻碍;
  • 各节点之间可通过主机名互相通信(对 KA 并非必须),建议使用 /etc/hosts 文件实现;
  • 确保各节点的用于集群服务的接口支持组播 MULTICAST 通信,使用 D 类 224-239 的地址。
    • 如果没开启使用 ip link set 打开即可;

注意keepalived 不支持重载,需要重启来重新加载配置文件。

CentOS 6.4 以上的 base 仓库提供,使用 yum 安装即可。

1
yum install keepalived -y

程序环境

  • 主配置文件:/etc/keepalived/keepalived.conf
  • 主程序文件:/usr/sbin/keepalived
  • Unit File: keepalived.service
  • Unit File 的环境配置文件:/etc/sysconfig/keepalived

配置文件

配置文件分为 3 段:

  • GLOBAL CONFIGURATION:全局
    • Global definitions:全局配置段;
    • Static routes/addresses/rules:静态路由和地址相关配置;
  • VRRPD CONFIGURATION:VRRP
    • VRRP script(s):脚本相关配置;
    • VRRP synchronization group(s):同步组相关配置;
    • VRRP gratuitous ARP:免费 ARP 相关配置;
    • VRRP instance:每个 vrrp instance 即对应一个 vrrp 路由器;
  • LVS CONFIGURATION: IPVS
    • Virtual server group(s):定义 ipvs 组;
    • Virtual server(s):定义 ipvs 服务,配置 ipvs 集群的 vs 和 rs。

三、Keepalived 的配置

1. GLOBAL CONFIGURATION 配置段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
global_defs {
notification_email { // 定义接收告警邮件的地址
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc // 定义邮件的发件人
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL // 当前物理设备的唯一标识,一般用使用主机名
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
// 定义组播地址,默认为 224.0.0.18,需要网卡支持 MULTICAST,如果没有使用 ip link set 打开即可
vrrp_mcast_group4 224.0.0.18
//注意:Keepalived 默认会生成一条 iptables 规则,DROP 掉所有 input 的请求,添加如下配置后可不添加任何 iptables 规则
vrrp_iptables
}

2. VRRP instance 配置段

配置 instance

1
2
3
vrrp_instance <STRING> {  // 定义一个虚拟路由器
... // 在这里写各种配置,有如下常用配置
}

专用参数

  • state MASTER|BACKUP:当前节点在此虚拟路由器上的初始状态;只能有一个是 MASTER,余下的都应该为 BACKUP;
  • interface IFACE_NAME:绑定为当前虚拟路由器使用的物理接口;
  • virtual_router_id VRID:当前虚拟路由器的惟一标识,同一组应该相同,范围是 0-255
  • priority 100:当前主机在此虚拟路由器中的优先级,范围 1-254
  • advert_int 1:vrrp 心跳检测的时间间隔,默认 1s

配置发送集群事务的认证信息

1
2
3
4
authentication {
auth_type PASS // 使用密码认证
auth_pass <PASSWORD> // 只使用指定密码的前 8 位
}

定义虚拟路由器 VIP

1
2
3
4
5
virtual_ipaddress {
// 语法:<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
192.168.200.17/24 dev eth1
192.168.200.18/24 dev eth2 label eth2:1
}

单主配置示例

  • VIP:192.168.50.200
  • keepalived_server:192.168.50.11
  • keepalived_server:192.168.50.12

vim /etc/keepalived/keepalived.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
! Configuration File for keepalived

global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1 // 主机名,在另一节点是 node2
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_mcast_group4 224.0.0.200
vrrp_iptables
}

vrrp_instance VI_1 { // 虚拟路由器名字
state MASTER // 另一节点是 BACKUP
interface ens33
virtual_router_id 1 // 当前虚拟路由器的惟一标识,多个节点必须相同
priority 100 // 优先级,另一节点是 98
advert_int 1
authentication {
auth_type PASS
auth_pass 11112222
}
virtual_ipaddress {
192.168.50.200/24 brd 192.168.50.255 dev ens33 label ens33:0 // 配置 VIP
}
}

复制到备用节点:scp /etc/keepalived/keepalived.conf node2:/etc/keepalived/keepalived.conf

备节点修改特有信息:

  • router_id node1 --> router_id node1
  • state MASTER --> state BACKUP
  • priority 100 --> priority 98

启动服务,完成。

1
systemctl start keepalived

双主双活配置示例

  • VIP:192.168.50.200
  • VIP:192.168.50.201
  • keepalived_server:192.168.50.11
  • keepalived_server:192.168.50.12

配置节点 1

vim /etc/keepalived/keepalived.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
! Configuration File for keepalived

global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1 // 主机名,在另一节点是 node2
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_mcast_group4 224.0.0.200
vrrp_iptables
}

// 这里配置第 1 个虚拟路由器
vrrp_instance VI_1 {
state MASTER // 状态为主,另一节点是 BACKUP
interface ens33
virtual_router_id 1 // 当前虚拟路由器的惟一标识,多个节点必须相同
priority 100 // 优先级,另一节点是 98
advert_int 1
authentication {
auth_type PASS
auth_pass 11112222
}
virtual_ipaddress {
192.168.50.200/24 brd 192.168.50.255 dev ens33 label ens33:0 // 配置为 VIP 1
}
}

// 这里配置第 2 个虚拟路由器
vrrp_instance VI_2 {
state BACKUP // 状态为备,另一节点是 MASTER
interface ens33
virtual_router_id 2 // 当前虚拟路由器的惟一标识,多个节点必须相同
priority 98 // 优先级,,另一节点是 100
advert_int 1
authentication {
auth_type PASS
auth_pass 11112222
}
virtual_ipaddress {
192.168.50.201/24 brd 192.168.50.255 dev ens33 label ens33:1 // 配置为 VIP 2
}
}

配置节点 2,与节点 1 基本相反

vim /etc/keepalived/keepalived.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
! Configuration File for keepalived

global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node2 // 主机名
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_mcast_group4 224.0.0.200
vrrp_iptables
}

// 这里配置第 1 个虚拟路由器
vrrp_instance VI_1 {
state BACKUP // 状态为备
interface ens33
virtual_router_id 1 // 当前虚拟路由器的惟一标识,与节点 1 必须相同
priority 98 // 优先级
advert_int 1
authentication {
auth_type PASS
auth_pass 11112222
}
virtual_ipaddress {
192.168.50.200/24 brd 192.168.50.255 dev ens33 label ens33:0 // 配置为 VIP 1
}
}

// 这里配置第 2 个虚拟路由器
vrrp_instance VI_2 {
state MASTER // 状态为主
interface ens33
virtual_router_id 2 // 当前虚拟路由器的惟一标识,与节点 1 必须相同
priority 100 // 优先级
advert_int 1
authentication {
auth_type PASS
auth_pass 11112222
}
virtual_ipaddress {
192.168.50.201/24 brd 192.168.50.255 dev ens33 label ens33:1 // 配置为 VIP 2
}
}

启动服务

1
systemctl start keepalived

在 DNS 定义两条 A 记录

1
2
vip.monster.com    A    192.168.50.200
vip.monster.com A 192.168.50.201

使用域名访问,完成

1
2
3
4
5
6
7
-> # ping vip.monster.com -c 1
PING vip.monster.com (192.168.50.200) 56(84) bytes of data.
64 bytes from 192.168.50.200 (192.168.50.200): icmp_seq=1 ttl=64 time=0.295 ms

-> # ping vip.monster.com -c 1
PING vip.monster.com (192.168.50.201) 56(84) bytes of data.
64 bytes from 192.168.50.201 (192.168.50.201): icmp_seq=1 ttl=64 time=0.277 ms

3. 通知机制

在节点发生状态改变时,可以使用通知机制,自动执行一个指定的脚本。

(1).VRRP instance 配置段中使用的语法:

  • 当一个节点的状态转为 MASTER 时,执行指定的脚本发给指定的用户 username
    • notify_master <STRING>|<QUOTED-STRING> [username [groupname]]
  • 转为 BACKUP 时。
    • notify_backup <STRING>|<QUOTED-STRING> [username [groupname]]
  • 转为 FAULT 时。
    • notify_fault <STRING>|<QUOTED-STRING> [username [groupname]]
  • 转为 STOP 时。
    • notify_stop <STRING>|<QUOTED-STRING> [username [groupname]]
  • 也可以手动指定。
    • notify <STRING>|<QUOTED-STRING> [username [groupname]]
  • 其中:
    • <STRING>:可以是字符串;
    • <QUOTED-STRING>:也可以使用带引号的字符串,当脚本路径有空白字符时就需要用引号括起来。

(2).VRRP synchronization group(s) 中配置时,大体上是一样的:

  • 当一个节点的状态转为 MASTER 时,执行指定的脚本发给指定的用户 username
    notify_master /path/to_master.sh [username [groupname]]
  • 转为 BACKUP 时。
    notify_backup /path/to_backup.sh [username [groupname]]
  • 转为 FAULT 时。
    notify_fault "/path/fault.sh VG_1" [username [groupname]]

也可以使用这样一个脚本,完成上述三个脚本的功能,但是需要传递一些变量。

  • notify /path/notify.sh [username [groupname]]

传递变量:

  • $1:一个组或实例;
  • $2:组或实例的名称;
  • $3:在节点转到什么状态时就警告;
    • MASTER | BACKUP | FAULT
  • $4:优先级的值;

示例:状态通知

使用这个通知机制,实现当 Keepalived 的自身状态发生变化时,给管理员发送一个邮件通知。

注意:要在主备中同时配置

创建通知脚本 vim /etc/keepalived/notify.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
#
contact='root@localhost'

notify() {
local mailsubject="$(hostname) to be $1, vip floating"
local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}

case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac

在虚拟路由器中定义好调用脚本的时机。

1
2
3
4
5
6
7
vrrp_instance VI_1 {
...
...
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}

可能需要安装 mailx:yum install mailx -y

重启 keepalived 服务,然后通过 mail 就可以看到状态转变的邮件通知了。

1
2
3
4
5
-> # mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 2 messages 2 unread
>U 1 root Mon Aug 19 23:14 19/677 "node1.monster.com to be backup, vip floating"
U 2 root Mon Aug 19 23:14 19/677 "node1.monster.com to be master, vip floating"

4. VRRP script(s)

Keepalived 支持自定义一个脚本,然后它会定期执行这个脚本,并用脚本的退出码作为判断实例健康与否的依据。

1. 使用方法

在一个新的上下文中定义脚本,语法:

1
2
3
4
5
6
7
8
9
10
vrrp_script <SCRIPT_NAME> {                // 定义一个名称
script <STRING>|<QUOTED-STRING> // 直接写要执行的脚本语句,或者一个路径
interval <INTEGER> // 每隔多久执行一次,默认为1秒
timeout <INTEGER> // 每次检测请求的超时时间是几秒钟
weight <INTEGER:-254..254> // 当判定为失败时,调整虚拟路由器的优先级,默认为 0,范围 -254 至 254。
rise <INTEGER> // 至少几次检测成功时,才会判断为成功
fall <INTEGER> // 至少几次检测不成功,才会判断为失败
user USERNAME [GROUPNAME] // 运行脚本的 用户/组 名称,组默认使用 user 的用户组
init_fail // 假设脚本最初处于失败状态,当执行成功后才判定成功
}

在 VRRP instance 中引用脚本才会生效,语法:

1
2
3
4
track_script {
<SCRIPT_NAME> // 脚本名字
<SCRIPT_NAME> weight <-254..254> // 也可以自定义优先级而不使用脚本中的优先级
}

2. 配置示例

两个节点:

  • node1 为 MASTER;
  • node2 为 BACKUP;

node1 上的配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    ...
...
vrrp_script maint {
script "/bin/bash -c '[[ -e /etc/keepalived/down ]]' && exit 1 || exit 0" // 判断 down 这个文件是否存在,存在即为错误的退出码
interval 1
fall 3
rese 2
weight -5 // 当判断为失败 3 次后把实例优先级 -5
timeout 1
}

vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 1
priority 100 // 默认优先级 100,BACKUP 上的优先级是 98
advert_int 1
authentication {
auth_type PASS
auth_pass 11112222
}
virtual_ipaddress {
192.168.50.200/24 brd 192.168.50.255 dev ens33 label ens33:1
}
track_script { // 引用脚本的上下文
maint
}
}

以上配置的意思是:使用 /bin/bash -c '[[ -e /etc/keepalived/down ]]' && exit 1 || exit 0 这个脚本语句每秒执行 1 次,如果检测到 /etc/keepalived/down 这个文件存在,退出码即为错误。那么在错误 3 次后就将实例的优先级减 5,之前默认优先级是 100,减 5 后为 95,就比 BACKUP 低了,所以 BACKUP 节点就会被激活变成主节点。

在组播地址 224.0.0.200 上抓包,可以看到 node1 节点的广播优先级是 100,目前最高,处于激活状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
~]# tcpdump -i ens33 host 224.0.0.200
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
19:17:38.560801 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 100, authtype simple, intvl 1s, length 20
19:17:39.561860 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 100, authtype simple, intvl 1s, length 20
19:17:40.563088 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 100, authtype simple, intvl 1s, length 20
19:17:41.564403 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 100, authtype simple, intvl 1s, length 20
19:17:42.565387 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 100, authtype simple, intvl 1s, length 20
19:17:43.566705 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 100, authtype simple, intvl 1s, length 20
# 此时新开一个终端来创建文件 touch /etc/keepalived/down,就可以看到 node1 的优先级减了 5,变成了 95,低于 node2 的优先级 98,于是 node2 被激活
19:17:44.568362 IP node1 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 95, authtype simple, intvl 1s, length 20
# node2 的优先级为 98,高于 95,于是被激活
19:17:44.568578 IP node2 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 98, authtype simple, intvl 1s, length 20
19:17:45.569353 IP node2 > 224.0.0.200: VRRPv2, Advertisement, vrid 1, prio 98, authtype simple, intvl 1s, length 20

3. 检测 Nginx 或 HAProxy 的健康状态

其实通过上述的使用方法,还可以用来检测其他进程的健康与否,如 NginxHAProxy。

Nginx 为例,可以使用 killall -0 nginx 这条命令向待检测的进程传递信号 0,信号 0 代表检测进程的运行状态,而不是去 kill 进程。进程运行正常就返回正确的状态码,否则返回错误的。

  • killall 命令由 psmisc 提供,需要安装 yum install psmisc -y

于是将上述示例中的脚本替换为:

1
script "killall -0 nginx" // 检测 Nginx 进程运行正常就返回正确的状态码,否则返回错误的

这样当 node1 上的 Nginx 进程运行异常时,node1 节点就会被降低优先级,node2 就会变为 MASTER

在某些时候,还可以结合通知机制,当 node1 被降级为 BACKUP 时,就调用脚本尝试重启 Nginx,不过在双主模式中,要仔细检查逻辑,防止出现混乱。

定义通知机制要触发的脚本

1
notify_backup "/etc/keepalived/restart_nginx.sh backup"

脚本内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
#
contact='root@localhost'

notify() {
local mailsubject="$(hostname) to be $1, vip floating"
local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}

case $1 in
master)
notify master
;;
backup)
notify backup
systemctl restart nginx ## 尝试重启
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac

4. LVS CONFIGURATION 配置段

定义 IPVS 配置的语法格式、常用参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 定义一个 Dirctory
virtual_server IP PORT { // 可以使用地址+端口,定义 vip 和 vport
virtual_server fwmark <INT> // 也可以使用防火墙标记
protocol TCP|UDP|SCTP // 定义 vport 要监听在 TCP、UDP 哪种协议
delay_loop // 每次健康检查之间的秒數
lb_algo rr|wrr|lc|wlc|lblc|sh|dh // 定义调度算法
lb_kind NAT|DR|TUN // 定义 LVS 工作类型
persistence_timeout [<INT>] // 定义 LVS 持久连接的超时时间
sorry_server <IPADDR> <PORT> // 定义一个 SORRY SERVER

// 定义 RS,每个 RS 一个独立的配置段,在 virtual_server IP PORT {} 内
real_server <IPADDR> <PORT> {
weight <INT> // 权重
notify_up <STRING>|<QUOTED-STRING> [username [groupname]] // 状态转换为 UP 的通知脚本
notify_down <STRING>|<QUOTED-STRING> [username [groupname]] // 状态转换为 DOWN 的通知脚本
uthreshold <INTEGER> // 此 RS 承载的最大连接数
lthreshold <INTEGER> // 此 RS 承载的最小连接数

// 定义健康转状态检测机制,支持 4、7 层,或者自定义
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|DNS_CHECK|MISC_CHECK

// 定义健康状态检测规则
HTTP_GET|SSL_GET
{
// 定义基于 7 层的健康状态检测
url {
path <STRING> // 定义要检测的 url,默认是 /
status_code <INT> // 定义响应码多少为正常,默认 200
digest <STRING> // 定义一个 HASH 码,只有 url 返回的页面 HASH 码一致才为正常,可使用 genhash 工具计算 HASH 值
}
nb_get_retry <INT> // 如果检测失败要重复几次后才判定不健康
delay_before_retry <INT> // 重复的间隔时间
connect_timeout <INTEGER> // 连接的超时时长,默认值是5秒
connect_ip <IP ADDRESS> // 对指定 IP 做健康状态检测,默认就是 RIP
connect_port <PORT> // 对指定 Port 做健康状态检测,默认就是 RS 的端口

}

// 也可定义基于 4 层的健康状态检测
TCP_CHECK {
connect_ip <IP ADDRESS>
connect_port <PORT>
fwmark <INTEGER>
connect_timeout <INTEGER> // 连接的超时时长,默认值是5秒
retry <INT> // 如果检测失败要重复几次后才判定不健康,默认 1 次
delay_before_retry <INT> // 重复的间隔时间,默认 1 秒
}

}
}

关于实现 LVS 双主双活的详细配置,可以看这篇
《 LVS 小宇宙爆发! 当 Keepalived 遇上 LVS,实现集群高可用 》

参考:https://blog.csdn.net/tjiyu/article/details/52643096