一.問題簡單描述
- HA即(high available)高可用,又被叫做雙機熱備;
- 用于關鍵性業務。簡單理解就是,有2臺機器 A 和 B,正常是 A 提供服務,B 待命閑置,當 A 宕機或服務宕掉,會切換至B機器繼續提供服務。
- 當A修復之后,啟動后,根據配置A可以繼續接管服務;
- 常見的實現高可用的開源軟件有
heartbeat
和keepalived
。 - 下面我們使用 heartbeat 來做 HA 集群,并且把 apache 服務作為 HA 對應的服務。
二.系統版本說明(測試)
- Ubuntu:14.04 64bit (主從均一致)
- apache: 2.4.12
三.服務器配置
-
主服務器 A
- eth0網卡IP: 192.168.9.145
- 主機名: dal.api.loc (可以臨時修改測試:sudo hostname dal.api.loc)
- uname -n
dal.api.loc
-
從服務器 B
- eth0網卡IP:192.168.9.22
- 主機名:ljdal.loc
浮動IP: 192.168.9.19 也就是vip(虛擬ip),不需要
四.先安裝apache服務器
-
因為我的兩臺測試機已經有apache了,但都是編譯安裝的,所以再次調整啟動腳本如下:(主從主機配置一致)
sudo ln -s /usr/local/apache/bin/apachectl /etc/init.d/apachectl //sysv-rc-conf是ubuntu下管理/etc/init.d/下服務的命令,相當與centos的chkconfig sudo sysv-rc-conf apachectl off //將apache設置為非開機自啟動 sudo sysv-rc-conf --list | grep apachectl apachectl 2:off 3:off 4:off 5:off
-
A的apache虛擬主機配置
<VirtualHost 192.168.9.19:8001> DocumentRoot "/home/ning/www/lxf_test ServerName dal.api.loc ErrorLog "/usr/local/apache/logs/bug.ljlj-error_log" CustomLog "/usr/local/apache/logs/bug.ljlj-access_log" common RewriteEngine on </VirtualHost> <VirtualHost 192.168.9.149:8001> DocumentRoot "/home/ning/www/lxf_test ServerName dal.api.loc ErrorLog "/usr/local/apache/logs/bug.ljlj-error_log" CustomLog "/usr/local/apache/logs/bug.ljlj-access_log" common RewriteEngine on </VirtualHost>
-
在/home/ning/www/lxf_test/index.html中寫入
Hello I am dal.api.loc主節點
-
B的apache虛擬主機配置
<VirtualHost 192.168.9.19:8001> DocumentRoot /home/lxf/www ServerName ljdal.loc ErrorLog logs/ljdal-error_log CustomLog logs/ljdal-access_log common </VirtualHost> <VirtualHost 192.168.9.22:8001> DocumentRoot /home/lxf/www ServerName ljdal.loc ErrorLog logs/ljdal-error_log CustomLog logs/ljdal-access_log common </VirtualHost>
五.A/B主機Host配置
192.168.9.145 dal.api.loc
192.168.9.22 ljdal.loc
六.A機安裝beartbeat
sudo apt-get install heartbeat
七.A機最主要的三個文件(如果沒有則自行創建)
/etc/ha.d/authkeys //安全驗證
/etc/ha.d/ha.cf //基本配置
/etc/ha.d/haresources //配置浮動ip以及服務
八.A機 authkeys
配置
- 配置內容:(注意:下面的
HI!
代表秘鑰,可以自行修改),當然還有其他驗證方式可以自行查閱auth 2 2 sha1 HI!
- 修改權限
sudo chmod 600 authkeys
九.A機配置 ha.cf
- 配置內容:
ebugfile /var/log/ha-debug logfile /var/log/ha-log keepalive 2 deadtime 30 warntime 10 initdead 120 udpport 694 logfacility local0 ucast eth0 192.168.9.22 node dal.api.loc node ljdal.loc auto_failback on watchdog /dev/watchdog
- 配置說明
debugfile /var/log/ha-debug:該文件保存heartbeat的調試信息。
logfile /var/log/ha-log:heartbeat的日志文件。
keepalive 2:心跳的時間間隔,默認時間單位為秒s。
deadtime 30:超出該時間間隔未收到對方節點的心跳,則認為對方已經死亡。
warntime 10:超出該時間間隔未收到對方節點的心跳,則發出警告并記錄到日志中。
initdead 60:在某系統上,系統啟動或重啟之后需要經過一段時間網絡才能正常工作,該選項用于解決這種情況產生的時間間隔,取值至少為deadtime的2倍。
udpport 694:設置廣播通信使用的端口,694為默認使用的端口號。
ucast eth1 192.168.9.22:設置對方機器心跳檢測的網卡和IP。
auto_failback on:heartbeat的兩臺主機分別為主節點和從節點。主節點在正常情況下占用資源并運行所有的服務,遇到故障時把資源交給從節點由從節點運行服務。在該選項設為on的情況下,一旦主節點恢復運行,則自動獲取資源并取代從節點,否則不取代從節點。
十.A機haresources
配置
-
配置信息(該配置信息配置后,代表 )
dal.api.loc IPaddr::192.168.9.19/24/eth0:0 apachectl
以上dal.api.loc代表
主節點
,那么配置ha.cf
配置文件中的ljdal.loc
也就自然成為了從節點
;192.168.9.19
代表vip(虛擬ip)/24
表示這個IP掩碼是255.255.255.0, 表示這個地址的前24(也就是IP前三位十進制)位為網絡位eth0:0
代表vip的虛擬網卡設備名apachectl
代表在/etc/init.d/apachectl
的apache服務啟動腳本, 如果有多個服務可以通過空格分割,啟動heartbeat的時候,服務從左向右啟動,關閉heartbeat的時候,服務從右向左關閉;
十一.把主節點A上的三個配置文件拷貝到從節點B
- 基本操作
# cd /etc/ha.d # sudo scp authkeys ha.cf haresources root@192.168.9.22:/etc/ha.d
- 修改從節點B的
ha.cf
的ucast
ucast eth0 192.168.9.145
十二.啟動A節點的 heartbeat
- 啟動順序是:
先主A,后從B
,(當然:先從B,后主A
也可以,只不過啟動B后vip并沒有分配,當啟動A后vip分配到A,后續當A掛掉后,B會自動分配vip)sudo service heartbeat start 或/etc/init.d/eartbeat start
- 啟動A成功后,A會自動將vip
192.168.9.19
配置到linux系統的 eth0:0網卡上
ifconfig
eth0 Link encap:以太網 硬件地址 8c:89:a5:be:08:03
inet 地址:192.168.9.145 廣播:192.168.9.255 掩碼:255.255.255.0
inet6 地址: fe80::8e89:a5ff:febe:803/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 躍點數:1
接收數據包:188574 錯誤:0 丟棄:254 過載:0 幀數:0
發送數據包:108060 錯誤:0 丟棄:0 過載:0 載波:0
碰撞:0 發送隊列長度:1000
接收字節:31455063 (31.4 MB) 發送字節:13805397 (13.8 MB)
eth0:0 Link encap:以太網 硬件地址 8c:89:a5:be:08:03
inet 地址:192.168.9.19 廣播:192.168.9.255 掩碼:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 躍點數:1
-
并且會自動啟動apache
sudo netstat -tunlp | grep 80 tcp6 0 0 :::8001 :::* LISTEN 22679/httpd tcp6 0 0 :::80 :::* LISTEN 22679/httpd
-
這時訪問
http://192.168.9.19:8001/
image.png -
查看A的日志
cat /var/log/ha-log
image.png
十三.啟動B節點的 heartbeat
- 啟動方式與A節點一樣,啟動后會提示:
以上并不是錯誤,個人理解:因為這時候,A節點在接管服務,所以這時候B節點不用分配 vip 地址,如果A節點掛了,這個時候B節點會自動將服務接管過來,下面我們繼續測試;Starting High-Availability services: INFO: Resource is stopped Done.
- 查看B節點的ip,并沒有
eth0:eth0
,因為A節點正常;eth0 Link encap:以太網 硬件地址 68:f7:28:62:bf:47 inet 地址:192.168.9.22 廣播:192.168.9.255 掩碼:255.255.255.0 inet6 地址: fe80::6af7:28ff:fe62:bf47/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 躍點數:1 接收數據包:1848852 錯誤:6 丟棄:0 過載:0 幀數:3 發送數據包:1509616 錯誤:0 丟棄:0 過載:0 載波:0 碰撞:0 發送隊列長度:1000 接收字節:1479395706 (1.4 GB) 發送字節:751655464 (751.6 MB) 中斷:20 Memory:e1300000-e1320000
十四.模擬A節點掛掉
-
關閉A節點上 heartbeat
sudo /etc/init.d/heartbeat stop Stopping High-Availability services: Done.
-
登錄B節點,查看ip,出現
eth0:eth0
vip,代表接管成功,服務又B提供eth0 Link encap:以太網 硬件地址 68:f7:28:62:bf:47 inet 地址:192.168.9.22 廣播:192.168.9.255 掩碼:255.255.255.0 inet6 地址: fe80::6af7:28ff:fe62:bf47/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 躍點數:1 接收數據包:1848852 錯誤:6 丟棄:0 過載:0 幀數:3 發送數據包:1509616 錯誤:0 丟棄:0 過載:0 載波:0 碰撞:0 發送隊列長度:1000 接收字節:1479395706 (1.4 GB) 發送字節:751655464 (751.6 MB) 中斷:20 Memory:e1300000-e1320000 eth0:0 Link encap:以太網 硬件地址 68:f7:28:62:bf:47 inet 地址:192.168.9.19 廣播:192.168.9.255 掩碼:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 躍點數:1 中斷:20 Memory:e1300000-e1320000
如果在分配vip失敗,查看日志:
cat /var/log/ha-logDec 20 02:00:05 centos.a heartbeat: [2905]: info: glib: ucast: write socket priority set to IPTOS_LOWDELAY on eth0 Dec 20 02:00:05 centos.a heartbeat: [2905]: info: glib: ucast: bound send socket to device: eth0 Dec 20 02:00:05 centos.a heartbeat: [2905]: ERROR: glib: ucast: error setting option SO_REUSEPORT(w): Protocol not available
以上錯誤說明是linux版本內核太低,可以使用
廣播
代替單播
,也就是修改ha.cf(A節點與B節點配置一致)bcast eth0 # Linux
-
查看B節點的日志
cat /var/log/ha-log
Dec 19 19:29:20 ljdal.loc heartbeat: [13187]: info: Received shutdown notice from 'dal.api.loc'. Dec 19 19:29:20 ljdal.loc heartbeat: [13187]: info: Resources being acquired from dal.api.loc. Dec 19 19:29:20 ljdal.loc heartbeat: [13246]: info: acquire local HA resources (standby). Dec 19 19:29:20 ljdal.loc heartbeat: [13246]: info: local HA resource acquisition completed (standby). Dec 19 19:29:20 ljdal.loc heartbeat: [13187]: info: Standby resource acquisition done [foreign]. ... mach_down(default)[13287]: 2017/12/19_19:29:20 info: mach_down takeover complete for node dal.api.loc.
-
再次訪問:http://192.168.9.19:8001,發現服務被B接管了
image.png
十五.注意
-
因為heartbeat是通過
udpport 694
的傳輸的,所以在Centos
下要開啟防火墻的 udp 的694
端口,注意如果防火墻配置不好會導致腦裂(也就是A, B主機通信失敗,各自接管資源,防火墻配置:http://m.blog.csdn.net/anonymalias/article/details/8478587)vim /etc/sysconfig/iptables, 加入如下一行 -A RH-Firewall-1-INPUT -p udp -s 192.168.11.202 -m udp --dport 694 -j ACCEPT
重啟 iptables
/etc/init.d/iptables restart
查看防火墻配置是否成功,執行命令:
iptables -L -n
fhq.jpg關閉
selinux
//臨時關閉 setenforce 0 getenforce //出現一下信息代表關閉成功 Permissive
//永久關閉 vim /etc/selinux/config SELINUX=disabled
Centos下安裝請參考
http://www.cnblogs.com/liwei0526vip/p/6391833.html
總結
- heartbeat 重要做兩步,
心跳檢測
和資源接管
- 以上我的例子中的
資源
包含vip分配
和apache服務
,當A掛掉后(A的apache自動關閉,vip丟失),B立即可接管vip分配
和apache服務
的啟動; - 當然我們也可以讓heartbeat只負責管理
vip分配
,不負責管理apache服務
,那么我們的haresources
配置文件的內容就變成了:centos.a IPaddr::192.168.9.19/24/eth0:0
- apache 虛擬主機配置的域名和linux系統
uname -n
的主機名可以不等; -
/etc/hosts
配置的域名指向完全是為了做資源接管
所用;
參考文章:
http://www.cnblogs.com/liwei0526vip/p/6391833.html
http://blog.51cto.com/jerry12356/1855421
http://m.blog.csdn.net/robinson_0612/article/details/49794263