Keepalived + HAProxy 高可用负载均衡部署

环境信息

角色 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 浮动在 MASTER/BACKUP 之间

架构图

20260702105224782-image

Keepalived VRRP 工作原理

20260702105615276-image

服务部署

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

20260702105938727-image

2.配置后端 Real Server

RS1 (Debian3)

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

RS2 (Debian4)

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

20260702110215573-image

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

20260702110511380-image

配置说明:

参数 说明
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                # 确认运行

20260702110557449-image

4. 配置 Keepalived

4.1 健康检查脚本(两台相同)

创建 /etc/keepalived/check_haproxy.sh

#!/bin/bash
systemctl is-active --quiet haproxy
chmod +x /etc/keepalived/check_haproxy.sh

4.2 MASTER 配置(Debian1)

/etc/keepalived/keepalived.conf

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
    }
}

20260702111509472-image

4.4 关键参数说明

参数 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

5. 启动服务

# 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

20260702111935187-image

验证

5.1 验证负载均衡

# 每次新建连接,验证轮询
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

预期输出(交替出现):

20260702112042483-image

20260702112126575-image

⚠️ 注意: 浏览器测试时所有请求可能打到同一台 RS。因为浏览器默认使用 HTTP Keep-Alive 长连接,HAProxy 是七层代理,同一条 TCP 连接内的请求会复用后端连接。用 Connection: close 或开多个标签页即可看到轮询效果。

5.2 验证 VIP 状态

# 查看 VIP 在哪台机器
ip addr show enp0s5 | grep 10.211.55.100

20260702112244846-image

5.3 验证故障切换

测试 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]'

20260702112421773-image

20260702112452973-image

测试 2:恢复 MASTER 的 haproxy

# Debian1 上执行
systemctl start haproxy

# 等待 5 秒后,VIP 应自动切回 Debian1
# 在 Debian1 上检查
ip addr show enp0s5 | grep 10.211.55.100

20260702112601331-image

5.4 查看切换日志

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

Debian 1

20260702112719466-image

Debian 2

20260702112740988-image

切换时可以看到类似日志:

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

HAProxy 调度算法详解

算法 说明 适用场景
roundrobin 轮询,请求依次分配给每台 RS 静态内容、各 RS 性能相近
leastconn 最小连接数,分配给当前连接最少的 RS 动态内容、长连接(WebSocket)
source 源 IP 哈希,同 IP 始终到同一台 RS 需要会话保持
uri URI 哈希,同 URI 始终到同一台 RS 缓存命中优化
hdr(name) 根据指定 HTTP 头哈希 高级路由需求

HAProxy 健康检查机制

20260702113054224-image

常用命令

# 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 的对比总结

对比项 LVS (IPVS) Keepalived + HAProxy
工作层级 L4(传输层) L7(应用层)
性能 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
健康检查 ❌ 需要外部工具 ✅ 内置,强大
七层路由 ❌ 不支持 ✅ URL/Cookie/Header
SSL 卸载 ❌ 不支持 ✅ 支持
配置复杂度 简单 中等
高可用方案 keepalived(VRRP) keepalived(VRRP)
典型规模 超大规模(万级并发) 中小规模(千级并发)
推荐场景 四层入口负载均衡 七层应用负载均衡

广告:

THE END
喜欢就支持一下吧
点赞7打赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容