高可用服務之Keepalived利用指令碼實現服務的可用性檢測
上一篇部落格主要聊到了keepalived高可用LVS叢集的相關配置,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13659428.html;keepalived高可用LVS叢集是Keepalived的設計之初的功能,所以它高可用LVS叢集內建了對LVS的RS的健康狀態檢測,自動生成IPVS規則;我們知道LVS是Linux核心功能,本質上在使用者空間不會監聽任何埠,它的主要作用是對使用者請求的流量做4層排程,所以對於這種沒有程序,沒有埠資訊的服務我們怎麼去判斷它是否正常就先得尤為重要;同樣的道理對於高可用nginx或haproxy這類在使用者空間有監聽埠和程序的服務來說,如果用keepalived做高可用,我們需要考慮到我們高可用的服務是否正常可用,從而實現在服務不正常的情況下,把對應的VIP能夠遷移到其他節點;為了實現能夠檢測到高可用的服務是否正常,keepalived提供了呼叫外部指令碼的介面,讓我們配置對高可用的服務做可用性檢測;根據我們定義的指令碼,keepalived會週期性的去執行我們的定義的指令碼,根據指令碼執行退出碼判斷服務是否可用,一旦發生服務不可用,或者可用性檢測不通過,它就會觸發當前keepalived節點的優先順序降低,從而實現當前節點在通告優先順序時,觸發備份節點接管VIP,從而實現VIP轉移,服務的高可用;
在keepalived的配置檔案中,我們可以用vrrp_script {...} 來定義我們可以執行的指令碼相關資訊;用track_script {..}在對應vrrp例項中呼叫vrrp_script定義的指令碼;
示例:利用指令碼對LVS做可用性檢測
1、編寫指令碼
[root@node01 keepalived]# ls check_lvs.sh keepalived.conf keepalived.conf.bak notify.sh [root@node01 keepalived]# chmod a+x check_lvs.sh [root@node01 keepalived]# ll total 16 -rwxr-xr-x 1 root root 98 Sep 13 22:26 check_lvs.sh -rw-r--r-- 1 root root 1611 Sep 13 22:24 keepalived.conf -rw-r--r-- 1 root root 3598 Sep 8 23:29 keepalived.conf.bak -rwxr-xr-x 1 root root 472 Sep 10 13:58 notify.sh [root@node01 keepalived]# cat check_lvs.sh #!/bin/bash ping -c 2 192.168.0.1 &> /dev/null if [ $? -eq 0 ];then exit 0 else exit 1 fi [root@node01 keepalived]#
提示:以上指令碼主要是利用ping 192.168.0.1這個地址來判斷推出碼是0還是1,正常退出時0,非正常退出為1;
2、配置keepalived呼叫上面的指令碼,並在VIP所在例項中引用;
提示:以上配置表示定義了一個指令碼,名為check_LVS(這個名稱可以任意起,主要起標識作用,後面在例項中引用的一個標識);這個指令碼執行時間間隔為每2秒執行一次,超時時長為2秒,如果指令碼執行失敗(退出碼非0)就把對應節點的優先順序降低20(通常這個降低的值要大於兩節點優先順序之差就行,意思就是降低後的優先順序要小於備份節點優先順序,這樣才有意義);指令碼執行連續3次檢測都為成功狀態(指令碼推出碼都為0),則keepalived就標記該例項為OK狀態,並會一直檢測下去,如果連續3次檢查都為失敗狀態(退出碼非0),則標記對應例項為KO狀態;一旦標記對應例項為失敗狀態就會觸發當前節點的優先順序降低;從而在通告心跳時,會通告降低後的優先順序,從而實現備份節點接管VIP來完成vip轉移;
完整的keepalived配置
[root@node01 keepalived]# cat keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from node01_keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node01 vrrp_skip_check_adv_addr vrrp_strict vrrp_iptables vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 224.0.12.132 } vrrp_script check_LVS { script "/etc/keepalived/check_lvs.sh" interval 2 timeout 2 weight -20 rise 3 fall 3 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 12345678 } virtual_ipaddress { 192.168.0.111/24 brd 192.168.0.255 dev ens33 label ens33:1 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" track_script { check_LVS } } virtual_server 192.168.0.111 80 { delay_loop 3 lb_algo wrr lb_kind DR protocol TCP sorry_server 127.0.0.1 80 real_server 192.168.0.43 80 { weight 1 nb_get_retry 2 delay_before_retry 2 connect_timeout 30 HTTP_GET { url { path /index.html status_code 200 } } } real_server 192.168.0.44 80 { weight 1 nb_get_retry 2 delay_before_retry 2 connect_timeout 30 HTTP_GET { url { path /index.html status_code 200 } } } } [root@node01 keepalived]#View Code
提示:vrrp_script中的script可以是指令碼路徑,也可以是一段命令;
驗證:重啟keepalived,修改指令碼中的IP地址,模擬故障,故意讓其對指定地址ping不通,看看對應vip是否會從master節點飄逸到備份節點?對應節點的優先順序是否有變化?
未修改指令碼時,vip在node01上
修改指令碼以後
提示:修改指令碼以後對應的VIP就沒有在node01上了;
檢視node01上keepalived的日誌資訊,看看它是如何故障轉移的
提示:從日誌檔案可以看到,當keepalived週期性去執行check_lvs.sh指令碼時,連續3次都執行失敗,就觸發了動態調整當前節點所在keepalived的優先順序,把原來優先順序為100調整至80,然後通告自己的心跳資訊時,又觸發了備份節點通告自己的優先順序資訊,對應主節點收到高於它的優先順序通告,所以它就自動轉換成backup狀態,並刪除了VIP;然後後續也在每隔2秒檢測一次指令碼執行否正常;
在node02上檢視vip是否存在?
訪問VIP看看服務是否可訪問?
提示:可以看到對應使用者訪問還是可以正常訪問;
驗證:修改指令碼為正常可通訊地址,看看對應節點是否會重新轉換為master角色呢?對應vip是否會漂移回來呢?
提示:可看到修改指令碼以後,對應vip就回來了;
檢視keepalived的日誌
提示:可以看到當指令碼執行成功以後,首先會觸發當前節點的優先順序還原為原有優先順序,並通告出去,然後把當前節點從backup角色轉換為master角色,接管VIP;
以上示例主要用於對那種高可用服務在使用者空間沒有監聽埠,沒有程序,我們需要藉助某種機制去判讀該服務是否正常,比如上面我們利用ping某個ip地址去判斷LVS是否正常,從而來決定對應節點的優先順序是否調整,進而來決定vip是否轉移;當然對於在使用者空間有監聽埠,有程序的服務也是同樣的套路,我們可以利用指令碼去檢測埠是否存在,或者對應程序是否正常來決定VIP是否轉移;
示例:keepalived利用指令碼來檢測nginx程序是否正常,從而來實現對nginx的高可用
1、編寫指令碼
提示:以上指令碼利用killall命令對nginx程序傳送0號訊號,去判斷對應的nginx程序是否存在,如果存在該命令會返回0,否則返回非0;利用命令的返回值來確定指令碼退出碼;
2、在keepalived的配置檔案中定義指令碼相關引數,並在vrrp例項中引用定義的指令碼資訊
完整的keepalived配置
[root@node01 ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from node01_keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node01 vrrp_skip_check_adv_addr vrrp_strict vrrp_iptables vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 224.0.12.132 } vrrp_script check_LVS { script "/etc/keepalived/check_lvs.sh" interval 2 timeout 2 weight -20 rise 3 fall 3 } vrrp_script check_nginx { script "/etc/keepalived/check_nginx.sh" interval 2 timeout 2 weight -20 rise 3 fall 3 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 12345678 } virtual_ipaddress { 192.168.0.111/24 brd 192.168.0.255 dev ens33 label ens33:1 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" track_script { check_LVS check_nginx } } [root@node01 ~]#View Code
提示:vrrp_script需要定義在例項之外,表示引用一段上下文來定義指令碼相關資訊;定義了指令碼資訊,如果不在例項中引用,它是不會週期性的去執行指令碼,只有在例項中引用的指令碼名稱以後(這裡的名稱是vrrp_script後面的名稱)才會使對應的腳本週期性的去執行;
在node01和node02上安裝nginx
yum install nginx -y
提供測試頁面
重啟keepalived 和nginx
systemctl restart nginx keepalived.service
提示:可以看到重啟nginx和keepalived以後,在node01上有VIP和80埠,在node02上沒有vip,但80埠處於監聽狀態;如果此時有使用者訪問vip,就會由node01上的nginx提供響應;
驗證:用瀏覽器訪問vip,看看響應的內容是否是我們在node01上提供的測試頁面?
驗證:把node01上的nginx停掉,看看對應的服務是否還可訪問?
提示:可以看到把node01上的nginx停掉以後,對應的vip也就隨之被刪除;
再次訪問vip看看是否會有響應?
提示:可以看到現在訪問vip響應的頁面內容變成了node02上nginx提供的測試頁面;說明現在是由node02上的nginx在提供服務;
到此keepalived高可用nginx的配置就完成了,至於nginx怎麼工作,是否為排程器,這裡的keepalived並不關心,它只關心nginx程序是否正常;對於keepalived高可用其他服務,思路都是類似的,不同的是對於不同的服務,檢測指令碼可能有所不