Keepalived是一個基於VRRP協議來實現的服務高可用方案,能夠利用其來避免IP單點故障,相似的工具還有heartbeat、corosync、pacemaker。nginx
可是它通常不會單獨出現,而是與其它負載均衡技術(如lvs、haproxy、nginx)一塊兒工做來達到集羣的高可用。web
Keepalived的做用是檢測服務器的狀態,若是有一臺web服務器死機,或工做出現故障,Keepalived將檢測到,並將有故障的服務器從系統中剔除,同時使用其餘服務器代替該服務器的工做;當服務器工做正常後Keepalived自動將服務器加入到服務器羣中,這些工做所有自動完成,不須要人工干涉,須要人工作的只是修復故障的服務器。shell
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
#配置啓動
cp keepalived/etc/init.d/keepalived.init /etc/init.d/keepalived
chmod +x /etc/init.d/keepalived
cp keepalived/etc/init.d/keepalived.sysconfig /etc/sysconfig/keepalived
cp keepalived/etc/keepalived/keepalived.conf /etc
keepalived.confbash
global_defs { notification_email { #指定keepalived在發生事情的時候,發送郵件告知,能夠有多個地址,每行一個。 acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from root@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 } }
service keepalived start|stop|restart
chkconfig keepalived on
驗證虛擬ip 可以使用 ip addr 驗證服務器
兩種模式:網絡
master服務器 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 } }
Backup服務器 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 } }
主備模式的缺點就是始終只有一臺機器位於工做狀態,另一臺機器永遠是備用狀態,存在資源浪費之問題。測試
雙主模式容許兩臺機器均處於工做狀態並互相做爲備份。搭建keepalived雙主模式的要素:spa
master1配置文件keepalived.conf
global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc #指定發件人 smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL 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 } }
master2節點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定義的檢測規則是:
但這裏有個小問題,若是本機或是網關偶爾出現一次故障,那麼咱們不能認爲是服務故障。更好的作法是若是連續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任務中(此程序已經做了單實例運行機制,加入計劃任務的做用就是防止腳本意外中斷後檢測功能失效),可實現的功能:
執行crontab -e , 加入如下內容:
*/1 * * * * /root/check_service.sh
測試