生產環境中非常經典和推薦的高可用負載均衡架構!
這種架構被稱為 “雙機熱備” 模式,通過 Keepalived 實現虛擬 IP(VIP)的故障自動切換,同時由 Nginx 實現後端 Web 服務器的負載均衡。
架構 overview
你將擁有兩台負載均衡服務器:
-
LB01 (主節點):
10.0.0.8 -
LB02 (備節點):
10.0.0.9 -
虛擬 IP (VIP):
10.0.0.100(這是對外提供服務的 IP) -
後端 Web 服務器:
- Web01:
10.0.0.11 - Web02:
10.0.0.12
- Web01:
工作流程:
- 正常情況下,
Keepalived在 LB01 上處於MASTER狀態,將10.0.0.100這個 VIP 綁定在 LB01 的網卡上。 - 用户通過
http://10.0.0.100訪問服務,流量全部進入 LB01。 - LB01 上的
Nginx作為反向代理,將請求負載均衡到後端的 Web01 和 Web02。 - 如果 LB01 發生故障(如服務器宕機、Nginx 停掉),
Keepalived會檢測到失敗。 Keepalived自動在 LB02 上切換到MASTER狀態,並將 VIP10.0.0.100綁定到 LB02 的網卡上。- 用户流量無縫切換到 LB02,由 LB02 上的
Nginx繼續提供負載均衡服務,整個過程對用户透明。
配置步驟
前提條件
- 在 LB01 和 LB02 上都安裝了
Nginx和Keepalived。sudo yum install -y nginx keepalived # CentOS/RHEL # sudo apt install -y nginx keepalived # Ubuntu/Debian - 確保後端 Web 服務器(10.0.0.11, 10.0.0.12)上的 Web 服務正常運行,並且 LB 服務器可以訪問它們的 80 端口。
- 關閉或配置防火牆,允許 VRRP 協議(
keepalived使用)和 HTTP/HTTPS 流量。# 允許 VRRP (默認使用協議號 112) sudo firewall-cmd --add-protocol=vrrp --permanent sudo firewall-cmd --add-port=80/tcp --permanent sudo firewall-cmd --add-port=443/tcp --permanent sudo firewall-cmd --reload
1. 配置 Nginx (在 LB01 和 LB02 上完全相同)
Nginx 的配置主要是定義一個** upstream 塊,列出後端 Web 服務器,然後在 server 塊中通過 proxy_pass **將請求轉發到這個 upstream。
-
編輯 Nginx 配置文件:
sudo vim /etc/nginx/nginx.conf -
在
http塊內添加以下配置:http { # ... 其他已有配置 ... # 定義後端 Web 服務器集羣 upstream backend_servers { server 10.0.0.11 weight=1; # Web01, weight 表示權重 server 10.0.0.12 weight=1; # Web02 # 可以添加更多 server ... # server 10.0.0.13 backup; # 備份服務器,只有主服務器都故障時才啓用 } # 定義負載均衡的虛擬主機 server { listen 80; server_name _; # 或者你的域名,如 www.example.com # 訪問日誌 access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location / { # 將請求轉發到後端服務器集羣 proxy_pass http://backend_servers; # 以下是一些推薦的 proxy 配置 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; } } # ... 其他已有配置 ... } -
檢查配置並重啓 Nginx:
sudo nginx -t sudo systemctl restart nginx sudo systemctl enable nginx
注意:LB01 和 LB02 上的 Nginx 配置必須一模一樣,這樣切換後服務才能無縫銜接。
2. 配置 Keepalived
Keepalived 的配置在主備節點上略有不同。核心是 state、priority 和 authentication 這幾個字段。
在 LB01 (主節點, 10.0.0.8) 上
-
編輯 Keepalived 配置文件:
sudo vim /etc/keepalived/keepalived.conf -
寫入以下配置:
! Configuration File for keepalived global_defs { notification_email { admin@example.com # 發生故障時發送郵件通知的地址 } notification_email_from keepalived@example.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL # 標識此節點的字符串,通常無需修改 } # 定義一個 VRRP 實例 vrrp_instance VI_1 { state MASTER # 標識此節點為主節點 interface eth0 # 綁定 VIP 的網卡名稱,請根據你的實際情況修改 virtual_router_id 51 # 虛擬路由 ID,主備節點必須相同 priority 100 # 優先級,主節點要高於備節點 advert_int 1 # 心跳通告間隔,單位秒 # 認證信息,主備節點必須相同 authentication { auth_type PASS auth_pass 1111 } # 虛擬 IP 地址,可以配置多個 virtual_ipaddress { 10.0.0.100/24 # VIP 及其子網掩碼 } }
在 LB02 (備節點, 10.0.0.9) 上
-
編輯 Keepalived 配置文件:
sudo vim /etc/keepalived/keepalived.conf -
寫入以下配置(注意與主節點的區別):
! Configuration File for keepalived global_defs { notification_email { admin@example.com } notification_email_from keepalived@example.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { state BACKUP # 標識此節點為備節點 interface eth0 # 同樣,確保網卡名稱正確 virtual_router_id 51 # 必須與主節點相同 priority 90 # 優先級,必須低於主節點 advert_int 1 authentication { auth_type PASS auth_pass 1111 # 必須與主節點相同 } virtual_ipaddress { 10.0.0.100/24 # 必須與主節點相同 } }
關鍵差異點:
state: 一個是MASTER,另一個是BACKUP。priority:MASTER的優先級(100)高於BACKUP(90)。
- 在兩台服務器上都啓動並設置 Keepalived 開機自啓:
sudo systemctl restart keepalived sudo systemctl enable keepalived
3. 測試與驗證
-
檢查 VIP 綁定: 在 LB01 上執行
ip addr,你應該能看到10.0.0.100已經綁定在eth0網卡上。 在 LB02 上執行ip addr,此時應該看不到10.0.0.100。 -
訪問測試: 在瀏覽器或另一台機器上訪問
http://10.0.0.100,應該能看到後端 Web 服務器的頁面。 你可以查看 Nginx 日誌(/var/log/nginx/access.log)來確認請求是否被負載均衡到了不同的 Web 節點。 -
故障切換測試:
- 在 LB01 上停止 Keepalived 或 Nginx 服務來模擬故障:
sudo systemctl stop keepalived # 或者 sudo systemctl stop nginx - 立即在 LB02 上執行
ip addr,你會發現10.0.0.100已經自動綁定到了 LB02 的eth0上。 - 再次訪問
http://10.0.0.100,服務應該依然可用,沒有中斷。
- 在 LB01 上停止 Keepalived 或 Nginx 服務來模擬故障:
-
恢復測試:
- 在 LB01 上重新啓動服務:
sudo systemctl start keepalived # 或者 sudo systemctl start nginx - 由於 LB01 的優先級更高,它會重新成為主節點。在 LB01 上執行
ip addr,10.0.0.100會“漂移”回來。(這個行為取決於nopreempt配置,默認是會搶佔的)。
- 在 LB01 上重新啓動服務:
至此,你已經成功搭建了一個高可用的負載均衡集羣!