Keepalived實現服務高可用

1、Keepalived介紹

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

1.1 Keepalived的功能

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

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廣播包,這時候備就會啓動相關的服務接管主的任務向外提供服務,以保證服務的正常使用。vim

2、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配置bash

! 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優先級不一致tcp

2.3 腦裂介紹

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

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
    }
}
相關文章
相關標籤/搜索