nginx+keepalived高可用

IT王小二發表於2021-07-01

一次面試過程中...

面試官:你這個使用 nginx 做負載,是使用單臺 nginx 嗎?如果 nginx 掛了怎麼辦?
我:是的,由於業務訪問量不大 nginx 掛的可能性不大,考慮服務的穩定性可以使用 keepalived。
面試官:你知道實現的思路和配置嗎?
我:。。。

一、傳統高可用

tomcat 高可用的思路是在 tomcat 叢集前面加一層負載nginx,如下圖:

傳統高可用

但是這種結構一旦 nginx 掛掉了,那麼整個服務就癱瘓了。

二、LVS思想解決高可用問題

1. 什麼是LVS

LVS是Linux Virtual Server的簡寫,意即Linux虛擬伺服器,是一個虛擬的伺服器叢集系統。本專案在1998年5月由章文嵩博士成立,是中國國內最早出現的自由軟體專案之一 -- 摘自百度百科

LVS 個人理解就是利用多個物理機叢集虛擬出一個虛擬ip(Virtual Server IP,簡稱VIP),虛擬ip不是實際存在的物理機,所以虛擬ip不會掛,而 LVS 的實現 Linux 核心已經幫助我們實現了,結構如下圖:

LVS示意圖

2. nginx+keepalived

在傳統高可用的基礎上,利用多臺伺服器叢集藉助 keepavlied 管理 LVS 虛擬出一個虛擬ip,只要兩臺 nginx 伺服器不當機那麼服務就不會癱瘓,如下圖:

nginx+keepalived

三、環境說明

  1. 演示機器ip:192.168.5.11,192.168.5.12
  2. Linux版本:CentOS Linux release 7.6.1810 (Core)
  3. keepalived版本:1.3.4
  4. nginx版本:1.13.1

四、keepalived具體配置

1. 前提

注意:兩臺機器都需要進行此步操作

1、修改 selinux,關閉 SELINUX,開啟 vim /etc/sysconfig/selinux,設定 SELINUX=disabled,我 VMWare 裡面安裝的 Linux 和騰訊雲的雲伺服器都預設關閉了,如下圖:

關閉selinux

2、安裝需要的依賴包。

yum -y install libnl libnl-devel libnfnetlink-devel

2. keepalived安裝

注意:兩臺機器都需要進行此步操作

1、不要使用 yum 方式安裝(有bug),keepalived 官網下載 keepalived 上傳,或者使用 wget 下載,下載後解壓。

wget https://www.keepalived.org/software/keepalived-1.3.4.tar.gz
tar -zxvf keepalived-1.3.4.tar.gz

2、解壓之後,指定目錄。

cd keepalived-1.3.4
./configure --prefix=/usr/local/keepalived --sysconf=/etc

注:

  • --prefix:指定安裝目錄。
  • --sysconf:keepalived配置檔案目錄,如果指定了其他配置目錄需要指定配置檔案啟動keepalived,如:/usr/local/keepalived/sbin/keepalived -D -f 配置檔案路徑

3、編譯安裝。

make && make install

3. keepalived配置

這一步略有不同,其中一臺機器作為主機(192.168.5.11),另外一臺機器作為備份機(192.168.5.12)

主機(192.168.5.11)配置

開啟 keepalived 配置檔案目錄(我的是/etc/keepalived)下的 keepalived.conf 檔案,配置如下資訊,其餘多餘配置刪除。

! Configuration File for keepalived

global_defs {
   router_id 192.168.5.11       # keepalived的唯一標識
}

vrrp_instance VI_1 {
    state MASTER                # 初始狀態,MASTER 和 BACKUP
    interface ens33             # 系統使用的網路卡介面名稱,可以使用ip addr檢視
    virtual_router_id 51        # 組名,參與此虛擬機器ip的機器配置一樣的值,即一個叢集內的機器都使用同一個值
    priority 200                # 優先順序,數值大的優先順序高,組內最高的勝出
    advert_int 1                # 心跳檢測1秒一次
    authentication {            # 授權,無需改動
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.5.10            # 虛擬ip
    }
}

備份機(192.168.5.12)配置

同樣開啟 keepalived 配置檔案目錄 ,開啟 keepalived.conf 檔案,配置如下資訊,和主機不同的是 router_id,interface,priority,配置如下:

! Configuration File for keepalived

global_defs {
   router_id 192.168.5.12       # keepalived的唯一標識
}

vrrp_instance VI_1 {
    state BACKUP                # 初始狀態,MASTER 和 BACKUP
    interface ens33             # 系統使用的網路卡介面名稱,可以使用ip addr檢視
    virtual_router_id 51        # 組名,參與此虛擬機器ip的機器配置一樣的值,即一個叢集內的機器都使用同一個值
    priority 100                # 優先順序,數值大的優先順序高,組內最高的勝出
    advert_int 1                # 心跳檢測1秒一次
    authentication {            # 授權,無需改動
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.5.10            # 虛擬ip
    }
}

