构建高可用负载均衡服务:LVS DR模式 + Nginx + Keepalived 完全指南
写作背景:由于在CS上面找LVS的搭建方法有一些需要收费,由此我写一篇免费的供大家参考。
本文将详细介绍如何使用 LVS (DR模式) 作为四层负载均衡器,结合 Nginx 作为七层负载均衡器,并通过 Keepalived 实现高可用与故障自动转移,构建一个高性能、高可用的分层负载均衡架构。
一、架构概述
本架构采用分层设计思想,充分发挥各组件优势:
-
LVS (DR模式):工作在传输层(四层),基于IP和端口进行高效流量分发,处理海量并发连接
-
Nginx:工作在应用层(七层),提供精细化的HTTP请求路由、SSL终结、内容缓存等功能
-
Keepalived:为LVS提供高可用保障,实现故障自动转移
二、架构拓扑
客户端
|
[虚拟IP: 192.168.1.100]
|
┌─────────────────────────────────────┐
│ LVS + Keepalived 集群 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ LVS主节点 │←→│ LVS备节点 │ │
│ │ 192.168.1.10 │ │192.168.1.11 │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────┘
↓ (DR模式分发)
┌─────────────────────────────────────┐
│ Nginx应用服务器集群 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Nginx-01 │ │ Nginx-02 │ │
│ │192.168.1.21 │ │192.168.1.22 │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────┘
↓ (反向代理)
┌─────────────────────────────────────┐
│ 后端应用服务器集群 │
│ 10.0.0.31:8080 10.0.0.32:8080 │
└─────────────────────────────────────┘
三、数据流向
-
客户端请求发送到虚拟IP(192.168.1.100)
-
当前活跃的LVS主节点接收请求
-
LVS通过DR模式将请求转发到后端的Nginx服务器
-
Nginx进行七层处理后将请求代理到后端应用服务器
-
应用服务器响应直接返回给客户端(不经过LVS)
四、环境准备
1、 服务器规划
| 角色 | 主机名 | IP地址 | 操作系统 | 最低配置 |
|---|---|---|---|---|
| LVS主节点 | lvs-master | 192.168.1.10 | CentOS 7.9+ | 2CPU/4GB |
| LVS备节点 | lvs-backup | 192.168.1.11 | CentOS 7.9+ | 2CPU/4GB |
| Nginx节点1 | nginx-01 | 192.168.1.21 | CentOS 7.9+ | 4CPU/8GB |
| Nginx节点2 | nginx-02 | 192.168.1.22 | CentOS 7.9+ | 4CPU/8GB |
| 虚拟IP | VIP | 192.168.1.100 | - | - |
| 应用服务器1 | app-01 | 10.0.0.31:8080 | 任意 | 根据应用需求 |
| 应用服务器2 | app-02 | 10.0.0.32:8080 | 任意 | 根据应用需求 |
2、 网络要求
-
所有服务器必须在同一局域网(同一广播域)
-
需要支持DR模式的网络环境
-
确保各节点间网络连通性
-
防火墙开放相应端口(80、443、VRRP协议端口112)
五、后端Nginx服务器配置
1 、 基础系统配置(所有Nginx节点执行)
# 1. 安装Nginx
sudo yum install -y epel-release
sudo yum install -y nginx
# 2. 配置内核参数(抑制ARP响应)
sudo cat /etc/sysctl.d/lvs-dr.conf << 'EOF'
# 抑制在lo接口上对VIP的ARP响应
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
EOF
sudo sysctl -p /etc/sysctl.d/lvs-dr.conf
# 3. 配置VIP到本地回环接口
sudo tee /etc/rc.local << 'EOF'
#!/bin/bash
# 在lo接口上添加VIP,设置32位掩码
ip addr add 192.168.1.100/32 dev lo label lo:0
# 启用路由本地地址
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
exit 0
EOF
sudo chmod +x /etc/rc.d/rc.local
sudo /etc/rc.d/rc.local # 立即生效
2 、Nginx应用层负载均衡配置
# 创建Nginx配置文件
sudo cat /etc/nginx/conf.d/loadbalance.conf << 'EOF'
# 上游应用服务器配置
upstream backend_servers {
# 使用最少连接数算法
least_conn;
# 后端应用服务器地址
server 10.0.0.31:8080 weight=3 max_fails=3 fail_timeout=30s;
server 10.0.0.32:8080 weight=2 max_fails=3 fail_timeout=30s;
# 健康检查配置
keepalive 32;
}
# 主服务器配置
server {
# 监听真实IP和VIP
listen 192.168.1.21:80; # 真实IP(根据节点修改)
listen 192.168.1.100:80; # 虚拟VIP
server_name your-domain.com www.your-domain.com;
# 访问日志配置
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
error_log /var/log/nginx/error.log warn;
# 静态文件优化
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
# 代理到后端
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 动态请求
location / {
# 反向代理配置
proxy_pass http://backend_servers;
# 传递真实客户端信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
# 缓冲区优化
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
# 健康检查端点(仅内部访问)
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
# 重定向HTTP到HTTPS(如果需要)
server {
listen 192.168.1.21:443 ssl http2;
listen 192.168.1.100:443 ssl http2;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/nginx/ssl/your-domain.crt;
ssl_certificate_key /etc/nginx/ssl/your-domain.key;
# SSL配置优化...
location / {
proxy_pass http://backend_servers;
# ...其他代理配置
}
}
EOF
# 启动并启用Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
六、LVS + Keepalived 高可用配置
1 、LVS主节点配置(lvs-master)
# 1. 安装必要软件
sudo yum install -y keepalived ipvsadm
# 2. 配置Keepalived
sudo tee /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_MASTER # 本机标识,主备不同
notification_email {
admin@your-domain.com
}
notification_email_from keepalived@your-domain.com
smtp_server smtp.your-domain.com
smtp_connect_timeout 30
}
# 对后端Nginx的健康检查脚本
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 3
weight -20
fall 2
rise 1
}
# VRRP实例配置
vrrp_instance VI_1 {
state MASTER
interface eth0 # 根据实际网卡修改
virtual_router_id 51
priority 100 # 主节点优先级更高
advert_int 1
authentication {
auth_type PASS
auth_pass 5a8d7f6e9c # 建议使用复杂密码
}
# 虚拟IP地址
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
# 状态切换时执行的脚本
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
# 关联健康检查
track_script {
chk_nginx
}
# 跟踪接口,如果接口down则降级优先级
track_interface {
eth0
}
}
# LVS虚拟服务配置
virtual_server 192.168.1.100 80 {
delay_loop 6
lb_algo wrr # 加权轮询
lb_kind DR # DR模式
persistence_timeout 50 # 会话保持50秒
protocol TCP
# 真实服务器1
real_server 192.168.1.21 80 {
weight 3
# TCP健康检查
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
# HTTP健康检查(更精确)
HTTP_CHECK {
url {
path /health
status_code 200
}
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
}
}
# 真实服务器2
real_server 192.168.1.22 80 {
weight 2
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
HTTP_CHECK {
url {
path /health
status_code 200
}
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
}
}
}
# HTTPS服务配置(如果需要)
virtual_server 192.168.1.100 443 {
delay_loop 6
lb_algo wrr
lb_kind DR
persistence_timeout 50
protocol TCP
real_server 192.168.1.21 443 {
weight 3
TCP_CHECK {
connect_timeout 5
connect_port 443
}
}
real_server 192.168.1.22 443 {
weight 2
TCP_CHECK {
connect_timeout 5
connect_port 443
}
}
}
EOF
# 3. 创建健康检查脚本
sudo tee /etc/keepalived/check_nginx.sh << 'EOF'
#!/bin/bash
# 检查后端Nginx服务状态
CHECK_PORT=80
TIMEOUT=2
RETRIES=2
for server in 192.168.1.21 192.168.1.22; do
for ((i=1; i<=RETRIES; i++)); do
if nc -z -w $TIMEOUT $server $CHECK_PORT; then
break
fi
if [ $i -eq $RETRIES ]; then
exit 1
fi
sleep 1
done
done
# 检查本地Nginx(如果运行在同一服务器)
if systemctl is-active --quiet nginx 2>/dev/null; then
if ! curl -s --max-time 3 http://localhost/health | grep -q "healthy"; then
exit 1
fi
fi
exit 0
EOF
sudo chmod +x /etc/keepalived/check_nginx.sh
# 4. 创建状态通知脚本
sudo tee /etc/keepalived/notify.sh << 'EOF'
#!/bin/bash
# Keepalived状态切换通知脚本
TYPE=$1
NAME=$2
STATE=$3
case $STATE in
"MASTER")
# 成为主节点时执行
echo "$(date): 本机成为MASTER节点" >> /var/log/keepalived-notify.log
# 可以在这里发送邮件或调用API通知
# 例如:sendmail -t <<< "Subject: Keepalived切换\n\n$HOSTNAME 已成为MASTER"
;;
"BACKUP")
# 成为备节点时执行
echo "$(date): 本机转为BACKUP节点" >> /var/log/keepalived-notify.log
;;
"FAULT")
# 进入故障状态时执行
echo "$(date): 本机进入FAULT状态" >> /var/log/keepalived-notify.log
;;
*)
echo "$(date): 未知状态: $STATE" >> /var/log/keepalived-notify.log
;;
esac
EOF
sudo chmod +x /etc/keepalived/notify.sh
# 5. 配置IPVS规则持久化
sudo tee /etc/sysconfig/ipvsadm << 'EOF'
#!ipvsadm-save
-A -t 192.168.1.100:80 -s wrr
-a -t 192.168.1.100:80 -r 192.168.1.21:80 -g -w 3
-a -t 192.168.1.100:80 -r 192.168.1.22:80 -g -w 2
-A -t 192.168.1.100:443 -s wrr
-a -t 192.168.1.100:443 -r 192.168.1.21:443 -g -w 3
-a -t 192.168.1.100:443 -r 192.168.1.22:443 -g -w 2
EOF
# 6. 启动服务
sudo systemctl enable keepalived
sudo systemctl enable ipvsadm
sudo systemctl start keepalived
2 、LVS备节点配置(lvs-backup)
# 1. 安装软件(同主节点)
sudo yum install -y keepalived ipvsadm
# 2. 配置Keepalived(与主节点主要区别在以下几行)
sudo tee /etc/keepalived/keepalived.conf << 'EOF'
global_defs {
router_id LVS_BACKUP # 修改标识
# ... 其他配置与主节点相同
}
vrrp_instance VI_1 {
state BACKUP # 修改为BACKUP
priority 90 # 优先级低于主节点
# ... 其他配置与主节点完全相同
}
# LVS配置部分与主节点完全相同
virtual_server 192.168.1.100 80 {
# ... 配置与主节点相同
}
EOF
# 3. 复制健康检查脚本和通知脚本(与主节点相同)
sudo scp root@192.168.1.10:/etc/keepalived/check_nginx.sh /etc/keepalived/
sudo scp root@192.168.1.10:/etc/keepalived/notify.sh /etc/keepalived/
sudo chmod +x /etc/keepalived/*.sh
# 4. 复制IPVS配置
sudo scp root@192.168.1.10:/etc/sysconfig/ipvsadm /etc/sysconfig/
# 5. 启动服务
sudo systemctl enable keepalived
sudo systemctl enable ipvsadm
sudo systemctl start keepalived
七、验证与测试
1 、基础功能验证
# 1. 检查VIP绑定
# 在主节点执行
ip addr show eth0 | grep 192.168.1.100
# 应显示:inet 192.168.1.100/24 scope global secondary eth0
# 2. 检查LVS规则
sudo ipvsadm -Ln
# 应显示配置的虚拟服务和真实服务器
# 3. 检查Keepalived状态
sudo systemctl status keepalived
journalctl -u keepalived -f --no-pager
# 4. 测试负载均衡
for i in {1..10}; do
curl -s http://192.168.1.100/ | grep "Server IP"
done
# 应看到请求被分配到不同的后端服务器
2 、高可用故障转移测试
# 1. 模拟主节点故障
# 在主节点执行
sudo systemctl stop keepalived
# 观察备节点日志
tail -f /var/log/messages
# 应看到备节点转换为MASTER状态
# 2. 验证VIP转移
# 在备节点执行
ip addr show eth0 | grep 192.168.1.100
# 现在VIP应该绑定在备节点上
# 3. 测试服务连续性
# 在客户端执行,观察服务是否中断
while true; do
curl -s -o /dev/null -w "%{http_code}" http://192.168.1.100/
echo " - $(date)"
sleep 1
done
# 应只有短暂中断(1-3秒)
# 4. 恢复主节点
# 在主节点执行
sudo systemctl start keepalived
# VIP应自动回切到主节点
3 、性能测试
# 使用ab进行压力测试
ab -n 10000 -c 100 http://192.168.1.100/
# 使用wrk进行更详细的测试
wrk -t4 -c100 -d30s http://192.168.1.100/
# 监控系统资源
top -b -d 1 -n 60 > performance.log
# 查看LVS连接统计
watch -n 1 "ipvsadm -Ln --stats"
4 、安装方法
1 、ApacheBench (ab)
-
安装 (以CentOS/RHEL为例):
sudo yum install -y httpd-tools
验证安装:ab -V
2 、wrk
-
安装 (需要编译):
# 安装编译依赖
sudo yum install -y git gcc make
# 克隆代码并编译
git clone https://github.com/wg/wrk.git
cd wrk
make
# 将可执行文件移动到系统路径
sudo cp wrk /usr/local/bin/
八、故障排查指南
1 、常见问题及解决方法
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| VIP无法访问 | 1. Keepalived未运行 2. 防火墙阻止 3. 网络配置错误 | 1. 检查keepalived状态 2. 检查防火墙规则 3. 验证网络配置 |
| 负载不均衡 | 1. LVS调度算法配置不当 2. 后端服务器权重设置错误 3. 会话保持时间过长 | 1. 调整调度算法 2. 重新配置权重 3. 调整persistence_timeout |
| 后端服务器健康检查失败 | 1. Nginx服务异常 2. 防火墙阻止健康检查 3. 网络问题 | 1. 检查Nginx状态 2. 配置防火墙规则 3. 检查网络连通性 |
| 故障转移时间过长 | 1. advert_int设置过大 2. fall/rise参数不合理 3. 网络延迟高 | 1. 调整advert_int 2. 优化健康检查参数 3. 检查网络质量 |
2 、诊断命令
# 网络诊断
ping -c 4 192.168.1.100
traceroute 192.168.1.100
mtr -r -c 10 192.168.1.100
# LVS诊断
sudo ipvsadm -Ln --stats # 查看统计信息
sudo ipvsadm -Ln --rate # 查看速率信息
sudo ipvsadm -L --timeout # 查看超时设置
# Keepalived诊断
sudo keepalived --check # 检查配置文件
sudo keepalived --dont-fork --log-console --log-detail # 调试模式
结束语:本人写一些笔记记录,以及工作中遇到的一些问题,方便之后重复阅读,每个人的搭建和操作都不一样,但是可以参考一下,感谢您的点击和阅读。
更多推荐
所有评论(0)