| 角色 | IP | 主机名 | 密码 | 服务 |
|---|---|---|---|---|
| MASTER(主负载均衡器) | 10.211.55.3 | Debian1 | vagrant | keepalived(MASTER) + haproxy |
| BACKUP(备负载均衡器) | 10.211.55.4 | Debian2 | vagrant | keepalived(BACKUP) + haproxy |
| Real Server 1 | 10.211.55.5 | Debian3 | vagrant | nginx:80 |
| Real Server 2 | 10.211.55.6 | Debian4 | vagrant | nginx:80 |
| VIP(虚拟 IP) | 10.211.55.100 | — | — |

Keepalived VRRP 工作原理

服务部署
1.安装服务
# Debian1 (10.211.55.3) - MASTER
apt install -y keepalived haproxy
# Debian2 (10.211.55.4) - BACKUP
apt install -y keepalived haproxy
# Debian3 (10.211.55.5) - RS1
apt install -y nginx
# Debian4 (10.211.55.6) - RS2
apt install -y nginx

2.配置后端 Real Server
cat > /var/www/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>RS1 - 10.211.55.5</title></head>
<body style="font-family: Arial; text-align: center; margin-top: 100px;">
<h1>Real Server 1</h1>
<h2 style="color: #2196F3;">10.211.55.5</h2>
<p>HAProxy 负载均衡测试 - 后端服务器 1</p>
</body>
</html>
EOF
systemctl restart nginx
cat > /var/www/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>RS2 - 10.211.55.6</title></head>
<body style="font-family: Arial; text-align: center; margin-top: 100px;">
<h1>Real Server 2</h1>
<h2 style="color: #4CAF50;">10.211.55.6</h2>
<p>HAProxy 负载均衡测试 - 后端服务器 2</p>
</body>
</html>
EOF
systemctl restart nginx

3.配置 HAProxy(Debian1 + Debian2 配置相同)
编辑 /etc/haproxy/haproxy.cfg:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend web_front
bind *:80
mode http
default_backend web_servers
backend web_servers
mode http
balance roundrobin
option httpchk GET /
server rs1 10.211.55.5:80 check
server rs2 10.211.55.6:80 check

配置说明:
| 参数 | 说明 |
|---|---|
frontend web_front |
前端入口,监听 80 端口 |
bind *:80 |
绑定所有网卡的 80 端口 |
mode http |
七层 HTTP 模式 |
default_backend web_servers |
默认转发到后端组 |
balance roundrobin |
轮询调度算法 |
option httpchk GET / |
健康检查,请求 / 路径 |
server rs1 ... check |
定义后端 RS,check 启用健康检查 |
haproxy -f /etc/haproxy/haproxy.cfg -c # 检查配置
systemctl restart haproxy
systemctl is-active haproxy # 确认运行

4. 配置 Keepalived
/etc/keepalived/check_haproxy.sh
#!/bin/bash
systemctl is-active --quiet haproxy
chmod +x /etc/keepalived/check_haproxy.sh
global_defs {
router_id LVS_MASTER
}
vrrp_script check_haproxy {
script "/etc/keepalived/check_haproxy.sh"
interval 2 # 每 2 秒检查一次
weight -60 # 失败时优先级减 60
fall 2 # 连续 2 次失败才判负
rise 2 # 连续 2 次成功才恢复
}
vrrp_instance VI_1 {
state MASTER
interface enp0s5
virtual_router_id 51
priority 150 # 主节点优先级
advert_int 1 # VRRP 广播间隔 1 秒
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
10.211.55.100/24 dev enp0s5
}
track_script {
check_haproxy
}
}

| 参数 | MASTER | BACKUP | 说明 |
|---|---|---|---|
state |
MASTER | BACKUP | 角色声明 |
priority |
150 | 100 | 优先级,越大越可能成为 MASTER |
virtual_router_id |
51 | 51 | 同一组 VRRP 实例必须相同 |
advert_int |
1 | 1 | VRRP 广播间隔(秒) |
auth_pass |
123456 | 123456 | 认证密码,同一组必须相同 |
weight |
-60 | -20 |
故障切换逻辑(可见文章上面的架构图):
haproxy 正常时:
MASTER 实际优先级 = 150
BACKUP 实际优先级 = 100
→ MASTER 持有 VIP
haproxy 故障时:
MASTER 实际优先级 = 150 - 60 = 90
BACKUP 实际优先级 = 100(BACKUP 的 haproxy 正常)
→ BACKUP 优先级 100 > MASTER 优先级 90
→ VIP 漂移到 BACKUP
haproxy 恢复时:
MASTER 实际优先级 = 150(恢复)
BACKUP 实际优先级 = 100
→ MASTER 优先级 150 > BACKUP 优先级 100
→ VIP 自动切回 MASTER
# Debian1 (MASTER)
systemctl restart keepalived
systemctl enable keepalived haproxy
# Debian2 (BACKUP)
systemctl restart keepalived
systemctl enable keepalived haproxy
# Debian3/4 (RS)
systemctl enable --now nginx
nginx -s reload

