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)、管理LVS軟件
(2)、基於VRRP實現高可用
(3)、健康檢查,故障切換docker
分層 | 功能 | 相關協議 |
---|---|---|
應用層 | 網絡服務和最終用戶的一個接口 | 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 |
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
# 安裝命令 # 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
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 } }
(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
Keepalived的主備配置文件的主要區別有:
(1)、router_id不一致
(2)、state描述信息不一致
(3)、priority優先級不一致tcp
在高可用系統中,若是兩個節點的心跳線斷開,原本兩個節點爲一個總體、動做協調的一個HA系統,如今因爲兩個之間的心跳線斷開致使它們分裂成了兩個單獨的個體。因爲雙方互相失去了聯繫,都會覺得對方出了故障。這時候這兩個單獨的個體就像"腦裂人"同樣互相爭搶共享資源、爭用應用服務,這樣就會形成嚴重問題:
(1)、共享資源被瓜分,兩邊服務都起不來;
(2)、兩邊服務都起來了,同時提供服務,同時讀寫存儲,致使數據不一致甚至損壞。oop
通常來講,腦裂的發生,有如下幾種緣由:
(1)、HA服務器之間心跳線故障,致使沒法正常通訊;
(2)、HA服務器上開啓了防火牆,阻擋了心跳線的信息傳輸;
(3)、HA服務器上心跳網卡配置不正確,致使心跳信息發送失敗;
(4)、其餘服務器配置不當的緣由。好比心跳方式不一樣,心跳廣播衝突,軟件BUG等;
(5)、Keepalived配置裏同一 VRRP實例中若是 virtual_router_id兩端參數配置不一致也會致使裂腦問題發生。
在實際環境中,咱們能夠從如下幾個方面來防止腦裂的問題:
(1)、同時使用串行線路或者以太網電纜鏈接,同時使用兩條心跳線路,若是一條壞了,另一條還能正常提供服務;
(2)、當檢測到腦裂時強行關閉一個節點(該功能須要特殊設備支持,如Stonith,feyce),至關於備節點接受不到心跳心跳消患,經過單獨的線路發送關機命令關閉主節點的電源;
(3)、作好腦裂監控報警(用zabbix等來監控),在問題發生時能在第一時間介入仲裁,下降損失。
(4)、啓動磁盤鎖。正在服務一方鎖住共享磁盤,「裂腦」發生時,讓對方徹底「搶不走」共享磁盤資源。但使用鎖磁盤也會有一個不小的問題,若是佔用共享盤的一方不主動「解鎖」,另外一方就永遠得不到共享磁盤。現實中假如服務節點忽然死機或崩潰,就不可能執行解鎖命令。後備節點也就接管不了共享資源和應用服務。因而有人在HA中設計了「智能」鎖。即:正在服務的一方只在發現心跳線所有斷開(察覺不到對端)時才啓用磁盤鎖,平時就不上鎖了;
(5)、加入仲裁機制。例如設置網關IP,當腦裂發生時,兩個節點都各自ping如下這個網關IP,不通則代表斷點就在本端,不只「心跳」、還兼對外「服務」的本端網絡鏈路斷了,即便啓動(或繼續)應用服務也沒有用了,那就主動放棄競爭,讓可以ping通網關IP的一端去起服務。更保險一些,ping不通網關IP的一方乾脆就自我重啓,以完全釋放有可能還佔用着的那些共享資源。
(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 } }
(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 } }