Keepalived實現服務高可用


一、Keepalived介紹

Keepalived的作用是檢測服務器狀態,如果一台服務器宕機或者出現其他故障導致當前服務器不可用,keep alived就會檢測到並將故障的服務器從系統中剔除,同時使用備用服務器替代該服務器的工作,當服務器工作正常后Keepalived自動將服務器加入到服務器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的服務器。
Keepalived軟件起初是專為LVS負載均衡軟件設計的,用來管理並監控LVS集群系統中各個服務節點的狀態,后來又加入了可以實現高可用的VRRP功能。因此,Keepalived除了能夠管理LVS軟件外,還可以作為其他服務(例如:Nginx、Haproxy、MySQL等)的高可用解決方案軟件。
Keepalived軟件主要是通過VRRP協議實現高可用功能的。VRRP是Virtual Router RedundancyProtocol(虛擬路由器冗余協議)的縮寫,VRRP出現的目的就是為了解決靜態路由單點故障問題的,它能夠保證當個別節點宕機時,整個網絡可以不間斷地運行。
所以,Keepalived 一方面具有配置管理LVS的功能,同時還具有對LVS下面節點進行健康檢查的功能,另一方面也可實現系統網絡服務的高可用功能。

1.1 Keepalived的功能

(1)、管理LVS軟件
(2)、基於VRRP實現高可用
(3)、健康檢查,故障切換

1.2 Keepalived的工作原理

1.2.1 OSI七層結構

分層 功能 相關協議
應用層 網絡服務和最終用戶的一個接口 TFTP,HTTP,SNMP,DNS,FTP,SMTP,TELNET
表示層 數據的表示、安全、壓縮 無協議
會話層 會話的建立、管理、中止 無協議
傳輸層 定義傳輸數據的協議端口號,以及流控和差錯校驗 TCP,UDP
網絡層 進行邏輯地址尋址,實現不同網絡之間的路徑選擇 IP,ICMP,RIP,OSPF,BGP,IGMP
數據鏈路層 建立邏輯連接、硬件地址尋址、差錯校驗等功能 SLIP,CSLIP,PPP,ARP,RARP,MTU
物理層 建立、連接、斷開物理連接 ISO2110,IEEE802,IEEE802.2

1.2.2 工作原理

Keepalived工作在TCP/IP協議的IP層、TCP層、應用層,既Layer 3/4/5;
Layer3:當Keepalived工作在這層時,它會定期向服務器群中的服務器發送ICMP包,如果發現某台服務器IP沒有激活就會報告這台服務器失效,並且將其從服務器群剔除。Layer3的是以服務器IP地址是否有效作為判斷是否存活的標准;
Layer4:當工作在這層時,主要是以TCP端口狀態來判斷服務器工作是否正常;
Layer5:當工作在這層時,主要是以用戶設定的服務運行是否正常來判斷是否存活;
Keepalived高可用主要是通過VRRP進行通信的,VRRP是通過競選機制來確定主備的,主的優先級高於備。所以正常工作時,主會優先提供服務,備處於等待階段,只有當主出現異常,備才會接管主的任務向外提供服務。
在Keepalived服務器群之間,只有作為主的服務器不斷發送VRRP廣播包,告訴備它還活着,此時備不會搶占主,只有當主不可用,既備接受不到主的VRRP廣播包,這時候備就會啟動相關的服務接管主的任務向外提供服務,以保證服務的正常使用。

二、Keepalived使用

2.1 Keepalived軟件安裝

# 安裝命令
# yum install keepalived -y

# rpm -ql keepalived
/etc/keepalived
/etc/keepalived/keepalived.conf			# 主配置文件
/etc/sysconfig/keepalived
/usr/bin/genhash
/usr/lib/systemd/system/keepalived.service
/usr/libexec/keepalived
/usr/sbin/keepalived

2.2 默認配置測試

2.2.1 配置介紹

