keepalived+nginx這樣的負載均衡配置,不少環境都用到,搭建配置都很簡單。nginx
可是在最近的一次搭建過程當中,出現了一種狀況,就是nginx進程宕掉後,在監測腳本不能將進程拉起來的狀況下,keepalived服務沒有被終止,從而致使VIP一直漂在這臺nginx已經宕掉的服務器上面,出現這樣的狀況,通常要麼是配置錯了,或者監測腳本錯了,然而狀況並不是如此;web
下面這個是keepalived+nginx的基本配置bash
環境信息 Ngx-Web1 虛擬IP:1.10 物理IP:1.1 Centos7.8 8080 Keepalived master keepalived-2.0.20 Nginx1.18.0 Ngx-Web2 物理IP:1.2 Centos7.8 8080 Keepalived backup keepalived-2.0.20 Nginx1.18.0
web1的keepalived配置服務器
! Configuration File for Keepalived global_defs { router_id 1.1 ##指定本機物理主機IP } vrrp_script chk_nginx { script "/data/keepalived/nginx_check.sh" ## 檢測 nginx服務狀態 interval 2 ## 檢測時間間隔 weight -20 ## 若是條件成立,權重-20 } vrrp_instance VI_1 { state MASTER ##指定這臺主機keepalived爲主節點 interface eth0 ##指定物理網卡接口 virtual_router_id 11 ## 虛擬路由的ID號,兩個節點設置必須同樣,建議用IP最後段 mcast_src_ip 1.1 ##指定本機物理主機IP priority 100 ## 節點優先級,值範圍0-254,MASTER要比BACKUP高 nopreempt ## 優先級高的設置 nopreempt 解決異常恢復後再次搶佔的問題 advert_int 1 ## 組播信息發送間隔,兩個節點設置必須同樣,默認 1s ## 設置驗證信息,兩個節點必須一致 authentication { auth_type PASS auth_pass 1111 } ## 將 track_script 塊加入 instance 配置塊 track_script { chk_nginx ## 執行 Nginx 監控的服務 } ## 虛擬 IP 池, 兩個節點設置必須同樣 virtual_ipaddress { 1.10 ## 虛擬ip,能夠定義多個 } }
web2的keepalived配置負載均衡
! Configuration File for Keepalived global_defs { router_id 1.2 ##指定本機物理主機IP } vrrp_script chk_nginx { script "/data/keepalived/nginx_check.sh" ## 檢測 nginx服務狀態 interval 2 ## 檢測時間間隔 weight -20 ## 若是條件成立,權重-20 } vrrp_instance VI_1 { state MASTER ##指定這臺主機keepalived爲主節點 interface eth0 ##指定物理網卡接口 virtual_router_id 11 ## 虛擬路由的ID號,兩個節點設置必須同樣,建議用IP最後段 mcast_src_ip 1.2 ##指定本機物理主機IP priority 80 ## 節點優先級,值範圍0-254,MASTER要比BACKUP高 nopreempt ## 優先級高的設置 nopreempt 解決異常恢復後再次搶佔的問題 advert_int 1 ## 組播信息發送間隔,兩個節點設置必須同樣,默認 1s ## 設置驗證信息,兩個節點必須一致 authentication { auth_type PASS auth_pass 1111 } ## 將 track_script 塊加入 instance 配置塊 track_script { chk_nginx ## 執行 Nginx 監控的服務 } ## 虛擬 IP 池, 兩個節點設置必須同樣 virtual_ipaddress { 1.10 ## 虛擬ip,能夠定義多個 } }
監測腳本/data/keepalived/nginx_check.sh,權限給777就能夠了oop
#!/bin/bash C=`ps -C nginx --no-header |wc -l` if [ $C -eq 0 ] then su - nginx -c /data/nginx-1.18.0/sbin/nginx sleep 2 if [ `ps -C nginx --no-header |wc -l` -eq 0 ] then ps -C keepalived --no-header | awk '{print $1}' | xargs kill fi fi
正常狀況下,上面的配置能夠知足下面的負載條件:測試
測試用例1 節點nginx服務進程中止
測試方法 手工模擬中止nginx服務,檢查nginx進程是否正常拉起
預計結果 Keepalived自動拉起nginx服務,業務訪問VIP正常
實際結果 Keepalived自動拉起nginx服務,業務訪問VIP正常
測試用例2 主節點宕機
測試方法 手工模擬將keepalived進程或是主機重啓
預計結果 VIP自動漂移到備節點,業務訪問VIP正常
實際結果 VIP自動漂移到備節點,業務訪問VIP正常
測試用例3 主節點恢復
測試方法 恢復主節點keepalived與nginx服務
預計結果 備節點VIP回切主節點,業務訪問VIP正常
實際結果 備節點VIP回切主節點,業務訪問VIP正常
可是,通過測試,仍是會出現一種狀況:節點nginx服務進程中止,監測腳本沒法拉起nginx的狀況下,keepalived服務沒有中止虛擬IP依然停留在nginx進程異常的節點上面,致使訪問過來的請求出現報錯。
一開始覺得是腳本的問題、配置的問題,後來手動執行監測腳本,確實能夠在nginx進程宕掉後,成功中止keepalived服務,而後虛擬IP漂到備節點上面,那就是腳本執行到一半就沒有往下執行了,因此腳本確實是執行了,致使權重也沒有減小,所以虛擬IP仍是沒有漂到備節點上面,配置、腳本都沒有問題,百思不解之下,經過網上搜查,發現了另外一個可行方案,監測腳本不變,可是web1的keepalived配置添加一個TCP監測項,監測nginx 的訪問端口
! Configuration File for Keepalived global_defs { router_id 1.1 ##指定本機物理主機IP } vrrp_script chk_nginx { script "/data/keepalived/nginx_check.sh" ## 檢測 nginx服務狀態 interval 2 ## 檢測時間間隔 weight -20 ## 若是條件成立,權重-20 } vrrp_instance VI_1 { state MASTER ##指定這臺主機keepalived爲主節點 interface eth0 ##指定物理網卡接口 virtual_router_id 11 ## 虛擬路由的ID號,兩個節點設置必須同樣,建議用IP最後段 mcast_src_ip 1.1 ##指定本機物理主機IP priority 100 ## 節點優先級,值範圍0-254,MASTER要比BACKUP高 nopreempt ## 優先級高的設置 nopreempt 解決異常恢復後再次搶佔的問題 advert_int 1 ## 組播信息發送間隔,兩個節點設置必須同樣,默認 1s ## 設置驗證信息,兩個節點必須一致 authentication { auth_type PASS auth_pass 1111 } ## 將 track_script 塊加入 instance 配置塊 track_script { chk_nginx ## 執行 Nginx 監控的服務 } ## 虛擬 IP 池, 兩個節點設置必須同樣 virtual_ipaddress { 1.10 ## 虛擬ip,能夠定義多個 } } virtual_server 1.10 8080 { ## 虛擬ip和nginx訪問端口 delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 5 protocol TCP real_server 1.1 8080 { ##本機物理主機IP和nginx訪問端口 weight 1 notify_down /data/keepalived/sbin/nginx_check.sh ##監測本地nginx進程端口宕掉後,執行腳本,中止keepalived TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 8080 #監測的NGINX的訪問的TCP端口 } } }
web2上面的keepalived配置跟web1同樣,添加一個TCP監測
! Configuration File for Keepalived global_defs { router_id 1.2 ##指定本機物理主機IP } vrrp_script chk_nginx { script "/data/keepalived/nginx_check.sh" ## 檢測 nginx服務狀態 interval 2 ## 檢測時間間隔 weight -20 ## 若是條件成立,權重-20 } vrrp_instance VI_1 { state MASTER ##指定這臺主機keepalived爲主節點 interface eth0 ##指定物理網卡接口 virtual_router_id 11 ## 虛擬路由的ID號,兩個節點設置必須同樣,建議用IP最後段 mcast_src_ip 1.2 ##指定本機物理主機IP priority 80 ## 節點優先級,值範圍0-254,MASTER要比BACKUP高 nopreempt ## 優先級高的設置 nopreempt 解決異常恢復後再次搶佔的問題 advert_int 1 ## 組播信息發送間隔,兩個節點設置必須同樣,默認 1s ## 設置驗證信息,兩個節點必須一致 authentication { auth_type PASS auth_pass 1111 } ## 將 track_script 塊加入 instance 配置塊 track_script { chk_nginx ## 執行 Nginx 監控的服務 } ## 虛擬 IP 池, 兩個節點設置必須同樣 virtual_ipaddress { 1.10 ## 虛擬ip,能夠定義多個 } } virtual_server 1.10 8080 { ## 虛擬ip和nginx訪問端口 delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 5 protocol TCP real_server 1.2 8080 { ##本機物理主機IP和nginx訪問端口 weight 1 notify_down /data/keepalived/sbin/nginx_check.sh ##監測本地nginx進程端口宕掉後,執行腳本,中止keepalived TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 8080 #監測的NGINX的訪問的TCP端口 } } }
當這個keepalived的配置改爲這樣後,監測腳本沒法拉起nginx的狀況下,keepalived服務也會由於TCP端口,就是nginx的訪問端口宕掉,而觸發腳本,將keepalived服務中止,而不會像前面的那樣,發現nginx進程沒法拉起後,一直重複執行拉起操做,可是不中止keepalived進程