對於負載均衡器來講,經常使用的有硬件解決方案,如CitrixNetscaler,F5Bigip,還有軟件級別的解決方案,如對於大型網站來講的LVS,對於流量不是很大的網站來講,HAproxy還有Nginx,而HAproxy+Keepalived能夠達到億pv/日,並且還很是穩定,因此對於中小企業來講是個不錯的選擇。javascript
Keepalived是常見的高可用解決方案之一,原創的目的是爲了LVSDirectorServer的高可用,固然也可也用於其餘服務的高可用,如nginx,HAProxy等服務,Keepaliaved使用VRRP協議,使得虛擬IP和虛擬MAC在可個物理節點間流動。一樣經過腳本能夠使得其餘資源在各節點上流動。css
Keepalived主要有兩個進程,一個爲VRRP負責資源的遷移,另一個爲Checkers.負責健康狀態的檢查,還有一個watchDog的進程,負責監控VRRP和Checkers是否存活。前端
咱們來實現一下HAProxy與雙主keepalived結合java
ROLEnginx |
IPredis |
HostName算法 |
虛擬ipvim |
172.16.11.15後端 172.16.11.16bash |
|
HAProxy節點1 |
172.16.11.12eth0 |
ha1.sysbo.net |
HAProxy節點2 |
172.16.11.13eth0 |
ha2.sysbo.net |
後端nginx節點1(靜態) |
172.16.11.21 |
rs1.sysbo.net |
後端nginx節點2(動態) |
172.16.11.22 |
rs2.sysbo.net |
後端nginx節點3(動態) |
172.16.11.23 |
rs3.sysbo.net |
下面是拓撲圖
先來解釋下,爲何要雙主keepalived,怎樣實現雙主keepalived
對於這個架構來講,keepalived的虛擬IP就是暴露在最外邊給客戶端訪問的,因此使用在DNS添加上兩個A記錄,能夠用負載均衡的做用,兩臺keepalived主機互爲主備,即添加了可用性又有負載均衡的做用,而實現的過程僅僅是添加兩個實例就能夠了。
在來看下下面所定義的代碼中,keepalived的工做流程,有圖有真相
在每一個節點/etc/hosts文件中添加以下行
172.16.11.12 ha1 ha1.sysbo.net 172.16.11.13 ha2 ha2.sysbo.net 192.168.0.1 rs1 rs1.sysbo.net 192.168.0.2 rs2 rs2.sysbo.net 192.168.0.3 rs3 rs3.sysbo.net
在ha1和ha2中開啓端口轉發
[root@ha1 ~]# vim /etc/sysctl.conf net.ipv4.ip_forward = 1 [root@ha1 ~]# sysctl –p
在ha1和ha2中安裝keepavlived
[root@ha1 ~]# yum install keepalived –y [root@ha1 ~]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { sysadmin@sysbo.net //定義收件人,別忘了加上你主管的名字哦 } notification_email_from ha@sysbo.net //定義發件人郵箱 smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_script chk_haproxy{ //檢查haproxy是否存活的腳本 script "killall -0 haproxy" //killall -0 是代價最低的 interval 1 //檢查頻率 weight -2 //檢查失敗,權重-2 } vrrp_instance VI_1 { //定義第一個實例 state MASTER //這個主機在這個實例中爲主節點 interface eth0 //通知端口 virtual_router_id 59 //每一個實例有不一樣的vitrual_route id,這個是虛擬MAC地址的最後一位 priority 100 //優先級 100,優先級大的就會被選爲MASTER advert_int 1 //通告時間 authentication { //驗證選項 auth_type PASS //使用與共享祕鑰驗證 auth_pass 1111 //與共享祕鑰 } virtual_ipaddress { //定義虛擬ip 172.16.11.15/16 dev eth0 label eth0:0 //漂移的虛擬ip地址將會在eth0:0 上 } track_script { //定義在這個實例中使用的腳本 chk_haproxy } modify_master "/etc/keepalived/notify.sh master" //若是檢測到此節點變爲了master/etc/keepalived/notify.sh ,而且給一個master參數 modify_backup "/etc/keepalived/notify.sh backup" modify_fault "/etc/keepalived/notify.sh fault" } vrrp_instance VI_2 { state BACKUP //注意,在實例2中,此節點爲BACKUP interface eth0 virtual_router_id 60 //與上面不一樣哦,不一樣的虛擬ip對應不一樣的MAC地址 priority 99 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.11.16/16 dev eth0 label eth0:0 } track_script { chk_haproxy} modify_master "/etc/keepalived/notify2.sh master" modify_backup "/etc/keepalived/notify2.sh backup" modify_fault "/etc/keepalived/notify2.sh fault" }
定義故障通知腳本/etc/keepalived/notify.sh
#!/bin/bash vip=172.16.11.15 //notify.sh對應vrrp_INSTANCE V1_1,對應v1_2再複製一份與此相同的腳本,VIP=172.16.11.16 便可 contact='root@localhost' notify() { mailsubject="`hostname` to be $1: $vip floating" mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1" echo $mailbody | mail -s "$mailsubject" $contact } case "$1" in master) notify master /etc/rc.d/init.d/haproxy start exit 0 ;; backup) notify backup /etc/rc.d/init.d/haproxy restart //若是服務宕掉,他會重啓 exit 0 ;; fault) notify fault exit 0 ;; *) echo 'Usage: `basename $0` {master|backup|fault}' exit 1 ;; esac
複製上面內容至ha2
[root@ha1 keepalived]# scp keepalived.conf ha2:/etc/keepalived/ [root@ha1 keepalived]# scp notify.sh ha2:/etc/keepalived/ [root@ha1 keepalived]# scp notify2.sh ha2:/etc/keepalived/
修改ha2中的內容
vrrp_instance VI_1 state BACKUP //此節點實例1爲BACKUP priority 99 //相應優先級爲99 vrrp_instance VI_2 state MASTER //此節點實例2爲MASTER priority 100 //相應優先級爲100
至此雙主keepalived部署完成
咱們接着部署HAproxy
兩個節點都安裝haproxy
[root@ha1 ~]# yum install haproxy –y haproxy的配置文件通常分爲全局配置(global),代理配置(defaults, frontend, backend, listen) [root@ha1 ~]# vim /etc/haproxy/haproxy.cfg global log 127.0.0.1 local2 //log日誌信息發往127.0.0.1 facility 爲local2 chroot /var/lib/haproxy //是否使用chroot pidfile /var/run/haproxy.pid //pid 文件存放位置 maxconn 4000 //每一個haproxy 進程能夠接受最大的併發鏈接數,等於命令選項 「-n」 「ulimit –n」自動計算的結果會參照此值得設定 user haproxy group haproxy daemon //獨立守護進程 # turn on stats unix socket stats socket /var/lib/haproxy/stats defaults //默認選項,若是沒有作特殊說明就按着這個選項執行 mode http //默認工做在7層http log global //使用全局日誌 option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 30000 listen stats //使用狀態通告 mode http bind 0.0.0.0:1080 stats enable stats hide-version stats uri /haproxyadmin?stats //uri地址 stats realm Haproxy\ Statistics stats auth admin:admin //帳號和密碼 stats admin if TRUE frontend http-in //前端選項 bind *:80 //默認綁定80端口 mode http log global option httpclose //支持長鏈接,服務器端關閉 option logasap option dontlognull capture request header Host len 20 //抓取請求報文的前20字節 capture request header Referer len 60 acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheet //定義acl規則,若是請求uri開始 爲/static /p_w_picpaths /javascript /stylesheet 就符合此此規則,此規則不區分大小寫,此規則的名字叫 url_static acl url_static path_end -i .jpg .jpeg .gif .png .css .js //定義acl規則,若是請求uri的結束符爲.jpg jpeg gif .png css .js將符合此規則,此規則不區分大小寫,此規則名字也叫 url_static use_backend static_servers if url_static //若是請求內容符合acl url_static 則將內容發往static_server default_backend dynamic_servers //其餘發往dynmic_servers,這樣就實現了動靜分離 backend static_servers //定義靜態服務器組 balance roundrobin //是用roundrobin 輪訓算法 server rs1 172.16.11.21:80 check maxconn 6000 //imgsrv1 是這個後端靜態服務器的名字,對應的IP爲192.168.0.1,使用80端口,最大鏈接數爲6000 backend dynamic_servers //定義動態服務器 balance source server rs2 172.16.11.22:80 check maxconn 1000 server rs3 192.16.11.23:80 check maxconn 1000
在生產環境中動態服務器應該部署同樣的東西,靜態服務器應該是圖片,css樣式表等
ha1
ha2
最後要寫明白的一點怎樣保持用戶seesion,對於DNS,原本就有TTL值能夠保證用戶解析到同一IP,而對於haproxy,backend中使用的souce算法,也保證使其始終發往同一服務器。
至此HAproxy+雙主Keepalived就告一段落,我還會繼續努力,作最好的本身