前言
一般情況下,如果是小型項目,客戶端使用一個Nginx做反向代理或者負載均衡即可。但是如果想做到高可用,Nginx也必須得有多個,一個Nginx服務掛掉,能自動切換到另一個Nginx服務上。使用Nginx + keepalived,對外提供一個虛擬ip,虛擬ip對應多台Nginx服務。出現故障時,ip自動漂移。如下所示:
准備
虛擬機兩台,安裝Nginx,安裝 keepalived 可直接使用命令 yum -y install keepalived 。
keepalived 默認配置文件路徑:/etc/keepalived/keepalived.conf
keepalived 默認日志存放路徑:/var/log/messages
網格划分如下:
名稱 | 操作系統 | IP | 虛擬IP | keepalived |
虛擬機1 | Centos7.6 | 192.168.20.12 | 192.168.20.100 | MASTER |
虛擬機2 | Centos7.6 | 192.168.20.16 | 192.168.20.100 | BACKUP |
1、啟動Nginx
簡單起見,也為了后面測試,只用Nginx自帶的靜態頁進行測試。
靜態頁面路徑:nginx/html/index.html,分別在index.html中增加一行"<span>ip:192.168.20.12</span>"和"<span>ip:192.168.20.16</span>"
切到 usr/local/nginx/sbin目錄下,執行啟動Nginx命令:
./nginx
2、keepalived搶占式配置
MASTER配置如下(默認配置文件:/etc/keepalived/keepalived.conf):
global_defs { router_id keep12 ##路由id,通常為 hostname } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" ## 檢測 nginx 狀態的腳本路徑 interval 2 ## 檢測時間間隔 weight -20 ## 如果條件成立,權重-20 } vrrp_instance VI_1 { state MASTER ##主節點為 MASTER,備份節點為 BACKUP interface ens32 ##綁定 VIP 的網絡接口,與本機IP地址所在網絡接口相同 virtual_router_id 100 ##虛擬路由id,主從節點必須保持一致 priority 100 ##節點優先級,直范圍0-254,MASTER 要比 BACKUP 高 advert_int 1 authentication { ##設置驗證信息,兩個節點必須一致 auth_type PASS auth_pass 123456 } track_script { chk_nginx ##執行 Nginx 監控 } virtual_ipaddress { 192.168.20.100 ##VIP,兩個節點必須設置一樣(可設置多個) } }
BACKUP配置如下(默認配置文件:/etc/keepalived/keepalived.conf):
global_defs { router_id keep16 ##路由id,通常為 hostname } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" ## 檢測 nginx 狀態的腳本路徑 interval 2 ## 檢測時間間隔 weight -20 ## 如果條件成立,權重-20 } vrrp_instance VI_1 { state BACKUP ##主節點為 MASTER,備份節點為 BACKUP interface ens32 ##綁定 VIP 的網絡接口,與本機IP地址所在網絡接口相同 virtual_router_id 100 ##虛擬路由id,主從節點必須保持一致 priority 90 ##節點優先級,直范圍0-254,MASTER 要比 BACKUP 高 advert_int 1 authentication { ##設置驗證信息,兩個節點必須一致 auth_type PASS auth_pass 123456 } track_script { chk_nginx ##執行 Nginx 監控 } virtual_ipaddress { 192.168.20.100 ##VIP,兩個節點必須設置一樣(可設置多個) } }
其中有幾個配置需要注意:
a、router_id,最好配置成hostname(需要在 /etc/hosts 文件中,增加一行,比如:127.0.0.1 keep12)
b、interface,本機IP地址所在網絡接口(可以通過 ifconfig 命令查看具體ip所對應的那個接口名稱)
3、增加檢測心跳腳本
由於某些原因(比如主備都開啟了防火牆),導致兩台高可用服務器(Nginx + keepalived)在指定時間內,無法檢測到對方存活心跳信號,從而導致互相搶占對方的服務所有權,然而兩台高可用服務器可能都還存活着。所以需要增加一個檢測Nginx是否存活的腳本,如果Nginx掛掉了,則停掉該服務器上的keepalived(所有的keepalived都要配置)。
在 /etc/keepalived 目錄下,新增文件 nginx_check.sh (和上面對應script中對應),然后添加內容:
#!/bin/bash #1、判斷Nginx是否存活 counter=`ps -C nginx --no-header | wc -l` if [ $counter -eq 0 ]; then #2、如果不存活則嘗試啟動Nginx ./usr/local/nginx/sbin/nginx sleep 2 #3、等待2秒后再次獲取一次Nginx狀態 counter=`ps -C nginx --no-header | wc -l` #4、再次進行判斷,如Nginx還不存活則停止Keepalived,讓地址進行漂移 if [ $counter -eq 0 ]; then killall keepalived fi fi
4、測試
為了方便測試,最好先將上面心跳腳本文件中的重啟nginx注釋掉,不然手動停止Nginx后,又會被keepalived復活。
a、分別啟動兩台機器上的 Nginx 和 keepalived,然后訪問虛擬ip:http://192.168.20.100
b、停掉192.168.20.12上的Nginx服務,在 keepalived的日志文件中可以看到心跳腳本被執行了,最后殺掉了keepalived:
然后訪問虛擬ip:http://192.168.20.100
c、重新啟動192.168.20.12上的Nginx和keepalived服務,發現又回到了"ip:192.168.20.12"
踩過的坑
keepalived日志文件:/var/log/messages
1、心跳腳本沒有被執行
原因:腳本文件寫錯了,多了一些字符
解決:重新編輯心跳腳本文件,可以通過sh nginx_check.sh 命令執行一下,看編寫的腳本是否正確
2、心跳腳本執行報錯,日志提示:WARNING - script '/etc/keepalived/nginx_check.sh' is not executable for uid:gid 0:0 - disabling.
原因:心跳腳本文件沒有執行權限
解決:chmod +x /etc/keepalived/nginx_check.sh
3、心跳腳本執行報錯,日志提示:/etc/keepalived/nginx_check.sh exited due to signal 15
原因:心跳檢查間隔時間太短了
解決:interval設置大一點(一定要大於sleep時間)
其它
1、如果要配置keepalived非搶占式,可以參考:https://www.cnblogs.com/t-bar/p/9940085.html
2、keepalived命令:
systemctl start keepalived #啟動服務
systemctl restart keepalived #重啟服務
systemctl stop keepalived #停止服務
systemctl status keepalived #查看服務狀態