Keepalived+Nginx双机热备:高可用负载均衡集群搭建实战

高可用集群架构设计与环境准备

服务器运维中,高可用集群是保障业务连续性的核心基础设施。单点故障是生产环境最大的风险来源,通过Keepalived+Nginx构建双机热备负载均衡集群,可以实现秒级故障切换,将服务可用性提升到99.99%以上。

典型的高可用负载均衡架构由两台Nginx服务器组成主备关系,通过Keepalived维护虚拟IP(VIP)。主节点持有VIP并处理所有流量,备节点持续监测主节点状态。当主节点故障时,备节点在秒级时间内接管VIP,实现无缝切换。后端应用服务器通过Nginx的upstream模块进行负载分发。

环境准备阶段需要规划网络拓扑。以下是一个标准部署方案:

网络规划:
  VIP: 192.168.1.100(对外提供服务的虚拟IP)
  Nginx-Master: 192.168.1.101(主负载均衡器)
  Nginx-Backup: 192.168.1.102(备负载均衡器)  
  Web-Server-1: 192.168.1.201(后端应用服务器)
  Web-Server-2: 192.168.1.202(后端应用服务器)
  Web-Server-3: 192.168.1.203(后端应用服务器)

# 在两台Nginx服务器上安装依赖
yum install -y nginx keepalived
# Ubuntu/Debian系统
apt install -y nginx keepalived

安装完成后,先确认内核参数允许非本地IP绑定。Keepalived的VIP绑定需要调整内核参数:

# 修改 /etc/sysctl.conf
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
sysctl -p

# 确认Nginx和Keepalived服务开机自启
systemctl enable nginx keepalived

Nginx负载均衡配置详解

Nginx的负载均衡通过upstream指令实现,支持轮询(round_robin)、加权轮询(weight)、IP哈希(ip_hash)等多种调度算法。生产环境中需要根据业务特征选择合适的算法,并配置健康检查机制。

以下是在两台Nginx服务器上配置完全相同的负载均衡规则:

# /etc/nginx/conf.d/load-balancer.conf

upstream backend_servers {
    # 加权轮询,按服务器性能分配权重
    server 192.168.1.201 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.202 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.203 weight=1 max_fails=3 fail_timeout=30s;
    
    # 备用服务器,当所有主服务器不可用时启用
    server 192.168.1.204 backup;
    
    # 保持长连接,减少TCP握手开销
    keepalive 32;
    keepalive_timeout 60s;
}

server {
    listen 80;
    server_name www.example.com;
    
    # 启用gzip压缩
    gzip on;
    gzip_types text/plain application/json application/javascript text/css;
    gzip_min_length 1024;
    
    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_http_version 1.1;
        proxy_set_header Connection "";
        
        # 超时设置
        proxy_connect_timeout 5s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
    
    # 健康检查端点
    location /health {
        access_log off;
        return 200 "ok";
        add_header Content-Type text/plain;
    }
}

配置中的max_fails和fail_timeout参数实现了被动健康检查。当某台后端服务器连续3次请求失败后,Nginx会在30秒内不再将请求分发到该服务器。这种方式无需额外模块,适合大多数场景。

对于需要主动健康检查的场景,可以使用nginx_upstream_check_module模块。该模块支持定时主动探测后端服务器状态,比被动检查更可靠:

# 安装主动健康检查模块后,在upstream中添加
upstream backend_servers {
    server 192.168.1.201:80;
    server 192.168.1.202:80;
    server 192.168.1.203:80;
    
    # 主动健康检查:每3秒检查一次,连续2次失败标记为下线,连续2次成功恢复
    check interval=3000 rise=2 fall=2 timeout=2000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

Keepalived双机热备配置

Keepalived基于VRRP(虚拟路由冗余协议)实现主备切换。主节点周期性发送VRRP广播包,备节点监听这些包。当备节点在指定时间内未收到主节点的广播包,认为主节点故障,自动接管VIP。

主节点配置文件:

# /etc/keepalived/keepalived.conf (主节点 192.168.1.101)

global_defs {
    router_id NGINX_MASTER
    # 启用脚本安全权限
    enable_script_security
}

# 健康检查脚本:检测Nginx进程是否存活
vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2          # 每2秒执行一次
    weight -20          # 脚本失败时,优先级降低20
    fall 2              # 连续2次失败才判定为故障
    rise 1              # 1次成功即恢复
}