4. 校驗LVS效果

1、分別啟動兩個機器上的 keepalived。

/usr/local/keepalived/sbin/keepalived

2、使用 ip addr 檢視效果,正常的結果是虛擬ip位於 192.168.5.11 這臺機器上,因為其配置的優先順序更高。可是...結果...不出意外的翻車了,哈哈哈!出現的問題是兩個機器出現了雙VIP,翻車截圖如下:

VM11ipaddr

VM12ipaddr

個人猜測是防火牆的原因,於是一波 Google 大法,果不其然,找到了原因:防火牆將 vrrp 廣播給攔截了,所以導致 BACKUP 接收不到 MASTER 的廣播。

查詢問題的過程:

區域網內任意一臺機器安裝抓包工具 tcpdump,命令:yum -y install tcpdump

執行 tcpdump -i ens33 vrrp -n 命令檢視情況,發現兩臺機器都在廣播,正常情況 BACKUP 不應該在廣播的。

抓包異常情況

為了驗證一下,把兩臺機器的防火牆全部關閉,命令:systemctl stop firewalld.service,發現情況正常了。

抓包正常情況

ip addr 檢視,發現配置成功了。

master_success

backup_success

不關閉防火牆放行 vrrp 廣播

正常情況我們們肯定不裸奔需要防火牆的,那麼就需要放行 vrrp 廣播。

# 需要注意命令中的網路卡名稱
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
# 重啟防火牆
firewall-cmd --reload

3、配置正常了,那麼就需要檢驗一下當 MASTER 主機當機之後虛擬ip是否會自動漂移到 BACKUP 備份機器了,當然為了模擬場景我只需要把 keepalived 服務幹掉就可以了。

kill_master

可以看到 BACKUP 備份機已經接管了。

BACKUP_MASTER

而當 MASTER 主機重啟之後,MASTER 主機又會搶回虛擬ip的控制權。

五、nginx+keepalived配合使用

前面配置好 keepalived 之後有人會問,這和nginx貌似沒啥關係,是滴,確實沒啥關係,但是接下來的配置就有關係了。

有時候,並非是伺服器當機了,而只是 nginx 掛掉了,而 keepalived 中並沒有相關配置,這樣的話如果 MASTER 主機中的 nginx 掛掉了,那麼虛擬ip也不會自動飄逸到 BACKUP 備份機,接下來就是為了結合 nginx的配置,使用 keepalived 來監控 nginx 。

1. 編輯心跳執行指令碼

我的執行指令碼位置儲存在 /usr/local/keepalived/chk_nginx_pid.sh,內容如下:

#!/bin/bash

A=`ps -C nginx --no-header |wc -l` # 統計nginx程式數,若為0,表明nginx被殺
if [ $A -eq 0 ];then
        # 重啟nginx,不是預設配置路徑所以需要指定路徑,因人而異
        /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
        # nginx重啟失敗,則停掉keepalived服務,進行VIP轉移
        if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
                # 殺掉,VIP就漫遊到另一臺機器
                killall keepalived
        fi
fi

注意:

  1. 儲存後賦予可執行許可權:chmod +x chk_nginx_pid.sh
  2. 檢視是否可以使用 killall 命令,如果無法使用 killall 命令則安裝psmisc: yum -y install psmisc

2. 配置keepalived配置檔案

增加的配置如圖:

keepalived心跳檢測nginx

vrrp_script check_nginx {
    script "/usr/local/keepalived/check_nginx.sh"       # 心跳執行的指令碼
    interval 2                                          # 每2秒檢測一次
    weight 2                                            # 指令碼結果導致的優先順序變更:10表示優先順序+10;-10則表示優先順序-10
}

track_script {
    check_nginx             # 呼叫檢測指令碼
}

3. 測試是否生效

關閉 keepalived 和 nginx的程式,重啟 keepalived,看 keepalived 是否可以自動啟動 nginx 。

killall keepalived

killall nginx

/usr/local/keepalived/sbin/keepalived

打不死的nginx

同理,BACKUP 備份機也同樣增加相同的心跳檢測指令碼和配置即可 。

測試發現,後面無論怎麼 kill 掉 nginx,nginx都會被 keepalived自動重啟,變成了打不死的小強,也就實現了 nginx 的高可用。

都讀到這裡了,來個 點贊、評論、關注、收藏 吧!

文章作者:IT王小二
首發地址:https://www.itwxe.com/posts/4c06301f/
版權宣告:文章內容遵循 署名-非商業性使用-禁止演繹 4.0 國際 進行許可,轉載請在文章頁面明顯位置給出作者與原文連結。

相關文章