生產環境中非常經典和推薦的高可用負載均衡架構!

這種架構被稱為 “雙機熱備” 模式,通過 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

工作流程

  1. 正常情況下,Keepalived 在 LB01 上處於 MASTER 狀態,將 10.0.0.100 這個 VIP 綁定在 LB01 的網卡上。
  2. 用户通過 http://10.0.0.100 訪問服務,流量全部進入 LB01。
  3. LB01 上的 Nginx 作為反向代理,將請求負載均衡到後端的 Web01 和 Web02。
  4. 如果 LB01 發生故障(如服務器宕機、Nginx 停掉),Keepalived 會檢測到失敗。
  5. Keepalived 自動在 LB02 上切換到 MASTER 狀態,並將 VIP 10.0.0.100 綁定到 LB02 的網卡上。
  6. 用户流量無縫切換到 LB02,由 LB02 上的 Nginx 繼續提供負載均衡服務,整個過程對用户透明。

配置步驟

前提條件

  1. 在 LB01 和 LB02 上都安裝了 NginxKeepalived
    sudo yum install -y nginx keepalived # CentOS/RHEL
    # sudo apt install -y nginx keepalived # Ubuntu/Debian
    
  2. 確保後端 Web 服務器(10.0.0.11, 10.0.0.12)上的 Web 服務正常運行,並且 LB 服務器可以訪問它們的 80 端口。
  3. 關閉或配置防火牆,允許 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。

  1. 編輯 Nginx 配置文件:

    sudo vim /etc/nginx/nginx.conf
    
  2. 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;
            }
        }
    
        # ... 其他已有配置 ...
    }
    
  3. 檢查配置並重啓 Nginx:

    sudo nginx -t
    sudo systemctl restart nginx
    sudo systemctl enable nginx
    

注意:LB01 和 LB02 上的 Nginx 配置必須一模一樣,這樣切換後服務才能無縫銜接。


2. 配置 Keepalived

Keepalived 的配置在主備節點上略有不同。核心是 statepriorityauthentication 這幾個字段。

在 LB01 (主節點, 10.0.0.8) 上

  1. 編輯 Keepalived 配置文件:

    sudo vim /etc/keepalived/keepalived.conf
    
  2. 寫入以下配置:

    ! 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) 上

  1. 編輯 Keepalived 配置文件:

    sudo vim /etc/keepalived/keepalived.conf
    
  2. 寫入以下配置(注意與主節點的區別):

    ! 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)。
  1. 在兩台服務器上都啓動並設置 Keepalived 開機自啓:
    sudo systemctl restart keepalived
    sudo systemctl enable keepalived
    

3. 測試與驗證

  1. 檢查 VIP 綁定: 在 LB01 上執行 ip addr,你應該能看到 10.0.0.100 已經綁定在 eth0 網卡上。 在 LB02 上執行 ip addr,此時應該看不到 10.0.0.100

  2. 訪問測試: 在瀏覽器或另一台機器上訪問 http://10.0.0.100,應該能看到後端 Web 服務器的頁面。 你可以查看 Nginx 日誌(/var/log/nginx/access.log)來確認請求是否被負載均衡到了不同的 Web 節點。

  3. 故障切換測試

    • 在 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,服務應該依然可用,沒有中斷。
  4. 恢復測試

    • 在 LB01 上重新啓動服務:
      sudo systemctl start keepalived
      # 或者 sudo systemctl start nginx
      
    • 由於 LB01 的優先級更高,它會重新成為主節點。在 LB01 上執行 ip addr10.0.0.100 會“漂移”回來。(這個行為取決於 nopreempt 配置,默認是會搶佔的)。

至此,你已經成功搭建了一個高可用的負載均衡集羣!