Keepalived+HAProxy 搭建高可用负载均衡

在现代互联网架构中,高可用性是系统设计的重要考量。本文将详细介绍如何使用Keepalived和HAProxy搭建高可用负载均衡集群,确保服务的连续性和可靠性。

实际配置部分没有落地验证,文章正文规划依赖AI完成

任务规划

技术简介

Keepalived 简介

Keepalived是一个基于VRRP(Virtual Router Redundancy Protocol)协议的高可用解决方案,主要用于实现服务器的故障切换和负载均衡。

主要特性:

  • VRRP协议支持:实现虚拟IP的主备切换
  • 健康检查:监控服务状态,自动故障转移
  • 配置简单:通过配置文件即可实现复杂的高可用架构
  • 轻量级:资源占用少,性能优异

工作原理: Keepalived通过VRRP协议在多台服务器之间共享一个虚拟IP地址。正常情况下,主服务器持有虚拟IP并提供服务;当主服务器发生故障时,备用服务器会自动接管虚拟IP,确保服务不中断。

HAProxy 简介

HAProxy是一个高性能的负载均衡器和反向代理服务器,广泛应用于高并发场景。

主要功能:

  • 负载均衡:支持多种负载均衡算法
  • 健康检查:实时监控后端服务器状态
  • SSL终结:支持HTTPS流量处理
  • 统计监控:提供详细的运行状态统计

应用场景:

  • Web服务负载均衡
  • 数据库连接池
  • 微服务网关
  • API接口代理

架构设计

整体架构

                    ┌─────────────────┐
                    │   Client        │
                    └─────────┬───────┘
                              │
                    ┌─────────▼───────┐
                    │  Virtual IP     │
                    │  (VIP)          │
                    └─────────┬───────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
    ┌─────────▼───────┐              ┌─────────▼───────┐
    │   HAProxy-1     │              │   HAProxy-2     │
    │  (Master)       │◄────────────►│   (Backup)      │
    │  + Keepalived   │   VRRP       │  + Keepalived   │
    └─────────┬───────┘              └─────────┬───────┘
              │                                │
              └──────────┬─────────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
┌───────▼───────┐ ┌──────▼──────┐ ┌───────▼───────┐
│  Web Server 1 │ │ Web Server 2│ │  Web Server 3 │
│   Backend     │ │   Backend   │ │   Backend     │
└───────────────┘ └─────────────┘ └───────────────┘

组件说明

  • 虚拟IP (VIP):客户端访问的统一入口
  • HAProxy主备节点:提供负载均衡服务,通过Keepalived实现高可用
  • 后端服务器:实际提供服务的Web服务器

环境准备

服务器规划

角色 IP地址 主机名 服务
HAProxy主节点 192.168.1.10 lb-master HAProxy + Keepalived
HAProxy备节点 192.168.1.11 lb-backup HAProxy + Keepalived
虚拟IP 192.168.1.100 - VIP
Web服务器1 192.168.1.20 web1 Nginx/Apache
Web服务器2 192.168.1.21 web2 Nginx/Apache
Web服务器3 192.168.1.22 web3 Nginx/Apache

软件安装

在HAProxy主备节点上安装必要软件:

# CentOS/RHEL
yum install -y haproxy keepalived

# Ubuntu/Debian
apt-get update
apt-get install -y haproxy keepalived

# 启用服务开机自启
systemctl enable haproxy keepalived

Keepalived 配置

主节点配置 (lb-master)

创建配置文件 /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
    router_id LB_MASTER
    script_user root
    enable_script_security
}

# 检查HAProxy服务状态的脚本
vrrp_script chk_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight -2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mypassword123
    }
    
    virtual_ipaddress {
        192.168.1.100/24
    }
    
    track_script {
        chk_haproxy
    }
    
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

备节点配置 (lb-backup)

创建配置文件 /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
    router_id LB_BACKUP
    script_user root
    enable_script_security
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight -2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mypassword123
    }
    
    virtual_ipaddress {
        192.168.1.100/24
    }
    
    track_script {
        chk_haproxy
    }
    
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

健康检查脚本

创建HAProxy健康检查脚本 /etc/keepalived/check_haproxy.sh

#!/bin/bash

# 检查HAProxy进程是否运行
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
    # 尝试启动HAProxy
    systemctl start haproxy
    sleep 2
    
    # 再次检查,如果还是没有运行则退出
    if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
        exit 1
    fi
fi

# 检查HAProxy端口是否监听
if ! netstat -tuln | grep -q ":80 "; then
    exit 1
fi

exit 0

状态通知脚本

创建状态通知脚本 /etc/keepalived/notify.sh

#!/bin/bash

TYPE=$1
NAME=$2
STATE=$3

case $STATE in
    "MASTER")
        echo "$(date): Became MASTER" >> /var/log/keepalived-state.log
        ;;
    "BACKUP")
        echo "$(date): Became BACKUP" >> /var/log/keepalived-state.log
        ;;
    "FAULT")
        echo "$(date): Fault detected" >> /var/log/keepalived-state.log
        ;;
    *)
        echo "$(date): Unknown state: $STATE" >> /var/log/keepalived-state.log
        ;;
esac

设置脚本执行权限:

chmod +x /etc/keepalived/check_haproxy.sh
chmod +x /etc/keepalived/notify.sh

HAProxy 配置

主配置文件

在主备节点上创建相同的HAProxy配置文件 /etc/haproxy/haproxy.cfg

global
    log 127.0.0.1:514 local0
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    mode http
    log global
    option httplog
    option dontlognull
    option log-health-checks
    option forwardfor except 127.0.0.0/8
    option redispatch
    retries 3
    timeout http-request 10s
    timeout queue 1m
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout http-keep-alive 10s
    timeout check 10s
    maxconn 3000

