[轉]使用keepalived搭建主備切換環境


使用keepalived搭建主備切換環境

1. keepalived介紹

Keepalived是Linux下一個輕量級的高可用解決方案,它與HeartBeat、RoseHA實現的功能類似,都可以實現服務或者網絡的高可用,但是又有差別:HeartBeat是一個專業的、功能完善的高可用軟件,它提供了HA軟件所需的基本功能,比如心跳檢測和資源接管,監測集群中的系統服務,在群集節點間轉移共享IP地址的所有者等,HeartBeat功能強大,但是部署和使用相對比較麻煩;與HeartBeat相比,Keepalived主要是通過虛擬路由冗余來實現高可用功能,雖然它沒有HeartBeat功能強大,但Keepalived部署和使用非常簡單,所有配置只需一個配置文件即可完成。

keepalived主要有三個模塊,分別是core、check和vrrp。core模塊為keepalived的核心,負責主進程的啟動、維護以及全局配置文件的加載和解析。check負責健康檢查,包括常見的各種檢查方式。vrrp模塊是來實現VRRP協議的。

keepalived實現的功能主要有三個:

  1. 將IP地址飄移到其他節點上,
  2. 在另一個主機上生成ipvs規則
  3. 健康狀況檢查。

keepalived通過軟件的方式在其內部模擬實現VRRP協議,然后借助於VRRP協議實現IP地址漂移。

2. keepalived用來做什么

Keepalived是基於VRRP協議的高級應用,作用於網絡層、傳輸層和應用層交換機制的處理高可用的軟件。主要用作RealServer的健康狀態檢查以及LoadBalance主機和BackUP主機之間failover的實現。

Keepalived起初是為LVS設計的,專門用來監控集群系統中各個服務節點的狀態。它根據layer3, 4 & 5交換機制檢測每個服務節點的狀態,如果某個服務節點出現異常,或工作出現故障,Keepalived將檢測到,並將出現故障的服務節點從集群系統中剔除,而在故障節點恢復正常后,Keepalived又可以自動將此服務節點重新加入到服務器集群中,這些工作全部自動完成,不需要人工干涉,需要人工完成的只是修復出現故障的服務節點。

Keepalived后來又加入了VRRP的功能,VRRP是Virtual Router Redundancy Protocol(虛擬路由器冗余協議)的縮寫,它出現的目的是為了解決靜態路由出現的單點故障問題,通過VRRP可以實現網絡不間斷地、穩定地運行。因此,Keepalived一方面具有服務器狀態檢測和故障隔離功能,另一方面也具有HA cluster功能。

keepalived可以實現輕量級的高可用,一般用於前端高可用,且不需要共享存儲,一般常用於兩個節點的高可用(常見的前端高可用組合有LVS+Keepalived、Nginx+Keepalived、HAproxy+Keepalived)。

3. Keepalived工作原理

Keepalived作為一個高性能集群軟件,它還能實現對集群中服務器運行狀態的監控及故障隔離。接下來介紹下Keepalived對服務器運行狀態監控和檢測的工作原理。 Keepalived工作在TCP/IP參考模型的第三、第四和第五層,也就是網絡層、傳輸層和應用層。根據TCP/IP參考模型各層所能實現的功能,Keepalived運行機制如下:

  1. 在網絡層,運行着四個重要的協議:互連網協議IP、互連網控制報文協議ICMP、地址轉換協議ARP以及反向地址轉換協議RARP。Keepalived在網絡層采用的最常見的工作方式是通過ICMP協議向服務器集群中的每個節點發送一個ICMP的數據包(類似於ping實現的功能),如果某個節點沒有返回響應數據包,那么就認為此節點發生了故障,Keepalived將報告此節點失效,並從服務器集群中剔除故障節點。
  2. 在傳輸層,提供了兩個主要的協議:傳輸控制協議TCP和用戶數據協議UDP。傳輸控制協議TCP可以提供可靠的數據傳輸服務,IP地址和端口,代表一個TCP連接的一個連接端。要獲得TCP服務,須在發送機的一個端口上和接收機的一個端口上建立連接,而Keepalived在傳輸層就是利用TCP協議的端口連接和掃描技術來判斷集群節點是否正常的。比如,對於常見的Web服務默認的80端口、SSH服務默認的22端口等,Keepalived一旦在傳輸層探測到這些端口沒有響應數據返回,就認為這些端口發生異常,然后強制將此端口對應的節點從服務器集群組中移除。
  3. 在應用層,可以運行FTP、TELNET、SMTP、DNS等各種不同類型的高層協議,Keepalived的運行方式也更加全面化和復雜化,用戶可以通過自定義Keepalived的工作方式,例如用戶可以通過編寫程序來運行Keepalived,而Keepalived將根據用戶的設定檢測各種程序或服務是否允許正常,如果Keepalived的檢測結果與用戶設定不一致時,Keepalived將把對應的服務從服務器中移除。