global_defs {
   notification_email {							# 定義郵件地址
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc			# 定義發送郵件地址
   smtp_server 192.168.200.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											# 狀態參數:MASTER/BACKUP只是說明
    interface eth0										# 虛擬IP放置的網卡地址
    virtual_router_id 51							# 設置集群ID,同一個組的ID要一致
    priority 100											# 優先級設置,數值越大優先級越高
    advert_int 1											# 主備通訊時間間隔
    authentication {									# 驗證相關
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {								# 虛擬IP地址
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

2.2.2 最終配置文件

(1)、Master配置

! Configuration File for keepalived

global_defs {
   router_id lb01
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.169.200
    }
}

(2)、Slave配置

! Configuration File for keepalived

global_defs {
   router_id lb02
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 140
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.169.200
    }
}

(3)、啟動Keepalived

# systemctl start keepalived

(4)、查看VIP是否啟動

[root@localhost keepalived]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:24:d1:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.169.131/24 brd 192.168.169.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.169.200/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::fd8:8531:b2e2:c6bb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

(5)、測試
關閉master上的keepalived,查看VIP是否漂移到備。

# 關閉主master
# systemctl stop keepalived

# 查看備上的IP信息
[root@localhost keepalived]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d9:69:08 brd ff:ff:ff:ff:ff:ff
    inet 192.168.169.130/24 brd 192.168.169.255 scope global dynamic ens33
       valid_lft 1464sec preferred_lft 1464sec
    inet 192.168.169.200/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::51f1:7ad1:f554:65cc/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:88:bb:94:f6 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever

2.2.3 總結

Keepalived的主備配置文件的主要區別有:
(1)、router_id不一致
(2)、state描述信息不一致
(3)、priority優先級不一致

2.3 腦裂介紹

在高可用系統中,如果兩個節點的心跳線斷開,本來兩個節點為一個整體、動作協調的一個HA系統,現在由於兩個之間的心跳線斷開導致它們分裂成了兩個單獨的個體。由於雙方互相失去了聯系,都會以為對方出了故障。這時候這兩個單獨的個體就像"腦裂人"一樣互相爭搶共享資源、爭用應用服務,這樣就會造成嚴重問題:
(1)、共享資源被瓜分,兩邊服務都起不來;
(2)、兩邊服務都起來了,同時提供服務,同時讀寫存儲,導致數據不一致甚至損壞。

2.3.1 產生腦裂的原因

一般來說,腦裂的發生,有以下幾種原因:
(1)、HA服務器之間心跳線故障,導致無法正常通信;
(2)、HA服務器上開啟了防火牆,阻擋了心跳線的信息傳輸;
(3)、HA服務器上心跳網卡配置不正確,導致心跳信息發送失敗;
(4)、其他服務器配置不當的原因。比如心跳方式不同,心跳廣播沖突,軟件BUG等;
(5)、Keepalived配置里同一 VRRP實例中如果 virtual_router_id兩端參數配置不一致也會導致裂腦問題發生。

2.3.2 常見的解決辦法

在實際環境中,我們可以從以下幾個方面來防止腦裂的問題:
(1)、同時使用串行線路或者以太網電纜連接,同時使用兩條心跳線路,如果一條壞了,另外一條還能正常提供服務;
(2)、當檢測到腦裂時強行關閉一個節點(該功能需要特殊設備支持,如Stonith,feyce),相當於備節點接受不到心跳心跳消患,通過單獨的線路發送關機命令關閉主節點的電源;
(3)、做好腦裂監控報警(用zabbix等來監控),在問題發生時能在第一時間介入仲裁,降低損失。
(4)、啟動磁盤鎖。正在服務一方鎖住共享磁盤,“裂腦”發生時,讓對方完全“搶不走”共享磁盤資源。但使用鎖磁盤也會有一個不小的問題,如果占用共享盤的一方不主動“解鎖”,另一方就永遠得不到共享磁盤。現實中假如服務節點突然死機或崩潰,就不可能執行解鎖命令。后備節點也就接管不了共享資源和應用服務。於是有人在HA中設計了“智能”鎖。即:正在服務的一方只在發現心跳線全部斷開(察覺不到對端)時才啟用磁盤鎖,平時就不上鎖了;
(5)、加入仲裁機制。例如設置網關IP,當腦裂發生時,兩個節點都各自ping以下這個網關IP,不通則表明斷點就在本端,不僅“心跳”、還兼對外“服務”的本端網絡鏈路斷了,即使啟動(或繼續)應用服務也沒有用了,那就主動放棄競爭,讓能夠ping通網關IP的一端去起服務。更保險一些,ping不通網關IP的一方干脆就自我重啟,以徹底釋放有可能還占用着的那些共享資源。

2.4 Keepalived監控nginx防止腦裂

(1)、執行腳本,用來檢測

vim check_keepalived.sh
#!/bin/bash
NGINX_SBIN=`which nginx`
NGINX_PORT=80
function check_nginx(){
    NGINX_STATUS=`nmap localhost -p ${NGINX_PORT} | grep "80/tcp open" | awk '{print $2}'`
    NGINX_PROCESS=`ps -ef | grep nginx|grep -v grep|wc -l`
}

check_nginx
if [ "$NGINX_STATUS" != "open"  -o  $NGINX_PROCESS -lt 2 ]
then
    ${NGINX_SBIN} -s stop
    ${NGINX_SBIN}
    sleep 3
    check_nginx
    if [ "$NGINX_STATUS" != "open"  -o  $NGINX_PROCESS -lt 2 ];then
        systemctl stop keepalived
    fi
fi

(2)、添加執行權限

chmod +x check_keepalived.sh

(3)、配置keepalived
master:

! Configuration File for keepalived

global_defs {
   router_id lb01
}

# 定義腳本
vrrp_script check_ng {
    script "/etc/keepalived/check_keepalived.sh"     # 腳本路徑
    interval 2                                       # 執行時間間隔
    weight -5                                        # 計算權重值,腳本結果導致的優先級變更,檢測失敗(腳本返回非0)則優先級 -5
    fall 3                                           # 檢測連續3次失敗才算確定是真失敗。會用weight減少優先級(1-255之間)
    rise 2                                           # 檢測2次成功就算成功。但不修改優先級
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.169.200
    }
    # 調用腳本
    track_script {
        check_ng
    }
}

slave:

! Configuration File for keepalived

global_defs {
   router_id lb02
}

vrrp_script check_ng {
    script "/etc/keepalived/check_keepalived.sh"
    interval 2
    weight -5
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 147
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.169.200
    }
    track_script {
        check_ng
    }
}

2.5 Keepalived設置master故障恢復后不重新搶回VIP

(1)、master配置

! Configuration File for keepalived

global_defs {
   router_id lb01
}

vrrp_script check_ng {
    script "/etc/keepalived/check_keepalived.sh"
    interval 2
    weight -5
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP					  # 主上也設置為備
    interface ens33
    virtual_router_id 51
    priority 150
    advert_int 1
    nopreempt							# 設置為不搶奪VIP
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.169.200
    }
    track_script {
        check_ng
    }
}

(2)、slave配置

! Configuration File for keepalived

global_defs {
   router_id lb02
}

vrrp_script check_ng {
    script "/etc/keepalived/check_keepalived.sh"
    interval 2
    weight -5
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 149 
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    
    virtual_ipaddress {
        192.168.169.200
    }
    track_script {
        check_ng
    }
}


免責聲明!

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



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