我想创建一个冗余的 HAProxy 配置:
- Keepalived-用于确定哪个 HA 代理处于活动状态
- HAProxy-用于执行负载平衡和故障转移
我将使用云服务提供商及其 VPS
- 每个 VPS 都有自己的公共 IP 地址
- 提供商有可购买的“故障转移 IP”
我以前在服务级别上使用 VRRP(而不是仅仅使用第 3 层技术)时遇到的问题是目标 IP 地址和回复 IP 地址不同。例如,当我考虑仅使用 Keepalived 进行负载平衡和故障转移时,我遇到了以下问题:
- 客户端将使用虚拟故障转移 IP 连接到服务器
- 服务器的响应将从服务器的物理 IP 地址发送,而不是从虚拟故障转移 IP
- 目标 IP 地址和响应 IP 地址不匹配
负载均衡器(如 HA Proxy)通过对流量进行本质上的 NAT 来在一定程度上解决这个问题,这样来自服务器的流量看起来是发送到/来自负载均衡器的 IP 地址。
- 回复不是来自服务器的物理 IP 地址,而是通过 NAT 发送到负载均衡器的 IP 地址
但是,如果我尝试使用虚拟故障转移 IP 和一对运行 keepalived 的 HA 代理,我预见到同样的问题。也就是说,
- 流量将发送到虚拟 IP 作为目标 IP
- 流量响应将从 HA 代理的 IP 地址发送,而不是从虚拟 IP
HA Proxy 有解决方案吗?我可以配置 HA Proxy 以使用虚拟 IP 回复吗?
答案1
为了使回复地址与源地址保持一致,请配置您的 haproxy 前端以绑定到 VIP。
例如,假设我们有两个 haproxy 服务器:
- 192.168.122.170
- 192.168.122.91
我们有一个 VIP 地址:
- 192.168.122.201
我们有一个后端服务器:
- 192.168.122.24
我们的 haproxy 配置可能如下所示:
frontend main
bind 192.168.122.201:80
default_backend app
backend app
balance roundrobin
server app1 192.168.122.24:80 check
查看bind
该部分中的声明frontend
:我们不是绑定到通配符地址(bind *:80
),而是专门绑定到 VIP 地址。
现在,你可能会想:当 haproxy 在节点上启动时,这不会导致错误吗?没有目前拥有 VIP?您可能会看到类似以下内容的内容:
[ALERT] (6559) : Starting frontend main: cannot bind socket (Cannot
assign requested address) [192.168.122.201:80]
通常情况下,你是对的!但在本例中,我们将 sysctl 设置net.ipv4.ip_nonlocal_bind
为1
:
sysctl -w net.ipv4.ip_nonlocal_bind=1
这允许软件绑定到主机上当前不可用的地址。有了这个配置,如果我们向 VIP 发出请求,我们也会看到 VIP 返回的请求。
例如,如果我从 172.17.0.0/16 网络上的主机向 192.168.122.201 发出请求,则会tcpdump
显示:
... 172.17.0.2.58250 > 192.168.122.201.http: Flags [S], ...
... 192.168.122.201.http > 172.17.0.2.58250: Flags [S.], ...
... 172.17.0.2.58250 > 192.168.122.201.http: Flags [.], ...
... 172.17.0.2.58250 > 192.168.122.201.http: Flags [P.], ...
... 192.168.122.201.http > 172.17.0.2.58250: Flags [P.], ...
... 172.17.0.2.58250 > 192.168.122.201.http: Flags [.], ...
... 192.168.122.201.http > 172.17.0.2.58250: Flags [F.], ...
... 172.17.0.2.58250 > 192.168.122.201.http: Flags [F.], ...
... 192.168.122.201.http > 172.17.0.2.58250: Flags [.], ...
您可以找到我用来测试此配置的所有文件 这里。