前言
軟件負載均衡一般通過兩種方式來實現:基於操作系統的軟負載實現和基於第三方應用的軟負載均衡。LVS是基於Linux操作系統實現的一種軟負載,而Haproxy則是基於第三方應用實現的軟負載。Haproxy相比LVS的使用要簡單很多,但跟LVS一樣,Haproxy自己並不能實現高可用,一旦Haprox節點故障,將會影響整個站點。本文是haprox基於keepalived實現web高可用及動靜分離。
相關介紹
HAProxy
haproxy是一款提供高可用性、負載均衡以及基於TCP和HTTP應用的代理軟件,Haproxy是完全免費的,藉助Haproxy可以快速並且可靠的提供基於TCP和HTTP應用的代理解決方案。Haproxy適用於那些負載較大的Web站點,這些站點通常又需要會話保持或七層出來。Haproxy可以支持數以萬計的併發連接,並且Haproxy的運行模式使得它可以很簡單安全的整合進架構中,同時可以包含web服務器不被暴露在網絡上。
keepalived
keepalived是基於VRRP(virtual router redundancy protocol,虛擬路由冗餘協議)熱備份協議工作的,以軟件的方式實現linux服務器的多機熱備功能。VRRP是針對路由器的一種備份解決方案----由多臺路由器組成一個熱備組。通過共用的虛擬IP地址對外提供服務;每個熱備組內同一時刻只有一臺主服務器提供服務,其他服務器處於冗餘狀態,若當前在線的服務器失敗,其他服務器會自動接替(優先級決定接替順序)虛擬IP地址,以繼續提供服務。
高可用解決方案拓撲
一、測試環境:Centos6.7+Centos7.1;使用5臺虛擬機
分別對他們設置主機名: 主機名 ip地址 軟件包 VIP mail 192.168.5.10 ansible+mysqld node1 192.168.5.11 haproxy+keepalived 192.168.5.9 node2 192.168.5.12 haproxy+keepalived 192.168.5.8 node3 192.168.5.13 lamp node4 192.168.5.14 httpd
二、準備工作:這裏基於ansible做一下簡單部署
1、基於ssh通信,先做密鑰; # ssh-copy-id -i /root/.ssh/id_rsa.pub node1 # ssh-copy-id -i /root/.ssh/id_rsa.pub node2 # ssh-copy-id -i /root/.ssh/id_rsa.pub node3 # ssh-copy-id -i /root/.ssh/id_rsa.pub node4 2、ansible設置及管理節點探測: # cd /etc/ansible/ # vim hosts [haproxy] node1 node2 [dynamic] node3 [p_w_picpaths] node4 # ansible all -m ping node3 | success >> { "changed": false, "ping": "pong" } node1 | success >> { "changed": false, "ping": "pong" } node2 | success >> { "changed": false, "ping": "pong" } node4 | success >> { "changed": false, "ping": "pong" }
三、在node1和node2上安裝haproxy和keepalived
時間同步 # ansible all -m shell -a 'ntpdate cn.pool.ntp.org' # ansible all -m shell -a 'date' 192.168.5.12 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 192.168.5.11 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 192.168.5.13 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 192.168.5.14 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 主機互信 [root@node1 ~]# ssh-keygen -t rsa [root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub node2 [root@node2 ~]# ssh-keygen -t rsa [root@node2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub node1 安裝所需程序 # ansible haproxy -m shell -a 'yum -y install haproxy keepalived' # ansible haproxy -m yum -a 'name=haproxy,keepalived state=present' (兩條命令,任選一條) 1、配置keepalived 在node1節點上修改keepalived [root@node1 keepalived]# cp keepalived.conf{,.bak} [root@node1 keepalived]# ls keepalived.conf keepalived.conf.bak [root@node1 keepalived]# vim keepalived.conf ! Configuration File for keepalived global_defs { #全局設置,設置報警的收件人 notification_email { root@localhost #指定通知的郵箱地址 } notification_email_from root #指定通知郵件時由誰發送的 smtp_server 127.0.0.1 #指定smtp郵件服務器地址 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { #定義VRRP實例,實例名自定義 state MASTER #指定keepalived的角色,MASTER爲主服務器,BACKUP爲備用服務器 interface eth0 #指定HA檢測接口 virtual_router_id 61 #虛擬路由標識(1-255),在一個VRRP實例中主備服務器ID必須一樣 priority 100 #指定優先級,注意,主的一定要比從的優先級數字大 advert_int 5 #指定主備同步時間間隔,單位秒 authentication { #設置驗證類型和密碼 auth_type PASS #驗證類型 auth_pass 1234 #指定認證密碼,同一實例中主備密碼必須一致 } virtual_ipaddress { 192.168.5.9 #指定VIP } } vrrp_instance VI_2 { #定義VRRP實例,實例名自定義 state BACKUP #指定keepalived的角色,MASTER爲主服務器,BACKUP爲備用服務器 interface eth0 #指定HA檢測接口 virtual_router_id 71 #虛擬路由標識(1-255),在一個VRRP實例中主備服務器ID必須一樣 priority 98 #指定優先級,注意,主的一定要比從的優先級數字大 advert_int 5 #指定主備同步時間間隔,單位秒 authentication { #設置驗證類型和密碼 auth_type PASS #驗證類型 auth_pass 2345 #指定認證密碼,同一實例中主備密碼必須一致 } virtual_ipaddress { 192.168.5.8 #指定VIP } } # scp keepalived.conf node2:/etc/keepalived keepalived.conf 100% 515 0.5KB/s 00:00 在node2節點上修改keepalived # cat keepalived.conf ! Configuration File for keepalived global_defs { #全局設置,設置報警的收件人 notification_email { root@localhost #指定通知的郵箱地址 } notification_email_from root #指定通知郵件時由誰發送的 smtp_server 127.0.0.1 #指定smtp郵件服務器地址 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { #定義VRRP實例,實例名自定義 state BACKUP #指定keepalived的角色,MASTER爲主服務器,BACKUP爲備用服務器 interface eth0 #指定HA檢測接口 virtual_router_id 61 #虛擬路由標識(1-255),在一個VRRP實例中主備服務器ID必須一樣 priority 88 #指定優先級,注意,主的一定要比從的優先級數字大 advert_int 5 #指定主備同步時間間隔,單位秒 authentication { #設置驗證類型和密碼 auth_type PASS #驗證類型 auth_pass 1234 #指定認證密碼,同一實例中主備密碼必須一致 } virtual_ipaddress { 192.168.5.9 #指定VIP } } vrrp_instance VI_2 { #定義VRRP實例,實例名自定義 state MASTER #指定keepalived的角色,MASTER爲主服務器,BACKUP爲備用服務器 interface eth0 #指定HA檢測接口 virtual_router_id 71 #虛擬路由標識(1-255),在一個VRRP實例中主備服務器ID必須一樣 priority 100 #指定優先級,注意,主的一定要比從的優先級數字大 advert_int 5 #指定主備同步時間間隔,單位秒 authentication { #設置驗證類型和密碼 auth_type PASS #驗證類型 auth_pass 2345 #指定認證密碼,同一實例中主備密碼必須一致 } virtual_ipaddress { 192.168.5.8 #指定VIP } r } # ansible haproxy -m shell -a 'service keepalived start' node1 | success | rc=0 >> Starting keepalived: [ OK ] node2 | success | rc=0 >> Starting keepalived: [ OK ] # ansible haproxy -m shell -a 'ip addr show' node2 | success | rc=0 >> 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:31:87:be brd ff:ff:ff:ff:ff:ff inet 192.168.5.12/24 brd 192.168.5.255 scope global eth0 inet 192.168.5.8/32 scope global eth0 inet6 fe80::20c:29ff:fe31:87be/64 scope link valid_lft forever preferred_lft forever node1 | success | rc=0 >> 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:8d:8c:c3 brd ff:ff:ff:ff:ff:ff inet 192.168.5.11/24 brd 192.168.5.255 scope global eth0 inet 192.168.5.9/32 scope global eth0 inet6 fe80::20c:29ff:fe8d:8cc3/64 scope link valid_lft forever preferred_lft forever ###可以看出VIP在node1和node2上各一個 2、配置Haproxy 在node1節點上修改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進行歸檔記錄 chroot /var/lib/haproxy #運行的安裝路徑 pidfile /var/run/haproxy.pid #pid文件存放位置 maxconn 4000 #最大連接數 user haproxy #運行程序使用haproxy用戶 group haproxy #運行程序使用haproxy組 daemon #以後臺模式運行haproxy # 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 #工作模式 log global #記錄日誌 option httplog #詳細記錄http日誌 option dontlognull #不記錄健康檢查的日誌信息 option http-server-close #啓用服務器端主動關閉 option forwardfor except 127.0.0.0/8 #傳遞客戶端IP option redispatch retries 3 #請求重試次數 timeout http-request 10s #http請求超時時間 timeout queue 1m #一個請求在隊列裏的超時時間 timeout connect 10s #連接服務器超時時間 timeout client 1m #客戶端超時時間 timeout server 1m #客戶端超時時間 timeout http-keep-alive 10s #持久連接超時時間 timeout check 10s #心跳檢測超市時間 maxconn 3000 #最大連接數 #--------------------------------------------------------------------- # main frontend which proxys to the backends #--------------------------------------------------------------------- frontend proxy *:80 #定義ACL acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js acl url_dynamic path_end -i .php .jsp use_backend dynamic if url_dynamic #調用後端服務器並檢查ACL規則是否被匹配 default_backend static #--------------------------------------------------------------------- # static backend for serving up p_w_picpaths, stylesheets and such #--------------------------------------------------------------------- backend static #後端算法 balance source server static 192.168.5.13:80 inter 1500 rise 2 fall 3 check #--------------------------------------------------------------------- listen statistics mode http #http 7 層模式 bind *:8080 #監聽地址 stats enable #啓用狀態監控 stats auth admin:admin #驗證的用戶與密碼 stats uri /admin?status #訪問路徑 stats hide-version #隱藏狀態頁面版本號 stats admin if TRUE #如果驗證通過了就允許登錄 stats refresh 3s #每3秒刷新一次 acl allow src 192.168.5.0/24 #允許的訪問的IP地址 tcp-request content accept if allow #允許的地址段就允許訪問 tcp-request content reject #拒絕非法連接 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- backend dynamic balance source server synamic 192.168.5.14:80 check inter 1500 rise 2 fall 3 #check inter 1500是檢測心跳頻率 #rise2 2次正確認爲服務器可用 #fall3 3次失敗認爲服務器不可用 將配置文件拷貝到node2上 [root@node1 haproxy]# scp haproxy.cfg node2:/etc/haproxy haproxy.cfg 100% 4737 4.6KB/s 00:00 配置web頁面 ##node3(static)靜態頁面服務器 [root@node3 ~]# yum -y install httpd [root@node3 ~]# echo "node3.bjwf125.com" > /var/www/html/index.html [root@node3 ~]# systemctl start httpd.service ##node4(dynamic)動態服務器 [root@node4 ~]# yum -y install httpd php php-mysql [root@node4 ~]# vim /var/www/html/index.php <h1>node4.bjwf125.com</h> <?php phpinfo(); ?> [root@node4 ~]# systemctl start httpd.service 啓動haproxy # ansible haproxy -m shell -a 'service haproxy start'
查看靜態頁面
查看動態頁面