我正在尝试制作一个多实例 keepalived 来控制 tarantool 服务器的主副本对并设置 VIP。服务器状态本身在 keepalived 之外进行管理。Keepalived 应该只管理 VIP:如果服务器处于主状态,它应该在 dummy1 iface 上设置 VIP1,如果服务器处于副本状态,它应该在同一个 dummy1 iface 上设置 VIP2,并确保在配置错误的情况下两个服务器上没有设置相同的 VIP。服务器位于延迟数据中心,因此多播不是一种选择。没有专用的服务器角色,两个服务器在初始状态下都可以是主服务器或副本服务器,因此我使用具有相同优先级配置的 BACKUP-BACKUP。这是我的配置:
global_defs {
enable_script_security # 1)
dynamic_interfaces
}
vrrp_script chk_trntl_db1_pri {
script "/bin/sh -c '/usr/bin/echo lua box.info.status | /usr/bin/tarantool -p 11011 | /usr/bin/grep -q primary'"
interval 1
fall 3
rise 2
}
vrrp_script chk_trntl_db1_rpl {
script "/bin/sh -c '/usr/bin/echo lua box.info.status | /usr/bin/tarantool -p 11011 | /usr/bin/grep -q connected'"
interval 1
fall 3
rise 2
}
vrrp_instance TRNTL_DB1_PRI {
interface eth0
state BACKUP # 3)
nopreempt # 4)
virtual_router_id 03
priority 100
advert_int 1
authentication {
auth_type PASS # TODO: test AH method
auth_pass XXXXXX
}
unicast_src_ip 10.161.133.20
unicast_peer {
10.161.133.19
}
virtual_ipaddress {
10.161.133.21/32 dev dummy1
}
track_script {
chk_trntl_db1_pri
}
}
vrrp_instance TRNTL_DB1_RPL {
interface eth0
state BACKUP # 3)
nopreempt # 4)
virtual_router_id 04
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass XXXXXX
}
unicast_src_ip 10.161.133.20
unicast_peer {
10.161.133.19
}
virtual_ipaddress {
10.161.133.22/32 dev dummy1
}
track_script {
chk_trntl_db1_rpl
}
}
这对的配置仅在unicast_src_ip
和 方面有所不同unicast_peer
- 它们是相反的。您可以注意到, 是virtual_router_id
每个实例独有的。
我发现,如果有多个实例,keepalived 永远不会将 BACKUP 实例提升为 MASTER 状态并设置 VIP。没有 TRNTL_DB1_PRI,无论是 TRNTL_DB1_PRI 还是相应的脚本,从一开始都始终成功,实例保持 BACKUP 状态。
以下是测试用例:SERVER1 的 tarantool 处于主状态,TRNTL_DB1_RPL
实例被注释掉(用于测试的单实例配置),chk_trntl_db1_pri
返回 0,TRNTL_DB1_PRI 变为 BACKUP,广告超时并提升为 MASTER,设置 VIP。同时,SERVER2 的 tarantool 处于副本状态,chk_trntl_db1_pri
返回 1,TRNTL_DB1_RPL
因此处于 FAULT 状态 - 正如预期的那样。但由于 tarantool 处于副本状态,chk_trntl_db1_rpl
返回 0,TRNTL_DB1_RPL 实例变为 BACKUP 并永远保持在该状态,即使它没有从其他节点收到任何针对其 virtual_router_id 的广告。我甚至关闭了 SERVER1 的 keepalived 以防止发送任何广告 - 不,TRNTL_DB1_RPL
将保持 BACKUP 状态。以下是日志:
Starting LVS and VRRP High Availability Monitor...
Starting Keepalived v2.0.7 (08/23,2018)
Running on Linux 3.10.0-862.3.2.el7.x86_64 #1 SMP Mon May 21 23:36:36 UTC 2018 (built for Linux 3.10.0)
Command line: '/usr/sbin/keepalived' '-D'
Opening file '/etc/keepalived/keepalived.conf'.
Starting VRRP child process, pid=14851
Registering Kernel netlink reflector
Registering Kernel netlink command channel
LVS and VRRP High Availability Monitor.
Opening file '/etc/keepalived/keepalived.conf'.
Assigned address 10.255.160.193 for interface eth0
Assigned address fe80::21a:4aff:fe16:12a for interface eth0
Registering gratuitous ARP shared channel
(TRNTL_DB1_PRI) removing VIPs.
(TRENT_DB1_RPL) removing VIPs.
VRRP sockpool: [ifindex(2), proto(112), unicast(1), fd(8,9)]
Script `chk_trntl_db1_pri` now returning 1
VRRP_Script(chk_trntl_db1_pri) failed (exited with status 1)
(TRNTL_DB1_PRI) Entering FAULT STATE
VRRP_Script(chk_trntl_db1_rpl) succeeded
(TRNTL_DB1_RPL) Entering BACKUP STATE
如果我TRENT_DB1_RPL
向 SERVER1 配置中添加部分,它将不会提升TRNTL_DB1_PRI
到 MASTER 状态并保持在 BACKUP 状态,就像TRNTL_DB1_RPL
在 SERVER2 上一样。
我发现,如果我从其中一个部分中删除所有与单播相关的选项,它将被提升为 MASTER 状态,但前提是一个实例是单播而另一个是多播。但如果同时是多播或单播,则无论检查脚本是否成功且另一侧没有主服务器,BACKUP 都永远不会被提升为 MASTER。
因为看起来即使 VIP 都设置在一个接口上,并且检查探测同一个守护进程的脚本,只要virtual_router_id
不同,它就是两个不同的独立实例,它们就应该一起工作。
那么,是我误解了什么吗,或者这是 keepalived 中的一个错误?
更新:已在 2.0.16 中修复。从源构建当前版本的 rpm 后,VRRP 完全按预期运行。