Keepalived簡介
?Keepalived? 是一個基于 ?VRRP(Virtual Router Redundancy Protocol)協議?的高可用性解決方案,主要用于實現?服務故障自動切換(Failover)和負載均衡?。通過管理虛擬 IP(VIP)和健康檢查機制,確保關鍵服務在服務器故障時快速恢復,提升系統可用性。
Keepalived 實現 Nginx 的高可用示意圖如下:
用戶由初始的訪問 Nginx 服務器改為訪問虛擬 IP,由虛擬 IP 指定 Nginx 服務器
Keepalived 的優缺點
2.1 優點
1)?部署簡單,配置靈活?
通過單一配置文件或結合簡單腳本即可完成主備切換和健康檢查配置;
支持主從(Master-Backup)和主主(Master-Master)模式,適應不同場景需求;
2)高可用性保障?
基于 ?VRRP 協議?實現秒級故障切換,確保服務的連續性?;
支持多種健康檢查方式(腳本、TCP/UDP 端口、HTTP/HTTPS 請求),靈活監控服務狀態;
3)?輕量級且資源占用低?
核心進程僅管理虛擬 IP 和健康檢查,對系統資源消耗較小?;
開源免費,無額外成本;
4)兼容性?好
支持對 ?Nginx、HAProxy、MySQL? 等多種服務的高可用管理?;
可與 ?LVS? 結合實現高可用負載均衡架構;
2.2 缺點
1)?資源利用率低?
主備模式下,備用節點長期處于空閑狀態,造成資源浪費?;
需額外工具(如 LVS)實現負載均衡,無法單獨擴展服務容量;
2)?腦裂(Split-Brain)風險?
若主備節點間網絡不穩定,可能導致雙方同時持有 VIP,引發服務沖突?;
需通過第三方仲裁或強制優先級配置降低腦裂概率?;
3)?網絡依賴性強?
依賴組播/單播通信,若防火墻未放行 VRRP 協議(IP 協議號 112),會導致心跳檢測失敗?;
組播模式配置簡單但易受網絡波動影響,單播更穩定但需手動指定節點 IP?;對于云服務器,部分云廠商(如阿里云、AWS、騰訊云)需提前申請虛擬IP并綁定到實例,且需要啟用單播通信;
4)?功能局限性?
僅提供四層(傳輸層)高可用,無法處理七層(應用層)流量調度?;
復雜場景需結合其他工具(如 Nginx、HAProxy)實現完整解決方案?;
5)性能瓶頸?
大規模并發場景下,單節點 Keepalived 可能成為性能瓶頸,需集群化部署或結合云服務優化?;
Keepalived 安裝
1)CentOS
yum install keepalived -y
2)Ubuntu
apt-get install keepalived -y
Keepalived 配置
Keepalived 的安裝目錄為 /etc/keepalived,自帶默認的配置文件 keepalived.conf。
keepalived.conf 的配置項如下:
4.1 global_defs 全局配置
global_defs 是 Keepalived 的全局配置塊,用于定義全局參數。
- log_file:指定日志路徑
log_file syslog,輸出到syslog
- router_id:標識當前 Keepalived 節點的唯一名稱,用于區分集群中的不同節點
- notification_email:定義接收告警通知的郵箱列表(需與 smtp 配置配合使用)
global_defs {notification_email {ops@example.com # 郵箱}
}
- notification_email_from:設置發送告警郵件的發件人郵箱
- smtp_server、smtp_port:指定 SMTP 服務器地址和端口,用于發送郵件通知。?默認端口為25
- smtp_connect_timeout:設置 SMTP 服務器連接超時時間(單位:秒)。默認為30秒
- enable_script_security:控制是否允許腳本中調用外部程序(如 systemctl 等)。建議開啟(設置為 true),避免惡意腳本執行
- lvs_flush:Keepalived 停止時是否自動清理 LVS(負載均衡)規則。默認為true
- vrrp_garp_interval:控制 ?Gratuitous ARP(免費ARP)? 的發送間隔(單位:秒)。默認值為0,表示單次切換僅發送 5 個 GARP 報文,間隔 200ms
當主備切換時,新的 Master 節點會廣播 GARP 報文,更新網絡中其他設備的 ARP 緩存,確保流量指向新主節點。
若網絡設備 ARP 緩存刷新慢,可增大發送頻率(如 vrrp_garp_interval 3,每3秒發送一次GARP)
- vrrp_gna_interval:控制 ?IPv6 Gratuitous Neighbor Advertisement(免費鄰居通告)? 的發送間隔(單位:秒)。功能類似 vrrp_garp_interval,但用于 IPv6 環境
- vrrp_skip_check_adv_addr:是否跳過對收到的 VRRP 廣告報文源 IP 地址的校驗。默認校驗源 IP 是否屬于當前 VRRP 實例的網段,若不屬于則丟棄報文。
當 VRRP 報文通過隧道或復雜路由傳遞時,源 IP 可能不匹配,需設為 on 跳過檢查。可能接收非法 VRRP 報文,導致腦裂
- vrrp_strict:啟用嚴格模式,強制遵守 VRRP 協議規范。校驗 VRRP 報文版本、校驗和等。若與不支持嚴格模式的設備互通,需設為 off
4.2 vrrp_instance VRRP實例
- vrrp_instance 是 Keepalived 的核心配置塊,用于定義 ?VRRP 實例?(即虛擬路由器),實現主備節點的狀態切換和虛擬 IP 管理。
- state:定義實例的初始狀態,可選 MASTER(主節點)或 BACKUP(備節點)
所有節點可都設為 BACKUP,通過 priority 參數決定主備角色,避免啟動競爭
- interface:指定綁定 VRRP 實例的物理/虛擬網絡接口
必須與節點實際網卡名稱一致,在 CentOS 中,通過 ip addr 可查看。如 eth0
- virtual_router_id:標識 VRRP 組的唯一 ID(范圍:1-255),同一組的節點必須一致
- priority:定義節點的優先級(范圍:1-254),優先級高的節點成為 MASTER
主節點優先級應高于備節點(如主節點 100,備節點 90)
- virtual_ipaddress:定義虛擬 IP(VIP),支持 IPv4 和 IPv6
對于云服務器,部分云廠商(如阿里云、AWS、騰訊云)需提前申請虛擬IP并綁定到實例,且需要啟用單播通信;
- track_script:引用 vrrp_script 定義的腳本,監控服務健康狀態
若腳本檢測失敗,節點優先級降低,觸發主備切換
- track_interface:監控其他網絡接口狀態,若接口故障,節點優先級降低
- unicast_src_ip 與 unicast_peer:在 ?云環境(禁用組播)? 中使用單播通信
unicast_src_ip:本節點內網 IP
unicast_peer:對端節點內網 IP
- authentication:配置 VRRP 報文認證,支持明文或加密
- nopreempt:禁止優先級高的節點搶占主節點角色,需與 state BACKUP 配合使用
確保主節點故障恢復后不自動切換回來
- preempt_delay:搶占延遲時間(單位:秒),防止網絡抖動導致頻繁切換
4.3 vrrp_script 檢查腳本
vrrp_script 用于定義 ?自定義健康檢查腳本,監控服務或資源的可用性。當檢測失敗時,觸發 VRRP 優先級調整,實現主備切換。
- script:指定健康檢查腳本的路徑或直接嵌入命令
腳本必須有執行權限,返回 0 表示成功,非 0 表示失敗
- interval:定義健康檢查的執行間隔(單位:秒)。根據業務敏感度調整(如 2 秒)
- timeout:設置腳本執行的超時時間(單位:秒),超時視為檢測失敗。默認無超時(需顯式配置)
- weight:調整優先級的權重值
?正值:檢測成功時增加優先級
?負值:檢測失敗時減少優先級
?典型值:±20(需與 priority 配合)
- fall 與 rise:定義觸發狀態變化的連續失敗/成功次數。避免網絡抖動導致誤切換
fall 3:連續 3 次失敗才認為檢測失敗
rise 2:連續 2 次成功才認為檢測恢復
4.4?virtual_server 負載均衡
virtual_server 是 Keepalived 實現 ?四層負載均衡(LVS)? 的核心配置塊,用于定義虛擬服務器、后端真實服務器(Real Server)及負載策略。
- virtual_server <VIP> 與 <Port>:虛擬服務器的 IP 和端口,客戶端通過此地址訪問服務
如:virtual_server 192.168.199.210 80
- delay_loop:健康檢查的時間間隔(單位:秒)。默認為5
- ?lb_algo:負載均衡調度算法
rr:輪詢(Round Robin)
wrr:加權輪詢(Weighted RR)
lc:最少連接(Least Connections)
wlc:加權最少連接(Weighted LC)
sh:源地址哈希(Session Persistence)
- ?lb_kind:定義 LVS 的工作模式
1)NAT:網絡地址轉換(需網關功能)
Director 修改請求報文的目標 IP 和端口(VIP → RIP),并將響應報文的源 IP 改回 VIP
2)DR:直接路由(高性能,需配置回環接口)irector 僅修改請求報文的 MAC 地址,將請求直接轉發給 Real Server
3)TUN:隧道模式(跨機房場景)
通過 IP 隧道封裝請求報文,發送到 Real Server,Real Server 解封裝后直接響應客戶端
?云環境注意:部分云平臺不支持 DR 模式
- persistence_timeout:會話保持時間,同一客戶端請求在一定時間內發往同一 Real Server,單位秒。默認為0。
- protocol:指定協議類型,支持 TCP、UDP、SCTP
- real_server <RIP> 與 <Port>:真實服務器的 IP 和端口
- weight:權重值(僅 wrr/wlc 算法生效),權重越高分配流量越多
- ?TCP_CHECK:TCP 端口連通性健康檢查
- HTTP_GET 或 ?SSL_GET:HTTP/HTTPS 狀態檢查
- ?MISC_CHECK:自定義腳本檢查
Keepalived 與 Nginx 負載均衡的區別
Keepalived 和 Nginx 均可實現負載均衡,但其設計目標、工作層級、功能特性及適用場景有顯著差異。
5.1 Keepalived(LVS)?
1)四層負載均衡:基于 IP 和端口進行流量分發,不解析應用層數據(如 HTTP Header)
2)適用協議:TCP、UDP、SCTP,適合非 HTTP 服務(如 MySQL、Redis、VoIP)
3)?性能優勢:內核態轉發,吞吐量高(可達百萬級并發)
4)源 IP 哈希:同一客戶端 IP 的請求始終轉發到同一后端服務器
5)基礎檢查:TCP/UDP 端口連通性
6)腳本擴展:通過 MISC_CHECK 執行自定義腳本(如檢查 MySQL 狀態)
7)性能:內核態轉發,適合高并發、低延遲場景(如視頻流、游戲服務器)
8)?擴展性:功能固定,依賴 LVS 內核模塊,無法靈活擴展
5.2 Nginx
?1)七層負載均衡:解析 HTTP/HTTPS 協議,支持基于 URL、Header、Cookie 的路由
2)?適用協議:HTTP、HTTPS、HTTP/2、WebSocket、gRPC
3)功能擴展:支持緩存、限流、重寫、SSL 終止等高級功能
?4)主動檢查:定期向后端發送 HTTP 請求,驗證狀態碼(如 200)和響應內容
5)?被動檢查:根據請求失敗率自動標記異常節點
6)性能:用戶態處理,雖不如 LVS 高效,但通過優化(如啟用 reuseport)可支持數萬并發
7)擴展性:模塊化設計,支持 Lua 腳本、動態模塊(如 ngx_http_geoip_module)
Keepalived + Nginx
6.1 準備工作
兩臺服務器,地址分別為 192.168.199.210、192.168.199.211,虛擬IP為192.168.199.223。
6.2 安裝 Keepalived
兩臺服務器分別安裝 Keepalived
6.3 安裝 Nginx
兩臺服務器分別安裝 Nginx。使用 Docker compose 安裝
1)創建 docker-compose.yml,內容如下:
version: '3.8'
services:nginx:image: nginx:1.27-alpine-otelcontainer_name: my-nginxports:- 80:80volumes:- ./html:/usr/share/nginx/html- ./conf.d:/etc/nginx/conf.d- ./logs:/var/log/nginx
2)在同一目錄中,創建 html、conf.d、logs 三個文件夾
3)在 conf.d 目錄中 default.conf 文件,內容如下:
server {listen 80;server_name localhost;location / {root /usr/share/nginx/html;index index.html index.htm;}error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}
}
配置 nginx,監聽 80 端口,根目錄指向 /usr/share/nginx/html。結合 docker-compose.yml 卷的映射,根目錄執行 2)中創建的 html 目錄。默認訪問文件為 index.html 或 index.htm。
4)在 html 目錄中創建 index.html
<h1>Hello Docker Nginx 192.168.199.210!</h1>
在 html 中,標題顯示當前服務器的 IP。便于在瀏覽器中判定 keepalived 是否實現自動切換。
5)執行安裝部署
docker-compose up -d
6.4 編寫 Nginx 檢測腳本
1)編寫 check_nginx.sh 腳本文件,內容如下:
#!/bin/bash
echo "執行 nginx 檢測"# 獲取 nginx 容器的id
containerId=$(docker ps | grep my-nginx | awk '{print $1}')
echo "my-nginx docker id:"$containerId
# 如果 容器id 為空,說明容器已停止,需要切換
if [ "$containerId" == "" ]; thenecho "nginx 停止"exit 1 # nginx 容器不存在,觸發VIP切換
fi
echo "nginx 執行中..."
exit 0
在 4.3 介紹 vrrp_script 腳本時說明,腳本返回 0 時,表示成功,非 0 表示失敗。所以當 nginx 容器不存在時,返回 1,否則返回 0
2)設置腳本為可執行
chmod +x check_nginx.sh
6.5 編寫 keepalived.conf 配置
1)192.168.199.210 的 keepalived.conf 配置如下:
global_defs {router_id nginx_master # 唯一標識
}vrrp_instance VI_1 {state MASTER # 初始角色interface enp0s3 # 網卡名稱(通過 ip addr 確認)virtual_router_id 51 # 集群內唯一 ID(范圍 1-255)priority 100 # 優先級(主節點 > 備份節點)authentication {auth_type PASSauth_pass 123456 # 集群節點相同密碼}virtual_ipaddress {192.168.199.223/24 # 虛擬 IP(VIP)}# 綁定健康檢查腳本track_script {chk_nginx}
}# 健康檢查腳本配置
vrrp_script chk_nginx {script "/etc/keepalived/check_nginx.sh"interval 2weight -5
}
2)192.168.199.211 中的 keepalived.conf 配置類似,差異如下:
global_defs {router_id nginx_bakcup # 唯一標識
}vrrp_instance VI_1 {state BACKUP # 初始角色interface enp0s3 # 綁定到物理網卡(通過 ip addr 確認名稱)virtual_router_id 51 # 集群內唯一 ID(范圍 1-255)priority 90 # 優先級(主節點 > 備份節點)
}
6.6 啟動 Keepalived
兩臺服務器都啟動 Keepalived。命令如下:
systemctl start keepalived??????? # 啟動
systemctl enable keepalived??? # 開機自啟動
6.7 測試驗證
關閉 192.168.199.210 中的 nginx
[root@localhost nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f108796688a nginx:1.27-alpine-otel "/docker-entrypoint.…" 6 days ago Up 2 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp my-nginx
[root@localhost nginx]# docker stop 8f108796688a
8f108796688a
重新訪問
結尾
以上為本篇分析的全部內容。
關于本篇內容你有什么自己的想法或獨到見解,歡迎在評論區一起交流探討下吧。