Keepalived安裝使用詳解


簡介

Keepalived是一個基於VRRP協議來實現的服務高可用方案,可以利用其來避免IP單點故障,類似的工具還有heartbeat、corosync、pacemaker。

但是它一般不會單獨出現,而是與其它負載均衡技術(如lvs、haproxy、nginx)一起工作來達到集群的高可用。

Keepalived的作用是檢測服務器的狀態,如果有一台web服務器死機,或工作出現故障,Keepalived將檢測到,並將有故障的服務器從系統中剔除,同時使用其他服務器代替該服務器的工作;

當服務器工作正常后Keepalived自動將服務器加入到服務器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的服務器。

安裝

#下載
wget http://www.keepalived.org/software/keepalived-1.2.23.tar.gz
#解壓
tar -zxvf keepalived-1.2.23.tar.gz
cd keepalived-1.2.23
#安裝
./configure --prefix=/usr/local/keepalived   #prefix指定安裝目錄
make
make install

 

配置

【/usr/local/keepalived/etc/keepalived/keepalived.conf】

global_defs {
    notification_email { #指定keepalived在發生事情的時候,發送郵件告知,可以有多個地址,每行一個。
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc #指定發件人
    smtp_server 127.0.0.1 #發送email的smtp地址
    smtp_connect_timeout 30 #超時時間
    router_id LVS_DEVEL #運行keepalived的機器的一個標識,多個節點標識可以相同,也可以不同
    vrrp_skip_check_adv_addr 
    vrrp_strict
    vrrp_garp_interval 0
    vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER #指定當前節點為主節點 備用節點上設置為BACKUP即可
    interface eth0 #綁定虛擬IP的網絡接口
    virtual_router_id 51 #VRRP組名,兩個節點的設置必須一樣,以指明各個節點屬於同一VRRP組
    priority 100 #主節點的優先級(1-254之間),備用節點必須比主節點優先級低
    advert_int 1
    authentication { #設置驗證信息,兩個節點必須一致
      auth_type PASS
      auth_pass 1111
    }
    virtual_ipaddress { #指定虛擬IP, 兩個節點設置必須一樣
      192.168.1.21/24
    }
}


【/usr/local/keepalived/etc/sysconfig/keepalived】

KEEPALIVED_OPTIONS="-D -f /usr/local/keepalived/etc/keepalived/keepalived.conf" #指定keepalived配置文件路徑

 

因為我們使用非默認路徑(/usr/local)安裝keepalived,需要設置一些軟鏈接以保證keepalived能正常啟動

ln -s /usr/local/keepalived/sbin/keepalived  /usr/bin #將keepalived主程序加入到環境變量
ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived  /etc/init.d/ #keepalived啟動腳本,放到/etc/init.d/目錄下就可以使用service命令便捷調用
ln -s /usr/local/keepalived/etc/sysconfig/keepalived  /etc/sysconfig/ #keepalived啟動腳本變量引用文件,默認文件路徑是/etc/sysconfig/,也可以不做軟鏈接,直接修改啟動腳本中文件路徑即可

 

啟動

service keepalived start|stop|restart
chkconfig keepalived on


默認的配置文件中,指定了虛擬IP :192.168.1.21,可使用ip addr(或ip a)命令驗證之。

 

應用

keepalived兩種模式:主-備主-主

主-備

虛擬IP:192.168.1.21         主節點:192.168.1.23          備用節點:192.168.1.24

主配置文件

【/usr/local/keepalived/etc/keepalived/keepalived.conf】

global_defs {
    notification_email { #指定keepalived在發生事情的時候,發送郵件告知,可以有多個地址,每行一個。
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc #指定發件人
    smtp_server 127.0.0.1 #發送email的smtp地址
    smtp_connect_timeout 30 #超時時間
    router_id LVS_DEVEL #運行keepalived的機器的一個標識,多個節點標識可以相同,也可以不同
    vrrp_skip_check_adv_addr 
    vrrp_strict
    vrrp_garp_interval 0
    vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER #指定當前節點為主節點 備用節點上設置為BACKUP即可
    interface eth0 #綁定虛擬IP的網絡接口
    virtual_router_id 51 #VRRP組名,兩個節點的設置必須一樣,以指明各個節點屬於同一VRRP組
    priority 100 #主節點的優先級(1-254之間),備用節點必須比主節點優先級低
    advert_int 1
    authentication { #設置驗證信息,兩個節點必須一致
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress { #指定虛擬IP, 兩個節點設置必須一樣
        192.168.1.21/24
    }
}    

 

備配置文件
【/usr/local/keepalived/etc/keepalived/keepalived.conf】

global_defs {
    notification_email { #指定keepalived在發生事情的時候,發送郵件告知,可以有多個地址,每行一個。
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc #指定發件人
    smtp_server 127.0.0.1 #發送email的smtp地址
    smtp_connect_timeout 30 #超時時間
    router_id LVS_DEVEL #運行keepalived的機器的一個標識,多個節點標識可以相同,也可以不同
    vrrp_skip_check_adv_addr 
    vrrp_strict
    vrrp_garp_interval 0
    vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP #指定當前節點為主節點 備用節點上設置為BACKUP即可
    interface eth0 #綁定虛擬IP的網絡接口
    virtual_router_id 51 #VRRP組名,兩個節點的設置必須一樣,以指明各個節點屬於同一VRRP組
    priority 99 #主節點的優先級(1-254之間),備用節點必須比主節點優先級低
    advert_int 1
    authentication { #設置驗證信息,兩個節點必須一致
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress { #指定虛擬IP, 兩個節點設置必須一樣
        192.168.1.21/24
    }
}

 

 

主-主

虛擬IP:192.168.1.21、192.168.1.22      A節點:192.168.1.23       B節點:192.168.1.24

主備模式的缺點就是始終只有一台機器位於工作狀態,另外一台機器永遠是備用狀態,存在資源浪費之問題。

雙主模式允許兩台機器均處於工作狀態並互相作為備份。搭建keepalived雙方模式的要素:

1.必須有兩個虛擬IP, 分別綁定至兩個節點上

2.每個節點作為某個虛擬IP的主節點,並同時作為另外一個虛擬IP的備用節點。

3.當某個節點產生故障時,兩個虛擬IP自動綁定至正常節點上

也就是說,兩個節點的配置應該是交叉的,對同個虛擬IP,交叉互為主備。

 

 

節點A配置文件

【/usr/local/keepalived/etc/keepalived/keepalived.conf】

global_defs {
    notification_email { #指定keepalived在發生事情的時候,發送郵件告知,可以有多個地址,每行一個。
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc #指定發件人
    smtp_server 127.0.0.1 #發送email的smtp地址
    smtp_connect_timeout 30 #超時時間
    router_id LVS_DEVEL #運行keepalived的機器的一個標識,多個節點標識可以相同,也可以不同
    vrrp_skip_check_adv_addr 
    vrrp_strict
    vrrp_garp_interval 0
    vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER 
    interface eth0 
    virtual_router_id 51 #本機兩個vrrp_instance組的此值不能相同,但對應備用節點的此值必須相同
    priority 100 #對應備用節點值應該比此值小
    advert_int 1
    authentication { 
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress { 
        192.168.1.21/24
    }
}

vrrp_instance VI_2 {
    state BACKUP 
    interface eth0 
    virtual_router_id 52 #本機兩個vrrp_instance組的此值不能相同,但對應備用節點的此值必須相同
    priority 99 #主節點的值應該比此值大
    advert_int 1
    authentication { 
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress { 
        192.168.1.22/24
    }
}

 


節點B配置文件
【/usr/local/keepalived/etc/keepalived/keepalived.conf】

global_defs {
   notification_email { #指定keepalived在發生事情的時候,發送郵件告知,可以有多個地址,每行一個。
    acassen@firewall.loc
    failover@firewall.loc
    sysadmin@firewall.loc
}
  notification_email_from Alexandre.Cassen@firewall.loc #指定發件人
  smtp_server 127.0.0.1 #發送email的smtp地址
  smtp_connect_timeout 30 #超時時間
  router_id LVS_DEVEL #運行keepalived的機器的一個標識,多個節點標識可以相同,也可以不同
  vrrp_skip_check_adv_addr 
  vrrp_strict
  vrrp_garp_interval 0
  vrrp_gna_interval 0
}

vrrp_instance VI_1 {
  state BACKUP 
  interface eth0 
  virtual_router_id 51 #本機兩個vrrp_instance組的此值不能相同,但對應備用節點的此值必須相同
  priority 99 #對應主節點值應該比此值大
  advert_int 1
  authentication { 
    auth_type PASS
    auth_pass 1111
  }
  virtual_ipaddress { 
    192.168.1.21/24
  }
}

vrrp_instance VI_2 {
  state MASTER 
  interface eth0 
  virtual_router_id 52 #本機兩個vrrp_instance組的此值不能相同,但對應備用節點的此值必須相同
  priority 100 #對應備用節點的值應該比此值小
  advert_int 1
  authentication { 
    auth_type PASS
    auth_pass 1111
  }
  virtual_ipaddress { 
    192.168.1.22/24
  }
}

 

腦裂問題

兩個節點實際都處於正常工作狀態,但是無法接收到彼此的組播通知,這時兩個節點均強行綁定虛擬IP,導致不可預料的后果。

這時就需要設置仲裁,即每個節點必須判斷自身的狀態(應用服務狀態及自身網絡狀態),要實現這兩點可使用自定義shell腳本實現,通過周期性地檢查自身應用服務狀態,並不斷ping網關(或其它可靠的參考IP)均可。當自身服務異常、或無法ping通網關,則認為自身出現故障,就應該移除掉虛擬IP(停止keepalived服務即可)。


主要借助keepalived提供的vrrp_script及track_script實現:

在keepalived的配置文件最前面加入以下代碼,定義一個跟蹤腳本:

vrrp_script check_local { #定義一個名稱為check_local的檢查腳本
  script "/usr/local/keepalived/bin/check_local.sh" #shell腳本的路徑
  interval 5 #運行間隔
}


再在vrrp_instance配置中加入以下代碼使用上面定義的檢測腳本:

track_script {
  check_local
}

我們在/usr/local/keepalived/bin/check_local.sh定義的檢測規則是:

1. 自身web服務故障(超時,http返回狀態不是200)

2. 無法ping通網關

3. 產生以上任何一個問題,均應該移除本機的虛擬IP(停止keepalived實例即可)


但這里有個小問題,如果本機或是網關偶爾出現一次故障,那么我們不能認為是服務故障。更好的做法是如果連續N次檢測本機服務不正常或連接N次無法ping通網關,才認為是故障產生,才需要進行故障轉移。

但這么做的缺點是,如果腳本檢測到故障產生,並停止掉了keepalived服務,那么當故障恢復后,keepalived是無法自動恢復的。

 

還可以利用獨立的腳本以秒級的間隔檢查自身服務及網關連接性,再根據故障情況控制keepalived的運行或是停止。

在每個節點運行shell腳本(check_service.sh)檢測本機的服務是否正常,一旦檢測到服務異常時,停止掉本機的keepalived, 如此虛擬IP自動轉移到備用機器之上,如每隔3秒檢測一次本機服務狀態,如果連接3次檢測失敗,則停止掉keepalived實例。同時如果本機服務是正常的,但是keepalived沒有啟動(故障恢復之后),則啟動keepalived,以達到故障恢復之目的。

check_service.sh文件的內容

#!/bin/bash

pidfile=/var/lock/subsys/`basename $0`.pid
if [ -f $pidfile ] && [ -e /proc/`cat $pidfile` ] ; then
  exit 1
fi

trap "rm -fr $pidfile ; exit 0" 1 2 3 15
echo $$ > $pidfile

maxfails=3
fails=0
success=0

while [ 1 ]
do
  /usr/bin/wget --timeout=3 --tries=1 http://127.0.0.1/ -q -O /dev/null
  if [ $? -ne 0 ] ; then
    let fails=$[$fails+1]
    success=0
  else
    fails=0
    let success=$[$success+1]
  fi

  if [ $fails -ge $maxfails ] ; then
    fails=0
    success=0

    #check keepalived is running ? try to stop it
    service keepalived status | grep running
    if [ $? -eq 0 ] ; then
      logger -is "local service fails $maxfails times ... try to stop keepalived."
      service keepalived stop 2>&1 | logger
    fi
  fi

  if [ $success -gt $maxfails ] ; then
    #check keepalived is stopped ? try to start it
    service keepalived status | grep stopped
    if [ $? -eq 0 ] ; then
      logger -is "service changes normal, try to start keepalived ."
      service keepalived start
    fi
    success=0
  fi
  sleep 3
done

 

兩個節點上均應運行此腳本,請將此腳本加入到cron任務中(此程序已經作了單實例運行機制,加入計划任務的作用就是防止腳本意外中斷后檢測功能失效),可實現的功能:

如果本地服務連續三次檢測失敗,就嘗試停止keepalived服務(如果keepalived處於運行狀態)

如果本地服務連接三次檢測成功,但keepalived沒有啟動,則啟動之

關鍵的執行點,均已經記錄到系統日志中(/var/log/messages)

執行crontab -e , 加入以下內容:

*/1 * * * * /root/check_service.sh

 


停止掉本機的keepalived, 稍過一會,就會keepalived服務被自動啟動了(這是因為本地服務檢測正常)

停止掉本機的nginx, 稍過一會,就會發現keepalived服務也被停止掉了

再啟動nginx, 稍過一會,發現keepalived也被正常啟動,並綁定了正確的虛擬IP

 


參考資料:

http://zhangxugg-163-com.iteye.com/blog/1665419

 


免責聲明!

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



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