Skip to content

综合实战

Keepalived + HAProxy + Nginx 这种双入口结构,关键在两件事:VIP 能在入口节点之间漂移,备用入口本身也能独立代理后端。验证时同时看 VIP 所在节点、HTTP 访问结果和后端健康状态。

一、示例架构

这次用 Keepalived + HAProxy + Nginx 后端做示例。LVS 也能放在这个位置,但 HAProxy 更容易观察后端状态和 HTTP 健康检查。

组件分工:

组件作用
Keepalived让 VIP 在 lb01/lb02 之间漂移
HAProxy接收 VIP 流量,转发到后端 Web
Nginx 后端提供 HTTP 服务和健康检查接口
VIP客户端访问入口

我个人会先用这种结构练清楚入口 HA,再上更复杂的多机房、多层网关。单机房双入口能稳定切换,后面的架构才有基础。

二、后端 Web 准备

web01:

bash
yum install -y nginx
systemctl enable --now nginx

# index 内容写成节点名,后面访问 VIP 时方便确认轮询到了哪台机器
cat > /usr/share/nginx/html/index.html <<'EOF'
web01
EOF

# /health 用作 HAProxy 健康检查,保持轻量,返回 200 即可
cat > /usr/share/nginx/html/health <<'EOF'
ok
EOF

web02:

bash
yum install -y nginx
systemctl enable --now nginx

# index 内容写成节点名,后面访问 VIP 时方便确认轮询到了哪台机器
cat > /usr/share/nginx/html/index.html <<'EOF'
web02
EOF

# /health 用作 HAProxy 健康检查,保持轻量,返回 200 即可
cat > /usr/share/nginx/html/health <<'EOF'
ok
EOF

验证:

bash
curl http://192.168.10.21/
curl http://192.168.10.22/
curl -f http://192.168.10.21/health
curl -f http://192.168.10.22/health

健康检查接口先保持简单,返回 200 就够。后面如果要检查数据库、Redis、磁盘空间,需要控制耗时和失败策略。

三、HAProxy 配置

lb01 和 lb02 使用同一份 HAProxy 配置:

haproxy
# /etc/haproxy/haproxy.cfg
global
    log 127.0.0.1 local2
    maxconn 10000
    daemon

defaults
    mode http
    log global
    option httplog
    option dontlognull
    option forwardfor
    timeout connect 3s
    timeout client  30s
    timeout server  30s

frontend web_entry
    bind *:80
    default_backend web_backend

backend web_backend
    balance roundrobin
    option httpchk GET /health
    http-check expect status 200
    server web01 192.168.10.21:80 check inter 2s fall 3 rise 2
    server web02 192.168.10.22:80 check inter 2s fall 3 rise 2

listen stats
    bind *:8404
    mode http
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:strong_password_here

option forwardfor 会把客户端 IP 追加到 X-Forwarded-For。后端 Nginx 或应用要按可信代理范围解析这个头,不能直接相信客户端自己传来的同名 Header。

启动:

bash
yum install -y haproxy
haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl enable --now haproxy

验证:

bash
curl http://192.168.10.11/
curl http://192.168.10.12/

HAProxy 两台机器都要能独立转发后端。Keepalived 只是决定 VIP 在谁身上,如果 standby 的 HAProxy 本身不可用,切过去也没有意义。

stats 示例为了实验方便监听 *:8404。生产里这个端口通常只放给管理网段,或者绑定到管理 IP,并配合防火墙限制来源。

四、Keepalived 配置

lb01:

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

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

    garp_master_delay 1
    garp_master_repeat 5

    authentication {
        auth_type PASS
        auth_pass 12345678
    }

    track_script {
        chk_haproxy
    }

    virtual_ipaddress {
        192.168.10.100/24 dev eth0
    }
}

lb02:

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

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

    garp_master_delay 1
    garp_master_repeat 5

    authentication {
        auth_type PASS
        auth_pass 12345678
    }

    track_script {
        chk_haproxy
    }

    virtual_ipaddress {
        192.168.10.100/24 dev eth0
    }
}

如果所在网络不支持 VRRP 组播,可以把 lb01/lb02 改成单播 peer。实验环境可以使用默认组播,出现“两台都有 VIP”时再重点看 VRRP 报文和防火墙。

检查脚本,两台都一样:

bash
# /etc/keepalived/check_haproxy.sh
#!/bin/bash
set -euo pipefail

pidof haproxy >/dev/null
ss -lntp | grep -q ':80'  # HAProxy 进程存在且入口端口仍在监听

授权并启动:

bash
chmod +x /etc/keepalived/check_haproxy.sh
yum install -y keepalived
systemctl enable --now keepalived

查看 VIP:

bash
ip addr show dev eth0 | grep 192.168.10.100

五、访问验证

从客户端访问 VIP:

bash
curl http://192.168.10.100/
curl http://192.168.10.100/
curl http://192.168.10.100/

正常会在 web01web02 之间轮询。也可以看 HAProxy stats:

text
http://192.168.10.100:8404/stats

基本检查项:

检查项命令
VIP 在哪台ip addr show dev eth0
HAProxy 是否监听`ss -lntp
后端是否健康HAProxy stats、curl /health
Keepalived 日志journalctl -u keepalived
HAProxy 日志/var/log/haproxy.log

六、后端故障演练

停止 web01:

bash
systemctl stop nginx

观察 HAProxy:

bash
curl http://192.168.10.100/

HAProxy stats 里 web01 应该变成 DOWN,流量只到 web02。恢复:

bash
systemctl start nginx
curl -f http://192.168.10.21/health

这里看的是后端摘除和恢复。VIP 不会漂,因为入口 HAProxy 没坏。

七、入口故障演练

在当前持有 VIP 的 lb01 上停止 HAProxy:

bash
systemctl stop haproxy

Keepalived 脚本失败后,lb01 优先级下降,VIP 应该漂到 lb02。

检查:

bash
# lb01/lb02 上分别执行
ip addr show dev eth0 | grep 192.168.10.100
journalctl -u keepalived -n 50 --no-pager

客户端验证:

bash
curl http://192.168.10.100/

恢复 lb01:

bash
systemctl start haproxy

如果配置允许抢占,VIP 可能漂回 lb01;如果配置了 nopreempt,VIP 会留在 lb02。生产演练时要提前知道是哪种行为,不然恢复动作本身会造成第二次切换。

八、常见故障现场

现象检查方向
VIP 能 ping,HTTP 不通VIP 所在机器 HAProxy 是否监听
VIP 不在任何机器Keepalived 配置、网卡名、服务状态
两台都有 VIPVRRP 包不通、防火墙、同组配置冲突
HAProxy 全部后端 DOWN健康检查路径、后端防火墙、状态码
切换后业务仍失败standby 上 HAProxy 配置或后端网络不同
客户端短暂失败ARP 更新、连接重建、应用重试

切换后除了看 VIP,还要访问一次业务路径。入口高可用的最终检查不是“VIP 漂了”,而是客户端请求能重新打到健康后端。

九、上线记录

上线前记录:

项目内容
VIP地址、网卡、网段
lb 节点主备 IP、优先级、是否抢占
后端列表IP、端口、健康检查路径
防火墙客户端到 VIP、lb 到后端、VRRP
日志HAProxy、Keepalived、后端 access log
回滚方式停止 keepalived、移除 VIP、恢复旧入口

变更时我会先验证 standby 入口能独立代理,再切 VIP。很多 HA 故障不是切换机制坏了,而是备用节点的配置、证书、路由或防火墙和主节点不一致。