前幾天使用了Heartbeat作爲高可用服務架構的解決方案,今天有試驗了一種全新的解決方案,即採用Keepalived來實現這個功能。
Keepalived 是一種高性能的服務器高可用或熱備解決方案,Keepalived可以用來防止服務器單點故障(單點故障是指一旦某一點出現故障就會導致整個系統架構的不可用)的發生,通過配合Nginx可以實現web前端服務的高可用。
Keepalived實現的基礎是VRRP協議,Keepalived就是巧用VRRP協議來實現高可用性(HA)的.
VRRP(Virtual Router Redundancy Protocol)協議是用於實現路由器冗餘的協議,VRRP協議將兩臺或多臺路由器設備虛擬成一個設備,對外提供虛擬路由器IP(一個或多個),而在路由器組內部,如果實際擁有這個對外IP的路由器如果工作正常的話就是MASTER,或者是通過算法選舉產生,MASTER實現針對虛擬路由器IP的各種網絡功能,如ARP請求,ICMP,以及數據的轉發等;其他設備不擁有該IP,狀態是BACKUP,除了接收MASTER的VRRP狀態通告信息外,不執行對外的網絡功能。當主機失效時,BACKUP將接管原先MASTER的網絡功能。
VRRP協議使用多播數據來傳輸VRRP數據,VRRP數據使用特殊的虛擬源MAC地址發送數據而不是自身網卡的MAC地址,VRRP運行時只有MASTER路由器定時發送VRRP通告信息,表示MASTER工作正常以及虛擬路由器IP(組),BACKUP只接收VRRP數據,不發送數據,如果一定時間內沒有接收到MASTER的通告信息,各BACKUP將宣告自己成爲MASTER,發送通告信息,重新進行MASTER選舉狀態。
1. 安裝Keeplived依賴
安裝keepalived之前,也要安裝一些依賴庫
安裝 openssl
yum install openssl*
安裝popt
yum install popt*
安裝ipvsadm
yum isntall ipvsadm
安裝libnl-dev
yum install libnl-dev*
2. 安裝Keepalived
keepalived安裝包地址:
http://www.keepalived.org/software/keepalived-1.2.7.tar.gz
下載解壓後編譯配置
./configure --prefix=/usr/local/keepalived
編譯配置需要確保一下幾項爲Yes狀態:
Use IPVS Framework : Yes IPVS sync daemon support : Yes IPVS use libnl : Yes Use VRRP Framework : Yes
然後就可以編譯安裝了:
make && make install
因爲沒有使用keepalived的默認路徑安裝(默認是/usr/local),安裝完成之後,需要做一些工作
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
#複製keepalived啓動文件到默認路徑,也可以通過設置環境變量的path實現
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
#複製服務啓動腳本到,以便可以通過service控制keepalived服務
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
#複製keepalived服務腳本到默認的地址,也通過修改init.d/keepalived文件中的相應配置實現
mkdir -p /etc/etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
vi /etc/keepalived/keepalived.conf
#複製默認配置文件到默認路徑,其實也可以在/etc/init.d/keepalived中設置路徑
chkconfig keepalived on
#開機啓動服務
3. 配置Keepalived
接下來就是配置了,很簡單,直接上配置文件
先是主服務器:
global_defs
{
notification_email #通知email,根據實際情況配置
{
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
stmp_connect_timeout 30
router_id node1 #節點名標識,主要用於通知中
}
vrrp_instance VI_NODE {
state MASTER #配置爲主服務器
interface eth0 #通訊網卡
virtual_router_id 100 #路由標識
priority 200 #優先級,0-254
advert_int 5 #通知間隔,實際部署時可以設置小一點,減少延時
authentication {
auth_type PASS
auth_pass 123456 #驗證密碼,用於通訊主機間驗證
}
virtual_ipaddress {
192.168.1.206 #虛擬ip,可以定義多個
}
}
接下是從服務器設置:
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
stmp_connect_timeout 30
router_id node2
}
vrrp_instance VI_NODE {
state BACKUP #與主服務器對應
interface eth0 #從服務器的通信網卡
virtual_router_id 100 #路由標識,和主服務器相同
priority 100 #優先級,小於主服務器即可
advert_int 5 #這裏是接受通知間隔,與主服務器要設置相同
authentication {
auth_type PASS
auth_pass 123456 #驗證密碼,與主服務器相同
}
virtual_ipaddress {
192.168.1.206 #虛擬IP,也要和主服務器相同
}
}
上面的設置是最基礎的設置,實現的功能是如果主服務器的Keepalived停止服務(一般情況下服務器宕機),則將虛擬IP切換至從服務器,主服務器恢復後從新切換回主服務器。
但是很多情況下我們面臨的處境是nginx掛掉了,而這個時候Keepalived就不能發揮作用,這時候就需要我們來改良下Keepalived了。通過向Keepalived添加一個自定義腳本來監控neginx的運行狀態,如果nginx進程結束,則kill Keepalived進程,以此來達到主從服務器的切換功能。
我們在修改上面配置的主服務器的配置文件,在中間添加腳本實現
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id nginx_master
}
vrrp_script chk_http_port {
script "/usr/local/keepalived/nginx.sh" #在這裏添加腳本鏈接
interval 3 #腳本執行間隔
weight 2 #腳本結果導致的優先級變更
}
vrrp_instance VI_NODE {
state MASTER
interface eth0
virtual_router_id 100
priority 200
advert_int 5
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_http_port #添加腳本執行
}
virtual_ipaddress {
192.168.1.206
}
}
具體的配置可以參考另一篇文章Keepalived配置詳解
如果我們使用了LVS+Keepalived集成,那麼keepalived可以代替ipvsadm來配置LVS,可以方便的通過配置就可以搞定,這在另一篇文章Keepalived+LVS配置詳解
修改完配置文件我們寫我們的上面配置的nginx.sh,當然我們假定Nginx已經安裝完成
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
killall keepalived
fi
上面的腳本簡單的查看nginx進程是否存在,不存在就kill keepalived進程。
接下來我們對上面的哦腳本修改一下,當腳本檢測到nginx沒有運行的時候會嘗試去啓動nginx以此,如果失敗則停掉keepalived進程
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx #nginx命令的路徑
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
把腳本保存到上面配置的具體路徑(我這裏是/usr/local/keepalived),然後很重要的一步是修改腳本的執行權限
chmod +x nginx.sh
4. 運行Keepalived
配置完成後就可以運行看下效果了,分別在主從服務器上啓動nginx和keepalived
service keepalived start
啓動之後通過·ip a·命令查看主服務器的網絡信息,可以看到在eth0網卡下生成了192.168.1.206這個虛擬ip,並可通過這個ip訪問到nginx
然後我們關閉nginx的進程(如果配置了一次嘗試重啓那要注意下),然後我們可以通過ps -e查看keepalived進程是否關閉,正常情況下查看網絡信息中,可以看到eth0網卡下的虛擬ip已經解除,然後在從服務器的網絡信息中可以看到從服務器的eth0網卡綁定了虛擬ip,通過這個ip就訪問到了從服務器的nginx去了,這是我們重新啓動主服務器的nginx和keepalieved,我們可以發現虛擬ip就綁回到了主服務器。
這樣就實現了基本雙擊主從熱備功能了。
這裏注意下防火牆的問題,就是這問題困擾了我很久。找了一些資料纔將問題解決
因爲Keepalived之間是通過組播來通知對方的是否存活,以及發送優先級的,並且通過組播來選舉MASTER的,而224.0.0.18就是常用的組播地址,防火牆開啓允許這個組播地址通信就可以了:
1.如果用的是默認防火牆,只需要添加:
iptables -I RH-Firewall-1-INPUT -d 224.0.0.18 -j ACCEPT
2.如果是自己用腳本設置的防火牆,需要添加如下規則
iptables -A OUTPUT -o eth0 -d 224.0.0.18 -j ACCEPT iptables -A OUTPUT -o eth0 -s 224.0.0.18 -j ACCEPT iptables -A INPUT -i eth0 -d 224.0.0.18 -j ACCEPT iptables -A INPUT -i eth0 -s 224.0.0.18 -j ACCEPT
5. 總結
- keepalived通過虛擬路由實現雙機熱備,相比其他方案具有一定的優越性
- 因爲是固定主從熱備,該方案比較適合兩個互備服務器性能有差異的情況
- Keepalived同樣可以實現雙主互備,通過設置互爲主備,然後通過DNS負載均衡到不同vip就可以實現