從原理到實操:基于 Keepalived 的 Nginx/HAProxy 高可用部署指南
前言
在互聯網架構中,負載均衡器(如 Nginx、HAProxy)是流量入口的核心組件,一旦單點故障將導致整個服務不可用。Keepalived基于VRRP(虛擬路由冗余協議)實現節點高可用,可與Nginx/HAProxy結合,構建負載均衡 + 故障自動切換的高可用架構。
核心概念
組件 | 核心作用 |
Keepalived | 基于 VRRP 協議,實現主備節點的 “虛擬 IP(VIP)” 漂移,完成故障自動切換 |
Nginx | 七層(HTTP/HTTPS)負載均衡器,支持反向代理、靜態資源緩存、SSL 終止等功能 |
HAProxy | 四層(TCP)/ 七層負載均衡器,支持會話保持、健康檢查、高并發場景,性能更優 |
VIP(虛擬 IP) | 對外提供服務的統一 IP 地址,主節點故障時自動切換到備節點,對業務無感知 |
VRRP 協議工作原理
圖片
VRRP 協議通過主備節點選舉實現IP冗余:
- 主節點(
Master):正常情況下持有VIP,對外提供服務,并定期向備節點發送VRRP通告報文(默認每1秒一次),告知自身狀態; - 備節點(
Backup):監聽主節點的通告報文,若超時(默認3秒)未收到,則認為主節點故障,自動升級為新主節點,搶占VIP; - 故障恢復:原主節點恢復后,根據優先級(默認主節點優先級更高)重新搶占
VIP,恢復主節點身份(可配置非搶占模式避免頻繁切換)。
部署配置
以一主一備架構為例(生產環境推薦2節點以上),拓撲如下:
[客戶端] → [VIP: 192.168.1.100]
↓(自動切換)
┌──────────────┐ ┌──────────────┐
│ 主節點(Master) │ │ 備節點(Backup) │
│ IP: 192.168.1.11 │ │ IP: 192.168.1.12 │
│ Keepalived + Nginx/HAProxy │ │ Keepalived + Nginx/HAProxy │
└──────────────┘ └──────────────┘
↓(負載均衡)
┌──────────────┐ ┌──────────────┐
│ 后端 Web 節點1 │ │ 后端 Web 節點2 │
│ IP: 192.168.1.21 │ │ IP: 192.168.1.22 │
└──────────────┘ └──────────────┘- 正常狀態:主節點持有
VIP,客戶端流量通過VIP進入主節點的Nginx/HAProxy,再轉發到后端Web節點; - 故障狀態:主節點宕機或負載均衡服務異常,備節點搶占
VIP,流量自動切換到備節點,業務無感知。
準備與規劃
節點角色 | IP 地址 | 安裝軟件 |
主節點(Master) | 192.168.1.11 | Keepalived + Nginx/HAProxy |
備節點(Backup) | 192.168.1.12 | Keepalived + Nginx/HAProxy |
虛擬 IP(VIP) | 192.168.1.100 | |
后端 Web 節點 1 | 192.168.1.21 | Nginx/Apache |
后端 Web 節點 2 | 192.168.1.22 | Nginx/Apache |
前置操作(所有節點)
# 關閉防火墻(CentOS 7)
systemctl stop firewalld && systemctl disable firewalld
# 關閉 SELINUX
setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/configKeepalived +Nginx/HAProxy安裝過程略,下面只進行配置講解
配置主節點(Master)Keepalived
! Configuration File for keepalived
global_defs {
router_id LVS_MASTER # 節點標識,主備需不同(如備節點設為 LVS_BACKUP)
}
# 健康檢查腳本:檢測 Nginx/HAProxy 是否存活,若服務停則觸發切換
vrrp_script check_lb {
script "/etc/keepalived/check_lb.sh"# 健康檢查腳本路徑
interval 2 # 檢查間隔(秒)
weight -20 # 若腳本返回失敗,節點優先級降低 20(確保備節點搶占)
}
vrrp_instance VI_1 {
state MASTER # 節點角色:MASTER(主)/BACKUP(備)
interface eth0 # 綁定 VIP 的網卡(需與實際網卡一致,用 ip addr 查看)
virtual_router_id 51 # 虛擬路由 ID,主備必須相同(0-255)
priority 100 # 優先級:主節點 > 備節點(如備節點設為 90)
advert_int 1 # VRRP 通告間隔(秒),主備需一致
# 認證配置:主備必須相同,防止非法節點接入
authentication {
auth_type PASS
auth_pass 1111 # 密碼(1-8 位)
}
# 虛擬 IP(VIP):可配置多個,用空格分隔
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:0 # 網卡別名,便于識別
}
# 調用健康檢查腳本
track_script {
check_lb
}
}配置備節點(Backup)Keepalived
備節點配置與主節點類似,僅需修改3處參數:
global_defs {
router_id LVS_BACKUP # 與主節點不同
}
vrrp_instance VI_1 {
state BACKUP # 角色為備節點
priority 90 # 優先級低于主節點(100)
# 其他參數(virtual_router_id、auth_pass、VIP 等)與主節點完全一致
}編寫健康檢查腳本
檢測負載均衡服務(以Nginx為例,HAProxy只需替換服務名):
#!/bin/bash
# 檢查 Nginx 進程是否存在
if ! ps aux | grep nginx | grep -v grep > /dev/null; then
# 嘗試重啟 Nginx(若重啟失敗則觸發切換)
systemctl start nginx
sleep 2
# 再次檢查,若仍失敗則停止 Keepalived(釋放 VIP)
if ! ps aux | grep nginx | grep -v grep > /dev/null; then
systemctl stop keepalived
fi
fi配置 Nginx 反向代理
# 定義后端 Web 節點池(weight 為權重,值越大分配到的流量越多)
upstream web_servers {
server 192.168.1.21:80 weight=1;
server 192.168.1.22:80 weight=1;
# 可選配置:故障重試、超時時間
keepalive 32; # 長連接數
proxy_next_upstream error timeout invalid_header;
}
# 配置反向代理
server {
listen 80;
server_name localhost; # 若有域名,可替換為實際域名(如 www.example.com)
location / {
proxy_pass http://web_servers; # 轉發到后端節點池
# 傳遞客戶端真實 IP 及請求頭
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}配置 HAProxy 四層負載均衡(以 TCP 為例)
global
log 127.0.0.1 local2 # 日志配置
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000 # 最大并發連接數
user haproxy
group haproxy
daemon # 后臺運行
defaults
mode tcp # 模式:tcp(四層)/http(七層)
log global
option tcplog
option dontlognull
retries 3 # 故障重試次數
timeout connect 5000ms # 連接超時
timeout client 50000ms # 客戶端超時
timeout server 50000ms # 服務端超時
# 前端監聽配置(監聽 VIP 的 80 端口)
frontend http_front
bind *:80
default_backend http_back # 轉發到后端節點池
# 后端節點池配置
backend http_back
balance roundrobin # 負載均衡算法:輪詢(roundrobin)/權重(static-rr)
server web1 192.168.1.21:80 check inter 2000 rise 2 fall 3 # check 啟用健康檢查
server web2 192.168.1.22:80 check inter 2000 rise 2 fall 3主節點故障切換測試
- 模擬主節點服務故障:在主節點(
192.168.1.11)停止Nginx/HAProxy服務 - 觀察
VIP漂移:在備節點(192.168.1.12)執行ip addr show eth0,若出現192.168.1.100(VIP),說明漂移成功; - 驗證業務連續性:客戶端再次訪問
192.168.1.100,若仍能正常訪問,說明故障切換生效(業務無感知)。
補充說明
virtual_server
virtual_server是Keepalived中LVS模塊的核心配置項,它的作用是:
- 在
Keepalived節點上直接實現 四層(TCP/UDP)負載均衡,將客戶端請求通過VIP轉發到后端真實服務器(Real Server),無需依賴Nginx/HAProxy等第三方負載均衡軟件。
! 基于 Keepalived + LVS 的配置(無需 Nginx/HAProxy)
global_defs {
router_id LVS_MASTER
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:0 # VIP
}
}
# 關鍵:配置 virtual_server(LVS 負載均衡規則)
virtual_server 192.168.1.100 80 { # VIP + 監聽端口(80 端口)
delay_loop 6 # 健康檢查間隔(秒)
lb_algo rr # 負載均衡算法:rr(輪詢)、wrr(權重輪詢)等
lb_kind DR # LVS 模式:DR(直接路由)、NAT、TUN(隧道)
persistence_timeout 50 # 會話保持時間(秒)
# 后端真實服務器(Real Server)
real_server 192.168.1.21 80 {
weight 1 # 權重
TCP_CHECK { # 健康檢查(TCP 端口檢測)
connect_timeout 3
retry 3
delay_before_retry 3
}
}
real_server 192.168.1.22 80 {
weight 1
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}

























