------ 什麼是腦裂(split-brain)
在"雙機熱備"高可用(HA)系統中,當聯繫兩個節點的"心跳線"斷開時(即兩個節點斷開聯繫時),原本爲一個總體、動做協調的HA系統,就分裂成爲兩個獨立的節點(即兩個獨立的個體)。因爲相互失去了聯繫,都覺得是對方出了故障,兩個節點上的HA軟件像"裂腦人"同樣,"本能"地爭搶"共享資源"、爭起"應用服務"。就會發生嚴重後果:1)或者共享資源被瓜分、兩邊"服務"都起不來了;2)或者兩邊"服務"都起來了,但同時讀寫"共享存儲",致使數據損壞(常見如數據庫輪詢着的聯機日誌出錯)。node
兩個節點相互爭搶共享資源,結果會致使系統混亂,數據損壞。對於無狀態服務的HA,無所謂腦裂不腦裂,但對有狀態服務(好比MySQL)的HA,必需要嚴格防止腦裂
[但有些生產環境下的系統按照無狀態服務HA的那一套去配置有狀態服務,結果就可想而知]。python
------ 集羣腦裂產生的緣由
通常來講,裂腦的發生,有如下幾種緣由:
1. 高可用服務器各節點之間心跳線鏈路發生故障,致使沒法正常通訊。
2. 因心跳線壞了(包括斷了,老化)。
3. 因網卡及相關驅動壞了,ip配置及衝突問題(網卡直連)。
4. 因心跳線間鏈接的設備故障(網卡及交換機)。
5. 因仲裁的機器出問題(採用仲裁的方案)。
6. 高可用服務器上開啓了iptables防火牆阻擋了心跳消息傳輸。
7. 高可用服務器上心跳網卡地址等信息配置不正確,致使發送心跳失敗。
8. 其餘服務配置不當等緣由,如心跳方式不一樣,心跳廣插衝突、軟件Bug等。web
提示: Keepalived配置裏同一VRRP實例若是virtual_router_id兩端參數配置不一致也會致使裂腦問題發生。數據庫
------ 如何預防HA集羣腦裂 [目前達成共識的有下面四種對策]
第一種:添加冗餘的心跳線 [即冗餘通訊的方法]
同時使用串行電纜和以太網電纜鏈接,同時用兩條心跳線路 (即心跳線也HA),這樣一條線路壞了,另外一個仍是好的,依然能傳送心跳消息,儘可能減小"腦裂"現象的發生概率。vim
第二種方法:設置仲裁機制
當兩個節點出現分歧時,由第3方的仲裁者決定聽誰的。這個仲裁者,多是一個鎖服務,一個共享盤或者其它什麼東西。例如設置參考IP(如網關IP),小心跳線徹底斷開時,2個節點都各自ping一下參考IP,不通則代表斷點就出在本端。不只"心跳"、還兼對外"服務"的本端網絡鏈路斷了,即便啓動(或繼續)應用服務也沒有用了,那就主動放棄競爭,讓可以ping通參考IP的一端去起服務。更保險一些,ping不通參考IP的一方乾脆就自我重啓,以完全釋放有可能還佔用着的那些共享資源。緩存
第三種方法:fence機制 [即共享資源的方法] [前提是必需要有可靠的fence設備]
當不能肯定某個節點的狀態時 ,經過fence設備強行關閉該心跳節點,確保共享資源被徹底釋放!至關於Backup備節點接收不到心跳信息,經過單獨的線路發送關機命令關閉主節點的電源。安全
理想狀況下,以上第2、三二者一個都不能少。可是若是節點沒有使用共享資源,好比基於主從複製的數據庫HA,也能夠安全的省掉fence設備,只保留仲裁,並且不少時候線上環境裏也也可能沒有可用的fence設備,好比在雲主機裏。bash
那麼可不能夠省掉仲裁機制,只留fence設備呢?這是不能夠的。由於,當兩個節點互相失去聯絡時會同時fencing對方。若是fencing的方式是reboot,那麼兩臺機器就會不停的重啓。若是fencing的方式是power off,那麼結局有多是2個節點玉石俱焚,也有可能活下來一個。可是若是兩個節點互相失去聯絡的緣由是其中一個節點的網卡故障,而活下來的正好又是那個有故障的節點,那麼結局同樣是悲劇。因此說: 單純的雙節點,不管如何也防止不了腦裂。服務器
第四種:啓用磁盤鎖
正在服務一方鎖住共享磁盤,"裂腦"發生時,讓對方徹底"搶不走"共享磁盤資源。但使用鎖磁盤也會有一個不小的問題,若是佔用共享盤的一方不主動"解鎖",另外一方就永遠得不到共享磁盤。現實中假如服務節點忽然死機或崩潰,就不可能執行解鎖命令。後備節點也就接管不了共享資源和應用服務。因而有人在HA中設計了"智能"鎖。即:正在服務的一方只在發現心跳線所有斷開(察覺不到對端)時才啓用磁盤鎖。平時就不上鎖了。網絡
------ 沒有fence設備是否安全
這裏以MySQL的數據複製爲例來講明這個問題。在基於複製場景下,主從節點沒有共享資源(沒有VIP),因此2個節點都活着自己沒有問題。問題是客戶端會不會訪問到本該死掉的那個節點。這又牽扯到客戶端路由的問題。客戶端路由有幾種方式: 基於VIP,基於Proxy,基於DNS或者乾脆客戶端維護一個服務端地址列表本身判斷主從。無論採用哪一種方式,主從切換的時候都要更新路由:
1)基於DNS的路由是不太靠譜的,由於DNS可能會被客戶端緩存,很難清乾淨。
2)基於VIP的路由有一些變數,若是本該死掉的節點沒有摘掉本身身上的VIP,那麼它隨時可能出來搗亂(即便新主已經經過arping更新了全部主機上的arp緩存,若是某個主機的arp過時,發一個arp查詢,那麼就會發生ip衝突)。因此能夠認爲VIP也是一種特殊的共享資源,必需把它從故障節點上摘掉。至於怎麼摘,最簡單的辦法就是故障節點發現本身失聯後本身摘,若是它還活着的話(若是它死了,也就不用摘了)。若是負責摘vip的進程沒法工做怎麼辦?這時候就能夠用上原本不太靠譜的軟fence設備了(好比ssh)。
3)基於Proxy的路由是比較靠譜的,由於Proxy是惟一的服務入口,只要把Proxy一個地方更新了,就不會發生客戶端誤訪問的問題了,可是也要考慮Proxy的高可用。
4)至於基於服務端地址列表的方法,客戶端須要經過後臺服務判斷主從(好比PostgreSQL/MySQL會話是否處於只讀模式)。這時,若是出現2個主,客戶端就會錯亂。爲防止這個問題,原主節點發現本身失聯後要本身把服務停掉,這和前面摘vip的道理是同樣的。
所以,爲了避免讓故障節點搗亂,故障節點應該在失聯後本身釋放資源,爲了應對釋放資源的進程自己出現故障,能夠加上軟fence。在這個前提下,能夠認爲沒有可靠的物理fence設備也是安全的。
------------------------------------------------------------------------------
什麼是Fence設備?
Fence設備是集羣中很重要的一個組成部分,經過Fence設備能夠避免因出現不可預知的狀況而形成的"腦裂"現象, Fence設備主要就是經過服務器或存儲自己的硬件管理接口或者外部電源管理設備,來對服務器或存儲直接發出硬件管理指令,將服務器重啓或關機,或者與網絡斷開鏈接。在設備爲知故障發生時,Fence負責讓佔有浮動資源的設備與集羣斷開。
每一個節點之間互相發送探測包進行判斷節點的存活性。通常會有專門的線路進行探測,這條線路稱爲"心跳線"(上圖直接使用eth0線路做爲心跳線)。假設node1的心跳線出問題,則node2和node3會認爲node1出問題,而後就會把資源調度在node2或者node3上運行,但node1會認爲本身沒問題不讓node2或者node3搶佔資源,此時就出現了"腦裂"(split brain)。此時若是在整個環境裏有一種設備直接把node1斷電,則能夠避免腦裂的發生,這種設備叫作fence或者stonith(Shoot The Other Node In The Head爆頭哥)。在物理機裏virsh是經過串口線管理虛擬機的,好比virsh destroy nodeX,這裏咱們把物理機當成fence設備。
------ 主從切換後數據可否保證不丟
主從切換後數據會不會丟和腦裂能夠認爲是兩個不一樣的問題。這裏還以MySQL的數據複製爲例來講明。對MySQL,即便配置成半同步複製,在超時發生後,它可能會自動降級爲異步複製。爲了防止MySQL的複製降級,能夠設置一個超大的rpl_semi_sync_master_timeout,同時保持rpl_semi_sync_master_wait_no_slave爲on(即默認值)。可是,這時若是從宕了,主也會hang住。這個問題的破解方法能夠配置成一主兩從,只要不是兩個從都宕機就沒事,或者由外部的集羣監視軟件動態切換半同步和異步。若是原本就是配置的異步複製,那就是說已經作好丟數據的準備了。這時候,主從切換時丟點數據也沒啥大不了,但要控制自動切換的次數。好比控制已經被failover掉的原主不容許自動上線,不然若是由於網絡抖動致使故障切換,那麼主從就會不停的來回切,不停的丟數據,破壞數據的一致性。
------ 如何實現"仲裁機制+fence機制"策略,防止集羣"腦裂"
能夠本身徹底從頭開始實現一套符合上述邏輯的腳本,可是建議使用成熟的集羣軟件去搭建,好比Pacemaker+Corosync+合適的資源Agent。Keepalived可能不太適合用於有狀態服務的HA,即便把仲裁,fence都加到方案裏,也總以爲彆扭。
使用Pacemaker+Corosync的方案須要注意:quorum能夠認爲是Pacemkaer自帶的仲裁機制,集羣的全部節點中的多數選出一個協調者,集羣的全部指令都由這個協調者發出,能夠完美的杜絕腦裂問題。爲了使這套機制有效運轉,集羣中至少有三個節點,而且把no-quorum-policy設置成stop,這也是默認值。(注意:no-quorum-policy最好不要設置成ignore,生產環境若是也這麼搞,又沒有其它仲裁機制,是很危險的!)
可是,若是隻有兩個節點該怎麼辦?
1. 拉一個機器借用一下湊足三個節點,再設置location限制,不讓資源分配到那個節點上。
2. 把多個不知足quorum小集羣拉到一塊兒,組成一個大的集羣,一樣適用location限制控制資源的分配的位置。
可是若是你有不少雙節點集羣,找不到那麼多用於湊數的節點,又不想把這些雙節點集羣拉到一塊兒湊成一個大的集羣(好比以爲不方便管理)。那麼能夠考慮第三種方法。
3. 第三種方法是配置一個搶佔資源,以及服務和這個搶佔資源的colocation約束,誰搶到搶佔資源誰提供服務。這個搶佔資源能夠是某個鎖服務,好比基於zookeeper包裝一個,或者乾脆本身從頭作一個,就像下面"corosync+pacemaker雙節點腦裂問題處理"的例子:
corosync做爲HA方案中成員管理層(membership layer),負責集羣成員管理、通訊方式(單播、廣播、組播)等功能,pacemaker做爲CRM層。 在利用corosync+pacemaker雙節點主備模式的實踐中,可能會遇到一個問題:腦裂問題。 何謂腦裂: 在HA集羣中,節點間經過心跳線進行網絡通訊,一旦心跳網絡異常。致使成員互不相認,各自做爲集羣中的DC,這樣資源同時會在主、備兩節點啓動。 腦裂緣由是corosync仍是pacemaker致使的? 開始可能認爲是corosync,緣由在於心跳端致使corosync不能正常通訊。 後來發如今pacemaker官網有找到腦裂(split-brain)的方案。pacemaker做爲crm,主責是管理資源,還有一個做用是選擇leader。 1. 解決方案:爲pacemaker配置搶佔資源。 原理在於,pacemaker 能夠定義資源的執行順序。若是將獨佔資源放在最前面,後面的資源的啓動則依賴與它,成也獨佔資源,敗也獨佔資源。 小心跳網絡故障時候,誰先搶佔到該資源,該節點就接管服務資源,提供服務。這種方案必須解決兩個問題,一是必須定義一個搶佔資源,二是自定義pacemaker RA,去搶奪資源。 2. 定義搶佔資源 下面利用互斥鎖來實現獨佔資源。具體由python實現一個簡單的web服務,提供lock,unlock,updatelock服務。 __author__ = 'ZHANGTIANJIONG629' import BaseHTTPServer import threading import time lock_timeout_seconds = 8 lock = threading.Lock() lock_client_ip = "" lock_time = 0 class LockService(BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(self): '''define url route''' pass def lock(self, client_ip): global lock_client_ip global lock_time # if lock is free if lock.acquire(): lock_client_ip = client_ip lock_time = time.time() self.send_response(200, 'ok') self.close_connection return # if current client hold lock,updte lock time elif lock_client_ip == client_ip: lock_time = time.time() self.send_response(200, 'ok,update') self.close_connection return else: # lock timeout,grab lock if time.time() - lock_time > lock_timeout_seconds: lock_client_ip = client_ip; lock_time = time.time() self.send_response(200, 'ok,grab lock') self.close_connection return else: self.send_response(403, 'lock is hold by other') self.close_connection def update_lock(self, client_ip): global lock_client_ip global lock_time if lock_client_ip == client_ip: lock_time = time.time() self.send_response(200, 'ok,update') self.close_connection return else: self.send_response(403, 'lock is hold by other') self.close_connection return def unlock(self, client_ip): global lock_client_ip global lock_time if lock.acquire(): lock.release() self.send_response(200, 'ok,unlock') self.close_connection return elif lock_client_ip == client_ip: lock.release() lock_time = 0 lock_client_ip = '' self.send_response(200, 'ok,unlock') self.close_connection return else: self.send_response(403, 'lock is hold by other') self.close_connection return if __name__ == '__main__': http_server = BaseHTTPServer.HTTPServer(('127.0.0.1', '88888'), LockService) http_server.serve_forever()
上面這個例子是基於http協議的短鏈接,更細緻的作法是使用長鏈接心跳檢測,這樣服務端能夠及時檢出鏈接斷開而釋放鎖。可是,必定要同時確保這個搶佔資源的高可用,能夠把提供搶佔資源的服務作成lingyig高可用的,也能夠簡單點,部署3個服務,雙節點上個部署一個,第三個部署在另一個專門的仲裁節點上,至少獲取3個鎖中的2個才視爲取得了鎖。這個仲裁節點能夠爲不少集羣提供仲裁服務(由於一個機器只能部署一個Pacemaker實例,不然能夠用部署了N個Pacemaker實例的仲裁節點作一樣的事情。)。可是,如非無可奈何,儘可能仍是採用前面的方法,即知足Pacemaker法定票數,這種方法更簡單,可靠。
------ 如何監控"腦裂"狀況
1. 在什麼服務器上進行"腦裂"狀況監控?
在備節點服務器上進行監控,可使用zabbix監控。
2. 監控什麼信息?
備節點服務器上面若是出現vip狀況,只多是下面兩種狀況
1)腦裂狀況出現。
2)正常主備切換也會出現。
3. 編寫監控腦裂腳本
[root@slave-node scripts]# vim check_keepalived.sh #!/bin/bash # 192.168.10.10是VIP地址 while true do if [ `ip a show eth0 |grep 192.168.10.10|wc -l` -ne 0 ] then echo "keepalived is error!" else echo "keepalived is OK !" fi done [root@slave-node scripts]# chmod 755 check_keepalived.sh
4)測試。確保兩個節點的負載均衡可以正常負載
[root@master-node ~]# curl -H Host:www.kevin.cn 192.168.10.30 server-node01 www [root@master-node ~]# curl -H Host:www.kevin.cn 192.168.10.31 server-node01 www [root@slave-node ~]# curl -H Host:www.bobo.cn 192.168.10.31 server-node02 bbs [root@slave-node ~]# curl -H Host:www.kevin.cn 192.168.10.30 server-node03 www
Keepalived腦裂問題分享一
1)解決keepalived腦裂問題
檢測思路:正常狀況下keepalived的VIP地址是在主節點上的,若是在從節點發現了VIP,就設置報警信息。腳本(在從節點上)以下:
[root@slave-ha ~]# vim split-brainc_check.sh #!/bin/bash # 檢查腦裂的腳本,在備節點上進行部署 LB01_VIP=192.168.1.229 LB01_IP=192.168.1.129 LB02_IP=192.168.1.130 while true do ping -c 2 -W 3 $LB01_VIP &>/dev/null if [ $? -eq 0 -a `ip add|grep "$LB01_VIP"|wc -l` -eq 1 ];then echo "ha is brain." else echo "ha is ok" fi sleep 5 done 執行結果以下: [root@slave-ha ~]# bash check_split_brain.sh ha is ok ha is ok ha is ok ha is ok 當發現異常時候的執行結果: [root@slave-ha ~]# bash check_split_brain.sh ha is ok ha is ok ha is ok ha is ok ha is brain. ha is brain.
2)keepalived腦裂的一個坑(若是啓用了iptables,不設置"系統接收VRRP協議"的規則,就會出現腦裂)
曾經在作keepalived+Nginx主備架構的環境時,當重啓了備用機器後,發現兩臺機器都拿到了VIP。這也就是意味着出現了keepalived的腦裂現象,檢查了兩臺主機的網絡連通狀態,發現網絡是好的。而後在備機上抓包:
[root@localhost ~]# tcpdump -i eth0|grep VRRP tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 22:10:17.146322 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:17.146577 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:17.146972 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:18.147136 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:18.147576 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:25.151399 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:25.151942 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:26.151703 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:26.152623 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:27.152456 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:27.153261 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:28.152955 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:28.153461 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:29.153766 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:29.155652 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:30.154275 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:30.154587 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:31.155042 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:31.155428 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:32.155539 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:32.155986 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:33.156357 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:33.156979 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:34.156801 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:34.156989 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 備機能接收到master發過來的VRRP廣播,那爲何還會有腦裂現象? 接着發現重啓後iptables開啓着,檢查了防火牆配置。發現系統不接收VRRP協議。 因而修改iptables,添加容許系統接收VRRP協議的配置: -A INPUT -i lo -j ACCEPT ----------------------------------------------------------------------------------------- 我本身添加了下面的iptables規則: -A INPUT -s 192.168.1.0/24 -d 224.0.0.18 -j ACCEPT #容許組播地址通訊 -A INPUT -s 192.168.1.0/24 -p vrrp -j ACCEPT #容許VRRP(虛擬路由器冗餘協)通訊 ----------------------------------------------------------------------------------------- 最後重啓iptables,發現備機上的VIP沒了。 雖然問題解決了,但備機明明能抓到master發來的VRRP廣播包,卻沒法改變自身狀態。只能說明網卡接收到數據包是在iptables處理數據包以前發生的事情。
3)預防keepalived腦裂問題
1. 能夠採用第三方仲裁的方法。因爲keepalived體系中主備兩臺機器所處的狀態與對方有關。若是主備機器之間的通訊出了網題,就會發生腦裂,此時keepalived體系中會出現雙主的狀況,產生資源競爭。
2. 通常能夠引入仲裁來解決這個問題,即每一個節點必須判斷自身的狀態。最簡單的一種操做方法是,在主備的keepalived的配置文件中增長check配置,服務器週期性地ping一下網關,若是ping不通則認爲自身有問題 。
3. 最容易的是藉助keepalived提供的vrrp_script及track_script實現。以下所示:
# vim /etc/keepalived/keepalived.conf ...... vrrp_script check_local { script "/root/check_gateway.sh" interval 5 } ...... track_script { check_local } 腳本內容: # cat /root/check_gateway.sh #!/bin/sh VIP=$1 GATEWAY=192.168.1.1 /sbin/arping -I em1 -c 5 -s $VIP $GATEWAY &>/dev/null check_gateway.sh 就是咱們的仲裁邏輯,發現ping不通網關,則關閉keepalived服務:"service keepalived stop"
4)推薦本身寫腳本
寫一個while循環,每輪ping網關,累計連續失敗的次數,當連續失敗達到必定次數則運行service keepalived stop關閉keepalived服務。若是發現又可以ping通網關,再重啓keepalived服務。最後在腳本開頭再加上腳本是否已經運行的判斷邏輯,將該腳本加到crontab裏面。
Keepalived腦裂問題分享二
在部署Nginx+Keepalived高可用集羣配置時可能會出行以下腦裂現象。處理過程以下:
查看兩個節點的日誌, 發現Master節點和Backup節點機器都是Mastaer模式啓動的! [root@Master-Ha ~]# tail -f /var/log/messages ......... ......... Dec 22 20:24:32 Master-Ha Keepalived_healtheckers[22518]:Activating healthchecker for server [xx.xx.xx.xx] Dec 22 20:24:35 Master-Ha Keepalived_keepalived_vrrp[22519]: VRRP_instance(VI_I) Transition to MASTER STATE Dec 22 20:24:38 Master-Ha Keepalived_keepalived_vrrp[22519]: VRRP_instance(VI_I) Entering MASTER STATE Dec 22 20:24:40 Master-Ha Keepalived_keepalived_vrrp[22519]: VRRP_instance(VI_I) setting protocol VIPs Dec 22 20:24:44 Master-Ha Keepalived_healtheckers[22518]:Netlink reflector reports IP xx.xx.xx.xx added ......... ......... [root@Slave-Ha ~]# tail -f /var/log/messages ......... ......... Dec 22 20:24:34 Slave-Ha Keepalived_healtheckers[29803]:Activating healthchecker for server [xx.xx.xx.xx] Dec 22 20:24:37 Slave-Ha Keepalived_keepalived_vrrp[29804]: VRRP_instance(VI_I) Transition to MASTER STATE Dec 22 20:24:40 Slave-Ha Keepalived_keepalived_vrrp[29804]: VRRP_instance(VI_I) Entering MASTER STATE Dec 22 20:24:43 Slave-Ha Keepalived_keepalived_vrrp[29804]: VRRP_instance(VI_I) setting protocol VIPs Dec 22 20:24:47 Slave-Ha Keepalived_keepalived_vrrp[29804]: VRRP_instance(VI_I) Sending gratuitous ARPS on ens160 xx.xx.xx.xx Dec 22 20:24:49 Slave-Ha Keepalived_healtheckers[22518]:Netlink reflector reports IP xx.xx.xx.xx added ......... .........
經過上面查看兩個節點機器的日誌,發現VRRP是基於報文實現的!!Master節點會設置必定時間發送一個報文給Backup節點,若是Backup沒有收到就本身成爲Master。由此能夠推出致使出現上面"腦裂"問題的根源在於Backup沒有收到來自Master發送的報文!因此它本身也成爲了Master。
VRRP控制報文只有一種:VRRP通告(advertisement)。它使用IP多播數據包進行封裝,組地址爲224.0.0.18,發佈範圍只限於同一局域網內。這保證了VRID在不一樣網絡中能夠重複使用。爲了減小網絡帶寬消耗只有主控路由器才能夠週期性的發送VRRP通告報文。備份路由器在連續三個通告間隔內收不到VRRP或收到優先級爲0的通告後啓動新的一輪VRRP選舉。
另外注意:Centos7安裝Keepalived後, 若是不關閉防火牆, 則須要在防火牆中放行VRRP的組播IP 244.0.0.18。不然虛擬ip不能實現漂移,雙機都爲Master,不能實現雙機熱備的效果。[相似於上面"分享一"中的狀況]
因爲不太習慣使用Centos7下默認的Firewall防火牆,能夠禁用掉Centos7默認的Firewall防火牆,使用Iptables防火牆進行設置: # systemctl stop firewalld.service # systemctl disable firewalld.service # yum install -y iptables-services # vim /etc/sysconfig/iptables 在文件中添加一下內容 -A OUTPUT -o eth0 -d 224.0.0.18 -j ACCEPT -A OUTPUT -o eth0 -s 224.0.0.18 -j ACCEPT -A INPUT -i eth0 -d 224.0.0.18 -j ACCEPT -A INPUT -i eth0 -s 224.0.0.18 -j ACCEPT # service iptables restart # systemctl enable iptables.service 此時就能實現虛擬ip的漂移,當Master掛掉時,虛擬ip會漂移到Backup上,Master啓動後虛擬ip會再次漂移回來。