vrrp_instance VI_1 {
    state MASTER        # 初始状态为主节点
    interface eth0      # 绑定的网络接口
    virtual_router_id 51  # 主备必须一致
    priority 100        # 优先级,主节点高于备节点
    advert_int 1        # VRRP广播间隔(秒)
    
    authentication {
        auth_type PASS
        auth_pass YourSecurePassword123
    }
    
    virtual_ipaddress {
        192.168.1.100/24    # 虚拟IP
    }
    
    track_script {
        check_nginx         # 关联健康检查脚本
    }
    
    # 主节点切换时的通知脚本
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault  "/etc/keepalived/notify.sh fault"
}

备节点配置文件与主节点基本相同,仅state和priority不同:

# /etc/keepalived/keepalived.conf (备节点 192.168.1.102)

vrrp_instance VI_1 {
    state BACKUP        # 初始状态为备节点
    interface eth0
    virtual_router_id 51
    priority 90         # 优先级低于主节点
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass YourSecurePassword123
    }
    
    virtual_ipaddress {
        192.168.1.100/24
    }
    
    track_script {
        check_nginx
    }
}

健康检查脚本check_nginx.sh的内容:

#!/bin/bash
# /etc/keepalived/check_nginx.sh

if [ -f /var/run/nginx.pid ]; then
    if kill -0 $(cat /var/run/nginx.pid) 2>/dev/null; then
        exit 0
    fi
fi
exit 1

集群故障自动切换与验证测试

配置完成后,通过模拟故障验证切换行为。这是服务器安全加固和运维验收的关键步骤。

# 1. 启动服务(两台Nginx服务器均执行)
systemctl start keepalived
systemctl start nginx

# 2. 在主节点上确认VIP已绑定
ip addr show eth0 | grep 192.168.1.100
# 预期输出:inet 192.168.1.100/24 scope global secondary eth0

# 3. 模拟主节点Nginx故障
systemctl stop nginx

# 4. 在备节点上检查VIP是否已接管(应在2-4秒内切换)
ip addr show eth0 | grep 192.168.1.100
# 预期输出:inet 192.168.1.100/24 scope global secondary eth0

# 5. 恢复主节点Nginx
systemctl start nginx

# 6. 观察VIP是否回切(取决于配置策略,默认会回切到主节点)

notify.sh通知脚本可以在切换时发送告警,集成到监控告警体系中:

#!/bin/bash
# /etc/keepalived/notify.sh

STATE=$1
HOSTNAME=$(hostname)
VIP="192.168.1.100"

case "$STATE" in
    master)
        MSG="$HOSTNAME 已成为主节点,VIP $VIP 已接管"
        ;;
    backup)
        MSG="$HOSTNAME 已切换为备节点"
        ;;
    fault)
        MSG="$HOSTNAME 发生故障"
        ;;
esac

# 发送到企业微信/钉钉webhook
curl -s -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY" \
    -H 'Content-Type: application/json' \
    -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"[Keepalived告警] $MSG\"}}"

logger -t keepalived "$MSG"

实际部署中还需要关注几个细节:VRRP广播包通过组播传输,跨子网部署需要改用单播模式(在vrrp_instance中添加unicast_src_ip和unicast_peer配置);split-brain问题(脑裂)可以通过设置nopreempt参数和调整priority策略来缓解;日志排查使用journalctl -u keepalived -f实时查看VRRP状态变化。这些细节在高可用集群的长期运维中至关重要。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/keepalivednginx-shuang-ji-re-bei-gao-ke-yong-fu-zai-jun/

(0)
小编小编
上一篇 10小时前
下一篇 10小时前

相关推荐