在前面的一篇中講到了Heartbeat做爲高可用服務架構的解決方案,今天有試驗了一種全新的解決方案,即採用Keepalived來實現這個功能。前端
Keepalived 是一種高性能的服務器高可用或熱備解決方案,Keepalived能夠用來防止服務器單點故障(單點故障是指一旦某一點出現故障就會致使整個系統架構的不可用)的發生,經過配合Nginx能夠實現web前端服務的高可用。node
Keepalived實現的基礎是VRRP協議,Keepalived就是巧用VRRP協議來實現高可用性(HA)的.nginx
VRRP(Virtual Router Redundancy Protocol)協議是用於實現路由器冗餘的協議,VRRP協議將兩臺或多臺路由器設備虛擬成一個設備,對外提供虛擬路由器IP(一個或多個),而在路由器組內部,若是實際擁有這個對外IP的路由器若是工做正常的話就是MASTER,或者是經過算法選舉產生,MASTER實現針對虛擬路由器IP的各類網絡功能,如ARP請求,ICMP,以及數據的轉發等;其餘設備不擁有該IP,狀態是BACKUP,除了接收MASTER的VRRP狀態通告信息外,不執行對外的網絡功能。當主機失效時,BACKUP將接管原先MASTER的網絡功能。web
VRRP協議使用多播數據來傳輸VRRP數據,VRRP數據使用特殊的虛擬源MAC地址發送數據而不是自身網卡的MAC地址,VRRP運行時只有MASTER路由器定時發送VRRP通告信息,表示MASTER工做正常以及虛擬路由器IP(組),BACKUP只接收VRRP數據,不發送數據,若是必定時間內沒有接收到MASTER的通告信息,各BACKUP將宣告本身成爲MASTER,發送通告信息,從新進行MASTER選舉狀態。算法
安裝keepalived以前,也要安裝一些依賴庫bash
安裝 openssl服務器
yum install openssl*網絡
安裝popt架構
yum install popt*負載均衡
安裝ipvsadm
yum isntall ipvsadm
安裝libnl-dev
yum install libnl-dev*
keepalived安裝包地址:
下載解壓後編譯配置
./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 #開機啓動服務
接下來就是配置了,很簡單,直接上配置文件
先是主服務器:
global_defs
{ notification_email #通知email,根據實際狀況配置 { admin@example.com } notification_email_from admin@example.com 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 { admin@example.com } notification_email_from admin@example.com 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 { admin@example.com } notification_email_from admin@example.com 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
配置完成後就能夠運行看下效果了,分別在主從服務器上啓動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