目錄
Keepalived
Keepalived 是什么(高可用)
安裝?Keepalived
LVS
LVS 是什么(負載均衡)
安裝 LVS
Keepalived + LVS + Nginx 實現 高可用 + 負載均衡
Keepalived
Keepalived 是什么(高可用)
Keepalived 是一個用于實現?高可用?性(High Availability, HA)的服務,是一款基于 VRRP 協議的高可用軟件,常用于主備切換和虛擬IP漂移,在服務故障時自動實現故障轉移。
Keepalived 的核心功能
功能 | 說明 |
---|---|
VRRP | Virtual Router Redundancy Protocol,實現主備切換,保障VIP持續可用 |
健康檢查(check) | 定時檢測真實服務(如 Nginx、LVS、MySQL)是否存活 |
VIP 漂移 | 將一個虛擬 IP 綁定到當前健康的主節點上,故障時自動轉移到備節點 |
結合 LVS | 通常與 LVS(Linux Virtual Server)一起部署,提供高可用負載均衡 |
安裝?Keepalived
sudo apt-get updatesudo apt-get install -y keepalived
查看是否安裝成功
keepalived -v
開啟開機自啟動:
sudo systemctl enable keepalived
Keepalived 常用命令
開啟開機自啟動:sudo systemctl enable keepalived
禁用開機自啟動:sudo systemctl disable keepalived
開啟服務:sudo systemctl start keepalived
關閉服務:sudo systemctl stop keepalived
重啟服務:sudo systemctl restart keepalived
查看狀態:sudo systemctl status keepalived
編輯配置文件
sudo vim /etc/keepalived/keepalived.conf
配置文件參數說明
## 全局配置,用于日志、調試、郵件通知等目的
global_defs {## router_id 是 Keepalived 的 全局標識符router_id LVS_DEVEL
}# 定義一個 VRRP 實例,VI_1 是自定義的實例名稱,每一個實例代表一個高可用虛擬路由組。
vrrp_instance VI_1 {## 指定該節點的初始角色,MASTER:主節點,正常情況下負責綁定虛擬IP(VIP)。BACKUP:備用節點,在主節點不可用時接管 VIP。# Keepalived 自動通過優先級判斷主備,不是硬編碼的主備,所以這個只是初始角色。state MASTER## 指定綁定 VIP 的網絡接口(網卡名),例如 eth0、ens33、enp0s3 等。使用 ip a 查看當前系統的網卡名。interface ens33## 虛擬路由器的 ID,用于識別一個 VRRP 實例的組。所有參與該 VRRP 實例(主備)的服務器必須一致。范圍:0~255,確保不同服務之間不要沖突。virtual_router_id 51## 指定該節點的優先級。數字越大,優先級越高。主節點應配置較高的值(如 100),備用節點配置較低(如 90)。當優先級高的節點恢復時,會自動搶占 VIPpriority 100## 指定 VRRP 廣播間隔時間(秒)。主節點每隔指定的秒發送一次心跳包,默認是 1 秒,一般無需修改advert_int 1## 禁用搶占# nopreempt # 即使此節點優先級更高也不搶占 MASTER## 延遲搶占 VIP# 主節點恢復后,希望它穩定運行一段時間再接管 VIP,防止主節點頻繁重啟時反復搶占,導致服務中斷# nopreempt 和 preempt_delay 不能同時使用。如果兩者都寫了,以 nopreempt 為準# preempt_delay 10 # 恢復后等待10秒才嘗試搶占 MASTER## 狀態通知腳本(可選)# notify_master "/path/to/script" # 成為 MASTER 時執行腳本# notify_backup "/path/to/script" # 成為 BACKUP 時執行腳本# notify_fault "/path/to/script" # 出現故障時執行腳本# notify "/path/to/script" # 所有狀態變更時都執行的統一腳本## 本機實際 IP 地址(作為 VRRP 包發送源 IP)unicast_src_ip 192.168.189.135## 用于將 Keepalived 的 VRRP 心跳通信改為“單播”(Unicast)模式。不配置的話默認的是“組播”(Multicast)模式。云服務器(如阿里云、騰訊云)中,出于安全限制,組播通常被禁用或不可用。unicast_peer {192.168.189.136192.168.189.137}## 用于設置主備之間的認證信息authentication {## 認證類型,一般用 PASS(明文密碼)auth_type PASS## 認證密碼(主備節點必須保持一致)auth_pass 123456}## 指定一個或多個虛擬IP(VIP)。VIP 是客戶端訪問的目標地址,當主節點故障,VIP 會自動漂移到備節點virtual_ipaddress {192.168.189.100 # 虛擬IP 1,例如用于 web 服務A192.168.189.101 # 虛擬IP 2,例如用于 web 服務B192.168.189.102 # 虛擬IP 3,例如用于 mysql 服務# 把 VIP 綁定到本機的 loopback 網卡(lo),LVS 的時候使用(只在Master節點生效,所以不推薦使用,推薦使用命令的方式)# 192.168.189.100/32 dev lo scope host}
}
配置文件實操
- 主節點:192.168.189.135,優先級為 100
- 備節點:192.168.189.136,優先級為 90
- 第三節點:192.168.189.137,優先級為 80
這些參數必須在所有節點一致:vrrp_instance、virtual_router_id、advert_int、authentication、virtual_ipaddress
1. 主節點(192.168.189.135)配置
sudo vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 100advert_int 1unicast_src_ip 192.168.189.135unicast_peer {192.168.189.136192.168.189.137}authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.189.100}
}
重啟 keepalived
sudo systemctl restart keepalived
2. 備節點(192.168.189.136)配置
sudo vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 90advert_int 1unicast_src_ip 192.168.189.136unicast_peer {192.168.189.135192.168.189.137}authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.189.100}
}
重啟 keepalived
sudo systemctl restart keepalived
3. 第三節點(192.168.189.137)配置
sudo vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 80advert_int 1unicast_src_ip 192.168.189.137unicast_peer {192.168.189.135192.168.189.136}authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.189.100}
}
重啟 keepalived
sudo systemctl restart keepalived
測試是否配置成功
測試步驟:查看VIP在哪個節點上?發現在主節點上,把主節點關閉后,發現VIP漂移到備用節點上了
1.?在主節點(192.168.189.135)運行:
ip a | grep 192.168.189.100
輸入如下內容,表示 VIP 被綁定到此節點
inet 192.168.189.100/32 scope global ens33
2.?關閉主節點的 Keepalived 服務:
sudo systemctl stop keepalived
3. 在備節點(192.168.189.136)運行:
ip a | grep 192.168.189.100
VIP 會自動漂移到備節點。
開啟 keepalived 日志
(所有節點都要執行)
1.?配置 rsyslog 接收 Keepalived 日志
sudo vim /etc/rsyslog.d/keepalived.conf
文件內容如下:
local0.* /var/log/keepalived.log
重啟 rsyslog 服務
sudo systemctl restart rsyslog
2. 執行命令
sudo keepalived --log-console --log-detail --log-facility=local0
重啟 Keepalived 服務
sudo systemctl restart keepalived
3. 查看日志
tail -500f /var/log/keepalived.log
LVS
LVS 是什么(負載均衡)
LVS(Linux Virtual Server)是一個運行在 Linux 內核中的負載均衡器,它可以將大量的請求分發到多臺后端服務器上,實現網站或服務的 Linux 內核級負載均衡。
LVS 的特點
特性 | 說明 |
---|---|
高性能 | 內核級處理,效率非常高,適合大規模并發 |
穩定可靠 | 運行在 Linux 內核中,成熟穩定 |
支持多種調度算法 | 如輪詢(RR)、最少連接(LC)、加權等 |
透明性高 | 客戶端無需感知后端服務器變化 |
擴展性強 | 可輕松添加或移除后端服務器 |
LVS 的負載均衡算法
算法名 | 全稱 | 說明 |
---|---|---|
rr | Round Robin | 輪詢,每臺服務器輪流處理請求,適用于服務器性能差不多的情況。 |
wrr | Weighted Round Robin | 加權輪詢,根據服務器權重分配請求,權重大者分配更多請求。 |
lc | Least Connection | 最少連接數優先,當前連接最少的服務器優先接收新請求。 |
wlc | Weighted Least Connection | 加權最少連接,在連接數基礎上再加權,適用于連接時長差異較大的情況。 |
lblc | Locality-Based Least Connection | 基于本地性和最少連接數,適用于緩存服務器,提高命中率。 |
lblcr | Locality-Based Least Connection with Replication | 類似于 lblc,但支持多個復制服務器。 |
dh | Destination Hashing | 目的地址哈希,將請求根據目標 IP 哈希分配,適合源地址多樣化場景。 |
sh | Source Hashing | 源地址哈希,將同一客戶端的請求始終發往同一后端,適用于會話保持。 |
LVS 負載均衡的轉發工作模式?
模式 | 簡介 | 優點 | 缺點或要求 |
---|---|---|---|
NAT | LVS 作為網關,所有流量都經過 LVS,再轉發給后端 | 配置簡單 | LVS 成為瓶頸,占用帶寬 |
DR(Direct Routing) | 請求從 LVS 發出,但響應由后端服務器直接返回客戶端 | 性能高,響應快 | 需要所有機器在同一網段,后端需綁定 VIP(不響應 ARP) |
TUN(IP隧道) | LVS 和后端服務器可以跨網段 | 跨地域部署可用 | 后端服務器需支持 IP 隧道 |
安裝 LVS
sudo apt-get update
sudo apt-get install -y ipvsadm
編輯配置文件
sudo vim /etc/keepalived/keepalived.conf
配置文件參數說明
LVS 一般和 keepalived 搭配使用,LVS 配置寫在 keepalived 的配置文件中
## 全局配置,用于日志、調試、郵件通知等目的
global_defs {## router_id 是 Keepalived 的 全局標識符router_id LVS_DEVEL
}## 定義一個 LVS 虛擬服務(VIP + 端口),192.168.189.100 是虛擬 IP(VIP),80 是端口。
virtual_server 192.168.189.100 80 {## 每 5 秒執行一次健康檢查。值越小,檢測頻率越高,發現異常越快,但系統負擔也會稍高。delay_loop 5## 指定使用什么 負載均衡算法lb_algo wrr## 指定負載均衡的轉發工作模式lb_kind DR## 設置客戶端 IP 的掩碼,用于判定哪些請求來自“同一個客戶端子網”。nat_mask 255.255.255.0 表示 LVS 只看客戶端 IP 地址的前 24 位(即 a.b.c.*),這意味著來自同一個子網(如 192.168.1.x)的所有客戶端請求會被認為是來自同一客戶端,并會被轉發到同一個 real server。例如:如果兩個客戶端 IP 分別是 192.168.1.10 和 192.168.1.20,它們被認為來自同一個子網。LVS 會將它們的請求始終轉發到同一個后端 real server(在持久連接有效時間內,即 persistence_timeout)。nat_mask 255.255.255.0## 保持客戶端連接的會話粘性,單位是秒,同一客戶端在 60 秒內的請求都發送到同一臺后端服務器。persistence_timeout 60## 該虛擬服務處理的是 TCP 協議的請求(如 HTTP、HTTPS、MySQL等)protocol TCP## 定義一臺真實后端服務器,監聽 IP 為 192.168.189.135,端口 80。real_server 192.168.189.135 80 {## 權重為 3(配合上面的 wrr 算法使用),3:表示這個服務接收3個請求weight 3## 健康檢查(TCP 方式)TCP_CHECK {## 每次 TCP 連接檢測最多等待 3 秒,3秒后就連接超時connect_timeout 3## 最多嘗試連接 3 次nb_get_retry 3## 重試前延遲時間,每次失敗后等待 2 秒再重試delay_before_retry 2## 檢查端口(默認是 real_server 的端口)connect_port 80}}## 定義一臺真實后端服務器,監聽 IP 為 192.168.189.136,端口 80。real_server 192.168.189.136 80 {## 權重為 2(配合上面的 wrr 算法使用),2:表示這個服務接收2個請求weight 2TCP_CHECK {connect_timeout 3nb_get_retry 3delay_before_retry 2connect_port 80}}## 定義一臺真實后端服務器,監聽 IP 為 192.168.189.137,端口 8080。real_server 192.168.189.137 8080 {weight 1# 健康檢查(HTTP GET 請求)HTTP_GET {url {## 檢查的路徑,例如 /healthz,你需要在該服務器上部署這個路徑返回 200,例如:GET http://<real_server_ip>:80/healthzpath /healthz## 響應體的 MD5 值,匹配這個 hash 才算健康,防止假回包。d41d8cd98f00b204e9800998ecf8427e:是空字符串("")的 MD5 值,即后端什么也不返回時的 MD5 值,這個值可以自定義digest d41d8cd98f00b204e9800998ecf8427e}## 每次 TCP 連接檢測最多等待 3 秒,3秒后就連接超時connect_timeout 3## GET 請求失敗后重試次數nb_get_retry 3## 重試前延遲時間,每次失敗后等待 2 秒再重試delay_before_retry 2## 請求的端口connect_port 8080}}
}
HTTP_GET 健康檢查 Restful API 示例:
1. 定義一個 get 接口
@RestController
public class HealthCheckController {@GetMapping("/healthz")public String healthCheck() {return "AAABBBCCC";}
}
2.?計算返回值的 MD5(用于 digest)
現在后端返回的是 "AAABBBCCC",你可以在 Linux 或 macOS 終端中執行:
echo -n "AAABBBCCC" | md5sum
輸出:6207b5df5796e963410d3bc4b6a4218b ?-?
把這個值配置在?HTTP_GET 健康檢查的 digest 屬性中,如下:
HTTP_GET {url {path /healthzdigest 6207b5df5796e963410d3bc4b6a4218b}......
}
LVS 狀態同步
查看狀態是否同步
ipvsadm -L --daemon
顯示如下:(syncid=0:表示當前的節點沒有設置同步ID或沒有正常啟動連接同步守護進程)
master sync daemon (mcast=ens33, syncid=0, maxlen=1472, group=224.0.0.81, port=8848, ttl=1)
Master 節點開啟同步(ens33是實際的物理網絡接口名稱,不是 lo。同一集群中的 syncid 1 要設置一致)
ipvsadm --start-daemon master --mcast-interface=ens33 --syncid 1
Backup 節點開啟同步
ipvsadm --start-daemon backup --mcast-interface=ens33 --syncid 1
Master 節點關閉同步
ipvsadm --stop-daemon master
Backup 節點關閉同步
ipvsadm --stop-daemon backup
Keepalived + LVS + Nginx 實現 高可用 + 負載均衡
- 主節點:192.168.189.135,優先級為 100
- 備節點:192.168.189.136,優先級為 90
- 第三節點:192.168.189.137,優先級為 80
1. 主節點(192.168.189.135)配置
sudo vim /etc/keepalived/keepalived.conf
global_defs {router_id LVS_NODE1
}vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 100advert_int 1unicast_src_ip 192.168.189.135unicast_peer {192.168.189.136192.168.189.137}authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.189.100}
}virtual_server 192.168.189.100 80 {delay_loop 5lb_algo rrlb_kind DRnat_mask 255.255.255.0persistence_timeout 60protocol TCPreal_server 192.168.189.135 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}real_server 192.168.189.136 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}real_server 192.168.189.137 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}
}
重啟 keepalived
sudo systemctl restart keepalived
2. 備節點(192.168.189.136)配置
sudo vim /etc/keepalived/keepalived.conf
global_defs {router_id LVS_NODE2
}vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 90advert_int 1unicast_src_ip 192.168.189.136unicast_peer {192.168.189.135192.168.189.137}authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.189.100}
}virtual_server 192.168.189.100 80 {delay_loop 5lb_algo rrlb_kind DRnat_mask 255.255.255.0persistence_timeout 60protocol TCPreal_server 192.168.189.135 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}real_server 192.168.189.136 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}real_server 192.168.189.137 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}
}
重啟 keepalived
sudo systemctl restart keepalived
3. 備節點(192.168.189.137)配置
sudo vim /etc/keepalived/keepalived.conf
global_defs {router_id LVS_NODE3
}vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 80advert_int 1unicast_src_ip 192.168.189.137unicast_peer {192.168.189.135192.168.189.136}authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.189.100}
}virtual_server 192.168.189.100 80 {delay_loop 5lb_algo rrlb_kind DRnat_mask 255.255.255.0persistence_timeout 60protocol TCPreal_server 192.168.189.135 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}real_server 192.168.189.136 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}real_server 192.168.189.137 80 {weight 1TCP_CHECK {connect_timeout 5nb_get_retry 3delay_before_retry 3}}
}
重啟 keepalived
sudo systemctl restart keepalived
# 如果想要測試負載均衡時即時看到效果,就先去掉這2個屬性? ? nat_mask、persistence_timeout
所有節點都配置完成后,使用?ipvsadm 查看當前的 LVS 配置
sudo ipvsadm -L -n
顯示如下內容,表示 LVS 配置成功
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.189.100:80 rr persistent 60-> 192.168.189.135:80 Route 1 3 0 -> 192.168.189.136:80 Route 1 3 0 -> 192.168.189.137:80 Route 1 3 0
參數說明:
TCP ?192.168.189.100:80 rr
部分 含義 TCP
LVS 監聽的是 TCP 協議(也可能是 UDP) 192.168.189.100:80
虛擬 IP 和端口,表示用戶訪問的目標(VIP:Port) rr
負載均衡算法,這里是 round-robin
(輪詢調度)-> 192.168.189.135:80 ? ? ? ? ? Route ? 1 ? ? ?3 ? ? ? ? ?0
字段位置 字段含義 說明 ->
后端 Real Server 表示這是一個轉發目標(后端服務器) 192.168.189.135:80
Real Server IP 和端口 LVS 將請求轉發到這里 Route
轉發方式 這里是 DR 模式(直接路由) 1
權重 (weight) 表示調度器給此 Real Server 分配的權重 3
活躍連接數 (active conn) 當前連接到此 Real Server 的客戶端連接數 0
不活躍連接數 (inactive conn) 表示已完成但仍保持連接的 TCP 會話(如等待關閉) 如果你看到多個后端的活躍連接數一致(比如每臺都是 3),說明 LVS 負載均衡配置是生效的。
4. 把 VIP 綁定到本機的 loopback 網卡(lo),(在所有節點上執行)
注意:DR 模式下 VIP 一定是綁定在 lo 上,并加上 /32。(192.168.189.100 ip 已經在 ens33 網卡上了,現在再綁定到 lo 上會出現 ARP 沖突問題,等會我們要解決這個問題)
使用 ip a 命令可以查看每個網卡上綁定的 ip
方式一:(臨時的,不推薦)
sudo ip addr add 192.168.189.100/32 dev lo
參數說明:
ip addr add 添加一個 IP 地址 192.168.189.100/32 要添加的 IP 地址, /32
表示只有這一個 IP(子網掩碼是255.255.255.255
)dev lo 添加到 lo
網卡上,也就是本機的回環接口
命令執行完成后,顯示如下內容,lo 下出現了 192.168.189.100,但是 ens33 之前就存在 192.168.189.100,這樣就參數了 ARP 沖突。
啟用本地回環網卡 lo
接口(默認應該就是開啟狀態):
sudo ip link set lo up
方式二:(永久的,推薦)
創建一個新的 systemd 服務文件
sudo vim /etc/systemd/system/vip-setup.service
在文件中添加如下內容:
[Unit]
Description=Setup VIP on lo interface
After=network.target[Service]
Type=oneshot
ExecStart=/usr/sbin/ip addr add 192.168.189.100/32 dev lo[Install]
WantedBy=multi-user.target
啟動服務、開機自啟動
sudo systemctl daemon-reload
sudo systemctl enable vip-setup.service
sudo systemctl start vip-setup.service
5. 處理 ARP 沖突問題(在所有節點上執行)
arp_ignore=1:表示只對目標是本地地址的 ARP 請求進行響應,即只有當請求目標是該機器的某個接口時,才會響應 ARP 請求。
arp_announce=2:表示選擇具有最優 IP 地址的接口來回應 ARP 請求,通常避免 lo 上的 IP 與其他真實網卡的 IP 沖突。
all:所有的網絡接口(包括 lo、eth0、ens33 等)默認 ARP 策略(全局)
創建配置文件(永久生效的方式)
sudo vim /etc/sysctl.d/99-lvs.conf
文件內容如下:
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
重新加載所有 sysctl 配置,包括你剛才創建的 99-lvs.conf
sudo sysctl --system
查看配置是否生效
cat /proc/sys/net/ipv4/conf/lo/arp_ignore
cat /proc/sys/net/ipv4/conf/lo/arp_announce
cat /proc/sys/net/ipv4/conf/all/arp_ignore
cat /proc/sys/net/ipv4/conf/all/arp_announce
6. 配置 Nginx
在所有節點上配置Nginx實例,配置一個普通的可以訪問靜態頁面的80端口(因為我們上面配置文件 real_server 監聽的是 80 端口)地址即可。
Nginx 示例配置請查看:Nginx配置
7. 測試 Keepalived + LVS + Nginx 實現 高可用 + 負載均衡
瀏覽器訪問:http://192.168.189.100,可以看到,流量負載到每一臺機器上面了,達到了負載均衡的目的。
當我們停掉 2 臺機器的時候,發現還有 1 臺機器在正常運行,達到了高可用的目的。
注意,節點切換為 Master 的過程中通常會出現短暫的服務不可達現象。這是一主架構的正常現象,因為VIP遷移、ARP 廣播、LVS 的連接狀態,它們的切換都要時間。想要解決這個問題,使用多主架構(多主熱備)的方式即可(當然也會產生其他問題),什么是多主架構:每臺服務器既是自己?VIP 的 MASTER,又是其它?VIP 的 BACKUP,這樣實現多個 VIP,同時負載均衡、互為備份。。。配置太多了,這里就不再配置了,實際工作中百分之90的加工作5年的程序員不是在大廠都用不上。用到的自行搜索一下吧很簡單的,本文就到這里了。