亲爱的 ServerFault 朋友们。我正在尝试(但失败了)设置一个负载平衡的 MySQL 服务器阵列。请指点迷津,指出我的方法中的错误。
当前设置:两个具有专用固定 IP(10.116.219.47 和 10.116.219.48)的 MySQL 服务器和一个使用 keepalived 共享的虚拟 IP(10.116.219.12)。此设置成功提供了故障转移。如果我们关闭 DB1 服务器,DB2 服务器会快速接管。只有在将 virtual_server 块添加到配置中时,事情才会开始出现问题。
DB1
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 60
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 3S83hbt200SbwY6
}
virtual_ipaddress {
10.116.219.12
}
}
DB2
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 60
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 3S83hbt200SbwY6
}
virtual_ipaddress {
10.116.219.12
}
}
我们一直在尝试向 keepalived 配置添加负载平衡,但这里 DB2 停止响应。
virtual_server 10.116.219.12 3306 {
delay_loop 2
lb_algo rr
lb_kind DR
protocol TCP
real_server 10.116.219.47 3306 {
weight 10
TCP_CHECK {
connect_port 3306
connect_timeout 1
}
}
real_server 10.116.219.48 3306 {
weight 10
TCP_CHECK {
connect_port 3306
connect_timeout 1
}
}
}
尝试连接到虚拟 IP(10.116.219.12)将会交替出现 DB1 的成功响应或 DB2 的超时。
到目前为止的调试:
- 连接到固定 IP 的 MySQL 在 DB1 和 DB2 上均可运行。防火墙/MySQL 绑定不会阻止传入连接。
- 在 DB1 和 DB2 上都设置 net.ipv4.ip_forward=1
- 在 DB2 上监听 TCP 入站连接将显示该尝试。(20:46:08.385786 IP 10.116.219.44.46211 > 10.116.219.12.mysql)
因此看起来 DB2 MySQL 服务器拒绝响应,我的猜测是因为传入的数据包目的地(共享虚拟 IP)对于 DB2 服务器来说是不知道的,因为 DB1 将其作为 keepalived master 携带。
答案1
由于您使用的是直接路由,因此需要同时在两台服务器上配置虚拟 IP。您可以通过使用第二个 vrrp 实例来实现此目的,该实例在辅助服务器的环回接口上配置 VIP (10.116.219.12)。当连接从负载平衡器转发到辅助服务器时,它将像往常一样在 eth0 上做出响应。
如果要这样做,您需要通过 sysctl 禁用源路由。例如:
# 不接受源路由 net.ipv4.conf.default.accept_source_route = 0
此外,您还需要更改 ARP 的发布方式和响应请求的方式(更多信息):
net.ipv4.conf.eth0.arp_ignore = 1 net.ipv4.conf.eth0.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2
另外,配置 rp 过滤:
net.ipv4.conf.eth0.rp_filter = 1 # 适用于 CentOS 5 或者 net.ipv4.conf.eth0.rp_filter = 2 # 适用于 CentOS 6+
默认的 rp_filter 设置在内核版本之间会有所不同,因此请确保选择正确的设置。 更多信息。
答案2
为了扩展 Gene 的回答,并让 jnovack “不丢失”,在 CentOS 7 上对我有用的是:
/etc/sysconfig/network-scripts/ifcfg-lo:1
在两个 MySQL 服务器上,创建包含以下内容的文件DEVICE=lo:1 BOOTPROTO=static ONBOOT=yes IPADDR=***your keepalived virtual IP*** NETMASK=255.255.255.255
在两个 MySQL 服务器上,配置 sysctl(不要忘记
sysctl -p
重新加载)net.ipv4.ip_nonlocal_bind=1 net.ipv4.ip_forward=1 net.ipv4.conf.default.arp_ignore=1 net.ipv4.conf.default.arp_announce=2 net.ipv4.conf.all.arp_ignore=1 net.ipv4.conf.all.arp_announce=2 net.ipv4.conf.default.rp_filter=0 net.ipv4.conf.all.rp_filter=0 net.ipv4.tcp_syncookies=1 net.ipv4.conf.all.log_martians=1 net.ipv4.conf.lo.arp_ignore=1 net.ipv4.conf.lo.arp_announce=2
重启网络服务
systemctl restart network # service network restart on CentOS 6
(您可以在环回执行时检查新的虚拟接口ifconfig
)
重启
keepalived
服务systemctl restart keepalived # service keepalived restart on CentOS 6