# 每次新建连接,验证轮询
for i in 1 2 3 4 5 6; do
curl -s -H "Connection: close" http://10.211.55.100 | grep -o '10.211.55.[56]'
done
预期输出(交替出现):


注意: 浏览器测试时所有请求可能打到同一台 RS。因为浏览器默认使用 HTTP Keep-Alive 长连接,HAProxy 是七层代理,同一条 TCP 连接内的请求会复用后端连接。用 Connection: close
# 查看 VIP 在哪台机器
ip addr show enp0s5 | grep 10.211.55.100

测试 1:停 MASTER 的 haproxy
# Debian1 上执行
systemctl stop haproxy
# 等待 5 秒后,VIP 应漂移到 Debian2
# 在 Debian2 上检查
ip addr show enp0s5 | grep 10.211.55.100
# 验证服务仍可用
curl -s -H "Connection: close" http://10.211.55.100 | grep -o '10.211.55.[56]'


测试 2:恢复 MASTER 的 haproxy
# Debian1 上执行
systemctl start haproxy
# 等待 5 秒后,VIP 应自动切回 Debian1
# 在 Debian1 上检查
ip addr show enp0s5 | grep 10.211.55.100

journalctl -u keepalived --no-pager -n 20
Debian 1

Debian 2

切换时可以看到类似日志:
VRRP_Script(check_haproxy) failed (exited with status 3)
(VI_1) Changing effective priority from 150 to 90
(VI_1) Master received advert from 10.211.55.4 with higher priority 100, ours 90
(VI_1) Entering BACKUP STATE
| 算法 | 说明 | 适用场景 |
|---|---|---|
| roundrobin | 轮询,请求依次分配给每台 RS | 静态内容、各 RS 性能相近 |
| leastconn | 最小连接数,分配给当前连接最少的 RS | 动态内容、长连接(WebSocket) |
| source | 源 IP 哈希,同 IP 始终到同一台 RS | 需要会话保持 |
| uri | URI 哈希,同 URI 始终到同一台 RS | 缓存命中优化 |
| hdr(name) | 根据指定 HTTP 头哈希 |
HAProxy 健康检查机制

# HAProxy
haproxy -f /etc/haproxy/haproxy.cfg -c # 检查配置
systemctl restart haproxy # 重启
systemctl status haproxy # 查看状态
# Keepalived
systemctl restart keepalived # 重启
journalctl -u keepalived -n 20 # 查看日志
ip addr show enp0s5 | grep 10.211.55.100 # 查看 VIP
# 后端验证
curl -s -H "Connection: close" http://10.211.55.100
| 现象 | 可能原因 | 排查命令 |
|---|---|---|
| VIP 不通 | keepalived 未启动 | systemctl is-active keepalived |
| VIP 在 MASTER 但访问不了 | haproxy 未启动 | systemctl is-active haproxy |
| 只有一台 RS 响应 | 另一台 RS 健康检查失败 | curl http://10.211.55.5 直接测 RS |
| 故障切换不生效 | 优先级计算不对 | journalctl -u keepalived -n 20 |
| VIP 漂移后服务中断 | BACKUP 的 haproxy 未配置 | 检查 BACKUP 的 haproxy.cfg |
| 连接都到同一台 RS | HTTP Keep-Alive 复用 | 用 Connection: close 测试 |
| LVS (IPVS) | Keepalived + HAProxy | |
|---|---|---|
| 工作层级 | L4(传输层) | L7(应用层) |
| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 健康检查 | ❌ 需要外部工具 | ✅ 内置,强大 |
| 七层路由 | ❌ 不支持 | ✅ URL/Cookie/Header |
| SSL 卸载 | ❌ 不支持 | ✅ 支持 |
| 配置复杂度 | 简单 | 中等 |
| 高可用方案 | keepalived(VRRP) | keepalived(VRRP) |
| 典型规模 | 超大规模(万级并发) | 中小规模(千级并发) |
| 推荐场景 | 四层入口负载均衡 |
广告:
THE END















暂无评论内容