4. 安裝

在線安裝:

# yum -y install keepalived ipvsadm

或者源碼安裝:

# wget http://www.keepalived.org/software/keepalived-1.2.15.tar.gz
# tar -xf keepalived-1.2.15.tar.gz && cd keepalived-1.2.15
# ./configure && make && make install
# wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
# tar -xf ipvsadm-1.26.tar.gz && cd ipvsadm-1.26/
# make && make install

關閉SELinux(改完需重啟服務器):

# sed -i 's#^SELINUX=.*#SELINUX=disabled#' /etc/sysconfig/selinux

5. 實戰

本文搭建、測試Keepalived高可用架構。測試環境使用兩台真實服務器,如下介紹:

虛擬ip     : 192.168.14.166,默認指向Master(192.168.14.8)
真實服務器1 : Master,192.168.14.8, 該機器上同時運行Apache Httpd服務(端口80)和一個python腳本的HttpServer服務(端口8000);
真實服務器2 : Backup,192.168.14.14, 該機器上同時運行Apache Httpd服務(端口80)和一個python腳本的HttpServer服務(端口8000);

系統部署結構如下所示:

+-------------+
                   |    router   |
                   +-------------+
                          |
                          +
    Master            keepalived           Backup
  192.168.14.8      192.168.14.166     192.168.14.14
+-------------+    +-------------+    +-------------+
|  httpd_01   |----| virtual IP  |----|  httpd_01   |
+-------------+    +-------------+    +-------------+

在Master和Backup的運行的兩個測試服務單獨運行效果如下:

Master(192.168.14.8):

Backup(192.168.14.14):

此時 虛擬ip(192.168.14.166)是不存在的,也即無法訪問。

5.1 創建keepalived配置文件

keepalived只有一個配置文件keepalived.conf,里面主要包括以下幾個配置區域,分別是global_defs、vrrp_script、vrrp_instance和virtual_server。其中vrrp_instance區域用來定義對外提供服務的VIP區域及其相關屬性, 而virtual_server和real_server區域是用來配合lvs使用的,本次暫時用不到。

在Master(192.168.14.8)上:

# cat /etc/keepalived/keepalived.conf
global_defs {
    notification_email {
        #mr@mruse.cn       # 指定keepalived在發生切換時需要發送email到的對象,一行一個
        #sysadmin@firewall.loc
    }
    notification_email_from xxx@163.com   # 指定發件人
    smtp_server smtp@163.com              # smtp 服務器地址
    smtp_connect_timeout 30               # smtp 服務器連接超時時間
    router_id LVS_1 # 標識本節點的字符串,通常為hostname,但不一定非得是hostname,故障發生時,郵件通知會用到
}

