1、場景
假使你有一套系統部署在一臺Linux機器上,這套系統執行的業務對你來說是相當重要的,要是某天系統崩潰了,業務會中斷,將帶來不可估量的損失。這時你會想,能不能部署兩臺機器,業務還是由其中一臺機器執行,要是這臺機器崩潰了,另一臺機器能自動接管業務呢。
keepalived採用的是虛擬IP的實現方式,恰好能滿足以上場景,這也是本文介紹的重點。
你可能會問,爲什麼讓另一臺機空閒,多浪費資源啊,直接用nginx實現負載均衡不是更好嗎?沒錯,優秀的程序員應該避免資源浪費。但是如果你的業務同一時間只能由一個實例執行呢,是不是nginx愛莫能助了?或者你有更好的實現方法,不妨留言分享下?謝謝。
2、虛擬IP原理
虛擬IP。何爲虛擬IP,就是一個未分配給真實主機的IP,也就是說對外提供服務的主機除了有一個真實IP外還有一個虛擬IP,使用這兩個IP中的任意一個都可以連接到這臺主機,當服務器發生故障無法對外提供服務時,動態將這個虛擬IP切換到備用主機。
虛擬IP實現原理主要是靠TCP/IP的ARP協議。因爲IP地址只是一個邏輯地址,在以太網中MAC地址纔是真正用來進行數據傳輸的物理地址,每臺主機中都有一個ARP高速緩存,存儲同一個網絡內的IP地址與MAC地址的對應關係,以太網中的主機發送數據時會先從這個緩存中查詢目標IP對應的MAC地址,會向這個MAC地址發送數據。操作系統會自動維護這個緩存。這就是整個實現 的關鍵。
3、舉例說明
假設我安裝並配置好keepalived後,過程順利,keepalived正常工作,下邊是服務器上的arp緩存的內容。(192.168.1.219) at 00:21:5A:DB:68:E8 [ether] on bond0
(192.168.1.217) at 00:21:5A:DB:68:E8 [ether] on bond0
(192.168.1.218) at 00:21:5A:DB:7F:C2 [ether] on bond0
192.168.1.217、192.168.1.218是兩臺真實的電腦,192.168.1.217爲對外提供數據庫服務的主機,192.168.1.218爲熱備的機器。
192.168.1.219爲虛擬IP。
大家注意,219、217的MAC地址是相同的。
現在我讓217宕機,之後的arp緩存如下:(192.168.1.219) at 00:21:5A:DB:7F:C2 [ether] on bond0
(192.168.1.217) at 00:21:5A:DB:68:E8 [ether] on bond0
(192.168.1.218) at 00:21:5A:DB:7F:C2 [ether] on bond0
這就是奧妙所在。當218 發現217宕機後會向網絡發送一個ARP數據包,告訴所有主機192.168.1.219這個IP對應的MAC地址是00:21:5A:DB:7F:C2,這樣所有發送到219的數據包都會發送到mac地址爲00:21:5A:DB:7F:C2的機器,也就是218的機器。而發現夥伴出問題,並廣播ARP數據包的工作正是keepalived做的。
4、安裝keepalived
在CentOS系統下安裝keepalived可使用如下命令:
yum install keepalived
本文不提供其它版本的系統或其它方式的安裝方法。另外需要注意的是,keepalived沒有windows版本。
5、測試系統的準備
當前手上有兩臺服務器,信息如下:
服務器A:192.168.14.132
服務器B:192.168.14.133
兩臺服務器都部署了一個測試網站並啓動順利。
訪問服務器A的測試頁:http://192.168.14.132:8080/WebTest/keepalived.html
訪問服務器B的測試頁:http://192.168.14.133:8080/WebTest/keepalived.html
6、配置
現在我把服務器A配置成MASTER,而服務器B配置成BACKUP。虛擬IP定爲:192.168.14.100
6.1、keepalived.conf文件配置
MASTER配置(/etc/keepalived/keepalived.conf):
/bin/bash: Configuration: command not found
bal_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost //這裏沒有使用keepalived的郵件通知服務,聽說郵件通知還是用監控軟件好。
smtp_server localhost
smtp_connect_timeout 30
router_id NodeA //當前服務器的ID
}
vrrp_script chk_maintainace { //定義一個健康檢查的腳本,用以告訴keepalived當前系統是否是健康的
script "/etc/keepalived/health_check.sh"
interval 3 //3秒執行一次檢查
weight -10 //如果腳本執行失敗,priority會相應減少,就會造成降級
}
vrrp_instance VI_1 {
state MASTER //主服務器
interface eno16777736 //配置成系統上網卡的名字
virtual_router_id 51
priority 100 //優先級,必須比備機上的大
advert_int 1
authentication { //郵件通知的配置
auth_type PASS
auth_pass specialpassword
}
virtual_ipaddress { //虛擬IP,如果當前系統獲取擁有虛擬IP的權限,就會向網卡添加如下虛擬IP,其中24是掩碼
192.168.14.100/24
}
track_script { //健康檢查的腳本
chk_maintainace
}
}
BACKUP配置(/etc/keepalived/keepalived.conf):
/bin/bash: Configuration: command not found
bal_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id NodeB
}
vrrp_script chk_maintainace {
script "/etc/keepalived/health_check.sh"
interval 3
weight -10
}
vrrp_instance VI_1 {
state BACKUP
interface eno16777736
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass specialpassword
}
virtual_ipaddress {
192.168.14.100/24
}
track_script {
chk_maintainace
}
}
6.2、Health check腳本文件配置
#!/bin/bash
count=$(ps aux | grep -v grep | grep tomcat | wc -l)
if [ $count -gt 0 ]
then
exit 0
else
exit 1
fi
本作者試過編輯腳本爲檢查業務系統的某個頁面或接口是否是200的http狀態,而單獨執行腳本則驗證通過,放到keepalived上則不能正常工作,實在不知道是什麼問題。
7、啓動keepalived服務
啓動服務命令:
service keepalived start
建議查找資料將服務做成開機自動運行。
檢查服務是否正常啓動敲如下命令查看日誌:
journalctl -xe
正常的日誌大體如下:
同樣服務器B也這樣啓動服務。
8、高可用測試
讓一臺服務器不健康,可kill掉keepalived進程或者kill掉tomcat進程,又或者直接關機。
8.1、服務器A和服務器B均健康
訪問http://192.168.14.100:8080/WebTest/keepalived.html:
8.2、服務器A不健康,服務器B健康
8.3、服務器A健康,服務器B不健康
9、拓展
你是否覺得,keepalived結合nginx使用更令人振奮呢。