Keepalived 原理與實戰

雪海覓隱香發表於2020-05-24

Keepalived 原理與實戰

隨著系統架構的逐漸演化,伺服器的數量和結構會越來越複雜,例如 Web 伺服器叢集的搭建,提高了系統的效能,同時也提高了系統維護的複雜度,我們需要對叢集中各臺伺服器進行監控,來保證為使用者提供服務的是正常執行的伺服器,整體系統的可用性就至關重要。

Keepalived 簡介

什麼是Keepalived ?

Keepalived一個基於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 雙機主備原理

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

  1. 解壓

    tar -zxvf keepalived-2.0.18.tar.gz
    
  2. 解壓後進入到解壓出來的目錄,看到會有configure,那麼就可以做配置了(配置安裝和nginx一模一樣)

    image-20200521210723704

  3. 使用configure命令配置安裝目錄與核心配置檔案所在位置

    ./configure --prefix=/usr/local/keepalived --sysconf=/etc
    
    • prefix:keepalived安裝的位置
    • sysconf:keepalived核心配置檔案所在位置,固定位置,改成其他位置則keepalived啟動不了,/var/log/messages中會報錯

    配置過程中可能會出現警告資訊,如下所示:

    image-20200521211303189

    解決方法:安裝 libnl/libnl-3 依賴 yum -y install libnl libnl-devel,重新configure一下就好了。

  4. 安裝keepalived

    make && make install
    
  5. 進入到/etc/keepalived,該目錄下為keepalived核心配置檔案

Keepalived 配置

把 Keepalived 註冊為系統服務

進入解壓縮安裝包的 etc 資料夾

image-20200521222326891

將系統配置檔案拷貝至系統 etc檔案

cp init.d/keepalived /etc/init.d/
cp sysconfig/keepalived /etc/sysconfig/

重新整理系統服務,載入新新增的 Keepalived 服務

systemctl daemon-reload

主伺服器(Master)配置

  1. 通過命令 vim keepalived.conf 開啟配置檔案,詳細配置如下
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

  1. 啟動 Keepalived

    在sbin目錄中進行啟動(同nginx),如下圖:

    image-20200521214728691

  2. 檢視程式

    ps -ef|grep keepalived
    

    image-20200521214838919

  3. 檢視虛擬 IP(VIP)

    在網路卡 ens33 下,多了一個 192.168.1.108 ,這個就是虛擬ip

    image-20200521220643981

Keepalived 實現雙機主備高可用

在配置完 Keepalived 主伺服器節點後,接下來就可以配置備用伺服器節點了,備用伺服器配置如下:

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

# 啟動keepalived
systemctl start keepalived
# 停止keepalived
systemctl stop keepalived
# 重啟keepalived
systemctl restart keepalived

檢視備用伺服器 Keepalived 程式

image-20200522235349567

現在主伺服器節點 192.168.1.104以及備用伺服器節點 192.168.1.105以及 Keepalived 虛擬 IP 192.168.1.105已配置完畢

image-20200522235637330

image-20200522235724708

這裡我在本地將 Keepalived 虛擬IP 192.168.1.108已對映至 www.keep.com

image-20200522235859619

所以直接訪問 www.keep.com 即可訪問主伺服器節點

image-20200523000014318

當主伺服器節點的 Keepalived 服務不可用時(這裡我直接將主伺服器的 Keepalived 服務直接停止systemctl stop keepalived.service,便於測試),虛擬IP 自動繫結至備用伺服器節點地址

image-20200523000333384

Keepalived 配置 Nginx 自動重啟

  1. 增加Nginx重啟檢測指令碼

    vim /etc/keepalived/check_nginx_alive_or_not.sh
    
    #!/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 狀態指令碼

    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中新增監控的指令碼

    track_script {
        check_nginx_alive   # 追蹤 nginx 指令碼
    }
    
  4. 重啟Keepalived使得配置檔案生效

    systemctl restart keepalived
    

Keepalived 實現雙主熱備高可用

image-20200523004644961

首先需要配置雲服務的 DNS 解析配置和負載均衡,詳細配置參考:

Keepalived 雙主熱備詳細配置:

規則:以一個虛擬ip分組歸為同一個路由

主節點配置

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
    }
}

備用節點配置

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
    }
}

參考文件

相關文章