# 统计页面配置
listen stats
    bind *:8080
    stats enable
    stats uri /stats
    stats realm HAProxy\ Statistics
    stats auth admin:password123
    stats refresh 30s

# 前端配置
frontend web_frontend
    bind *:80
    default_backend web_servers

# 后端服务器配置
backend web_servers
    balance roundrobin
    option httpchk GET /health
    
    server web1 192.168.1.20:80 check inter 2000 rise 2 fall 3
    server web2 192.168.1.21:80 check inter 2000 rise 2 fall 3
    server web3 192.168.1.22:80 check inter 2000 rise 2 fall 3

配置说明

全局配置:

  • log:日志配置
  • chroot:安全沙箱
  • stats socket:管理接口
  • daemon:后台运行

默认配置:

  • mode http:HTTP模式
  • balance roundrobin:轮询负载均衡
  • option httpchk:HTTP健康检查
  • timeout:各种超时设置

后端服务器:

  • check:启用健康检查
  • inter 2000:检查间隔2秒
  • rise 2:连续2次成功标记为可用
  • fall 3:连续3次失败标记为不可用

服务启动与测试

启动服务

在主备节点上启动服务:

# 启动HAProxy
systemctl start haproxy
systemctl status haproxy

# 启动Keepalived
systemctl start keepalived
systemctl status keepalived

验证VIP绑定

检查虚拟IP是否正确绑定:

# 在主节点查看IP地址
ip addr show

# 应该能看到类似输出:
# eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
#     inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0
#     inet 192.168.1.100/24 scope global secondary eth0:0

功能测试

1. 负载均衡测试

# 多次访问VIP,观察请求分发
for i in {1..10}; do
    curl -s http://192.168.1.100/ | grep "Server"
done

2. 故障切换测试

# 在主节点停止HAProxy服务
systemctl stop haproxy

# 观察VIP是否切换到备节点
ip addr show

# 测试服务是否正常
curl http://192.168.1.100/

3. 后端服务器故障测试

# 停止其中一台Web服务器
# 在web1服务器上:
systemctl stop nginx

# 观察HAProxy统计页面
curl http://192.168.1.100:8080/stats

监控与维护

日志监控

HAProxy日志

# 查看HAProxy日志
tail -f /var/log/haproxy.log

# 查看访问统计
grep "HTTP/1.1" /var/log/haproxy.log | tail -20

Keepalived日志

# 查看Keepalived日志
tail -f /var/log/messages | grep keepalived

# 查看状态变化日志
tail -f /var/log/keepalived-state.log

性能监控

统计页面监控

访问HAProxy统计页面:http://192.168.1.100:8080/stats

关键指标:

  • Session Rate:会话速率
  • Session Total:总会话数
  • Bytes In/Out:流量统计
  • Response Time:响应时间
  • Server Status:服务器状态

命令行监控

# 查看HAProxy进程状态
ps aux | grep haproxy

# 查看端口监听状态
netstat -tuln | grep -E "(80|8080)"

# 查看连接数
ss -ant | grep :80 | wc -l

常见问题排查

1. VIP无法切换

问题现象: 主节点故障后,VIP没有切换到备节点

排查步骤:

# 检查Keepalived配置
keepalived -t -f /etc/keepalived/keepalived.conf

# 查看VRRP通信
tcpdump -i eth0 vrrp

# 检查防火墙设置
iptables -L | grep vrrp

解决方案:

  • 确保VRRP协议通信正常
  • 检查网络接口配置
  • 验证认证密码一致性

2. 健康检查失败

问题现象: 后端服务器被标记为不可用

排查步骤:

# 手动执行健康检查
curl -I http://192.168.1.20/health

# 查看HAProxy日志
grep "Health check" /var/log/haproxy.log

解决方案:

  • 确保健康检查URL可访问
  • 调整检查间隔和阈值
  • 检查后端服务器状态

3. 负载不均衡

问题现象: 请求没有均匀分发到后端服务器

排查步骤:

# 查看统计页面
curl -s http://192.168.1.100:8080/stats

# 分析访问日志
awk '{print $6}' /var/log/haproxy.log | sort | uniq -c

解决方案:

  • 检查负载均衡算法配置
  • 验证服务器权重设置
  • 考虑会话保持需求

优化建议

1. 性能优化

# 调整系统参数
echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65535' >> /etc/sysctl.conf
sysctl -p

# 优化HAProxy配置
# 增加maxconn值
# 调整timeout参数
# 启用压缩功能

2. 安全加固

# 限制统计页面访问
# 在haproxy.cfg中添加ACL规则
acl allowed_ips src 192.168.1.0/24
http-request deny if !allowed_ips

# 启用SSL/TLS
bind *:443 ssl crt /etc/ssl/certs/server.pem
redirect scheme https if !{ ssl_fc }

3. 监控告警

# 集成监控系统
# 配置Prometheus监控
# 设置Grafana仪表板
# 配置告警规则

总结

通过Keepalived和HAProxy的组合,我们成功构建了一个高可用的负载均衡集群。这个方案具有以下优势:

  1. 高可用性:通过VRRP协议实现自动故障切换
  2. 负载均衡:智能分发请求,提高系统性能
  3. 健康检查:实时监控服务状态,自动剔除故障节点
  4. 易于维护:配置简单,管理方便
  5. 成本效益:使用开源软件,降低运维成本

在生产环境中部署时,还需要考虑网络安全、监控告警、备份恢复等方面的完善,以确保系统的稳定可靠运行。

金融IT程序员的瞎折腾、日常生活的碎碎念
使用 Hugo 构建
主题 StackJimmy 设计