Linux高可用集群搭建教程:Keepalived+Nginx负载均衡故障切换配置

服务器运维场景中,单点故障是导致业务中断的常见原因。Keepalived基于VRRP协议实现VIP(虚拟IP)浮动,配合Nginx反向代理负载均衡,可构建秒级故障切换的高可用集群。本文以两台CentOS 9服务器为例,完整演示Keepalived+Nginx高可用架构的搭建、配置与故障切换验证过程。

高可用集群架构设计与网络规划

典型双机高可用架构包含以下组件:

  • 主服务器(MASTER):192.168.1.10,运行Nginx,持有VIP
  • 备服务器(BACKUP):192.168.1.11,运行Nginx,监听VIP
  • 虚拟IP(VIP):192.168.1.100,对外提供服务的浮动IP
  • 后端应用服务器:192.168.1.20-22,运行业务应用

VRRP协议通过组播(224.0.0.18)在主备之间发送优先级通告。MASTER默认每1秒发送一次VRRP Advertisement,BACKUP在3个通告周期(3秒)内未收到MASTER通告时,自动接管VIP。

Keepalived安装与VRRP协议配置

在主备两台服务器上分别安装Keepalived:

# 安装Keepalived
dnf install -y keepalived

# 确认内核加载VRRP模块
modprobe vrrp
lsmod | grep vrrp

主服务器(MASTER)配置文件 /etc/keepalived/keepalived.conf

global_defs {
    router_id NGINX_HA_MASTER
    enable_script_security
    script_user root
}

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    weight -20
    fall 2
    rise 1
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass YourVrrpPass2026
    }

    virtual_ipaddress {
        192.168.1.100/24 dev eth0
    }

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

备服务器(BACKUP)配置文件:

global_defs {
    router_id NGINX_HA_BACKUP
    enable_script_security
    script_user root
}

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    weight -20
    fall 2
    rise 1
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 90
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass YourVrrpPass2026
    }

    virtual_ipaddress {
        192.168.1.100/24 dev eth0
    }

    track_script {
        check_nginx
    }

    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
}

关键参数说明:

  • priority:MASTER设为100,BACKUP设为90,差值需大于weight调整值
  • weight -20:检测脚本失败时优先级减20,MASTER降为80低于BACKUP的90,触发切换
  • virtual_router_id:主备必须一致,同一网段内不同VRRP实例必须唯一
  • fall 2:连续2次检测失败才判定为故障,避免网络抖动误判

Nginx健康检查脚本编写与负载均衡配置

Nginx健康检查脚本 /etc/keepalived/check_nginx.sh

#!/bin/bash
# 检查Nginx进程存活状态
if ! pidof nginx > /dev/null 2>&1; then
    # 尝试重启Nginx
    systemctl restart nginx
    sleep 2
    if ! pidof nginx > /dev/null 2>&1; then
        echo "$(date) - Nginx is DOWN" >> /var/log/keepalived-check.log
        exit 1
    fi
fi

# 检查Nginx端口可用性
if ! curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:80 | grep -q '200\|301\|302'; then
    echo "$(date) - Nginx port check failed" >> /var/log/keepalived-check.log
    exit 1
fi

exit 0
chmod +x /etc/keepalived/check_nginx.sh

Nginx负载均衡配置 /etc/nginx/conf.d/load-balancer.conf

upstream backend_servers {
    # 后端应用服务器池
    server 192.168.1.20:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.21:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.22:8080 weight=1 max_fails=3 fail_timeout=30s;

    # 备用服务器,所有主服务器故障时启用
    server 192.168.1.23:8080 backup;

    keepalive 32;
    keepalive_timeout 60s;
}

server {
    listen 80;
    server_name 192.168.1.100;

    # 健康检查端点
    location /health {
        access_log off;
        return 200 "OK\n";
    }

    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_read_timeout 60s;
        proxy_send_timeout 60s;

        proxy_next_upstream error timeout http_502 http_503 http_504;
        proxy_next_upstream_tries 3;
    }
}

故障切换测试与脑裂防护验证

启动服务并验证初始状态:

# 主服务器启动
systemctl enable --now keepalived
systemctl enable --now nginx

# 查看VIP绑定状态
ip addr show eth0 | grep 192.168.1.100
# 输出: inet 192.168.1.100/24 scope global secondary eth0

# 查看VRRP状态
journalctl -u keepalived -f
# 输出: Entering MASTER STATE

模拟主服务器Nginx故障,验证切换过程:

# 在主服务器上停止Nginx
systemctl stop nginx

# 2秒后检查脚本检测到故障(check_nginx.sh重启失败)
# 4秒后Keepalived将优先级从100降为80
# BACKUP(90) > MASTER(80),触发VIP切换

# 在备服务器上验证VIP已接管
ip addr show eth0 | grep 192.168.1.100
# 输出: inet 192.168.1.100/24 scope global secondary eth0

# 在主服务器上查看状态变更
journalctl -u keepalived --since "1 min ago"
# 输出: VRRP_Instance(VI_1) Entering BACKUP STATE

脑裂(Split-Brain)防护是高可用集群的关键风险点。当主备之间的网络中断但两台服务器均正常运行时,双方都无法收到对方的VRRP通告,导致同时持有VIP。防护方案:

# 方案1:使用串口线作为备用心跳通道
vrrp_instance VI_1 {
    # ...
    unicast_src_ip 192.168.1.10
    unicast_peer {
        192.168.1.11
    }
}

# 方案2:仲裁脚本检测网关可达性
vrrp_script check_gateway {
    script "ping -c 2 -W 1 192.168.1.1 > /dev/null 2>&1"
    interval 2
    weight -30
    fall 2
}

# 方案3:fencing机制 - 检测到脑裂时强制关机
notify_fault "/etc/keepalived/fence.sh"

服务器高可用集群生产环境加固清单

防火墙需放行VRRP协议和Nginx端口:

firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload

SELinux策略调整,避免Keepalived执行脚本被拦截:

setsebool -P keepalived_connect_any 1
audit2allow -a -M keepalived_custom
semodule -i keepalived_custom.pp

日志集中收集与告警通知脚本 /etc/keepalived/notify.sh

#!/bin/bash
STATE=$1
HOSTNAME=$(hostname)
VIP="192.168.1.100"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

MESSAGE="${TIMESTAMP} - ${HOSTNAME} VRRP状态变更: ${STATE} (VIP: ${VIP})"

# 写入日志
echo "$MESSAGE" >> /var/log/keepalived-notify.log

# 发送WebHook告警
curl -s -X POST "https://alert.example.com/api/webhook" \
    -H "Content-Type: application/json" \
    -d "{"text": "$MESSAGE", "priority": "critical"}"

# 邮件通知
echo "$MESSAGE" | mail -s "HA集群告警: ${HOSTNAME} -> ${STATE}" ops@yunthe.com

切换通知脚本需配合企业IM(钉钉/飞书)WebHook实现即时告警,确保运维团队在30秒内感知故障切换事件。定期进行混沌测试——每月模拟一次主服务器宕机、网络分区、Nginx进程崩溃场景,验证RTO(恢复时间目标)是否在5秒以内。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-gao-ke-yong-ji-qun-da-jian-jiao-cheng-keepalivednginx/

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

相关推荐