Keepalived 原理與實戰
隨著系統架構的逐漸演化,伺服器的數量和結構會越來越複雜,例如 Web 伺服器叢集的搭建,提高了系統的效能,同時也提高了系統維護的複雜度,我們需要對叢集中各臺伺服器進行監控,來保證為使用者提供服務的是正常執行的伺服器,整體系統的
可用性
就至關重要。
Keepalived 簡介
什麼是Keepalived ?
Keepalived一個基於VRRP 協議來實現的 LVS 服務高可用方案,可以利用其來解決單點故障。一個LVS服務會有2臺伺服器執行Keepalived,一臺為主伺服器(MASTER),一臺為備份伺服器(BACKUP),但是對外表現為一個虛擬IP
,主伺服器會傳送特定的訊息給備份伺服器,當備份伺服器收不到這個訊息的時候,即主伺服器當機的時候, 備份伺服器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。
Keepalived 的作用
如上述所說,Keepalived 提供了很好的高可用性保障服務
,它可以檢查伺服器的狀態,如果有伺服器出現問題,Keepalived 會將其從系統中移除,並且同時使用備份伺服器代替該伺服器的工作,當這臺伺服器可以正常工作後,Keepalived 再將其放入伺服器群中,這個過程是 Keepalived 自動完成的,不需要人工干涉,我們只需要修復出現問題的伺服器即可。
Keepalived 原理
基於VRRP協議的理解
Keepalived 是以 VRRP
協議為實現基礎的,VRRP全稱Virtual Router Redundancy Protocol
,即虛擬路由冗餘協議
。
虛擬路由冗餘協議,可以認為是實現路由器高可用的協議,即將N臺提供相同功能的路由器組成一個路由器組,這個組裡面有一個master 和多個 backup,master 上面有一個對外提供服務的 VIP(Virtual IP Address)
(該路由器所在區域網內其他機器的預設路由為該 vip),master 會發組播,當 backup 收不到 vrrp 包時就認為 master 宕掉了,這時就需要根據 VRRP 的優先順序來選舉
一個 backup 當 master。這樣的話就可以保證路由器的高可用了。
keepalived 主要有三個模組,分別是core、check 和 vrrp。core 模組為keepalived的核心,負責主程式的啟動、維護以及全域性配置檔案的載入和解析。check 負責健康檢查,包括常見的各種檢查方式。vrrp 模組是來實現 VRRP 協議的。
基於TCP/IP協議的理解
以檢測 web 伺服器為例,Keepalived 從3個層次來檢測伺服器的狀態
Layer3 、Layer4 以及 Layer7 工作在IP/TCP協議棧的IP層,TCP層,及應用層,原理分別如下:
Layer3:
Keepalived使用Layer3的方式工作時,Keepalived會定期向伺服器群中的伺服器傳送一個ICMP的資料包(既我們平時用的Ping程式),如果發現某臺服務的IP地址沒有啟用,Keepalived 便報告這臺伺服器失效,並將它從伺服器群中剔除,這種情況的典型例子是某臺伺服器被非法關機。Layer3 的方式是以伺服器的IP地址
是否有效作為伺服器工作正常與否的標準。
Layer4:
如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP 埠的狀態
來決定伺服器工作正常與否。如 web server 的服務埠一般是80,如果 Keepalived 檢測到80埠沒有啟動,則 Keepalived 將把這臺伺服器從伺服器群中剔除。
Layer7:
Layer7 就是工作在具體的應用層了,比Layer3,Layer4要複雜一點,在網路上佔用的頻寬也要大一些。Keepalived 將根據使用者的設定檢查伺服器程式的執行是否正常,如果與使用者的設定不相符,則 Keepalived 將把伺服器從伺服器群中剔除。
Keepalived 選舉策略
選舉策略
首先,每個節點有一個初始優先順序,由配置檔案中的priority
配置項指定,MASTER 節點的 priority 應比 BAKCUP 高。執行過程中 keepalived 根據 vrrp_script 的 weight
設定,增加或減小節點優先順序。規則如下:
weight
值為正時,指令碼檢測成功時”weight”值會加到”priority”上,檢測失敗時不加- 主失敗: 主priority < 備priority+weight之和時會切換
- 主成功: 主priority+weight之和 > 備priority+weight之和時,主依然為主,即不發生切換
weight
為負數時,指令碼檢測成功時”weight”不影響”priority”,檢測失敗時,Master節點的權值將是“priority“值與“weight”值之差- 主失敗: 主priotity-abs(weight) < 備priority時會發生切換
- 主成功: 主priority > 備priority 不切換
- 當兩個節點的優先順序相同時,以節點傳送
VRRP通告
的 IP 作為比較物件,IP較大者為MASTER。
priority 和 weight 的設定
- 主從的優先順序初始值priority和變化量weight設定非常關鍵,配錯的話會導致無法進行主從切換。比如,當MASTER初始值定得太高,即使script指令碼執行失敗,也比BACKUP的priority + weight大,就沒法進行VIP漂移了。
- 所以priority和weight值的設定應遵循: abs(MASTER priority - BAKCUP priority) < abs(weight)。一般情況下,初始值MASTER的priority值應該比較BACKUP大,但不能超過weight的絕對值。 另外,當網路中不支援多播(例如某些雲環境),或者出現網路分割槽的情況,keepalived BACKUP節點收不到MASTER的VRRP通告,就會出現腦裂(split brain)現象,此時叢集中會存在多個MASTER節點。
Keepalived 實戰進階
Keepalived 安裝部署
- 下載安裝包
Keepalived 官網下載地址:https://www.keepalived.org/download.html
-
解壓
tar -zxvf keepalived-2.0.18.tar.gz
-
解壓後進入到解壓出來的目錄,看到會有
configure
,那麼就可以做配置了(配置安裝和nginx一模一樣) -
使用
configure
命令配置安裝目錄與核心配置檔案所在位置./configure --prefix=/usr/local/keepalived --sysconf=/etc
- prefix:keepalived安裝的位置
- sysconf:keepalived核心配置檔案所在位置,固定位置,改成其他位置則keepalived啟動不了,/var/log/messages中會報錯
配置過程中可能會出現警告資訊,如下所示:
解決方法:安裝 libnl/libnl-3 依賴
yum -y install libnl libnl-devel
,重新configure
一下就好了。 -
安裝keepalived
make && make install
-
進入到
/etc/keepalived
,該目錄下為keepalived核心配置檔案
Keepalived 配置
把 Keepalived 註冊為系統服務
進入解壓縮安裝包的 etc
資料夾
將系統配置檔案拷貝至系統 etc
檔案
cp init.d/keepalived /etc/init.d/
cp sysconfig/keepalived /etc/sysconfig/
重新整理系統服務,載入新新增的 Keepalived 服務
systemctl daemon-reload
主伺服器(Master)配置
- 通過命令
vim keepalived.conf
開啟配置檔案,詳細配置如下
global_defs {
# 路由id:當前安裝keepalived的節點主機識別符號,保證全域性唯一
router_id keep_104
}
vrrp_instance VI_1 {
# 表示狀態是MASTER主機還是備用機BACKUP
state MASTER
# 該例項繫結的網路卡名稱
interface ens33
# 保證主備節點一致即可
virtual_router_id 51
# 權重,master權重一般高於backup,如果有多個,那就是選舉,誰的權重高,誰就當選
priority 100
# 主備之間同步檢查時間間隔,單位秒
advert_int 2
# 認證許可權密碼,防止非法節點進入
authentication {
auth_type PASS
auth_pass 1111
}
# 虛擬出來的ip,可以有多個(vip)
virtual_ipaddress {
192.168.1.108
}
}
附:檢視網路卡名稱
-
啟動 Keepalived
在sbin目錄中進行啟動(同nginx),如下圖:
-
檢視程式
ps -ef|grep keepalived
-
檢視虛擬 IP(VIP)
在網路卡 ens33 下,多了一個
192.168.1.108
,這個就是虛擬ip
Keepalived 實現雙機主備高可用
在配置完 Keepalived 主伺服器節點後,接下來就可以配置備用伺服器節點了,備用伺服器配置如下:
global_defs {
router_id keep_105
}
vrrp_instance VI_1 {
# 備用機設定為BACKUP
state BACKUP
interface ens33
virtual_router_id 51
# 權重低於MASTER
priority 80
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
# 注意:主備兩臺的vip都是一樣的,繫結到同一個vip
192.168.1.108
}
}
啟動 Keepalived
# 啟動keepalived
systemctl start keepalived
# 停止keepalived
systemctl stop keepalived
# 重啟keepalived
systemctl restart keepalived
檢視備用伺服器 Keepalived 程式
現在主伺服器節點 192.168.1.104
以及備用伺服器節點 192.168.1.105
以及 Keepalived 虛擬 IP 192.168.1.105
已配置完畢
這裡我在本地將 Keepalived 虛擬IP 192.168.1.108
已對映至 www.keep.com
所以直接訪問 www.keep.com
即可訪問主伺服器節點
當主伺服器節點的 Keepalived 服務不可用時(這裡我直接將主伺服器的 Keepalived 服務直接停止systemctl stop keepalived.service
,便於測試),虛擬IP 自動繫結至備用伺服器節點地址
Keepalived 配置 Nginx 自動重啟
-
增加Nginx重啟檢測指令碼
vim /etc/keepalived/check_nginx_alive_or_not.sh
#!/bin/bash A=`ps -C nginx --no-header |wc -l` # 判斷nginx是否當機,如果當機了,嘗試重啟 if [ $A -eq 0 ];then /usr/local/nginx/sbin/nginx # 等待一小會再次檢查nginx,如果沒有啟動成功,則停止keepalived,使其啟動備用機 sleep 3 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then killall keepalived fi fi
增加執行許可權
chmod +x /etc/keepalived/check_nginx_alive_or_not.sh
-
在 keepalived.conf 配置定時監聽 nginx 狀態指令碼
vrrp_script check_nginx_alive { script "/etc/keepalived/check_nginx_alive_or_not.sh" interval 2 # 每隔兩秒執行上一行指令碼 weight 10 # 如果指令碼執行成功,則升級權重+10 # weight -10 # 如果指令碼執行失敗,則升級權重-10 }
-
在
vrrp_instance
中新增監控的指令碼track_script { check_nginx_alive # 追蹤 nginx 指令碼 }
-
重啟Keepalived使得配置檔案生效
systemctl restart keepalived
Keepalived 實現雙主熱備高可用
首先需要配置雲服務的 DNS 解析配置和負載均衡,詳細配置參考:
- 阿里雲:https://help.aliyun.com/document_detail/52528.html
- 騰訊雲:https://cloud.tencent.com/document/product/302/11358
Keepalived 雙主熱備詳細配置:
規則:以一個虛擬ip分組歸為同一個路由
主節點配置
global_defs {
router_id keep_104
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.108
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.138
}
}
備用節點配置
global_defs {
router_id keep_105
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.108
}
}
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.138
}
}