內容簡介
Heartbeat是一款開源程序,負責將集羣基礎設施容量——包括集羣成員與消息收發——交付至客戶服務器。Hearbeat在高可用性服務器基礎設施當中扮演着關鍵性角色。我們通常需要將Heartbeat與Pacemaker等集羣資源管理器(簡稱CRM)相結合,從而實現完整的高可用性設置。不過在今天的教程中,我們將演示如何利用Heartbeat與DigitalOcean Floating IP輕鬆創建一套雙節點高可用性服務器設置。
如果大家希望進一步提升可用性水平,不妨嘗試Corosync與Pacemaker這一組合或者Keepalived。
目標設定
在完成之後,這套高可用性設置將由兩臺Ubuntu 14.04服務器建立的主動/被動配置構成。要實現這項目標,我們需要藉助Floating IP——負責指定用戶訪問服務或者網站的實際方式——以指向主服務器或者說活動服務器,除非其檢測到該服務器存在故障。一旦Hearbeat服務發現主服務器不可用,第二臺服務器將自動運行一套腳本以將Floating IP通過DigitalOcean API重新分配給自己。如此一來,指向Floating IP的後續網絡流量將會被定向至我們的輔助服務器,並在主服務器恢復正常之前由其擔任活動服務器的角色(在主服務器恢復正常後,其同樣會將Floating IP分配給自己以實現切換)。
備註:今天的教程只涉及在網關層級設置主動/被動高可用性體系,其中包含Floating IP以及負載均衡服務器——主服務器與副服務器。此外,出於演示的目的,我們不會爲每臺服務器配置反向代理負載均衡器,而是通過簡單配置使其分別響應對應的主機名與公共IP地址。
爲實現這一目標,我們將採取以下步驟:
- 創建2個Droplet用於接收流量
- 創建Floating IP並將其分別給其中1個Droplet
- 創建DNS A記錄並指向Floating IP(可選)
- 在2個Droplet上安裝Heartbeat
- 配置Heartbeat以運行Floating IP重新分配服務
- 創建Floating IP重新分配服務
- 測試故障轉移效果
先決條件
爲了實現Floating IP的自動重新分配,我們必須使用DigitalOcean API。這意味着大家需要生成一條個人訪問令牌(簡稱PAT),該API令牌能夠用於認證我們的DigitalOcean賬戶,並根據API指南部分《如何生成個人訪問令牌》章節的指導實現讀取與寫入訪問。大家的PAT將通過腳本進行使用,而該腳本則被添加至集羣中的兩臺服務器內,從而確保其安全訪問DIgitalOcean賬戶以供引用。
除了該API,這分教程還將採用以下DigitalOcean元素:
大家可以點擊對應鏈接瞭解更多與之相關的細節信息。
創建Droplet
第一步是在同一數據中心之內創建2個Ubuntu Droplet,二者將分別作爲之前所提到的主、副服務器。在我們的示例設置當中,二者將分別被命名爲“primary”與“secondary”以便於引用。我們將在2個Droplet上分別安裝Nginx並利用其惟一標識信息替換掉其索引頁。通過這種方式,我們能夠輕鬆證明這套高可用性設置是否實際起效。在真實設置當中,大家的服務器應當根據實際需求運行Web服務器或者負載均衡器。
創建2個Ubuntu 14.04 Droplet,分別爲primary與secondary,而以下bash腳本則作爲用戶數據:
用戶數據示例:
#!/bin/bash
apt-get -y update
apt-get -y install nginx
export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
echo Droplet: $HOSTNAME, IP Address: $PUBLIC_IPV4 > /usr/share/nginx/html/index.html
此腳本將安裝Nginx並利用該Droplet的主機名稱與IP地址(通過引用Metadata服務)替換index.html
的內容。在通過公共IP地址進行訪問時,對應Droplet將顯示一套包含該Droplet主機名稱與IP地址的基本頁面,幫助用戶測試任意時段內該Floating
IP指向哪個Droplet。
創建Floating IP
在DigitalOcean控制面板中,點擊頂部菜單中的“Networking”,接下來在後續菜單中選定“Floating IPs”。
爲我們的primary Droplet分配一個Floating IP,而後點擊“Assign Floating IP”按鈕。
在Floating IP分配完成後,通過網絡瀏覽器對該IP進行訪問,以確認其被正確分配至既定Droplet。
http://your_floating_ip
這時大家應該能夠看到自己的primary Droplet索引頁。
配置DNS(可選)
如果大家希望通過域名訪問自己的主可用性設置,則可在DNS當中創建一條A記錄,其負責將域名指向對應的Floating IP地址。如果大家的域名使用DigitalOcean的域名服務器,則可遵循《如何利用DigitalOcean設置一項主機名稱》教程中的第三步指引。設置完成後,大家即可通過該域名訪問自己的活動服務器。
在這裏我們使用的示例域名爲example.com
。如果大家暫時沒有域名可用,則應使用Floating IP地址。
安裝Heartbeat
下一步是在兩臺服務器上安裝Heartbeat。最簡單的Heartbeat安裝方式自然是使用apt-get:
sudo apt-get update
sudo apt-get install heartbeat
Heartbeat現在已經安裝完成,不過我們需要對其進行配置才能讓它正常發揮作用。
配置Heartbeat
爲了保證集羣正常啓動與運行,我們必須在/etc/ha.d目錄下的文件中進行Heartbeat配置——兩臺服務器均採用同樣的配置方式:
- ha.cf: Heartbeat集羣的全局配置,包括其各成員節點。
- authkeys: 添加一個安全密鑰以保證集羣對節點進行驗證。
- haresources: 指定由集羣管理的服務以及作爲該服務持有者的對應節點。需要注意,我們在通過Pacemaker等CRM方案進行設置時無需使用此文件。
我們還需要提供一套腳本,負責在primary Droplet的可用性發生變更時執行Floating IP重新分配。
收集節點信息
在對ha.cf進行配置之前,我們應當首先查看各節點名稱。Heartbeat要求每個節點的名稱與其對應的uname -n
輸出結果相匹配。
在兩臺服務器上運行以下命令,旨在查找對應的節點名稱:
* uname -n
請注意該命令的輸出結果。示例中的節點名稱爲“primary”與“secondary”,與我們的Droplet命名完全匹配。
我們還需要查看各個節點用於同集羣內其它節點進行通信的網絡接口與IP地址,從而瞭解當前哪些節點處於可用狀態。大家可以使用任意網絡接口,只要確保集羣內各節點的相互通信能力即可。在這裏我們使用Droplet的公共接口,恰好爲eth0。
在兩臺服務器上,使用以下命令以查找eth0接口的IP地址(或者通過DigitalOcean控制面板進行查看):
* ip addr show eth0
ip addr show eth0 output:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 04:01:76:a5:45:01 brd ff:ff:ff:ff:ff:ff
inet 104.236.6.11/18 brd 104.236.63.255 scope global eth0
valid_lft forever preferred_lft forever
inet 10.17.0.28/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::601:76ff:fea5:4501/64 scope link
valid_lft forever preferred_lft forever
請注意該網絡接口的IP地址(在本示例中以高亮顯示)。確保獲取兩臺服務器的對應IP地址。
創建ha.cf文件
在兩臺服務器上利用大家熟悉的編輯器打開/etc/ha.d/ha.cf文件。我們在這裏使用vi:
* sudo vi /etc/ha.d/ha.cf
該文件的內容此次應當爲空。我們需要向其中添加集羣內各節點的網絡接口與名稱。
將該配置複製並粘貼到此文件當中,而後利用前面查找到的對應主機名稱與IP地址替換其中的具體值。在本次示例中,primary的IP地址爲104.236.6.11,而secondary的IP地址爲104.236.6.22:
node primary
ucast eth0 104.236.6.11
node secondary
ucast eth0 104.236.6.22
保存並退出。接下來,我們將設置這套集羣的驗證密鑰。
創建authkeys文件
驗證密鑰的作用是允許各集羣成員加入集羣。出於這一目的,我們可以輕鬆創建一條隨機密鑰。
在primary節點當中運行以下命令,從而在名爲AUTHKEY的環境變量當中生成一條合適的驗證密鑰:
if [ -z "${AUTH_KEY}" ]; then
export AUTH_KEY="$(command dd if='/dev/urandom' bs=512 count=1 2>'/dev/null' \
| command openssl sha1 \
| command cut --delimiter=' ' --fields=2)"
fi
後來利用以下命令編寫/etc/ha.d/authkeys 文件:
sudo bash -c "{
echo auth1
echo 1 sha1 $AUTH_KEY
} > /etc/ha.d/authkeys"
通過以下命令檢查該authkeys文件內容:
* sudo cat /etc/ha.d/authkeys
執行結果應該如下所示(只是具體驗證密鑰有所區別):
/etc/ha.d/authkeys example:
auth1
1 sha1 d1e6557e2fcb30ff8d4d3ae65b50345fa46a2faa
確保該文件只可供root讀取:
sudo chmod 600 /etc/ha.d/authkeys
現在將該/etc/ha.d/authkeys 文件從primary節點複製到我們的secondary節點當中。大家可以通過手動方式或者利用scp實現。
在secondary服務器上,確保對該authkeys文件的權限進行設置:
sudo chmod 600 /etc/ha.d/authkeys
現在兩臺服務器應該已經擁有相同的/etc/ha.d/authkeys 文件了。
創建haresources文件
這裏的haresources文件負責指定與集羣所管理的各項服務對應的preferred host。所謂preferred host即首選主機,指服務在對應節點處於可用狀態時應優先選擇的運行選項。如果首選主機不可用,即無法由集羣接入,則另一節點則將接掌其職責。換言之,secondary服務器將在primary服務器發生故障時頂替其角色。
在兩臺服務器上通過大家熟悉的編輯器打開該haresources文件。在這裏我們使用vi:
sudo vi /etc/ha.d/haresources
現在將以下一行添加至該文件中,並將我們自己的primary節點名稱替換進去:
/etc/ha.d/haresources
primary floatip
保存並退出。現在該primary服務器已經被配置爲floatip服務的首選主機,不過floatip服務本身尚未進行定義。因此下一步任務就是設置floatip服務。
創建Floating IP重新分配服務
我們的Heartbeat集羣的配置目標在於保證floatip服務能夠始終正常運行,其中一個節點用於將Floating IP分配給自身。不過這項服務本身也需要單獨創建。在設置服務本體之前,我們首先創建一套腳本,用於通過DigitalOcean API將該Floating IP分配至其運行所在的節點。接下來,我們將創建負責運行該Floating IP重新分配腳本的floatip服務。
創建assign-ip腳本
在示例中,我們將下載一套基礎Python腳本以利用DigitalOcean API向給定Droplet ID分配一個Floating IP。
在兩臺服務器上下載該assign-ip Python腳本:
sudo curl -L -o /usr/local/bin/assign-ip http://do.co/assign-ip
在兩臺服務器上爲其提供執行權限:
sudo chmod +x /usr/local/bin/assign-ip
使用assign-ip腳本還需要注意以下細節:
- Floating IP: 該腳本中的第一項參數,指定需要分配的Floating IP。
- Droplet ID: 該腳本中的第二項參數,指定該Floating IP被分配到的Droplet ID。
- DigitalOcean PAT (API令牌): 作爲環境變量DOTOKEN進行傳遞,即我們的讀取/寫入DigitalOcean PAT。
在進行下一步之前,請大家認真審查這部分腳本內容。
現在我們已經做好了創建floatip服務的一切準備。
創建floatip服務
要創建floatip服務,我們需要首先創建一個init腳本以調用此前編寫完成的assign-ip腳本,同時響應start與stop子命令。該init腳本將負責通過Droplet Metadata服務查找服務器的Droplet ID。另外,該腳本還需要獲取被分配Floating IP以及DigitalOcean API令牌(即我們在先決條件部分中提到過的個人訪問令牌)。
在兩臺服務器上,利用編輯器打開/etc/init.d/floatip :
sudo vi /etc/init.d/floatip
而後將以下內容複製並粘貼到init腳本當中,同時利用大家自己的DigitalOcean API密鑰與需要分配的Floating IP替換其中的高亮部分:
/etc/init.d/floatip
#!/bin/bash
param=$1
export DO_TOKEN='b7d03a6947b217efb6f3ec3bd3504582'
IP='45.55.96.8'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
if [ "start" == "$param" ] ; then
python /usr/local/bin/assign-ip $IP $ID
exit 0
elif [ "stop" == "$param" ] ; then
exit 0;
elif [ "status" == "$param" ] ; then
exit 0;
else
echo "no such command $param"
exit 1;
fi
保存並退出。
爲該腳本提供執行權限。
sudo chmod u+x /etc/init.d/floatip
當該floatip服務啓動時,其會直接調用assign-ip Python腳本並將指定的Floating IP分配至執行該腳本的Droplet。在正常運行情況下,該腳本供secondary服務器使用以將Floating IP分配給自身,從而實現primary服務器的故障轉移能力。同樣的,該腳本亦可在primary重新加入集羣后被其用於將Floating IP重新分配給自身。
啓動Heartbeat
現在Heartbeat已經配置完成,而其運行所需要的全部腳本亦已準備就緒——我們可以馬上啓動這套Heartbeat集羣了!
在兩臺服務器上運行以下命令以啓動Heartbeat:
sudo service heartbeat start
大家應該看到以下輸出結果:
Heartbeat output:
Starting High-Availability services: Done.
我們的高可用性設置已經完成!接下來是對其工作狀態進行測試。
測試高可用性
對高可用性設置的工作狀態進行測試非常重要,因此我們這就着手開始。
目前,該Floating IP被分配至primary節點。我們可以通過IP地址或者指向它的域名對Floating IP加以訪問,並由此查看primary服務器的索引頁面。如果大家使用示例提供的用戶數據腳本,則顯示結果應如下所示:
Floating IP is pointing to primary server
Droplet: primary, IP Address: 104.236.6.11
這意味着該Floating IP實際上被分配至primary Droplet處。
現在讓我們打開終端,並使用curl以1秒循環訪問該Floating IP。大家可使用以下命令實現這一目標,不過請注意將URL部分替換成各位的實際域名或者Floating IP地址:
while true; do curl http://example.com; sleep 1; done
目前其會輸出同樣的Droplet名稱與primary服務器IP地址。如果我們讓primary服務器處於不可用狀態——例如將其關閉或者停止Heartbeat服務,則會看到Floating IP被重新分配至secondary服務器。
現在讓我們關閉primary服務器。大家可以通過DigitalOcean控制面板或者在primary服務器上運行以下命令將其關閉:
sudo poweroff
片刻之後,該primary服務器將不再可用。需要注意運行在終端內的curl循環的輸出結果。大家應該會看到以下輸出內容:
curl loop output:
Droplet: primary, IP Address: 104.236.6.11
...
curl: (7) Failed to connect to example.com port 80: Connection refused
Droplet: secondary, IP Address: 104.236.6.22
Droplet: secondary, IP Address: 104.236.6.22
...
這時Floating IP地址應該被重新分配至secondary服務器的IP地址,也就是說我們的高可用性設置已經正常起效,即成功實現了自動化故障轉移功能。
大家可能會發現一項Connection refused錯誤——當然也可能不會,原因在於大家的Floating IP訪問嘗試發生在primary服務器故障與該Floating IP重新分配完成這兩個事件之間。
現在大家可以通過DigitalOcean控制面板重新啓動自己的primary Droplet。由於Heartbeat在配置當中將primary Droplet作爲preferred host以運行Floating IP重新分配腳本,因此該Floating IP會在可用性恢復後自動重新指向primary服務器。
總結
恭喜大家!現在我們已經擁有了一套利用Heartbeat與DigitalOcean Floating IP實現的基礎高可用性服務器設置。
如果大家希望進一步提高可用性水平,亦可考慮使用Corosync與Pacemaker組合或者Keepalived。
如果大家希望擴展自己的Heartbeat設置,那麼下一步工作就是利用反向代理負載均衡器替代示例中的Nginx設置。大家也可以使用Nginx或者HAProxy實現同樣的效果。需要注意的是,大家需要將該負載均衡器綁定至另一個IP地址,從而確保用戶只能夠通過Floating IP地址訪問服務器(而非通過各服務器的公共IP地址)。
本文源自DigitalOcean Community。英文原文:How To Create a High Availability Setup with Heartbeat and Floating IPs on Ubuntu 14.04 by Mitchell Anicas