Keepalived 高可用詳解

KingArmy發表於2023-12-25

Keepalived 詳解


1、Keepalived介紹

​ Keepalived是一個基於VRRP協議來實現LVS服務高可用方案,可以利用其來避免單點故障。一個LVS服務會使用2臺伺服器執行Keepalived,一臺為主伺服器MASTER,另一臺為備份伺服器BACKUP,但是對外表現為一個虛擬IP,主伺服器會傳送特定的訊息給備份伺服器,當備份伺服器收不到這個訊息的時候,即主伺服器當機的時候,備份伺服器就會接管虛擬IP,繼續提供服務,從而保證高可用性。Keepalived是VRRP的完美實現

2、Keepalived設計

​ 1、核心元件

​ 1)LVS 框架:使用 getsockopt 和 setsockopt 呼叫來獲取和設定套接字上的選項。

​ 2)Netfilter框架:支援NAT和偽裝的IPVS程式碼。

​ 3)Netlink 介面:設定和刪除網路介面上的 VRRP 虛擬 IP。

​ 4)組播:VRRP 通告傳送到保留的 VRRP MULTICAST 組 (224.0.0.18)。

​ 2、原子元素

​ 包含有控制平面(Control Plane)、排程器 - I/O 多路複用器(Scheduler - I/O Multiplexer)、記憶體管理(Memory Management)、看門狗(WatchDog)、VRRP協議棧(VRRP Stack)等

​ 3、健康檢查

​ 採用tcp、http,udp 、echo請求等方式對實際的伺服器進行保活,可以透過自定義監測指令碼來自定義健康監測內容機制

​ 4、故障切換

​ Keepalived 實現了用於控制器故障轉移的VRRP 協議,VRRP資料包排程程式負責為每個VRRP例項解複用特定的 I/O。

​ 主要應用在主備上,當主伺服器出現問題時自動由備用伺服器頂上,最大程度的保證系統的穩定性

3、Keepalived配置檔案(重點)

​ 配置檔案是etc/keepalived/keepalived.conf,該檔案主要由global_defs、vrrp_instance和virtual_server三個模組構成。global_defs:全域性配置;vrrp_instance:可配置虛擬路由,可以用來做高可用;virtual_server:虛擬伺服器,可以用來做負載均衡

​ 負載一般會放在nginx上使用,主要了解一下global_defs、vrrp_instance這兩個模組,看看高可用是怎麼做的,先看看配置檔案

! Configuration File for keepalived

# 全域性配置
global_defs {
   # 接收郵件
   notification_email {
        sunarmy@gmail.com
        sunarmy@163.com
   }
   # 傳送的郵箱
   notification_email_from sunarmy@163.com
   # 郵件伺服器
   smtp_server 127.0.0.1
   # 郵件伺服器超時時間
   smtp_connect_timeout 30
   # 路由id,唯一的
!   router_id LVS_DEVEL
!   vrrp_skip_check_adv_addr
   # 開啟了此項後沒有設定vrrp_iptables則會自動開啟iptables防火牆規則,導致VIP地址無法訪問,建議不加此項
!   vrrp_strict
   # 與vrrp_strict同時設定時可禁止iptables規則的生成,註釋或者無vrrp_strict時可不加此項
!   vrrp_iptables
   # 設定ARP介面之間傳送報文的延遲時間,可以精確到毫秒,預設是0
!   vrrp_garp_interval 0
   # 設定非請求訊息的傳送延遲時間,預設為0
!   vrrp_gna_interval 0
   # 指定要在其下執行指令碼的預設使用者名稱/組名,如果未指定此選項,則如果該使用者存在,則使用者預設為keepalived_script,否則為root,如果未指定groupname,則預設為使用者的組。
   script_user root
}

