Keepalived 负载平衡 MySQL。备份服务器超时

Keepalived 负载平衡 MySQL。备份服务器超时

亲爱的 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
    

相关内容