vrrp_instance VI_1 {  # 實例名稱
    state MASTER      # 可以是MASTER或BACKUP,不過當其他節點keepalived啟動時會將priority比較大的節點選舉為MASTER
    interface eth0    # 節點固有IP(非VIP)的網卡,用來發VRRP包做心跳檢測
    virtual_router_id 51 # 虛擬路由ID,取值在0-255之間,用來區分多個instance的VRRP組播,同一網段內ID不能重復;主備必須為一樣;
    priority 100      # 用來選舉master的,要成為master那么這個選項的值最好高於其他機器50個點,該項取值范圍是1-255(在此范圍之外會被識別成默認值100)
    advert_int 1      # 檢查間隔默認為1秒,即1秒進行一次master選舉(可以認為是健康查檢時間間隔)
    authentication {  # 認證區域,認證類型有PASS和HA(IPSEC),推薦使用PASS(密碼只識別前8位)
        auth_type PASS  # 默認是PASS認證
        auth_pass MrUse # PASS認證密碼
    }
    virtual_ipaddress {
        192.168.14.166    # 虛擬VIP地址,允許多個
    }
}

在Backup(192.168.14.14)上keepalived.conf文件和Master上的基本一致,拷貝過來,並修改其中的以下幾項即可:

state BACKUP     # 此值可設置或不設置,只要保證下面的priority不一致即可
interface eth0   # 根據實際情況選擇網卡
priority 40      # 此值要一定小於Master機器上的值,最好相差不少於50

注意:在配置keepalived.conf時,需要特別注意配置文件的語法格式以及出現重復的VIP,因為keepalived在啟動時並不檢測配置文件的正確性,即使沒有配置文件,keepalived也能照樣啟動,所以一定要保證配置文件的正確性。

啟動Keepalived並加入開機啟動:

/etc/init.d/keepalived restart
chkconfig keepalived on

啟動Keepalived:

# service keepalived start  # 此時會嘗試讀取/etc/keepalived/keepalived.conf配置文件
如果配置文件位於其他地方,則:
# keepalived -f /xxx/path/keepalived.conf

啟動之后,keepalived會運行三個進程:

# ps -ef | grep keepalived
root      2030     1  0 08:59 ?        00:00:01 keepalived -f /etc/keepalived/keepalived.conf
root      2041  2030  0 08:59 ?        00:00:01 keepalived -f /etc/keepalived/keepalived.conf
root      2042  2030  0 08:59 ?        00:00:03 keepalived -f /etc/keepalived/keepalived.conf

通過以下命令可以查看VIP當前綁定在哪個機器上:

# ip addr 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:8e:b8:31 brd ff:ff:ff:ff:ff:ff
    inet 192.168.14.8/16 brd 192.168.255.255 scope global eth0
    inet 192.168.14.166/32 scope global eth0            ## 注意此行

5.2 測試正常情況

在Master和Backup上分別啟動keepalived。此時VIP(192.168.14.166)是可訪問的,也可以ping通,通過虛擬ip(192.168.14.166)訪問兩個測試服務:

會發現此時VIP(192.168.14.166)指向了Master(192.168.14.8)上的服務。如果從另一台機器上通過ssh連接VIP(192.168.14.166),可以登陸成功且登陸的主機即是Master(192.168.14.8)。

此時在Master(192.168.14.8)上運行以下命令,會發現VIP綁定在了Master上:

# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:8e:b8:31 brd ff:ff:ff:ff:ff:ff
inet 192.168.14.8/16 brd 192.168.255.255 scope global eth0

5.3 測試Master宕掉的情況

現在停掉Master(192.168.14.8)上的keepalived用來模擬Master機器宕掉或者網絡不通,此時再通過虛擬ip(192.168.14.166)訪問兩個測試服務會發現 所有服務都已指向了Backup (192.168.14.14):

此時在Backup(192.168.14.14)上運行以下命令,會發現VIP綁定在了Backup上:

# ip addr show eth0 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:76:6c:46 brd ff:ff:ff:ff:ff:ff
inet 192.168.14.14/16 brd 192.168.255.255 scope global eth0
inet 192.168.14.166/32 scope global eth0

而Master上已經沒有了該VIP(192.168.14.166)。

疑問:

  1. 多次測試時有的時候停掉Master上的keepalived,通過VIP切到Backup上時比較慢;
  2. 如果停掉Master的網絡,發現不能切換;

不知道是我哪里設置錯了???????????