# 配置虛擬路由器
vrrp_instance VIP_1 {
    # 設定此虛擬路由器的初始狀態,可選擇MASTER或者BACKUP
    state MASTER
    # 繫結當前虛擬路由器所使用的物理介面,如eth0、lo等
    interface eth0
    # 設定虛擬路由器的唯一標識,取值範圍為0-255,每個虛擬路由器的該項值必須是唯一的,否則無法啟動服務,並且同屬一個虛擬路由器的多個keepalived節點必須相同,務必要確認在同一網路中此值必須唯一
    virtual_router_id 51
    # 設定當前物理節點在此虛擬路由器中的優先順序,優先順序取值範圍為1-254,值越大優先順序越高,每個keepalived節點取值不同
    priority 100
    # 設定VRRP通告的時間間隔,預設為1秒
    advert_int 1
    # 設定認證機制
    authentication {
        # 認證型別,可選擇AH和PASS兩種,AH為IPSC網際網路安全協議認證,PASS為簡單密碼認證,推薦PASS認證
        auth_type PASS
        # 預共享秘鑰設定,僅前8位有效,同一虛擬路由器的多個keepalived節點auth_pass值必須保持一致
        auth_pass 1111
    }
    # 新增虛擬路由器的IP,並可設定IP對應的子網掩碼、網路卡和標籤等,生產中可能會在同一個虛擬路由器上新增上百個IP,不同的IP分行隔開,不指定網路卡時預設新增在eth0上,不設定子網掩碼時預設為32位。在新增IP地址時,需確保將要使用的IP不存在
    virtual_ipaddress {
        10.211.55.11
    }
    #指定當切換到master時,執行的指令碼
    notify_master /opt/keepalived/etc/script/notify_fifo.sh
    #指定當切換到backup時,執行的指令碼
    notify_backup /opt/keepalived/etc/script/notify_fifo.sh
    #故障時執行的指令碼
    notify_fault /opt/keepalived/etc/script/notify_fifo.sh
    # 通知
    notify /opt/keepalived/etc/script/notify_fifo.sh
    #使用global_defs中提供的郵件地址和smtp伺服器傳送郵件通知 
    smtp_alert
}

​ 這個是把預設配置檔案中常用的一些說明都寫出來了,接下來我來講一下我個人對於keepalived做高可用的配置的一些理解,看是否能有助於各位理解

分模組講講

​ global_defs主要是全域性配置,其實很多都是關於郵件通知的配置,如果你不需要郵件通知(這個在大中國也確實不怎麼實用),其他的一些配置一般情況下用不到,總之這裡的配置對於我們的總體功能使用沒有太大影響,如果是新學的,可以暫時不太關注這塊

​ vrrp_instance模組,這個就是虛擬路由,這個就是高可用的配置模組了,虛擬路由顧名思義,會生成一個虛擬的路由地址,我們可以理解為虛擬IP,就是virtual_ipaddress裡面配置的地址,有了IP我們需要給他繫結到一個網路卡上,interface這個就是設定你需要繫結的網路卡,這個時候我們就基本上知道了,訪問這個虛擬IP所有流量都會走interface繫結的網路卡,OK,到這裡這個模組的核心功能你已經知道了

​ 當有多臺機器都部署keepalived並且配置跟這個機器一摸一樣的vrrp_instance模組,那麼是不是每個機器都會有這麼一個虛擬IP呢,要知道同一網路下IP是不能重複的,所以即使部署了N臺機器,同一時間也只會有一臺機器的網路卡繫結虛擬IP,多臺機器不就構成了一個叢集,我們再透過authentication來設定新增的機器是否可以加入這個叢集,到這兒網路方面的配置基本上就好了,同一個IP可以自動繫結在多臺機器上,多臺機器只有一臺機器繫結,這個時候一個叢集不就好了

4、配置郵件

​ 在etc/keepalived/samples/下有一個官方給的一個郵件指令碼sample_notify_fifo.sh

​ 1、配置郵箱伺服器

​ 要想傳送郵件就必須要一個郵箱伺服器,keepalived官方預設用的是sendmail,我們也配置這個,很多機器上預設就有這個,但是、但是、但是,別理他刪了再說,這玩意兒我不知道為啥,反正不能用,直接把他幹掉,然後重新裝一個

# 幹掉自帶sendmail,如果本來就沒有那就算了
yum remove -y sendmail
# 看看有沒有mail,有的話也幹掉,避免搶佔郵件伺服器埠,注意卸妝的時候是mailx
yum install -y mailx
# 重新安裝	
yum install -y sendmail
# 檢視一下sendmail服務,是否起來沒有起來就起來
檢視狀態:systemctl status sendmail
啟動:systemctl start sendmail
重啟:systemctl restart sendmail
停止:systemctl stop sendmail
# 檢視25埠是否已經存在
netstat -tunlp|grep 25
# 正常返回
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1864/sendmail: acce

OK,現在可以試試是否能夠傳送郵件

# 測試一下,可能會比較慢,耐心等待一下
echo "這是郵件內容" | sendmail -s "這是郵件主題" email@163.com

當然很大可能你的郵件發不出去,可以檢視一下日誌 vim /var/log/messages,好的,日誌沒有一點報錯資訊

接下來想到郵件伺服器,檢視一下狀態 systemctl start sendmail

看來我的域名解析有點問題,那就改一下吧。vim /etc/hosts,把提示的域名和hostname都加到127.0.0.1和:::1後面 儲存之後再次測試,

也可以使用其他方式,條條大路通羅馬,官方給了一個樣例在etc/keepalived/samples這個地方,sample_notify_fifo.sh. 樣例通知指令碼

5、keepalived日誌

​ 1、預設的日誌位置在/var/log/message,我們開啟看一下可以發現幾乎系統下的應用日誌都輸出到了這裡而不僅僅只有keepalived日誌

​ 2、怎麼把日誌剝離出來,自定義我們的日誌位置

​ 根據keepalived.service可以看到啟動引數在etc/sysconfig/keepalived,開啟檔案之後發現有很多引數

# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp               -P    Only run with VRRP subsystem.
# --check              -C    Only run with Health-checker subsystem.
# --dont-release-vrrp  -V    Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop.
# --dump-conf          -d    Dump the configuration data.
# --log-detail         -D    Detailed log messages.
# --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON)
#

KEEPALIVED_OPTIONS="-D"

​ 預設-D,日誌輸出的messages,日誌的高階配置引數是"--log-facility",該引數的作用就是借用syslog的0-7使用者自定義功能來定製keepalived服務的日誌資訊。我們可以基於該引數來定製我們的keepalived日誌。

# 編輯啟動引數,加入-S 0,使用0使用者輸出日誌資訊
vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 0"
# 編輯rsyslog配置檔案,定製rsyslog的使用者自定義日誌功能
vim /etc/rsyslog.conf
local0.*       /var/log/keepalived.log
# 重啟rsyslog服務
systemctl restart rsyslog
# 重啟keepalived服務
systemctl restart keepalived

​ 最開始我定義的日誌檔案在我keepalived的安裝目錄下,發現沒有keepalived.log檔案生成,然後透過日誌發現是沒有許可權,後來查了一下資料https://www.rsyslog.com/rsyslog-error-2433/ 好像是系統制定的規則,所以老老實實在/var/log/下單獨配置一個keepalived的日誌檔案了

​ 根據上面的配置即可

6、隨便講講keepalived

1、IP漂移

​ 我們知道了IP會在發生故障的時候自動切換到別的機器,這個就是IP漂移,那麼IP是根據什麼進行切換的?那麼就涉及到了主備切換的模式,keepalived有兩種模式:搶佔式和非搶佔式

​ 1、搶佔式:一種動態的排程策略,當主節點出現故障時,備份節點會搶佔成為新的主節點。在搶佔模式下,主節點和備份節點之間會進行競爭,優先順序高的節點會成為新的主節點。這種排程策略適用於需要快速恢復服務的情況,可以減少故障時間

​ 2、非搶佔式:一種靜態的排程策略,主節點和備份節點之間不會進行競爭。在非搶佔模式下,不會輕易發生IP漂移。這種排程策略適用於需要保證服務穩定性的情況,可以避免由於競爭導致的網路不穩定。之所以說不會輕易發生IP漂移是隻有當keepalived發生故障的時候(當前節點不可用)其他節點才會出來幹活

2、HA怎麼監聽服務狀態

​ 在vrrp_instance中可以配置track_script,來透過自定義指令碼監測服務狀態,而track_script中的weight可以控制當前節點的優先順序,在搶佔模式中,節點中的角色就可以透過這個值來控制

3、怎麼做通知

​ 關於通知除了上面提到過的郵件通知外,還有一些配置再進行一些說明

以下是notify_fifo、notify_fifo_script、vrrp_notify_fifo、vrrp_notify_fifo_script、notify_master、notify_backup、notify_fault、notify這些配置項的簡要說明:

