Appearance
综合实战
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
EOFweb02:
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_hereoption 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/正常会在 web01 和 web02 之间轮询。也可以看 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 haproxyKeepalived 脚本失败后,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 配置、网卡名、服务状态 |
| 两台都有 VIP | VRRP 包不通、防火墙、同组配置冲突 |
| HAProxy 全部后端 DOWN | 健康检查路径、后端防火墙、状态码 |
| 切换后业务仍失败 | standby 上 HAProxy 配置或后端网络不同 |
| 客户端短暂失败 | ARP 更新、连接重建、应用重试 |
切换后除了看 VIP,还要访问一次业务路径。入口高可用的最终检查不是“VIP 漂了”,而是客户端请求能重新打到健康后端。
九、上线记录
上线前记录:
| 项目 | 内容 |
|---|---|
| VIP | 地址、网卡、网段 |
| lb 节点 | 主备 IP、优先级、是否抢占 |
| 后端列表 | IP、端口、健康检查路径 |
| 防火墙 | 客户端到 VIP、lb 到后端、VRRP |
| 日志 | HAProxy、Keepalived、后端 access log |
| 回滚方式 | 停止 keepalived、移除 VIP、恢复旧入口 |
变更时我会先验证 standby 入口能独立代理,再切 VIP。很多 HA 故障不是切换机制坏了,而是备用节点的配置、证书、路由或防火墙和主节点不一致。