5.4 測試Master宕掉又恢復的情況

接上一測試,此時再重新啟動Master(192.168.14.8)上的keepalived,模擬Master機器已開機或網絡已修復,,此時再通過虛擬ip(192.168.14.166)訪問兩個測試服務會發現所有服務 又都重新指向了Master (192.168.14.8),這里就不截圖了,可以自行驗證。

5.5 測試某一服務掛掉的情況

這里假設所有設置都是初始狀態,VIP指向Master,但將Master(192.168.14.8)的Apache Httpd服務停掉,然后通過VIP訪問:

此時發現VIP仍指向Master,但是80端口的Http服務已不可訪問,而8000端口的服務還可以繼續訪問且仍指向Master。

6 解決Master存在但服務宕掉的問題

如果解決上面VIP指向Master,但是Master上服務宕掉的問題呢?其實也簡單,我們在keepalived.conf中增加對Httpd服務的檢測(完整配置文件):

# cat /etc/keepalived/keepalived.conf 
global_defs {
   notification_email {
   #  acassen@firewall.loc   # 指定keepalived在發生切換時需要發送email到的對象,一行一個
   #  sysadmin@firewall.loc
   }
   #notification_email_from Alexandre.Cassen@firewall.loc  # 指定發件人
   #smtp_server 192.168.200.1     # smtp 服務器地址 
   #smtp_connect_timeout 30       # smtp 服務器連接超時時間
   router_id LVS_DEVEL            # 標識本節點的字符串,通常為hostname,但不一定非得是hostname,故障發生時,郵件通知會用到
}
### 新增 ###
vrrp_script chk_httpd {
    script "/etc/keepalived/check_and_start_httpd.sh"   # apache httpd 服務檢測並試圖重啟
    interval 2                    # 每2s檢查一次
    weight -5                     # 檢測失敗(腳本返回非0)則優先級減少5個值
    fall 3                        # 如果連續失敗次數達到此值,則認為服務器已down
    rise 2                        # 如果連續成功次數達到此值,則認為服務器已up,但不修改優先級
}

vrrp_instance VI_1 {              # 實例名稱
    state MASTER                  # 可以是MASTER或BACKUP,不過當其他節點keepalived啟動時會自動將priority比較大的節點選舉為MASTER
    interface eth0                # 節點固有IP(非VIP)的網卡,用來發VRRP包做心跳檢測
    virtual_router_id 51          # 虛擬路由ID,取值在0-255之間,用來區分多個instance的VRRP組播,同一網段內ID不能重復;主備必須為一樣
    priority 100                  # 用來選舉master的,要成為master那么這個選項的值最好高於其他機器50個點,該項取值范圍是1-255(在此范圍之外會被識別成默認值100)
    advert_int 1                  # 檢查間隔默認為1秒,即1秒進行一次master選舉(可以認為是健康查檢時間間隔)
    authentication {              # 認證區域,認證類型有PASS和HA(IPSEC),推薦使用PASS(密碼只識別前8位)
        auth_type PASS            # 默認是PASS認證
        auth_pass 1111            # PASS認證密碼
    }
    virtual_ipaddress {
        192.168.14.166            # 虛擬VIP地址,允許多個,一行一個
    #    192.168.200.17
    }
    ### 新增 ###
    track_script {                # 引用VRRP腳本,即在 vrrp_script 部分指定的名字。定期運行它們來改變優先級,並最終引發主備切換。
        chk_httpd          
    }                
}

再寫一個腳本:

# cat /etc/keepalived/check_and_start_httpd.sh 
#!/bin/bash
counter=$(ps -C httpd --no-heading|wc -l)
if [ "${counter}" = "0" ]; then
    service httpd start
    sleep 2
    counter=$(ps -C httpd --no-heading|wc -l)
    if [ "${counter}" = "0" ]; then
        /etc/rc.d/init.d/keepalived stop
    fi
fi

該腳本的目的是用來檢測httpd服務是否存在,如果不存在就重啟,重啟失敗就關閉本機keepalived以便VIP切換到Backup機器上。該腳本由keepalived進行調用。

