集群技术笔记-HAProxy 与 Keepalived 高可用负载均衡实战
目录
前言
HAProxy
一、HAProxy介绍
(一)定义
(二)核心优势
(三)调度算法速查表
(四)工作模式
(五)配置文件结构
(六)健康检查字段
二、搭建负载均衡集群
(一)准备基本环境
(二)配置流程
配置真实服务器
配置代理服务器
(三)客户端验证
三、配置健康检查页面
(一)修改配置文件
追加配置内容
(二)重启服务
(三)浏览器访问验证
Keepalived
一、Keepalived介绍
(一)定义
(二)功能
(三)工作原理
(四) 优势
(五) 应用场景
二、配置文件
(一)global_defs 全局定义段
(二)vrrp_instance 段(VRRP 实例)
(三)virtual_ipaddress 段(VIP 列表)
(四)virtual_server 段(LVS 虚拟服务)
(五)real_server 段(后端节点)
(六)健康检查块(嵌套在 real_server 内)
(七)track_script 段(自定义脚本)
三、LVS高可用
(一)准备基本环境
(二)配置流程
配置真实服务器
配置调度服务器(LVS)
LVS1和LVS2
LVS1
LVS2
客户端验证
功能验证
高可用切换验证
四、Web高可用
(一)准备基本环境
(二)配置流程
配置 Web1`和 Web2
配置 Web1
配置 Web2
客户端验证
前言
- 本文介绍HAProxy和Keepalived的使用,
- LVS的使用可以参考集群技术笔记-LVS高并发负载均衡原理对比与实践。
HAProxy
一、HAProxy介绍
(一)定义
- HAProxy(High Availability Proxy)是一款开源、C 语言实现的高性能负载均衡器与代理服务器,工作在 OSI 第四层(TCP)与第七层(HTTP)。
- 单进程、事件驱动模型,单机可稳定维持数万并发连接,CPU 与内存占用低于多进程或多线程实现。
- 支持 SSL/TLS 终止、TCP/HTTP 健康检查、ACL 路由、会话保持、WebSocket、gRPC 与统计页面。
- 无需修改后端应用即可插入现有架构,对外隐藏真实服务器,提高安全性及横向扩展能力。
- Keepalived 官网、Keepalived 官方文档
(二)核心优势
- 高吞吐:事件驱动 + 零拷贝,单进程即可支撑数万并发连接。
- 调度算法:roundrobin、static-rr、leastconn、source、uri、hdr、rdp-cookie 等十余种。
- 七层路由:按 URL、Header、Cookie 精确分流,无需后端改动。
- 健康检查:TCP/HTTP/SSL 多层探测,故障节点自动下线。
- SSL 终端:内置加解密、证书热更新、OCSP Stapling。
- 高可用:配合 Keepalived 实现 VIP 漂移,切换时间 <1 秒。
- 安全策略:ACL、速率限制、黑白名单、chroot、最小权限、完整日志审计。
(三)调度算法速查表
算法 | 说明 | 适用场景 |
---|---|---|
roundrobin | 简单轮询 | 服务器性能一致、无状态业务 |
static-rr | 加权轮询 | 服务器性能差异明显 |
leastconn | 最少连接 | 长连接、WebSocket、DB |
source | 源地址哈希 | 会话保持,同 IP 落到同一 RS |
uri | URI 哈希 | 静态资源缓存、CDN 场景 |
url_param | URL 参数哈希 | 按业务字段(user_id)分片 |
hdr(name) | HTTP 头哈希 | 按 Host、X-Forwarded-For 路由 |
rdp-cookie | Cookie 值哈希 | 登录态保持 |
(四)工作模式
模式 | 适用层级 | 功能说明 | 典型场景 |
---|---|---|---|
mode http | 第 7 层(HTTP/HTTPS/WebSocket/gRPC/HTTP2) | 解析完整 HTTP 报文,支持 URL、Header、Cookie 路由、压缩、重写、重定向、ACL、会话保持 | Web 站点、API 网关、微服务入口 |
mode tcp | 第 4 层(TCP/UDP) | 仅转发原始字节流,不解析应用数据,零拷贝,低延迟 | MySQL、Redis、SMTP、SSH、游戏、VoIP 等任意 TCP/UDP 服务 |
mode health | 健康检查专用 | 不转发业务流量,仅按配置对后端做 TCP/HTTP/HTTPS 探活,返回检查状态 | 独立监控节点、灰度验证、无流量场景 |
(五)配置文件结构
- 主配置文件
/etc/haproxy/haproxy.cfg
:- global
- 全局作用域,影响整个 HAProxy 进程。
- 常见指令:日志设备、最大连接数、线程数、SSL 默认参数、chroot、用户/组、Runtime API 套接字等。
子选项 作用简述 log <addr><facility><level> 日志输出位置与级别 maxconn <num> 进程级最大并发连接 nbthread <num> 启用多线程并指定线程数 user / group 运行身份 chroot <dir> chroot 安全隔离目录 stats socket <path> Runtime API 套接字 ssl-default-bind-ciphers <cipher-list> 默认 TLS 加密套件 ssl-default-bind-options <options> 默认 TLS 选项(如 no-sslv3) daemon 以后台守护进程方式运行 pidfile <file> 指定 pid 文件
- defaults
- 为后续所有 frontend、backend、listen 块提供默认模板。
- 可统一设置超时、模式(http/tcp)、错误页面、连接重试次数、健康检查默认值等。
- 若下级段落重复同名指令,则以局部配置覆盖 defaults。
子选项 作用简述 mode http / tcp 默认工作模式 timeout connect <time> 与后端建立 TCP 连接的超时 timeout client <time> 客户端读超时 timeout server <time> 后端响应超时 retries <num> 连接失败重试次数 option httplog / tcplog 日志格式 option dontlognull 不记录空连接 option redispatch 会话失败时重新调度 errorfile <code><file> 自定义错误页 balance <algorithm> 默认负载均衡算法
- frontend
- 定义“入口”监听。
- 关键字:bind(地址+端口)、mode(http/tcp)、ACL 规则、http-request/redirect/use_backend 路由逻辑。
- 作用是把客户端流量接入并按规则分发到 backend。
子选项 作用简述 bind ip:port [ssl crt <pem>] 监听地址/端口及可选证书 mode http / tcp 该前端的工作模式 acl <name> 定义访问控制列表 http-request redirect / deny / allow 7 层重定向、拒绝、允许 use_backend <backend><acl> 按 ACL 路由到指定后端 default_backend <backend> 默认后端 option forwardfor 添加 X-Forwarded-For 头 capture request header <name><n> 采集请求头
- backend
- 定义“后端”服务器池。
- 关键字:balance(算法)、server(IP:端口 权重 健康检查)、option(httpchk/tcp-check)、cookie(会话保持)。
- 真正完成负载均衡与健康检查。
子选项 作用简述 balance <algorithm> 指定调度算法 server <name> 添加真实服务器 check inter <ms><n><n> 健康检查间隔、成功/失败阈值 weight <n> 权重 backup 备用节点标记 ssl verify none / verify required 与后端之间是否校验证书 option httpchk <method><uri> HTTP 健康检查 cookie <name> 会话保持 cookie http-request / http-response set-header 修改请求/响应头 option tcp-check 四层自定义检查脚本
- listen
- 将 frontend 与 backend 合并的监听块。
- 适合快速配置或简单场景,减少层级,写法更紧凑。
子选项 作用简述 bind ip:port [ssl crt <pem>] 监听地址/端口及可选证书 mode http / tcp 该前端的工作模式 balance <algorithm> 指定调度算法 server 行 添加真实服务器 acl / http-request / option httpchk … 可直接写在 listen 内,实现一体化配置
- global
(六)健康检查字段
字段类别 | 子字段 | 含义 |
---|---|---|
Queue | Cur | 当前排队请求数 |
Max | 历史峰值 | |
Limit | 队列硬限制 | |
Session rate | Cur | 每秒新建会话 |
Max | 历史峰值 | |
Limit | 配置上限 | |
Sessions | Cur | 当前活跃会话 |
Max | 历史峰值 | |
Total | 启动后累计会话 | |
Bytes | In / Out | 入站 / 出站字节数 |
Denied / Errors / Warnings | — | 拒绝、连接、响应错误计数 |
Server | Status | UP / DOWN / MAINT |
LastChk | 上次健康检查时间 | |
Wght | 权重 | |
Act / Bck | 活跃 / 备用节点 | |
Dwn / Dwntme | 故障时长(秒) |
二、搭建负载均衡集群
(一)准备基本环境
主机名 | IP地址 | 角色 |
---|---|---|
HAProxy | 192.168.88.77/24 | 代理服务器 |
Web1 | 192.168.88.7824 | 真实服务器 |
Web2 | 192.168.88.79/24 | 真实服务器 |
Client | 192.168.88.80/24 | 客户端 |
(二)配置流程
配置真实服务器
- Web1
yum -y remove firewalld #卸载防火墙
yum -y install nginx
systemctl enable --now nginx
echo "Web1" > /usr/share/nginx/html/index.html
curl 192.168.88.78 # 确保返回页面
- Web2
yum -y install nginx
systemctl enable --now nginx
echo "Web2" > /usr/share/nginx/html/index.html
curl 192.168.88.79 # 确保返回页面
配置代理服务器
- 安装和启动 HAProxy
yum -y install haproxy
systemctl enable --now haproxy
- 备份并准备配置文件
cp /etc/haproxy/haproxy.cfg{,.bak-$(date +%F_%T)}
- 修改配置文件
#删除官方示例 64 行之后的内容
sed -i '64,$d' /etc/haproxy/haproxy.cfg#追加以下配置到文件末尾
cat >> /etc/haproxy/haproxy.cfg << EOF# web 业务监听
listen webservers
#定义虚拟服务器,一个名为webservers的监听块,同时配置前端(监听请求)和后端(负载均衡策略)bind 0.0.0.0:80
#定义监听的IP地址和端口,0.0.0.0表示监听所有网络接口mode http
#定义工作模式为HTTP(第七层负载均衡)balance roundrobin
#定义调度算法为轮询server web1 192.168.88.78:80 check inter 2000 rise 2 fall 5 server web2 192.168.88.79:80 check inter 2000 rise 2 fall 5
#添加真实服务器 check对后端服务器进行健康检查,inter健康检查心跳包发送时间间隔(毫秒),rise连续检查N次有响应(成功)则认为健康,fall 连续检查N次无响应(失败)则认为故障EOF
(三)客户端验证
# Web 负载测试(预期 1:1 轮询)
for i in {1..6}; do curl -s http://192.168.88.77
三、配置健康检查页面
(一)修改配置文件
追加配置内容
# 统计/健康检查页面
listen status #定义虚拟服务器,名称为statsbind 0.0.0.0:8080 #定义监听的ip地址和端口stats uri /status #定义请求路径stats refresh 60s #定义页面刷新时间,每一分钟刷新一次stats auth admin:admin #定义用户和密码
(二)重启服务
systemctl restart haproxy
(三)浏览器访问验证
访问http://192.168.88.77:8080/status 输入用户和密码 均为admin
Keepalived
一、Keepalived介绍
(一)定义
- Keepalived 是一款基于 VRRP 的轻量级高可用方案,最初为弥补 LVS 对后端真实服务器的监控缺口而生,后通过引入 VRRP 实现了 VIP 漂移与故障转移,既能自动监控服务状态并在故障时切换到备用节点以保障业务连续性,又可与 LVS 等结合完成后端流量负载均衡,从而解决了静态路由的单点故障问题。
- Keepalived 官网、Keepalived 官方文档
(二)功能
- LVS 规则管理:自动生成、下发、刷新 ipvsadm 规则,无需手动维护。
- 真实服务器状态监测:支持 ICMP、TCP、HTTP 等多层健康检查,实时剔除/恢复故障节点。
- VIP(虚拟 IP)管理:通过 VRRP 实现主备节点间 VIP 秒级漂移,对外提供统一入口,零中断切换。
(三)工作原理
- VRRP 主备同步
- 主节点周期性发送 VRRP Advert 报文。
- 备节点在 3×advert_int 内未收到心跳即触发选举,立即接管 VIP。
- 多层健康探测
- Layer3 ICMP、Layer4 TCP/UDP、Layer7 HTTP/HTTPS 探针实时检测所有真实服务器。
- 故障节点自动从 LVS/HAProxy 后端池剔除;恢复后自动重新加入,并同步到对端节点。
(四) 优势
- 高可用:VRRP 秒级故障转移,VIP 零中断漂移,彻底消除单点。
- 轻量高效:C 语言实现,常驻内存 < 2 MB,支撑万级并发无压力。
- 负载均衡一体化:内置 LVS 驱动,完整支持 RR、WRR、LC、WLC、SH、DH、URI、URI_PARAM、HTTP_HEADER、LBLC、LBLCR 等算法。
- 多层健康检查:ICMP / TCP / HTTP / HTTPS 全覆盖,实时探活、自动剔除与恢复节点。
- 灵活配置:单文件定义 VIP、虚拟服务、健康脚本与故障转移策略,支持热重载。
- 多实例扩展:同一主机可并行运行多个 VRRP 实例,独立管理多套高可用集群。
- 开源可靠:协议宽松、社区活跃、文档齐全,企业级稳定性。
(五) 应用场景
- Web 服务器高可用:Keepalived 为 Nginx 主备提供漂移 VIP,主节点宕机秒切备用节点,保障网站 7×24 不中断。
- 数据库主从:Keepalived 监控 MySQL 主库心跳,主库故障时 VIP 漂至从库,读写继续正常。
- 微服务入口:Keepalived+LVS/HAProxy 做高可用负载均衡,后端实例健康检查,VIP 漂移实现流量无缝迁移。
二、配置文件
(一)global_defs 全局定义段
子选项 | 说明 |
---|---|
router_id | 节点唯一标识,通常用主机名 |
notification_email | 故障通知邮箱 |
smtp_server | 邮件服务器地址 |
smtp_connect_timeout | SMTP 连接超时(秒) |
vrrp_mcast_group4 | IPv4 组播地址 |
vrrp_mcast_group6 | IPv6 组播地址 |
vrrp_version | VRRP 版本 |
vrrp_iptables | 自动放行 VRRP 协议 |
| 严格遵守VRRP规则 |
vrrp_check_unicast_src | 校验单播源地址 |
script_user | 脚本运行身份 |
enable_script_security | 禁止脚本提权 |
(二)vrrp_instance 段(VRRP 实例)
子选项 | 说明 |
---|---|
state MASTER/BACKUP | 初始角色 |
interface <iface> | 绑定的物理网卡 |
virtual_router_id <1-255> | VRID,主备必须一致 |
priority <1-254> | 优先级,高者为主 |
advert_int <sec> | 心跳间隔 |
authentication { … } | VRRP 认证 |
track_interface { … } | 网卡状态跟踪 |
track_script { … } | 自定义脚本结果跟踪 |
virtual_ipaddress { … } | VIP 列表 |
(三)virtual_ipaddress 段(VIP 列表)
virtual_ipaddress { #/定义VIPPv4 虚拟地址/子网掩码 dev 网卡名 label 网卡别名 #VIP地址及绑定网卡虚拟接口标签
}
(四)virtual_server 段(LVS 虚拟服务)
子选项 | 说明 |
---|---|
delay_loop <sec> | 健康检查延迟 |
lb_algo <rr、wrr、lc…> | LVS 调度算法 |
lb_kind <DR、NAT、TUN> | LVS 模式 |
persistence_timeout <sec> | 会话保持时长 |
protocol <TCP | UDP> |
ha_suspend | 当节点为 BACKUP 时暂停检查 |
virtualhost <FQDN> | Layer7 检查 Host 头 |
(五)real_server 段(后端节点)
子选项 | 说明 |
---|---|
weight <0-255> | 权重 |
inhibit_on_failure | 故障时权重置 0 |
notify_up <script> | 节点上线钩子 |
notify_down <script> | 节点下线钩子 |
(六)健康检查块(嵌套在 real_server 内)
类型 | 子选项 |
---|---|
TCP_CHECK | connect_port, connect_timeout, retry |
HTTP_GET | url path status_code digest |
SSL_GET | url path status_code digest,支持 https |
MISC_CHECK | misc_path, misc_timeout |
(七)track_script 段(自定义脚本)
vrrp_script 脚本块名 {script "脚本路径"interval <sec> #定义脚本执行频率
}
三、LVS高可用
(一)准备基本环境
主机名 | IP地址 | 角色 |
---|---|---|
LVS1 | 192.168.88.81/24 | LVS 调度服务器 |
LVS2 | 192.168.88.82/24 | LVS 调度服务器 |
Web1 | 192.168.88.83/24 | 真实服务器 |
Web2 | 192.168.88.84/24 | 真实服务器 |
Client | 192.168.88.85/24 | 客户端 |
(二)配置流程
配置真实服务器
- Web1和Web2
yum -y remove firewalld #卸载防火墙
yum -y install nginx
systemctl enable --now nginxyum -y install network-scripts
cat > /etc/sysconfig/network-scripts/ifcfg-lo:0 <<EOF
DEVICE=lo:0 #定义回环接口名称,回环接口用于本机内部通信
NAME=lo:0
IPADDR=192.168.88.86
PREFIX=32 #子网掩码为32,只有一个主机位,仅表示本机IP地址
ONBOOT=yes
EOFifup lo:0
# 追加 ARP 抑制
cat >> /etc/sysctl.conf <<EOF
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
EOF
sysctl -p
- Web1
echo "Web1" > /usr/share/nginx/html/index.html
curl 192.168.88.83 # 确保返回页面
- Web2
echo "Web2" > /usr/share/nginx/html/index.html
curl 192.168.88.84 # 确保返回页面
配置调度服务器(LVS)
LVS1和LVS2
yum -y install ipvsadm keepalived #绑定 VIP
yum -y install network-scripts #提供if up/down 命令管理网络接口配置cat > /etc/sysconfig/network-scripts/ifcfg-eth0:0 <<EOF
TYPE=Ethernet #指定接口类型为以太网
DEVICE=eth0:0 #定义接口名称
NAME=eth0:0 #接口的描述性名称,通常与 DEVICE 一致
IPADDR=192.168.88.86 #为该接口分配的静态 IP 地址
PREFIX=24 #子网掩码的 CIDR 表示法
ONBOOT=yes #系统启动时自动激活该接口
EOF
ifup eth0:0
#根据 /etc/sysconfig/network-scripts/ifcfg-eth0:0 的配置,激活虚拟接口 eth0:0
LVS1
- 修改Keepalived的配置文件/etc/keepalived/keepalived.conf
global_defs {router_id LVS1 #集群节点的唯一标识vrrp_iptables #放行防火墙规则vrrp_strict #严格遵守VRRP规则...
}
vrrp_instance VI_1 {state MASTER #状态为主节点,主服务器interface eth0 #/网卡virtual_router_id 51 #虚拟路由唯一标识符,主备服务器的VRID号必须一致priority 100 #设置优先级,数字越大优先级越高advert_int 1 #心跳包间隔时间authentication { #认证方式auth_type PASS #密码认证auth_pass test #集群密码,主备服务器的密码必须一致}virtual_ipaddress { #定义VIP192.168.88.86/24 dev eth0 label eth0:0 #VIP地址及绑定网卡虚拟接口标签}
}
virtual_server 192.168.88.86 80 { #定义LVS虚拟服务器delay_loop 5 #健康检查延时5s开始lb_algo wrr #调度算法为加权轮询lb_kind DR #LVS工作模式为DR模式persistence_timeout 60 #60s内相同客户端发起请求由同一服务器处理protocol TCP #虚拟服务器协议real_server 192.168.88.83 80 { #定义真实服务器weight 1 #设置后端服务器的权重为1 TCP_CHECK { connect_timeout 2 #连接超时时间为2snb_get_retry 3 #连续3次访问失败则认为真实服务器故障delay_before_retry 3 #健康检查包时间间隔}}real_server 192.168.88.84 80 {weight 2TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 }}
}
- 启动 LVS1
systemctl enable --now keepalived
ipvsadm -Ln
ip a | grep 88.86
LVS2
rsync -av root@192.168.88.81:/etc/keepalived/keepalived.conf /etc/keepalived/# 只改三行
router_id LVS2
state BACKUP
priority 50
systemctl enable --now keepalived
客户端验证
功能验证
for i in {1..6}; do curl 192.168.88.86; done #预期 1:0或0:1# LVS 注释 persistence_timeout 后重启 Keepalived
for i in {1..6}; do curl 192.168.88.86; done #预期 1:2
高可用切换验证
#LVS1执行
systemctl stop keepalived
ipvsadm -Ln #显示为空#LVS2执行
ip a | grep 88.86 #秒级抢占 VIP
ipvsadm -Ln #规则仍在#Client执行
for i in {1..6}; do curl 192.168.88.86; done #客户端 curl 正常,全程用户无感知。
四、Web高可用
(一)准备基本环境
主机名 | IP地址 | 角色 |
---|---|---|
Web1 | 192.168.88.87/24 | Web服务器 |
Web2 | 192.168.88.88/24 | Web服务器 |
Client | 192.168.88.89/24 | 客户端 |
(二)配置流程
配置 Web1`和 Web2
yum -y install keepalived nginx
systemctl enable --now nginx
配置 Web1
- 修改Keepalived的配置文件/etc/keepalived/keepalived.conf(删除 LVS 段,仅保留 VRRP)
删除34行之后的内容,之后的内容为LVS相关的配置
global_defs {router_id Web1vrrp_iptablesvrrp_strict...
}vrrp_script chk_nginx {script "/etc/keepalived/check_nginx.sh"interval 2
}vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass test}virtual_ipaddress {192.168.88.90/24 dev eth0 label eth0:1}track_script {chk_nginx}
}
- Nginx 探活脚本/etc/keepalived/check_nginx.sh
#!/bin/bash
ss -anltpu | grep -q nginx && exit 0 || exit 1
#通过 ss 命令查看nginx服务是否运行,运行返回0,运行返回1chmod +x /etc/keepalived/check_nginx.sh
- 启用Keepalived
systemctl enable --now keepalived
- 编写测试网页文件
echo "Web1" > /usr/share/nginx/html/index.html
curl 192.168.88.87 # 确保返回页面
配置 Web2
- 同理配置Keepalived
global_defs {router_id Web2vrrp_iptablesvrrp_strict
}vrrp_instance VI_1 {state BACKUPinterface eth0virtual_router_id 51priority 50advert_int 1authentication {auth_type PASSauth_pass test}virtual_ipaddress {192.168.88.90/24 dev eth0 label eth0:1}
}
- 启用Keepalived
systemctl enable --now keepalived
- 编写测试网页文件
echo "Web1" > /usr/share/nginx/html/index.html
curl 192.168.88.88 # 确保返回页面
客户端验证
for i in {1..6}; do curl 192.168.88.90; done #返回Web1
#Web1执行
systemctl stop nginx#Web2执行
ip -a | grep 88.90 #几秒后查看VIP#Client执行
curl 192.168.88.90 #返回Web2页面#Web1执行
systemctl start nginx #启动nginx,等待一段时间VIP自动回到Web1