我有一个由 3 台服务器组成的扁平网络(还没有路由),每台服务器都有一个服务(http、mysqld,无关紧要)侦听 0.0.0.0(ip_nonlocal_bind 和 ip_forward 已打开)并运行 keepalived。
virtual_server 10.0.0.80 3306 {
delay_loop 2
lb_algo rr
lb_kind DR
protocol TCP
real_server 10.0.0.81 3306 {
weight 10
TCP_CHECK {
connect_timeout 1
}
}
real_server 10.0.0.82 3306 {
weight 10
TCP_CHECK {
connect_port 3306
connect_timeout 1
}
}
real_server 10.0.0.83 3306 {
weight 10
TCP_CHECK {
connect_port 3306
connect_timeout 1
}
}
}
keepalived(作为服务)正在工作,并且每个框都失败。然而,virtual_server 仅从 keepalived 当前具有 IP 的盒子中提供页面(或数据库查询,或其他任何内容),它们在另外 2/3 的时间内失败(平均加权)。
示例:当 BOX1 具有 keepalived 地址时,请求将 WORK、FAIL、FAIL、重复,它仅以“box1”应答。当 BOX2 作为 keepalived 地址时,请求会 FAIL、WORK、FAIL,仅回复“box2”。
我确信非 keepalived IP 盒子拒绝回答查询,因为它们不拥有或不知道它们应该作为 keepalived IP 进行回答。如何让非 keepalived 盒子始终应答?
这不是我的第一个 keepalived 设置,但这是我的第一个 virtual_server 设置。我只需要一个负载均衡器,不需要 HAProxy 提供的高可用性。
答案1
感谢帮助在 serverfault.com 问题中我能够解决我的问题。
简短回答:
我将虚拟 IP 添加到我的虚拟接口并确保net.ipv4.conf.default.accept_source_route
是0
。
长答案:
虚拟接口的目的是轻松禁用/启用/故障转移 keepalived,而无需停止和启动服务。只需向上或向下虚拟接口即可将 VIP 故障转移到另一台服务器。
为了轻松做到这一点,我创建系统服务叫/usr/local/src/dummy.service
.
[Unit]
Description=Create dummy network interface
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ip link set dummy0 up
ExecStop=/usr/sbin/ip link set dummy0 down
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
然后启用它。
# systemctl enable /usr/local/src/dummy.service
此外,我还加载了虚拟模块驱动程序。
文件/etc/modules-load.d/dummy.conf
:
dummy
文件/etc/modprobe.d/dummy.conf
:
alias dummy0 dummy
options dummy numdummies=1
shutdown -r now
我发现此时更容易证明它有效,但如果您愿意,您可以重新加载 modprobe。
然后您应该看到有一个新界面:
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 12:23:34:45:56:7a brd ff:ff:ff:ff:ff:ff
valid_lft forever preferred_lft forever
我在其中keepalived.conf
跟踪我的 vrrp_instance:
vrrp_instance mysql {
...
track_interface {
dummy0
}
...
}
这是我工作中需要改变的。
我需要将 VIP IP 地址添加到dummy0
接口中。修改/usr/local/src/dummy.service
和# systemctl daemon-reload
ExecStart=/usr/sbin/ip link set dummy0 up && ip addr add 10.0.0.100 dev dummy0
我需要确保未启用源路由,以便任何网络设备都可以回答查询,然后重新启动。
# cat "net.ipv4.conf.default.access_source_route = 0" > /etc/sysctl.d/10-keepalived.conf
为了完整起见,我的整个/etc/sysctl.d/10-keepalived.conf
:
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.conf.eno16777736.arp_ignore = 1
net.ipv4.conf.eno16777736.arp_announce = 2
net.ipv4.conf.eno16777736.rp_filter = 2
net.ipv4.conf.default.accept_source_route = 0