此時停掉Apache Httpd服務:

# date && service httpd status
2016年 09月 13日 星期二 11:32:07 CST
httpd (pid  20374) 正在運行...
# date && service httpd stop  
2016年 09月 13日 星期二 11:32:13 CST
停止 httpd:                                               [確定]
# date && service httpd status
2016年 09月 13日 星期二 11:32:14 CST
httpd (pid  21623) 正在運行...

可以發現Httpd停掉之后就進行自動重啟了(前后pid不一樣),而且重啟速度也比較快(從date顯示的時間可以看到)。當然這也不能保證所有的Http請求都不丟棄(事實上很可能有部分請求是失敗的)。

配置8000端口的python版HttpServer測試服務,與上面類似,這里就不再驗證了。

vrrp_script

告訴 keepalived 在什么情況下切換,所以尤為重要。可以有多個 vrrp_script

  • script : 自己寫的檢測腳本。也可以是一行命令如killall -0 nginx
  • interval 2 : 每2s檢測一次
  • weight -5 : 檢測失敗(腳本返回非0)則優先級 -5
  • fall 2 : 檢測連續 2 次失敗才算確定是真失敗。會用weight減少優先級(1-255之間)
  • rise 1 : 檢測 1 次成功就算成功。但不修改優先級

這里要提示一下script一般有2種寫法:

  1. 通過腳本執行的返回結果,改變優先級,keepalived繼續發送通告消息,backup比較優先級再決定
  2. 腳本里面檢測到異常,直接關閉keepalived進程,backup機器接收不到advertisement會搶占IP

上文 vrrp script 配置部分`/etc/keepalived/check and start httpd.sh`屬於第2種情況(腳本中關閉keepalived)。個人更傾向於通過shell腳本判斷,但有異常時exit 1,正常退出exit 0,然后keepalived根據動態調整的 vrrp_instance 優先級選舉決定是否搶占VIP:

  • 如果腳本執行結果為0,並且weight配置的值大於0,則優先級相應的增加
  • 如果腳本執行結果非0,並且weight配置的值小於0,則優先級相應的減少
  • 其他情況,原本配置的優先級不變,即配置文件中priority對應的值

提示:

  • 優先級不會不斷的提高或者降低
  • 可以編寫多個檢測腳本並為每個檢測腳本設置不同的weight(在配置中列出就行)
  • 不管提高優先級還是降低優先級,最終優先級的范圍是在[1,254],不會出現優先級小於等於0或者優先級大於等於255的情況
  • 在MASTER節點的 vrrp_instance 中 配置 nopreempt ,當它異常恢復后,即使它 prio 更高也不會搶占,這樣可以避免正常情況下做無謂的切換

以上可以做到利用腳本檢測業務進程的狀態,並動態調整優先級從而實現主備切換。

上面寫的check and start_httpd.sh腳本在發現httpd關閉時會試圖重啟httpd,如果重啟失敗則停掉本機的keepalived,以觸發主備切換。事實上,腳本內容可以根據自己的業務靈活定義,比如使用curl命令連續獲取2次主頁,如果3s內沒有響應則觸發切換:

#!/bin/bash
count=0
for (( k=0; k<2; k++ ))
do
    check_code=$( curl --connect-timeout 3 -sL -w "%{http_code}\\n" http://localhost/index.html -o /dev/null )
    if [ "$check_code" != "200" ]; then
        count=$(expr $count + 1)
        sleep 3
        continue
    else
        count=0
        break
    fi
done
if [ "$count" != "0" ]; then
#   /etc/init.d/keepalived stop
    exit 1
else
    exit 0
fi

7. 其他

以上演示中,主要以Apache Httpd作為測試服務,其實這里使用Nginx也是可以的,這樣就相當於Nginx是前端,做到高可用,然后Nginx上部署反向代理、負載均衡,將業務請求轉發到真實的業務服務器上, 一套主備切換+負載均衡的高可用架構就形成了

8. Reference


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM