1. 程式人生 > >Keepalived 原理與實戰

Keepalived 原理與實戰

# Keepalived 原理與實戰 > 隨著系統架構的逐漸演化,伺服器的數量和結構會越來越複雜,例如 Web 伺服器叢集的搭建,提高了系統的效能,同時也提高了系統維護的複雜度,我們需要對叢集中各臺伺服器進行監控,來保證為使用者提供服務的是正常執行的伺服器,整體系統的`可用性`就至關重要。 ## Keepalived 簡介 ### 什麼是Keepalived ? Keepalived一個基於[VRRP](https://link.zhihu.com/?target=http%3A//en.wikipedia.org/wiki/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 雙機主備原理](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-20-151648.png) ## Keepalived 選舉策略 ### 選舉策略 首先,每個節點有一個初始優先順序,由配置檔案中的`priority`配置項指定,MASTER 節點的 priority 應比 BAKCUP 高。執行過程中 keepalived 根據 vrrp_script 的 `weight` 設定,增加或減小節點優先順序。規則如下: 1. `weight`值為正時,指令碼檢測成功時”weight”值會加到”priority”上,檢測失敗時不加 - 主失敗: 主priority < 備priority+weight之和時會切換 - 主成功: 主priority+weight之和 > 備priority+weight之和時,主依然為主,即不發生切換 2. `weight`為負數時,指令碼檢測成功時”weight”不影響”priority”,檢測失敗時,Master節點的權值將是“priority“值與“weight”值之差 - 主失敗: 主priotity-abs(weight) < 備priority時會發生切換 - 主成功: 主priority > 備priority 不切換 3. 當兩個節點的優先順序相同時,以節點發送`VRRP通告`的 IP 作為比較物件,IP較大者為MASTER。 ### priority 和 weight 的設定 1. 主從的優先順序初始值priority和變化量weight設定非常關鍵,配錯的話會導致無法進行主從切換。比如,當MASTER初始值定得太高,即使script指令碼執行失敗,也比BACKUP的priority + weight大,就沒法進行VIP漂移了。 2. 所以priority和weight值的設定應遵循: abs(MASTER priority - BAKCUP priority) < abs(weight)。一般情況下,初始值MASTER的priority值應該比較BACKUP大,但不能超過weight的絕對值。 另外,當網路中不支援多播(例如某些雲環境),或者出現網路分割槽的情況,keepalived BACKUP節點收不到MASTER的VRRP通告,就會出現腦裂(split brain)現象,此時叢集中會存在多個MASTER節點。 ## Keepalived 實戰進階 ### Keepalived 安裝部署 1. 下載安裝包 Keepalived 官網下載地址:https://www.keepalived.org/download.html ![image-20200521210358933](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-21-130359.png) 2. 解壓 ```bash tar -zxvf keepalived-2.0.18.tar.gz ``` 3. 解壓後進入到解壓出來的目錄,看到會有`configure`,那麼就可以做配置了(配置安裝和nginx一模一樣) ![image-20200521210723704](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-21-130724.png) 4. 使用`configure`命令配置安裝目錄與核心配置檔案所在位置 ```bash ./configure --prefix=/usr/local/keepalived --sysconf=/etc ``` - prefix:keepalived安裝的位置 - sysconf:keepalived核心配置檔案所在位置,固定位置,改成其他位置則keepalived啟動不了,/var/log/messages中會報錯 配置過程中可能會出現警告資訊,如下所示: ![image-20200521211303189](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-21-131303.png) 解決方法:安裝 libnl/libnl-3 依賴 `yum -y install libnl libnl-devel`,重新`configure`一下就好了。 5. 安裝keepalived ```bash make && make install ``` 6. 進入到`/etc/keepalived`,該目錄下為keepalived核心配置檔案 ### Keepalived 配置 #### 把 Keepalived 註冊為系統服務 進入解壓縮安裝包的 `etc` 資料夾 ![image-20200521222326891](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-21-142327.png) 將系統配置檔案拷貝至系統 `etc`檔案 ```bash cp init.d/keepalived /etc/init.d/ cp sysconfig/keepalived /etc/sysconfig/ ``` 刷新系統服務,載入新新增的 Keepalived 服務 ```bash systemctl daemon-reload ``` #### 主伺服器(Master)配置 1. 通過命令 `vim keepalived.conf` 開啟配置檔案,詳細配置如下 ```bash 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 } } ``` **附:檢視網絡卡名稱** ![image-20200521214418246](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-21-134419.png) 2. 啟動 Keepalived 在sbin目錄中進行啟動(同nginx),如下圖: ![image-20200521214728691](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-21-134728.png) 3. 檢視程序 ```bash ps -ef|grep keepalived ``` ![image-20200521214838919](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/03/2020-05-21-134839.png) 4. 檢視虛擬 IP(VIP) 在網絡卡 ens33 下,多了一個 `192.168.1.108` ,這個就是虛擬ip ![image-20200521220643981](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-21-140644.png) #### Keepalived 實現雙機主備高可用 在配置完 Keepalived 主伺服器節點後,接下來就可以配置備用伺服器節點了,備用伺服器配置如下: ```bash 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 ```bash # 啟動keepalived systemctl start keepalived # 停止keepalived systemctl stop keepalived # 重啟keepalived systemctl restart keepalived ``` 檢視備用伺服器 Keepalived 程序 ![image-20200522235349567](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-155350.png) 現在主伺服器節點 `192.168.1.104`以及備用伺服器節點 `192.168.1.105`以及 Keepalived 虛擬 IP `192.168.1.105`已配置完畢 ![image-20200522235637330](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-155638.png) ![image-20200522235724708](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-155725.png) 這裡我在本地將 Keepalived 虛擬IP `192.168.1.108`已對映至 `www.keep.com` ![image-20200522235859619](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-155859.png) 所以直接訪問 `www.keep.com` 即可訪問主伺服器節點 ![image-20200523000014318](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-160014.png) 當主伺服器節點的 Keepalived 服務不可用時(這裡我直接將主伺服器的 Keepalived 服務直接停止`systemctl stop keepalived.service`,便於測試),虛擬IP 自動繫結至備用伺服器節點地址 ![image-20200523000333384](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-160333.png) #### Keepalived 配置 Nginx 自動重啟 1. 增加Nginx重啟檢測指令碼 ```bash vim /etc/keepalived/check_nginx_alive_or_not.sh ``` ```shell #!/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` 2. 在 keepalived.conf 配置定時監聽 nginx 狀態指令碼 ```bash vrrp_script check_nginx_alive { script "/etc/keepalived/check_nginx_alive_or_not.sh" interval 2 # 每隔兩秒執行上一行指令碼 weight 10 # 如果指令碼執行成功,則升級權重+10 # weight -10 # 如果指令碼執行失敗,則升級權重-10 } ``` 3. 在`vrrp_instance`中新增監控的指令碼 ```bash track_script { check_nginx_alive # 追蹤 nginx 指令碼 } ``` 4. 重啟Keepalived使得配置檔案生效 ```bash systemctl restart keepalived ``` #### Keepalived 實現雙主熱備高可用 ![image-20200523004644961](https://blog-figure-bed.oss-cn-shanghai.aliyuncs.com/2020/05/2020-05-22-164645.png) 首先需要配置雲服務的 DNS 解析配置和負載均衡,詳細配置參考: - 阿里雲:https://help.aliyun.com/document_detail/52528.html - 騰訊雲:https://cloud.tencent.com/document/product/302/11358 Keepalived 雙主熱備詳細配置: 規則:以一個虛擬ip分組歸為同一個路由 **主節點配置** ```nginx 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 } } ``` **備用節點配置** ```nginx 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 } } ``` ## 參考文件 - https://www.huweihuang.com/linux-notes/keepalived/keepalived-introduct