haproxy+keepalived實現高可用,負載均衡,動靜分離 ...
---恢復內容開始---
一、haproxy介紹:
HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機。HAProxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運行在時下的硬體上,完全可以支持數以萬計的併發連接。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web伺服器不被暴露到網路上。HAProxy實現了一種事件驅動、單一進程模型,此模型支持非常大的併發連接數。多進程或多線程模型受記憶體限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千併發連接。事件驅動模型因為在有更好的資源和時間管理的用戶端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程式通常擴展性較差。這就是為什麼他們必須進行優化以 使每個CPU時間片(Cycle)做更多的工作。
在linux內核版本為2.6或打了epoll補丁的linux2.4上運行haproxy能獲得其最好的性能。
二、keepalived介紹:
keepalived理論工作原理
keepalived可提供vrrp以及health-check功能,可以只用它提供雙機浮動的vip(vrrp虛擬路由功能),這樣可以簡單實現一個雙機熱備高可用功能。
keepalived是一個類似於layer3, 4 & 5交換機制的軟體,也就是我們平時說的第3層、第4層和第5層交換。Keepalived的作用是檢測web 伺服器的狀態。 Layer3,4&5工作在IP/TCP協議棧的IP層,TCP層,及應用層,原理分別如下:
Layer3:Keepalived使用Layer3的方式工作式時,Keepalived會定期向伺服器群中的伺服器 發送一個ICMP的數據包(既我們平時用的Ping程式),如果發現某台服務的IP地址沒有激活,Keepalived便報告這台伺服器失效,並將它從伺服器群中剔除,這種情況的典型例子是某台伺服器被非法關機。Layer3的方式是以伺服器的IP地址是否有效作為伺服器工作正常與否的標準。在本文中將採用這種方式。
Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP埠的狀態來決定伺服器工作正常與否。如web server的服務埠一般是80,如果Keepalived檢測到80埠沒有啟動,則Keepalived將把這台伺服器從伺服器群中剔除。
Layer5:Layer5就是工作在具體的應用層了,比Layer3,Layer4要複雜一點,在網路上占用的帶寬也要大一些。Keepalived將根據用戶的設定檢查伺服器程式的運行是否正常,如果與用戶的設定不相符,則Keepalived將把伺服器從伺服器群中剔除。
vip即虛擬ip,是附在主機網卡上的,即對主機網卡進行虛擬,此IP仍然是占用了此網段的某個IP。
keepalived的用途:
Keepalived是一個基於VRRP協議來實現的WEB 服務高可用方案,可以利用其來避免單點故障。一個WEB服務至少會有2台伺服器運行Keepalived,一臺為主伺服器(MASTER),一臺為備份伺服器(BACKUP),但是對外表現為一個虛擬IP,主伺服器會發送特定的消息給備份伺服器,當備份伺服器收不到這個消息的時候,即主伺服器宕機的時候,備份伺服器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。
在lvs+keepalived高可用負載均衡架構中,lvs本身不支持對後端real server進行健康狀態檢測,而keepalived的誕生不僅能是lvs均衡器實現了高可用,而且還能對lvs後端的real server進行健康狀態檢測。如果有一臺web伺服器死機,或工作出現故障,Keepalived將檢測到,並將有故障的web伺服器從系統中剔除,當web伺服器工作正常後Keepalived自動將web伺服器加入到伺服器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修複故障的web伺服器。
配置過程:
在配置之前,先將HA中個節點進行時間同步,主機名之間相互解析,以及配置雙機互信。
在haproxy1.daixiang.com上配置:
[root@haproxy1 ~]# vim /etc/hosts 172.16.0.1 haproxy1.daixiang.com haproxy1 172.16.0.2 haproxy2.daixiang.com haproxy2
[root@haproxy1 ~]# ssh-keygen -t rsa -P '' [root@haproxy1 ~]# ssh-copy-id haproxy2 [root@haproxy1 ~]# ntpdate s2c.time.edu.cn
在haproxy2.daixiang.com上配置:
[root@haproxy2 ~]# vim /etc/hosts 172.16.0.1 haproxy1.daixiang.com haproxy1 172.16.0.2 haproxy2.daixiang.com haproxy2 [root@haproxy2 ~]# ssh-keygen -t rsa -P '' [root@haproxy2 ~]# ssh-copy-id haproxy1 [root@haproxy2 ~]# ntpdate s2c.time.edu.cn
安裝haproxy和keepalived:
在haproxy1和haproxy2節點上進行同樣的操作:
[root@haproxy1 ~]# yum install keepalived haproxy -y [root@haproxy1 ~]# cd /etc/keepalived/ [root@haproxy1 keepalived]# cp keepalived.conf{,.bak}
配置keepalived:雙主模型
[root@haproxy1 keepalived]# vim keepalived.conf ! Configuration File for keepalived global_defs { notification_email { #定義收件人郵箱 root@localhost } notification_email_from root@localhost #定義發件人郵箱 smtp_server 127.0.0.1 #定義郵件伺服器地址 smtp_connect_timeout 30 #定有郵件伺服器連接超時時長為30秒 router_id LVS_DEVEL #運行keepalive的機器的標識 } vrrp_instance VI_1 { #定義VRRP實例,實例名自定義 state MASTER #指定當前節點的角色,master為主,backup為從 interface eth1 #直接HA監測的介面 virtual_router_id 51 #虛擬路由標識,在同一VRRP實例中,主備伺服器ID必須一樣 priority 100 #定義節點優先順序,數字越大越優先,主伺服器優先順序高於從伺服器 advert_int 1 #設置主備之間永不檢查時間間隔,單位為秒 authentication { 設置主從之間驗證類型和密碼 auth_type PASS auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e } virtual_ipaddress { 192.168.80.200 #定義虛擬ip地址 } } vrrp_instance VI_2 { state BACKUP interface eth1 virtual_router_id 52 priority 99 advert_int 1 authentication { auth_type PASS auth_pass 56f7663077966379d4106e8ee30eb1a5 } virtual_ipaddress { 192.168.80.201 } }View Code
將此配置文件同步到另一個haproxy2.daixiang.com上:
[root@haproxy1 keepalived]# scp keepalived.conf haproxy2:/etc/keepalived/
在haproxy2.daixiang.com上修改keepalived.conf配置文件:
[root@haproxy2 keepalived]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from root@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { state BACKUP interface eth1 virtual_router_id 51 priority 99 advert_int 1 authentication { auth_type PASS auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e } virtual_ipaddress { 192.168.80.200 } } vrrp_instance VI_2 { state MASTER interface eth1 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 56f7663077966379d4106e8ee30eb1a5 } virtual_ipaddress { 192.168.80.201 } }View Code
重啟keepalived:
[root@haproxy1 keepalived]# service keepalived restart [root@haproxy1 keepalived]# ssh haproxy2 'service keepalived restart'
配置haproxy:
先將原始配置文件進行備份:
[root@haproxy1 ~]# cd /etc/haproxy/ [root@haproxy1 haproxy]# cp haproxy.cfg{,.bak} ##節點2也進行同樣的操作
編輯其配置文件修改其內容如下:
[root@haproxy1 haproxy]# vim haproxy.cfg #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global #定義全局配置段 # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 #通過rsyslog將日誌進行歸檔記錄,在/etc/rsyslog.conf配置文件中,添加‘local2.* /var/log/haproxy',並且啟用$ModLoad imudp,$UDPServerRun 514,$ModLoad imtcp,$InputTCPServerRun 514 此四項功能,最後重啟rsyslog進程。 chroot /var/lib/haproxy #指定haproxy進程工作的目錄 pidfile /var/run/haproxy.pid #指定pid文件 maxconn 4000 #最大併發連接數 user haproxy #運行haproxy的用戶 group haproxy #運行haproxy的組 daemon #以守護進程的形式運行,即後臺運行 # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults #預設配置端 mode http #工作模式,源碼包編譯預設為tcp log global #記錄全局日誌 option httplog #詳細記錄http日誌 option dontlognull #不記錄健康檢測的日誌信息 option http-server-close #啟用伺服器端主動關閉功能 option forwardfor except 127.0.0.0/8 #傳遞client端IP至後端real server option redispatch #基於cookie做會話保持時,後端對應存放session的伺服器出現故障時,會話會被重定向至別的伺服器 retries 3 #請求重傳次數 timeout http-request 10s #斷開客戶端連接的時長 timeout queue 1m #一個請求在隊列里的超時時長 timeout connect 10s #設定在haproxy轉發至後端upstream server時等待的超時時長 timeout client 1m #client的一次非活動狀態的超時時長 timeout server 1m #等待伺服器端的非活動的超時時長 timeout http-keep-alive 10s #持久連接超時時長 timeout check 10s #檢查請求連接的超時時長 maxconn 3000 #最大連接數 #--------------------------------------------------------------------- # main frontend which proxys to the backends #--------------------------------------------------------------------- frontend webserver *:80 acl url_static path_beg -i /static /images /javascript /stylesheets #匹配path以/static,/images開始的,且不區分大小寫 acl url_static path_end -i .jpg .gif .png .css .js .html acl url_static hdr_beg(host) -i img. video. download. ftp. imgs. image. acl url_dynamic path_end .php .jsp use_backend static if url_static #滿足名為url_static這條acl規則,則將請求轉發至後端名為static的real server組中去 use_backend dynamic if url_dynamic default_backend static #如果上面所有acl規則都不滿足,將請求轉發到static組中 #--------------------------------------------------------------------- # static backend for serving up images, stylesheets and such #--------------------------------------------------------------------- backend static #定義後端real server組,組名為static balance roundrobin #支持動態權重修改,支持慢啟動 server static_1 172.16.0.100:80 check inter 3000 fall 3 rise 1 maxconn 30000 server static_2 172.16.0.101:80 check inter 3000 fall 3 rise 1 maxconn 30000 server static_Error 172.16.0.1:8080 backup check #當此組中的所有server全部不能提供服務,才將請求調度至此server上 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- backend dynamic cookie cookie_name insert nocache #使用cookie實現session綁定,且不記錄緩存 balance roundrobin server dynamic1 172.16.0.200:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic1 server dynamic2 172.16.0.201:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic2 #定義dynamic組中的server,將此server命名為dynamic2,每隔3000ms檢測一個健康狀態,如果檢測3次都失敗,將此server剔除。在離線的狀態下,只要檢測1次成功,就讓其上線,此server支持最大的併發連接數為1000,cookie的值為dynamic2 listen state # 使用單獨輸出,不需要frontedn調用:定義haproxy的狀態統計頁面 bind *:8001 # 監聽的地址 mode http # http 7層工作模式:對應用層數據做深入分析,因此支持7層的過濾、處理、轉換等機制 stats enable # 開啟統計頁面輸出 stats hide-version # 隱藏狀態頁面版本號 stats uri /haproxyadmin?stats # 指定狀態頁的訪問路徑 stats auth admin:admin # 基於用戶名,密碼驗證。 stats admin if TRUE # 驗證通過時運行登錄。 acl num1 src 192.168.80.0/24 # 定義源地址為192.168.80.0/24網段的acl規則,將其命名為num1 tcp-request content accept if num1 # 如果滿足此規則,則允許訪問 tcp-request content reject # 拒絕其他所有的訪問
將此配置文件同步當另一個haproxy節點上去:
[root@haproxy1 haproxy]# scp haproxy.cfg haproxy2:/etc/haproxy/
重啟haproxy服務:
[root@haproxy1 haproxy]# service haproxy restart [root@haproxy1 haproxy]# ssh haproxy2 'service haproxy restart'
查看這兩個節點獲取ip的情況:
haproxy1.daixiang.com:
[root@haproxy1 ~]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:52:3b:c0 brd ff:ff:ff:ff:ff:ff inet 172.16.0.1/16 brd 172.16.255.255 scope global eth1 inet 192.168.80.200/32 scope global eth1 inet6 fe80::20c:29ff:fe52:3bc0/64 scope link valid_lft forever preferred_lft forever 3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:52:3b:ca brd ff:ff:ff:ff:ff:ff inet 192.168.80.125/24 brd 192.168.80.255 scope global eth0 inet6 fe80::20c:29ff:fe52:3bca/64 scope link valid_lft forever preferred_lft forever [root@haproxy1 ~]#View Code
haproxy2.daixiang.com:
[root@haproxy2 haproxy]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ae:5c:b3 brd ff:ff:ff:ff:ff:ff inet 192.168.80.128/24 brd 192.168.80.255 scope global eth0 inet6 fe80::20c:29ff:feae:5cb3/64 scope link valid_lft forever preferred_lft forever 6: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:ae:5c:a9 brd ff:ff:ff:ff:ff:ff inet 172.16.0.2/16 brd 172.16.255.255 scope global eth1 inet 192.168.80.201/32 scope global eth1 inet6 fe80::20c:29ff:feae:5ca9/64 scope link valid_lft forever preferred_lft foreverView Code
在後端的real server提供測試頁面,測試的結果如下:
請求以.html結尾的文件,haproxy將請求代理至後端static組中的server處理:
請求以.php結尾的文件,haproxy將請求代理至後端dynamic組中server處理:
註意:本文在haproxy.cfg的配置文件中,將dynamic組中的server配置了基於cookie的session綁定,所以,用同一瀏覽器看不出負載均衡的效果來。換個瀏覽器再訪問一次或者清空瀏覽器的cookie記錄就能顯示效果,如下圖。
haproxy的統計頁面輸出效果:
至此,實驗完結,但是對於haproxy的兩個節點,keepalived對於這兩節點是怎麼進行心跳檢測,其工作原理是什麼,此知識點比較模糊,求大神賜教。
---恢復內容結束---