notify_fifo:
這是一個FIFO(First In, First Out)檔案,用於在Keepalived程式之間傳遞通知事件。當Keepalived例項接收到通知事件時,它會將事件寫入到該FIFO檔案中

notify_fifo_script:
這是一個指令碼,當Keepalived例項接收到通知事件時,它會執行這個指令碼。指令碼的輸出會被寫入到notify_fifo檔案中,格式為:INSTANCE "VI_x" MASTER yyyy,其中x是虛擬路由器的ID,yyyy是優先順序值。

vrrp_notify_fifo 和 vrrp_notify_fifo_script:
這些配置項與上述的notify_fifo和notify_fifo_script類似,但它們是專門用於VRRP(Virtual Router Redundancy Protocol)的通知

當VRRP例項接收到通知事件時,它會使用這些配置項來處理通知。
notify_master、notify_backup、notify_fault:

這些是通知型別,用於指定當特定的事件發生時傳送通知。
notify_master:當主節點變為備份節點時傳送通知。
notify_backup:當備份節點變為主節點時傳送通知。
notify_fault:當節點出現故障時傳送通知。

7、高可用實戰

1、我這裡準備三臺機器使用nginx作為服務

​ 1、機器server、application、client,每臺機器上安裝nginx,然後啟動

​ 2、每臺機器上安裝keepalived

​ 配置如下

! Configuration File for keepalived

# 全域性配置
global_defs {
   # 接收郵件
   notification_email {
	     mm_mm@163.com
   }
   # 傳送的郵箱
   notification_email_from root@server
   # 郵件伺服器
    smtp_server 127.0.0.1
   # 郵件伺服器超時時間
   smtp_connect_timeout 30
   # 指定要在其下執行指令碼的預設使用者名稱
   script_user root
#   enable_script_security
}

vrrp_script check_nginx{
        # 指定指令碼絕對路徑
        script /opt/keepalived/etc/script/nginx_check_status.sh
        # 指令碼執行的時間間隔(以秒為單位)
        interval 1
        # 權重值。weight為正數時,執行結果為真,優先順序提升;執行結果為假,優先順序保持不變;weight為負數時,執行結果為真,優先順序不變;執行結果為假,優先順序會提升。
         weight -2
    }

# 配置虛擬路由器
vrrp_instance VI_1 {
    # 設定此虛擬路由器的初始狀態,可選擇MASTER或者BACKUP
    state BACKUP
    # 繫結當前虛擬路由器所使用的物理介面,如eth0、lo等
    interface eth0
    virtual_router_id 50
    priority 100
    # 設定VRRP通告的時間間隔,用於設定MASTER與BACKUP主機之間同步檢查的時間間隔,單位是秒。預設為1秒
    advert_int 1
    # 非搶佔模式,預設搶佔模式
#    nopreempt
    authentication {
        auth_type PASS
        auth_pass password
    }
    virtual_ipaddress {
        10.211.55.11
    }
    track_script{
	check_nginx
    }
    smtp_alert
}

nginx_check_status.sh指令碼如下

#!/bin/sh
check_command=`pidof nginx 2> /dev/null`
if [ -z "$check_command" ] ; then
	exit 2
fi
exit 0

在application和client配置和它一樣的配置

3、觀察虛擬IP在哪個機器上

​ 1)瀏覽器訪問虛擬IP:10.211.55.11

看到現在IP是在server上

​ 4透過停止nginx來模擬服務中斷,觀察IP是否會漂移

​ 停止server上的nginx,看是否還能訪問,IP在哪裡?

我們看到當我們把server上的nginx停止之後,IP自動漂移到了application機器上,原來的虛擬iP正常訪問只是服務已經由application提供,這樣已經達到了我們的目的

實戰說明:

​ 這裡配置的很潦草,只能說明大概的一個配置方式,最終使用的時候還是根據大家不同的業務場景和需求去定製化配置各自的高可用,在這個裡面,如果是線上環境的話通知是必不可少的,我這裡實際上也配置了郵件通知,只不過時靈時不靈,跟郵件伺服器有關係,郵件在國內還是有點雞肋,不多做介紹,大家可以使用notify_master、notify_backup、notify_fault這些指令,透過自定義指令碼去定製化自己的通知,比如釘釘之類的可用性會更好一點

說在最後,我不是在教學,我只是希望大家和我一起學習

相關文章